Thu Mar 3 05:51:27 2022 UTC ()
usbnet drivers: No need for usbnet_busy in uno_mcast.

This callback always runs with IFNET_LOCK held, and during a task
that usbnet_detach prevents scheduling anew and waits for finishing
before completing the detach, so there is no need to hang onto a
reference count here.


(riastradh)
diff -r1.135 -r1.136 src/sys/dev/usb/if_axe.c
diff -r1.77 -r1.78 src/sys/dev/usb/if_axen.c
diff -r1.95 -r1.96 src/sys/dev/usb/if_cue.c
diff -r1.108 -r1.109 src/sys/dev/usb/if_kue.c
diff -r1.11 -r1.12 src/sys/dev/usb/if_mos.c
diff -r1.67 -r1.68 src/sys/dev/usb/if_mue.c
diff -r1.75 -r1.76 src/sys/dev/usb/if_smsc.c
diff -r1.82 -r1.83 src/sys/dev/usb/if_udav.c
diff -r1.82 -r1.83 src/sys/dev/usb/if_url.c
diff -r1.44 -r1.45 src/sys/dev/usb/if_ure.c

cvs diff -r1.135 -r1.136 src/sys/dev/usb/if_axe.c (switch to unified diff)

--- src/sys/dev/usb/if_axe.c 2022/03/03 05:51:17 1.135
+++ src/sys/dev/usb/if_axe.c 2022/03/03 05:51:27 1.136
@@ -1,1349 +1,1347 @@ @@ -1,1349 +1,1347 @@
1/* $NetBSD: if_axe.c,v 1.135 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_axe.c,v 1.136 2022/03/03 05:51:27 riastradh Exp $ */
2/* $OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */ 2/* $OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg@openbsd.org> 5 * Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg@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/* 20/*
21 * Copyright (c) 1997, 1998, 1999, 2000-2003 21 * Copyright (c) 1997, 1998, 1999, 2000-2003
22 * Bill Paul <wpaul@windriver.com>. All rights reserved. 22 * Bill Paul <wpaul@windriver.com>. All rights reserved.
23 * 23 *
24 * Redistribution and use in source and binary forms, with or without 24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions 25 * modification, are permitted provided that the following conditions
26 * are met: 26 * are met:
27 * 1. Redistributions of source code must retain the above copyright 27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer. 28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright 29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the 30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution. 31 * documentation and/or other materials provided with the distribution.
32 * 3. All advertising materials mentioning features or use of this software 32 * 3. All advertising materials mentioning features or use of this software
33 * must display the following acknowledgement: 33 * must display the following acknowledgement:
34 * This product includes software developed by Bill Paul. 34 * This product includes software developed by Bill Paul.
35 * 4. Neither the name of the author nor the names of any co-contributors 35 * 4. Neither the name of the author nor the names of any co-contributors
36 * may be used to endorse or promote products derived from this software 36 * may be used to endorse or promote products derived from this software
37 * without specific prior written permission. 37 * without specific prior written permission.
38 * 38 *
39 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 39 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
40 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 42 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
43 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 43 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
44 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 44 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
45 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 45 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
46 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 46 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
49 * THE POSSIBILITY OF SUCH DAMAGE. 49 * THE POSSIBILITY OF SUCH DAMAGE.
50 */ 50 */
51 51
52/* 52/*
53 * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver. 53 * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver.
54 * Used in the LinkSys USB200M and various other adapters. 54 * Used in the LinkSys USB200M and various other adapters.
55 * 55 *
56 * Written by Bill Paul <wpaul@windriver.com> 56 * Written by Bill Paul <wpaul@windriver.com>
57 * Senior Engineer 57 * Senior Engineer
58 * Wind River Systems 58 * Wind River Systems
59 */ 59 */
60 60
61/* 61/*
62 * The AX88172 provides USB ethernet supports at 10 and 100Mbps. 62 * The AX88172 provides USB ethernet supports at 10 and 100Mbps.
63 * It uses an external PHY (reference designs use a RealTek chip), 63 * It uses an external PHY (reference designs use a RealTek chip),
64 * and has a 64-bit multicast hash filter. There is some information 64 * and has a 64-bit multicast hash filter. There is some information
65 * missing from the manual which one needs to know in order to make 65 * missing from the manual which one needs to know in order to make
66 * the chip function: 66 * the chip function:
67 * 67 *
68 * - You must set bit 7 in the RX control register, otherwise the 68 * - You must set bit 7 in the RX control register, otherwise the
69 * chip won't receive any packets. 69 * chip won't receive any packets.
70 * - You must initialize all 3 IPG registers, or you won't be able 70 * - You must initialize all 3 IPG registers, or you won't be able
71 * to send any packets. 71 * to send any packets.
72 * 72 *
73 * Note that this device appears to only support loading the station 73 * Note that this device appears to only support loading the station
74 * address via autoload from the EEPROM (i.e. there's no way to manually 74 * address via autoload from the EEPROM (i.e. there's no way to manually
75 * set it). 75 * set it).
76 * 76 *
77 * (Adam Weinberger wanted me to name this driver if_gir.c.) 77 * (Adam Weinberger wanted me to name this driver if_gir.c.)
78 */ 78 */
79 79
80/* 80/*
81 * Ax88178 and Ax88772 support backported from the OpenBSD driver. 81 * Ax88178 and Ax88772 support backported from the OpenBSD driver.
82 * 2007/02/12, J.R. Oldroyd, fbsd@opal.com 82 * 2007/02/12, J.R. Oldroyd, fbsd@opal.com
83 * 83 *
84 * Manual here: 84 * Manual here:
85 * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf 85 * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf
86 * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf 86 * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf
87 */ 87 */
88 88
89#include <sys/cdefs.h> 89#include <sys/cdefs.h>
90__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.135 2022/03/03 05:51:17 riastradh Exp $"); 90__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.136 2022/03/03 05:51:27 riastradh Exp $");
91 91
92#ifdef _KERNEL_OPT 92#ifdef _KERNEL_OPT
93#include "opt_usb.h" 93#include "opt_usb.h"
94#include "opt_net_mpsafe.h" 94#include "opt_net_mpsafe.h"
95#endif 95#endif
96 96
97#include <sys/param.h> 97#include <sys/param.h>
98 98
99#include <dev/usb/usbnet.h> 99#include <dev/usb/usbnet.h>
100#include <dev/usb/usbhist.h> 100#include <dev/usb/usbhist.h>
101#include <dev/usb/if_axereg.h> 101#include <dev/usb/if_axereg.h>
102 102
103struct axe_type { 103struct axe_type {
104 struct usb_devno axe_dev; 104 struct usb_devno axe_dev;
105 uint16_t axe_flags; 105 uint16_t axe_flags;
106}; 106};
107 107
108struct axe_softc { 108struct axe_softc {
109 struct usbnet axe_un; 109 struct usbnet axe_un;
110 110
111 /* usbnet:un_flags values */ 111 /* usbnet:un_flags values */
112#define AX178 __BIT(0) /* AX88178 */ 112#define AX178 __BIT(0) /* AX88178 */
113#define AX772 __BIT(1) /* AX88772 */ 113#define AX772 __BIT(1) /* AX88772 */
114#define AX772A __BIT(2) /* AX88772A */ 114#define AX772A __BIT(2) /* AX88772A */
115#define AX772B __BIT(3) /* AX88772B */ 115#define AX772B __BIT(3) /* AX88772B */
116#define AXSTD_FRAME __BIT(12) 116#define AXSTD_FRAME __BIT(12)
117#define AXCSUM_FRAME __BIT(13) 117#define AXCSUM_FRAME __BIT(13)
118 118
119 uint8_t axe_ipgs[3]; 119 uint8_t axe_ipgs[3];
120 uint8_t axe_phyaddrs[2]; 120 uint8_t axe_phyaddrs[2];
121 uint16_t sc_pwrcfg; 121 uint16_t sc_pwrcfg;
122 uint16_t sc_lenmask; 122 uint16_t sc_lenmask;
123 123
124}; 124};
125 125
126#define AXE_IS_178_FAMILY(un) \ 126#define AXE_IS_178_FAMILY(un) \
127 ((un)->un_flags & (AX178 | AX772 | AX772A | AX772B)) 127 ((un)->un_flags & (AX178 | AX772 | AX772A | AX772B))
128 128
129#define AXE_IS_772(un) \ 129#define AXE_IS_772(un) \
130 ((un)->un_flags & (AX772 | AX772A | AX772B)) 130 ((un)->un_flags & (AX772 | AX772A | AX772B))
131 131
132#define AXE_IS_172(un) (AXE_IS_178_FAMILY(un) == 0) 132#define AXE_IS_172(un) (AXE_IS_178_FAMILY(un) == 0)
133 133
134#define AX_RXCSUM \ 134#define AX_RXCSUM \
135 (IFCAP_CSUM_IPv4_Rx | \ 135 (IFCAP_CSUM_IPv4_Rx | \
136 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | \ 136 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | \
137 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx) 137 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx)
138 138
139#define AX_TXCSUM \ 139#define AX_TXCSUM \
140 (IFCAP_CSUM_IPv4_Tx | \ 140 (IFCAP_CSUM_IPv4_Tx | \
141 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx | \ 141 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx | \
142 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx) 142 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx)
143 143
144/* 144/*
145 * AXE_178_MAX_FRAME_BURST 145 * AXE_178_MAX_FRAME_BURST
146 * max frame burst size for Ax88178 and Ax88772 146 * max frame burst size for Ax88178 and Ax88772
147 * 0 2048 bytes 147 * 0 2048 bytes
148 * 1 4096 bytes 148 * 1 4096 bytes
149 * 2 8192 bytes 149 * 2 8192 bytes
150 * 3 16384 bytes 150 * 3 16384 bytes
151 * use the largest your system can handle without USB stalling. 151 * use the largest your system can handle without USB stalling.
152 * 152 *
153 * NB: 88772 parts appear to generate lots of input errors with 153 * NB: 88772 parts appear to generate lots of input errors with
154 * a 2K rx buffer and 8K is only slightly faster than 4K on an 154 * a 2K rx buffer and 8K is only slightly faster than 4K on an
155 * EHCI port on a T42 so change at your own risk. 155 * EHCI port on a T42 so change at your own risk.
156 */ 156 */
157#define AXE_178_MAX_FRAME_BURST 1 157#define AXE_178_MAX_FRAME_BURST 1
158 158
159 159
160#ifdef USB_DEBUG 160#ifdef USB_DEBUG
161#ifndef AXE_DEBUG 161#ifndef AXE_DEBUG
162#define axedebug 0 162#define axedebug 0
163#else 163#else
164static int axedebug = 0; 164static int axedebug = 0;
165 165
166SYSCTL_SETUP(sysctl_hw_axe_setup, "sysctl hw.axe setup") 166SYSCTL_SETUP(sysctl_hw_axe_setup, "sysctl hw.axe setup")
167{ 167{
168 int err; 168 int err;
169 const struct sysctlnode *rnode; 169 const struct sysctlnode *rnode;
170 const struct sysctlnode *cnode; 170 const struct sysctlnode *cnode;
171 171
172 err = sysctl_createv(clog, 0, NULL, &rnode, 172 err = sysctl_createv(clog, 0, NULL, &rnode,
173 CTLFLAG_PERMANENT, CTLTYPE_NODE, "axe", 173 CTLFLAG_PERMANENT, CTLTYPE_NODE, "axe",
174 SYSCTL_DESCR("axe global controls"), 174 SYSCTL_DESCR("axe global controls"),
175 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 175 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
176 176
177 if (err) 177 if (err)
178 goto fail; 178 goto fail;
179 179
180 /* control debugging printfs */ 180 /* control debugging printfs */
181 err = sysctl_createv(clog, 0, &rnode, &cnode, 181 err = sysctl_createv(clog, 0, &rnode, &cnode,
182 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 182 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
183 "debug", SYSCTL_DESCR("Enable debugging output"), 183 "debug", SYSCTL_DESCR("Enable debugging output"),
184 NULL, 0, &axedebug, sizeof(axedebug), CTL_CREATE, CTL_EOL); 184 NULL, 0, &axedebug, sizeof(axedebug), CTL_CREATE, CTL_EOL);
185 if (err) 185 if (err)
186 goto fail; 186 goto fail;
187 187
188 return; 188 return;
189fail: 189fail:
190 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 190 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
191} 191}
192 192
193#endif /* AXE_DEBUG */ 193#endif /* AXE_DEBUG */
194#endif /* USB_DEBUG */ 194#endif /* USB_DEBUG */
195 195
196#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(axedebug,1,FMT,A,B,C,D) 196#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(axedebug,1,FMT,A,B,C,D)
197#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(axedebug,N,FMT,A,B,C,D) 197#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(axedebug,N,FMT,A,B,C,D)
198#define AXEHIST_FUNC() USBHIST_FUNC() 198#define AXEHIST_FUNC() USBHIST_FUNC()
199#define AXEHIST_CALLED(name) USBHIST_CALLED(axedebug) 199#define AXEHIST_CALLED(name) USBHIST_CALLED(axedebug)
200 200
201/* 201/*
202 * Various supported device vendors/products. 202 * Various supported device vendors/products.
203 */ 203 */
204static const struct axe_type axe_devs[] = { 204static const struct axe_type axe_devs[] = {
205 { { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE2000 }, 0 }, 205 { { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE2000 }, 0 },
206 { { USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2 }, 0 }, 206 { { USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2 }, 0 },
207 { { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET }, AX772 }, 207 { { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET }, AX772 },
208 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172 }, 0 }, 208 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172 }, 0 },
209 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772 }, AX772 }, 209 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772 }, AX772 },
210 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772A }, AX772 }, 210 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772A }, AX772 },
211 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B }, AX772B }, 211 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B }, AX772B },
212 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B_1 }, AX772B }, 212 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B_1 }, AX772B },
213 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178 }, AX178 }, 213 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178 }, AX178 },
214 { { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T }, 0 }, 214 { { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T }, 0 },
215 { { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055 }, AX178 }, 215 { { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055 }, AX178 },
216 { { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR }, 0}, 216 { { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR }, 0},
217 { { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2 }, AX772A }, 217 { { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2 }, AX772A },
218 { { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0 }, 218 { { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0 },
219 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100 }, 0 }, 219 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100 }, 0 },
220 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1 }, AX772 }, 220 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1 }, AX772 },
221 { { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DUBE100B1 }, AX772 }, 221 { { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DUBE100B1 }, AX772 },
222 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100C1 }, AX772B }, 222 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100C1 }, AX772B },
223 { { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E }, 0 }, 223 { { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E }, 0 },
224 { { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2 }, AX178 }, 224 { { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2 }, AX178 },
225 { { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1 }, 0 }, 225 { { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1 }, 0 },
226 { { USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_ETHERNET }, AX772B }, 226 { { USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_ETHERNET }, AX772B },
227 { { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_HG20F9 }, AX772B }, 227 { { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_HG20F9 }, AX772B },
228 { { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M }, 0 }, 228 { { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M }, 0 },
229 { { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000 }, AX178 }, 229 { { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000 }, AX178 },
230 { { USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LAN_GTJU2 }, AX178 }, 230 { { USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LAN_GTJU2 }, AX178 },
231 { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2GT }, AX178 }, 231 { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2GT }, AX178 },
232 { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX }, 0 }, 232 { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX }, 0 },
233 { { USB_VENDOR_MSI, USB_PRODUCT_MSI_AX88772A }, AX772 }, 233 { { USB_VENDOR_MSI, USB_PRODUCT_MSI_AX88772A }, AX772 },
234 { { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120 }, 0 }, 234 { { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120 }, 0 },
235 { { USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS }, AX772 }, 235 { { USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS }, AX772 },
236 { { USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T }, AX178 }, 236 { { USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T }, AX178 },
237 { { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029 }, 0 }, 237 { { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029 }, 0 },
238 { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028 }, AX178 }, 238 { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028 }, AX178 },
239 { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN031 }, AX178 }, 239 { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN031 }, AX178 },
240 { { USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL }, 0 }, 240 { { USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL }, 0 },
241}; 241};
242#define axe_lookup(v, p) ((const struct axe_type *)usb_lookup(axe_devs, v, p)) 242#define axe_lookup(v, p) ((const struct axe_type *)usb_lookup(axe_devs, v, p))
243 243
244static const struct ax88772b_mfb ax88772b_mfb_table[] = { 244static const struct ax88772b_mfb ax88772b_mfb_table[] = {
245 { 0x8000, 0x8001, 2048 }, 245 { 0x8000, 0x8001, 2048 },
246 { 0x8100, 0x8147, 4096 }, 246 { 0x8100, 0x8147, 4096 },
247 { 0x8200, 0x81EB, 6144 }, 247 { 0x8200, 0x81EB, 6144 },
248 { 0x8300, 0x83D7, 8192 }, 248 { 0x8300, 0x83D7, 8192 },
249 { 0x8400, 0x851E, 16384 }, 249 { 0x8400, 0x851E, 16384 },
250 { 0x8500, 0x8666, 20480 }, 250 { 0x8500, 0x8666, 20480 },
251 { 0x8600, 0x87AE, 24576 }, 251 { 0x8600, 0x87AE, 24576 },
252 { 0x8700, 0x8A3D, 32768 } 252 { 0x8700, 0x8A3D, 32768 }
253}; 253};
254 254
255static int axe_match(device_t, cfdata_t, void *); 255static int axe_match(device_t, cfdata_t, void *);
256static void axe_attach(device_t, device_t, void *); 256static void axe_attach(device_t, device_t, void *);
257 257
258CFATTACH_DECL_NEW(axe, sizeof(struct axe_softc), 258CFATTACH_DECL_NEW(axe, sizeof(struct axe_softc),
259 axe_match, axe_attach, usbnet_detach, usbnet_activate); 259 axe_match, axe_attach, usbnet_detach, usbnet_activate);
260 260
261static void axe_uno_stop(struct ifnet *, int); 261static void axe_uno_stop(struct ifnet *, int);
262static void axe_uno_mcast(struct ifnet *); 262static void axe_uno_mcast(struct ifnet *);
263static int axe_uno_init(struct ifnet *); 263static int axe_uno_init(struct ifnet *);
264static int axe_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 264static int axe_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
265static int axe_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 265static int axe_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
266static void axe_uno_mii_statchg(struct ifnet *); 266static void axe_uno_mii_statchg(struct ifnet *);
267static void axe_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 267static void axe_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
268 uint32_t); 268 uint32_t);
269static unsigned axe_uno_tx_prepare(struct usbnet *, struct mbuf *, 269static unsigned axe_uno_tx_prepare(struct usbnet *, struct mbuf *,
270 struct usbnet_chain *); 270 struct usbnet_chain *);
271 271
272static void axe_ax88178_init(struct axe_softc *); 272static void axe_ax88178_init(struct axe_softc *);
273static void axe_ax88772_init(struct axe_softc *); 273static void axe_ax88772_init(struct axe_softc *);
274static void axe_ax88772a_init(struct axe_softc *); 274static void axe_ax88772a_init(struct axe_softc *);
275static void axe_ax88772b_init(struct axe_softc *); 275static void axe_ax88772b_init(struct axe_softc *);
276 276
277static const struct usbnet_ops axe_ops = { 277static const struct usbnet_ops axe_ops = {
278 .uno_stop = axe_uno_stop, 278 .uno_stop = axe_uno_stop,
279 .uno_mcast = axe_uno_mcast, 279 .uno_mcast = axe_uno_mcast,
280 .uno_read_reg = axe_uno_mii_read_reg, 280 .uno_read_reg = axe_uno_mii_read_reg,
281 .uno_write_reg = axe_uno_mii_write_reg, 281 .uno_write_reg = axe_uno_mii_write_reg,
282 .uno_statchg = axe_uno_mii_statchg, 282 .uno_statchg = axe_uno_mii_statchg,
283 .uno_tx_prepare = axe_uno_tx_prepare, 283 .uno_tx_prepare = axe_uno_tx_prepare,
284 .uno_rx_loop = axe_uno_rx_loop, 284 .uno_rx_loop = axe_uno_rx_loop,
285 .uno_init = axe_uno_init, 285 .uno_init = axe_uno_init,
286}; 286};
287 287
288static usbd_status 288static usbd_status
289axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf) 289axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
290{ 290{
291 AXEHIST_FUNC(); AXEHIST_CALLED(); 291 AXEHIST_FUNC(); AXEHIST_CALLED();
292 struct usbnet * const un = &sc->axe_un; 292 struct usbnet * const un = &sc->axe_un;
293 usb_device_request_t req; 293 usb_device_request_t req;
294 usbd_status err; 294 usbd_status err;
295 295
296 usbnet_isowned_core(un); 296 usbnet_isowned_core(un);
297 297
298 if (usbnet_isdying(un)) 298 if (usbnet_isdying(un))
299 return -1; 299 return -1;
300 300
301 DPRINTFN(20, "cmd %#jx index %#jx val %#jx", cmd, index, val, 0); 301 DPRINTFN(20, "cmd %#jx index %#jx val %#jx", cmd, index, val, 0);
302 302
303 if (AXE_CMD_DIR(cmd)) 303 if (AXE_CMD_DIR(cmd))
304 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 304 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
305 else 305 else
306 req.bmRequestType = UT_READ_VENDOR_DEVICE; 306 req.bmRequestType = UT_READ_VENDOR_DEVICE;
307 req.bRequest = AXE_CMD_CMD(cmd); 307 req.bRequest = AXE_CMD_CMD(cmd);
308 USETW(req.wValue, val); 308 USETW(req.wValue, val);
309 USETW(req.wIndex, index); 309 USETW(req.wIndex, index);
310 USETW(req.wLength, AXE_CMD_LEN(cmd)); 310 USETW(req.wLength, AXE_CMD_LEN(cmd));
311 311
312 err = usbd_do_request(un->un_udev, &req, buf); 312 err = usbd_do_request(un->un_udev, &req, buf);
313 if (err) 313 if (err)
314 DPRINTF("cmd %jd err %jd", cmd, err, 0, 0); 314 DPRINTF("cmd %jd err %jd", cmd, err, 0, 0);
315 315
316 return err; 316 return err;
317} 317}
318 318
319static int 319static int
320axe_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 320axe_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
321{ 321{
322 AXEHIST_FUNC(); AXEHIST_CALLED(); 322 AXEHIST_FUNC(); AXEHIST_CALLED();
323 struct axe_softc * const sc = usbnet_softc(un); 323 struct axe_softc * const sc = usbnet_softc(un);
324 usbd_status err; 324 usbd_status err;
325 uint16_t data; 325 uint16_t data;
326 326
327 DPRINTFN(30, "phy %#jx reg %#jx\n", phy, reg, 0, 0); 327 DPRINTFN(30, "phy %#jx reg %#jx\n", phy, reg, 0, 0);
328 328
329 if (un->un_phyno != phy) 329 if (un->un_phyno != phy)
330 return EINVAL; 330 return EINVAL;
331 331
332 axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 332 axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
333 333
334 err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &data); 334 err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &data);
335 axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); 335 axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
336 336
337 if (err) { 337 if (err) {
338 device_printf(un->un_dev, "read PHY failed\n"); 338 device_printf(un->un_dev, "read PHY failed\n");
339 return EIO; 339 return EIO;
340 } 340 }
341 341
342 *val = le16toh(data); 342 *val = le16toh(data);
343 if (AXE_IS_772(un) && reg == MII_BMSR) { 343 if (AXE_IS_772(un) && reg == MII_BMSR) {
344 /* 344 /*
345 * BMSR of AX88772 indicates that it supports extended 345 * BMSR of AX88772 indicates that it supports extended
346 * capability but the extended status register is 346 * capability but the extended status register is
347 * reserved for embedded ethernet PHY. So clear the 347 * reserved for embedded ethernet PHY. So clear the
348 * extended capability bit of BMSR. 348 * extended capability bit of BMSR.
349 */ 349 */
350 *val &= ~BMSR_EXTCAP; 350 *val &= ~BMSR_EXTCAP;
351 } 351 }
352 352
353 DPRINTFN(30, "phy %#jx reg %#jx val %#jx", phy, reg, *val, 0); 353 DPRINTFN(30, "phy %#jx reg %#jx val %#jx", phy, reg, *val, 0);
354 354
355 return 0; 355 return 0;
356} 356}
357 357
358static int 358static int
359axe_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 359axe_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
360{ 360{
361 struct axe_softc * const sc = usbnet_softc(un); 361 struct axe_softc * const sc = usbnet_softc(un);
362 usbd_status err; 362 usbd_status err;
363 uint16_t aval; 363 uint16_t aval;
364 364
365 if (un->un_phyno != phy) 365 if (un->un_phyno != phy)
366 return EINVAL; 366 return EINVAL;
367 367
368 aval = htole16(val); 368 aval = htole16(val);
369 369
370 axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 370 axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
371 err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &aval); 371 err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &aval);
372 axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); 372 axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
373 373
374 if (err) 374 if (err)
375 return EIO; 375 return EIO;
376 return 0; 376 return 0;
377} 377}
378 378
379static void 379static void
380axe_uno_mii_statchg(struct ifnet *ifp) 380axe_uno_mii_statchg(struct ifnet *ifp)
381{ 381{
382 AXEHIST_FUNC(); AXEHIST_CALLED(); 382 AXEHIST_FUNC(); AXEHIST_CALLED();
383 383
384 struct usbnet * const un = ifp->if_softc; 384 struct usbnet * const un = ifp->if_softc;
385 struct axe_softc * const sc = usbnet_softc(un); 385 struct axe_softc * const sc = usbnet_softc(un);
386 struct mii_data *mii = usbnet_mii(un); 386 struct mii_data *mii = usbnet_mii(un);
387 int val, err; 387 int val, err;
388 388
389 if (usbnet_isdying(un)) 389 if (usbnet_isdying(un))
390 return; 390 return;
391 391
392 val = 0; 392 val = 0;
393 if (AXE_IS_172(un)) { 393 if (AXE_IS_172(un)) {
394 if (mii->mii_media_active & IFM_FDX) 394 if (mii->mii_media_active & IFM_FDX)
395 val |= AXE_MEDIA_FULL_DUPLEX; 395 val |= AXE_MEDIA_FULL_DUPLEX;
396 } else { 396 } else {
397 if (mii->mii_media_active & IFM_FDX) { 397 if (mii->mii_media_active & IFM_FDX) {
398 val |= AXE_MEDIA_FULL_DUPLEX; 398 val |= AXE_MEDIA_FULL_DUPLEX;
399 if (mii->mii_media_active & IFM_ETH_TXPAUSE) 399 if (mii->mii_media_active & IFM_ETH_TXPAUSE)
400 val |= AXE_178_MEDIA_TXFLOW_CONTROL_EN; 400 val |= AXE_178_MEDIA_TXFLOW_CONTROL_EN;
401 if (mii->mii_media_active & IFM_ETH_RXPAUSE) 401 if (mii->mii_media_active & IFM_ETH_RXPAUSE)
402 val |= AXE_178_MEDIA_RXFLOW_CONTROL_EN; 402 val |= AXE_178_MEDIA_RXFLOW_CONTROL_EN;
403 } 403 }
404 val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC; 404 val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
405 if (un->un_flags & AX178) 405 if (un->un_flags & AX178)
406 val |= AXE_178_MEDIA_ENCK; 406 val |= AXE_178_MEDIA_ENCK;
407 switch (IFM_SUBTYPE(mii->mii_media_active)) { 407 switch (IFM_SUBTYPE(mii->mii_media_active)) {
408 case IFM_1000_T: 408 case IFM_1000_T:
409 val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK; 409 val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK;
410 usbnet_set_link(un, true); 410 usbnet_set_link(un, true);
411 break; 411 break;
412 case IFM_100_TX: 412 case IFM_100_TX:
413 val |= AXE_178_MEDIA_100TX; 413 val |= AXE_178_MEDIA_100TX;
414 usbnet_set_link(un, true); 414 usbnet_set_link(un, true);
415 break; 415 break;
416 case IFM_10_T: 416 case IFM_10_T:
417 usbnet_set_link(un, true); 417 usbnet_set_link(un, true);
418 break; 418 break;
419 } 419 }
420 } 420 }
421 421
422 DPRINTF("val=%#jx", val, 0, 0, 0); 422 DPRINTF("val=%#jx", val, 0, 0, 0);
423 err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL); 423 err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
424 if (err) 424 if (err)
425 device_printf(un->un_dev, "media change failed\n"); 425 device_printf(un->un_dev, "media change failed\n");
426} 426}
427 427
428static void 428static void
429axe_rcvfilt_locked(struct usbnet *un) 429axe_rcvfilt_locked(struct usbnet *un)
430{ 430{
431 AXEHIST_FUNC(); AXEHIST_CALLED(); 431 AXEHIST_FUNC(); AXEHIST_CALLED();
432 struct axe_softc * const sc = usbnet_softc(un); 432 struct axe_softc * const sc = usbnet_softc(un);
433 struct ifnet * const ifp = usbnet_ifp(un); 433 struct ifnet * const ifp = usbnet_ifp(un);
434 struct ethercom *ec = usbnet_ec(un); 434 struct ethercom *ec = usbnet_ec(un);
435 struct ether_multi *enm; 435 struct ether_multi *enm;
436 struct ether_multistep step; 436 struct ether_multistep step;
437 uint16_t rxmode; 437 uint16_t rxmode;
438 uint32_t h = 0; 438 uint32_t h = 0;
439 uint8_t mchash[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 439 uint8_t mchash[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
440 440
441 if (usbnet_isdying(un)) 441 if (usbnet_isdying(un))
442 return; 442 return;
443 443
444 if (axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode)) { 444 if (axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode)) {
445 device_printf(un->un_dev, "can't read rxmode"); 445 device_printf(un->un_dev, "can't read rxmode");
446 return; 446 return;
447 } 447 }
448 rxmode = le16toh(rxmode); 448 rxmode = le16toh(rxmode);
449 449
450 rxmode &= 450 rxmode &=
451 ~(AXE_RXCMD_ALLMULTI | AXE_RXCMD_PROMISC | AXE_RXCMD_MULTICAST); 451 ~(AXE_RXCMD_ALLMULTI | AXE_RXCMD_PROMISC | AXE_RXCMD_MULTICAST);
452 452
453 ETHER_LOCK(ec); 453 ETHER_LOCK(ec);
454 if (ifp->if_flags & IFF_PROMISC) { 454 if (ifp->if_flags & IFF_PROMISC) {
455 ec->ec_flags |= ETHER_F_ALLMULTI; 455 ec->ec_flags |= ETHER_F_ALLMULTI;
456 ETHER_UNLOCK(ec); 456 ETHER_UNLOCK(ec);
457 /* run promisc. mode */ 457 /* run promisc. mode */
458 rxmode |= AXE_RXCMD_ALLMULTI; /* ??? */ 458 rxmode |= AXE_RXCMD_ALLMULTI; /* ??? */
459 rxmode |= AXE_RXCMD_PROMISC; 459 rxmode |= AXE_RXCMD_PROMISC;
460 goto update; 460 goto update;
461 } 461 }
462 ec->ec_flags &= ~ETHER_F_ALLMULTI; 462 ec->ec_flags &= ~ETHER_F_ALLMULTI;
463 ETHER_FIRST_MULTI(step, ec, enm); 463 ETHER_FIRST_MULTI(step, ec, enm);
464 while (enm != NULL) { 464 while (enm != NULL) {
465 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 465 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
466 ec->ec_flags |= ETHER_F_ALLMULTI; 466 ec->ec_flags |= ETHER_F_ALLMULTI;
467 ETHER_UNLOCK(ec); 467 ETHER_UNLOCK(ec);
468 /* accept all mcast frames */ 468 /* accept all mcast frames */
469 rxmode |= AXE_RXCMD_ALLMULTI; 469 rxmode |= AXE_RXCMD_ALLMULTI;
470 goto update; 470 goto update;
471 } 471 }
472 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 472 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
473 mchash[h >> 29] |= 1U << ((h >> 26) & 7); 473 mchash[h >> 29] |= 1U << ((h >> 26) & 7);
474 ETHER_NEXT_MULTI(step, enm); 474 ETHER_NEXT_MULTI(step, enm);
475 } 475 }
476 ETHER_UNLOCK(ec); 476 ETHER_UNLOCK(ec);
477 if (h != 0) 477 if (h != 0)
478 rxmode |= AXE_RXCMD_MULTICAST; /* activate mcast hash filter */ 478 rxmode |= AXE_RXCMD_MULTICAST; /* activate mcast hash filter */
479 axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, mchash); 479 axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, mchash);
480 update: 480 update:
481 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 481 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
482} 482}
483 483
484static void 484static void
485axe_ax_init(struct usbnet *un) 485axe_ax_init(struct usbnet *un)
486{ 486{
487 struct axe_softc * const sc = usbnet_softc(un); 487 struct axe_softc * const sc = usbnet_softc(un);
488 488
489 int cmd = AXE_178_CMD_READ_NODEID; 489 int cmd = AXE_178_CMD_READ_NODEID;
490 490
491 if (un->un_flags & AX178) { 491 if (un->un_flags & AX178) {
492 axe_ax88178_init(sc); 492 axe_ax88178_init(sc);
493 } else if (un->un_flags & AX772) { 493 } else if (un->un_flags & AX772) {
494 axe_ax88772_init(sc); 494 axe_ax88772_init(sc);
495 } else if (un->un_flags & AX772A) { 495 } else if (un->un_flags & AX772A) {
496 axe_ax88772a_init(sc); 496 axe_ax88772a_init(sc);
497 } else if (un->un_flags & AX772B) { 497 } else if (un->un_flags & AX772B) {
498 axe_ax88772b_init(sc); 498 axe_ax88772b_init(sc);
499 return; 499 return;
500 } else { 500 } else {
501 cmd = AXE_172_CMD_READ_NODEID; 501 cmd = AXE_172_CMD_READ_NODEID;
502 } 502 }
503 503
504 if (axe_cmd(sc, cmd, 0, 0, un->un_eaddr)) { 504 if (axe_cmd(sc, cmd, 0, 0, un->un_eaddr)) {
505 aprint_error_dev(un->un_dev, 505 aprint_error_dev(un->un_dev,
506 "failed to read ethernet address\n"); 506 "failed to read ethernet address\n");
507 } 507 }
508} 508}
509 509
510 510
511static void 511static void
512axe_reset(struct usbnet *un) 512axe_reset(struct usbnet *un)
513{ 513{
514 514
515 usbnet_isowned_core(un); 515 usbnet_isowned_core(un);
516 516
517 if (usbnet_isdying(un)) 517 if (usbnet_isdying(un))
518 return; 518 return;
519 519
520 /* 520 /*
521 * softnet_lock can be taken when NET_MPAFE is not defined when calling 521 * softnet_lock can be taken when NET_MPAFE is not defined when calling
522 * if_addr_init -> if_init. This doesn't mix well with the 522 * if_addr_init -> if_init. This doesn't mix well with the
523 * usbd_delay_ms calls in the init routines as things like nd6_slowtimo 523 * usbd_delay_ms calls in the init routines as things like nd6_slowtimo
524 * can fire during the wait and attempt to take softnet_lock and then 524 * can fire during the wait and attempt to take softnet_lock and then
525 * block the softclk thread meaning the wait never ends. 525 * block the softclk thread meaning the wait never ends.
526 */ 526 */
527#ifndef NET_MPSAFE 527#ifndef NET_MPSAFE
528 /* XXX What to reset? */ 528 /* XXX What to reset? */
529 529
530 /* Wait a little while for the chip to get its brains in order. */ 530 /* Wait a little while for the chip to get its brains in order. */
531 DELAY(1000); 531 DELAY(1000);
532#else 532#else
533 axe_ax_init(un); 533 axe_ax_init(un);
534#endif 534#endif
535} 535}
536 536
537static int 537static int
538axe_get_phyno(struct axe_softc *sc, int sel) 538axe_get_phyno(struct axe_softc *sc, int sel)
539{ 539{
540 int phyno; 540 int phyno;
541 541
542 switch (AXE_PHY_TYPE(sc->axe_phyaddrs[sel])) { 542 switch (AXE_PHY_TYPE(sc->axe_phyaddrs[sel])) {
543 case PHY_TYPE_100_HOME: 543 case PHY_TYPE_100_HOME:
544 /* FALLTHROUGH */ 544 /* FALLTHROUGH */
545 case PHY_TYPE_GIG: 545 case PHY_TYPE_GIG:
546 phyno = AXE_PHY_NO(sc->axe_phyaddrs[sel]); 546 phyno = AXE_PHY_NO(sc->axe_phyaddrs[sel]);
547 break; 547 break;
548 case PHY_TYPE_SPECIAL: 548 case PHY_TYPE_SPECIAL:
549 /* FALLTHROUGH */ 549 /* FALLTHROUGH */
550 case PHY_TYPE_RSVD: 550 case PHY_TYPE_RSVD:
551 /* FALLTHROUGH */ 551 /* FALLTHROUGH */
552 case PHY_TYPE_NON_SUP: 552 case PHY_TYPE_NON_SUP:
553 /* FALLTHROUGH */ 553 /* FALLTHROUGH */
554 default: 554 default:
555 phyno = -1; 555 phyno = -1;
556 break; 556 break;
557 } 557 }
558 558
559 return phyno; 559 return phyno;
560} 560}
561 561
562#define AXE_GPIO_WRITE(x, y) do { \ 562#define AXE_GPIO_WRITE(x, y) do { \
563 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, (x), NULL); \ 563 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, (x), NULL); \
564 usbd_delay_ms(sc->axe_un.un_udev, hztoms(y)); \ 564 usbd_delay_ms(sc->axe_un.un_udev, hztoms(y)); \
565} while (0) 565} while (0)
566 566
567static void 567static void
568axe_ax88178_init(struct axe_softc *sc) 568axe_ax88178_init(struct axe_softc *sc)
569{ 569{
570 AXEHIST_FUNC(); AXEHIST_CALLED(); 570 AXEHIST_FUNC(); AXEHIST_CALLED();
571 struct usbnet * const un = &sc->axe_un; 571 struct usbnet * const un = &sc->axe_un;
572 int gpio0, ledmode, phymode; 572 int gpio0, ledmode, phymode;
573 uint16_t eeprom, val; 573 uint16_t eeprom, val;
574 574
575 axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL); 575 axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
576 /* XXX magic */ 576 /* XXX magic */
577 if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom) != 0) 577 if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom) != 0)
578 eeprom = 0xffff; 578 eeprom = 0xffff;
579 axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL); 579 axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL);
580 580
581 eeprom = le16toh(eeprom); 581 eeprom = le16toh(eeprom);
582 582
583 DPRINTF("EEPROM is %#jx", eeprom, 0, 0, 0); 583 DPRINTF("EEPROM is %#jx", eeprom, 0, 0, 0);
584 584
585 /* if EEPROM is invalid we have to use to GPIO0 */ 585 /* if EEPROM is invalid we have to use to GPIO0 */
586 if (eeprom == 0xffff) { 586 if (eeprom == 0xffff) {
587 phymode = AXE_PHY_MODE_MARVELL; 587 phymode = AXE_PHY_MODE_MARVELL;
588 gpio0 = 1; 588 gpio0 = 1;
589 ledmode = 0; 589 ledmode = 0;
590 } else { 590 } else {
591 phymode = eeprom & 0x7f; 591 phymode = eeprom & 0x7f;
592 gpio0 = (eeprom & 0x80) ? 0 : 1; 592 gpio0 = (eeprom & 0x80) ? 0 : 1;
593 ledmode = eeprom >> 8; 593 ledmode = eeprom >> 8;
594 } 594 }
595 595
596 DPRINTF("use gpio0: %jd, phymode %jd", gpio0, phymode, 0, 0); 596 DPRINTF("use gpio0: %jd, phymode %jd", gpio0, phymode, 0, 0);
597 597
598 /* Program GPIOs depending on PHY hardware. */ 598 /* Program GPIOs depending on PHY hardware. */
599 switch (phymode) { 599 switch (phymode) {
600 case AXE_PHY_MODE_MARVELL: 600 case AXE_PHY_MODE_MARVELL:
601 if (gpio0 == 1) { 601 if (gpio0 == 1) {
602 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0_EN, 602 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0_EN,
603 hz / 32); 603 hz / 32);
604 AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN, 604 AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN,
605 hz / 32); 605 hz / 32);
606 AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2_EN, hz / 4); 606 AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2_EN, hz / 4);
607 AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN, 607 AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN,
608 hz / 32); 608 hz / 32);
609 } else { 609 } else {
610 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 | 610 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
611 AXE_GPIO1_EN, hz / 3); 611 AXE_GPIO1_EN, hz / 3);
612 if (ledmode == 1) { 612 if (ledmode == 1) {
613 AXE_GPIO_WRITE(AXE_GPIO1_EN, hz / 3); 613 AXE_GPIO_WRITE(AXE_GPIO1_EN, hz / 3);
614 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN, 614 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN,
615 hz / 3); 615 hz / 3);
616 } else { 616 } else {
617 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | 617 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN |
618 AXE_GPIO2 | AXE_GPIO2_EN, hz / 32); 618 AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
619 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | 619 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN |
620 AXE_GPIO2_EN, hz / 4); 620 AXE_GPIO2_EN, hz / 4);
621 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | 621 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN |
622 AXE_GPIO2 | AXE_GPIO2_EN, hz / 32); 622 AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
623 } 623 }
624 } 624 }
625 break; 625 break;
626 case AXE_PHY_MODE_CICADA: 626 case AXE_PHY_MODE_CICADA:
627 case AXE_PHY_MODE_CICADA_V2: 627 case AXE_PHY_MODE_CICADA_V2:
628 case AXE_PHY_MODE_CICADA_V2_ASIX: 628 case AXE_PHY_MODE_CICADA_V2_ASIX:
629 if (gpio0 == 1) 629 if (gpio0 == 1)
630 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0 | 630 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0 |
631 AXE_GPIO0_EN, hz / 32); 631 AXE_GPIO0_EN, hz / 32);
632 else 632 else
633 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 | 633 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
634 AXE_GPIO1_EN, hz / 32); 634 AXE_GPIO1_EN, hz / 32);
635 break; 635 break;
636 case AXE_PHY_MODE_AGERE: 636 case AXE_PHY_MODE_AGERE:
637 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 | 637 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
638 AXE_GPIO1_EN, hz / 32); 638 AXE_GPIO1_EN, hz / 32);
639 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 | 639 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 |
640 AXE_GPIO2_EN, hz / 32); 640 AXE_GPIO2_EN, hz / 32);
641 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2_EN, hz / 4); 641 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2_EN, hz / 4);
642 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 | 642 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 |
643 AXE_GPIO2_EN, hz / 32); 643 AXE_GPIO2_EN, hz / 32);
644 break; 644 break;
645 case AXE_PHY_MODE_REALTEK_8211CL: 645 case AXE_PHY_MODE_REALTEK_8211CL:
646 case AXE_PHY_MODE_REALTEK_8211BN: 646 case AXE_PHY_MODE_REALTEK_8211BN:
647 case AXE_PHY_MODE_REALTEK_8251CL: 647 case AXE_PHY_MODE_REALTEK_8251CL:
648 val = gpio0 == 1 ? AXE_GPIO0 | AXE_GPIO0_EN : 648 val = gpio0 == 1 ? AXE_GPIO0 | AXE_GPIO0_EN :
649 AXE_GPIO1 | AXE_GPIO1_EN; 649 AXE_GPIO1 | AXE_GPIO1_EN;
650 AXE_GPIO_WRITE(val, hz / 32); 650 AXE_GPIO_WRITE(val, hz / 32);
651 AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32); 651 AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
652 AXE_GPIO_WRITE(val | AXE_GPIO2_EN, hz / 4); 652 AXE_GPIO_WRITE(val | AXE_GPIO2_EN, hz / 4);
653 AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32); 653 AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
654 if (phymode == AXE_PHY_MODE_REALTEK_8211CL) { 654 if (phymode == AXE_PHY_MODE_REALTEK_8211CL) {
655 axe_uno_mii_write_reg(un, un->un_phyno, 0x1F, 0x0005); 655 axe_uno_mii_write_reg(un, un->un_phyno, 0x1F, 0x0005);
656 axe_uno_mii_write_reg(un, un->un_phyno, 0x0C, 0x0000); 656 axe_uno_mii_write_reg(un, un->un_phyno, 0x0C, 0x0000);
657 axe_uno_mii_read_reg(un, un->un_phyno, 0x0001, &val); 657 axe_uno_mii_read_reg(un, un->un_phyno, 0x0001, &val);
658 axe_uno_mii_write_reg(un, un->un_phyno, 0x01, val | 0x0080); 658 axe_uno_mii_write_reg(un, un->un_phyno, 0x01, val | 0x0080);
659 axe_uno_mii_write_reg(un, un->un_phyno, 0x1F, 0x0000); 659 axe_uno_mii_write_reg(un, un->un_phyno, 0x1F, 0x0000);
660 } 660 }
661 break; 661 break;
662 default: 662 default:
663 /* Unknown PHY model or no need to program GPIOs. */ 663 /* Unknown PHY model or no need to program GPIOs. */
664 break; 664 break;
665 } 665 }
666 666
667 /* soft reset */ 667 /* soft reset */
668 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); 668 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
669 usbd_delay_ms(un->un_udev, 150); 669 usbd_delay_ms(un->un_udev, 150);
670 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 670 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
671 AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL); 671 AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
672 usbd_delay_ms(un->un_udev, 150); 672 usbd_delay_ms(un->un_udev, 150);
673 /* Enable MII/GMII/RGMII interface to work with external PHY. */ 673 /* Enable MII/GMII/RGMII interface to work with external PHY. */
674 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL); 674 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL);
675 usbd_delay_ms(un->un_udev, 10); 675 usbd_delay_ms(un->un_udev, 10);
676 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 676 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
677} 677}
678 678
679static void 679static void
680axe_ax88772_init(struct axe_softc *sc) 680axe_ax88772_init(struct axe_softc *sc)
681{ 681{
682 AXEHIST_FUNC(); AXEHIST_CALLED(); 682 AXEHIST_FUNC(); AXEHIST_CALLED();
683 struct usbnet * const un = &sc->axe_un; 683 struct usbnet * const un = &sc->axe_un;
684 684
685 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL); 685 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
686 usbd_delay_ms(un->un_udev, 40); 686 usbd_delay_ms(un->un_udev, 40);
687 687
688 if (un->un_phyno == AXE_772_PHY_NO_EPHY) { 688 if (un->un_phyno == AXE_772_PHY_NO_EPHY) {
689 /* ask for the embedded PHY */ 689 /* ask for the embedded PHY */
690 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 690 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0,
691 AXE_SW_PHY_SELECT_EMBEDDED, NULL); 691 AXE_SW_PHY_SELECT_EMBEDDED, NULL);
692 usbd_delay_ms(un->un_udev, 10); 692 usbd_delay_ms(un->un_udev, 10);
693 693
694 /* power down and reset state, pin reset state */ 694 /* power down and reset state, pin reset state */
695 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); 695 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
696 usbd_delay_ms(un->un_udev, 60); 696 usbd_delay_ms(un->un_udev, 60);
697 697
698 /* power down/reset state, pin operating state */ 698 /* power down/reset state, pin operating state */
699 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 699 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
700 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); 700 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
701 usbd_delay_ms(un->un_udev, 150); 701 usbd_delay_ms(un->un_udev, 150);
702 702
703 /* power up, reset */ 703 /* power up, reset */
704 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL); 704 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL);
705 705
706 /* power up, operating */ 706 /* power up, operating */
707 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 707 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
708 AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL); 708 AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL);
709 } else { 709 } else {
710 /* ask for external PHY */ 710 /* ask for external PHY */
711 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_EXT, 711 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_EXT,
712 NULL); 712 NULL);
713 usbd_delay_ms(un->un_udev, 10); 713 usbd_delay_ms(un->un_udev, 10);
714 714
715 /* power down internal PHY */ 715 /* power down internal PHY */
716 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 716 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
717 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); 717 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
718 } 718 }
719 719
720 usbd_delay_ms(un->un_udev, 150); 720 usbd_delay_ms(un->un_udev, 150);
721 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 721 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
722} 722}
723 723
724static void 724static void
725axe_ax88772_phywake(struct axe_softc *sc) 725axe_ax88772_phywake(struct axe_softc *sc)
726{ 726{
727 AXEHIST_FUNC(); AXEHIST_CALLED(); 727 AXEHIST_FUNC(); AXEHIST_CALLED();
728 struct usbnet * const un = &sc->axe_un; 728 struct usbnet * const un = &sc->axe_un;
729 729
730 if (un->un_phyno == AXE_772_PHY_NO_EPHY) { 730 if (un->un_phyno == AXE_772_PHY_NO_EPHY) {
731 /* Manually select internal(embedded) PHY - MAC mode. */ 731 /* Manually select internal(embedded) PHY - MAC mode. */
732 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 732 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0,
733 AXE_SW_PHY_SELECT_EMBEDDED, NULL); 733 AXE_SW_PHY_SELECT_EMBEDDED, NULL);
734 usbd_delay_ms(un->un_udev, hztoms(hz / 32)); 734 usbd_delay_ms(un->un_udev, hztoms(hz / 32));
735 } else { 735 } else {
736 /* 736 /*
737 * Manually select external PHY - MAC mode. 737 * Manually select external PHY - MAC mode.
738 * Reverse MII/RMII is for AX88772A PHY mode. 738 * Reverse MII/RMII is for AX88772A PHY mode.
739 */ 739 */
740 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_SS_ENB | 740 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_SS_ENB |
741 AXE_SW_PHY_SELECT_EXT | AXE_SW_PHY_SELECT_SS_MII, NULL); 741 AXE_SW_PHY_SELECT_EXT | AXE_SW_PHY_SELECT_SS_MII, NULL);
742 usbd_delay_ms(un->un_udev, hztoms(hz / 32)); 742 usbd_delay_ms(un->un_udev, hztoms(hz / 32));
743 } 743 }
744 744
745 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPPD | 745 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPPD |
746 AXE_SW_RESET_IPRL, NULL); 746 AXE_SW_RESET_IPRL, NULL);
747 747
748 /* T1 = min 500ns everywhere */ 748 /* T1 = min 500ns everywhere */
749 usbd_delay_ms(un->un_udev, 150); 749 usbd_delay_ms(un->un_udev, 150);
750 750
751 /* Take PHY out of power down. */ 751 /* Take PHY out of power down. */
752 if (un->un_phyno == AXE_772_PHY_NO_EPHY) { 752 if (un->un_phyno == AXE_772_PHY_NO_EPHY) {
753 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL); 753 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL);
754 } else { 754 } else {
755 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRTE, NULL); 755 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRTE, NULL);
756 } 756 }
757 757
758 /* 772 T2 is 60ms. 772A T2 is 160ms, 772B T2 is 600ms */ 758 /* 772 T2 is 60ms. 772A T2 is 160ms, 772B T2 is 600ms */
759 usbd_delay_ms(un->un_udev, 600); 759 usbd_delay_ms(un->un_udev, 600);
760 760
761 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); 761 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
762 762
763 /* T3 = 500ns everywhere */ 763 /* T3 = 500ns everywhere */
764 usbd_delay_ms(un->un_udev, hztoms(hz / 32)); 764 usbd_delay_ms(un->un_udev, hztoms(hz / 32));
765 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL); 765 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL);
766 usbd_delay_ms(un->un_udev, hztoms(hz / 32)); 766 usbd_delay_ms(un->un_udev, hztoms(hz / 32));
767} 767}
768 768
769static void 769static void
770axe_ax88772a_init(struct axe_softc *sc) 770axe_ax88772a_init(struct axe_softc *sc)
771{ 771{
772 AXEHIST_FUNC(); AXEHIST_CALLED(); 772 AXEHIST_FUNC(); AXEHIST_CALLED();
773 773
774 /* Reload EEPROM. */ 774 /* Reload EEPROM. */
775 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM, hz / 32); 775 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM, hz / 32);
776 axe_ax88772_phywake(sc); 776 axe_ax88772_phywake(sc);
777 /* Stop MAC. */ 777 /* Stop MAC. */
778 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 778 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
779} 779}
780 780
781static void 781static void
782axe_ax88772b_init(struct axe_softc *sc) 782axe_ax88772b_init(struct axe_softc *sc)
783{ 783{
784 AXEHIST_FUNC(); AXEHIST_CALLED(); 784 AXEHIST_FUNC(); AXEHIST_CALLED();
785 struct usbnet * const un = &sc->axe_un; 785 struct usbnet * const un = &sc->axe_un;
786 uint16_t eeprom; 786 uint16_t eeprom;
787 int i; 787 int i;
788 788
789 /* Reload EEPROM. */ 789 /* Reload EEPROM. */
790 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM , hz / 32); 790 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM , hz / 32);
791 791
792 /* 792 /*
793 * Save PHY power saving configuration(high byte) and 793 * Save PHY power saving configuration(high byte) and
794 * clear EEPROM checksum value(low byte). 794 * clear EEPROM checksum value(low byte).
795 */ 795 */
796 if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, AXE_EEPROM_772B_PHY_PWRCFG, 796 if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, AXE_EEPROM_772B_PHY_PWRCFG,
797 &eeprom)) { 797 &eeprom)) {
798 aprint_error_dev(un->un_dev, "failed to read eeprom\n"); 798 aprint_error_dev(un->un_dev, "failed to read eeprom\n");
799 return; 799 return;
800 } 800 }
801 801
802 sc->sc_pwrcfg = le16toh(eeprom) & 0xFF00; 802 sc->sc_pwrcfg = le16toh(eeprom) & 0xFF00;
803 803
804 /* 804 /*
805 * Auto-loaded default station address from internal ROM is 805 * Auto-loaded default station address from internal ROM is
806 * 00:00:00:00:00:00 such that an explicit access to EEPROM 806 * 00:00:00:00:00:00 such that an explicit access to EEPROM
807 * is required to get real station address. 807 * is required to get real station address.
808 */ 808 */
809 uint8_t *eaddr = un->un_eaddr; 809 uint8_t *eaddr = un->un_eaddr;
810 for (i = 0; i < ETHER_ADDR_LEN / 2; i++) { 810 for (i = 0; i < ETHER_ADDR_LEN / 2; i++) {
811 if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, 811 if (axe_cmd(sc, AXE_CMD_SROM_READ, 0,
812 AXE_EEPROM_772B_NODE_ID + i, &eeprom)) { 812 AXE_EEPROM_772B_NODE_ID + i, &eeprom)) {
813 aprint_error_dev(un->un_dev, 813 aprint_error_dev(un->un_dev,
814 "failed to read eeprom\n"); 814 "failed to read eeprom\n");
815 eeprom = 0; 815 eeprom = 0;
816 } 816 }
817 eeprom = le16toh(eeprom); 817 eeprom = le16toh(eeprom);
818 *eaddr++ = (uint8_t)(eeprom & 0xFF); 818 *eaddr++ = (uint8_t)(eeprom & 0xFF);
819 *eaddr++ = (uint8_t)((eeprom >> 8) & 0xFF); 819 *eaddr++ = (uint8_t)((eeprom >> 8) & 0xFF);
820 } 820 }
821 /* Wakeup PHY. */ 821 /* Wakeup PHY. */
822 axe_ax88772_phywake(sc); 822 axe_ax88772_phywake(sc);
823 /* Stop MAC. */ 823 /* Stop MAC. */
824 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 824 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
825} 825}
826 826
827#undef AXE_GPIO_WRITE 827#undef AXE_GPIO_WRITE
828 828
829/* 829/*
830 * Probe for a AX88172 chip. 830 * Probe for a AX88172 chip.
831 */ 831 */
832static int 832static int
833axe_match(device_t parent, cfdata_t match, void *aux) 833axe_match(device_t parent, cfdata_t match, void *aux)
834{ 834{
835 struct usb_attach_arg *uaa = aux; 835 struct usb_attach_arg *uaa = aux;
836 836
837 return axe_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 837 return axe_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
838 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 838 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
839} 839}
840 840
841/* 841/*
842 * Attach the interface. Allocate softc structures, do ifmedia 842 * Attach the interface. Allocate softc structures, do ifmedia
843 * setup and ethernet/BPF attach. 843 * setup and ethernet/BPF attach.
844 */ 844 */
845static void 845static void
846axe_attach(device_t parent, device_t self, void *aux) 846axe_attach(device_t parent, device_t self, void *aux)
847{ 847{
848 AXEHIST_FUNC(); AXEHIST_CALLED(); 848 AXEHIST_FUNC(); AXEHIST_CALLED();
849 USBNET_MII_DECL_DEFAULT(unm); 849 USBNET_MII_DECL_DEFAULT(unm);
850 struct axe_softc *sc = device_private(self); 850 struct axe_softc *sc = device_private(self);
851 struct usbnet * const un = &sc->axe_un; 851 struct usbnet * const un = &sc->axe_un;
852 struct usb_attach_arg *uaa = aux; 852 struct usb_attach_arg *uaa = aux;
853 struct usbd_device *dev = uaa->uaa_device; 853 struct usbd_device *dev = uaa->uaa_device;
854 usbd_status err; 854 usbd_status err;
855 usb_interface_descriptor_t *id; 855 usb_interface_descriptor_t *id;
856 usb_endpoint_descriptor_t *ed; 856 usb_endpoint_descriptor_t *ed;
857 char *devinfop; 857 char *devinfop;
858 unsigned bufsz; 858 unsigned bufsz;
859 int i; 859 int i;
860 860
861 KASSERT((void *)sc == un); 861 KASSERT((void *)sc == un);
862 862
863 aprint_naive("\n"); 863 aprint_naive("\n");
864 aprint_normal("\n"); 864 aprint_normal("\n");
865 devinfop = usbd_devinfo_alloc(dev, 0); 865 devinfop = usbd_devinfo_alloc(dev, 0);
866 aprint_normal_dev(self, "%s\n", devinfop); 866 aprint_normal_dev(self, "%s\n", devinfop);
867 usbd_devinfo_free(devinfop); 867 usbd_devinfo_free(devinfop);
868 868
869 un->un_dev = self; 869 un->un_dev = self;
870 un->un_udev = dev; 870 un->un_udev = dev;
871 un->un_sc = sc; 871 un->un_sc = sc;
872 un->un_ops = &axe_ops; 872 un->un_ops = &axe_ops;
873 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 873 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
874 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 874 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
875 un->un_rx_list_cnt = AXE_RX_LIST_CNT; 875 un->un_rx_list_cnt = AXE_RX_LIST_CNT;
876 un->un_tx_list_cnt = AXE_TX_LIST_CNT; 876 un->un_tx_list_cnt = AXE_TX_LIST_CNT;
877 877
878 err = usbd_set_config_no(dev, AXE_CONFIG_NO, 1); 878 err = usbd_set_config_no(dev, AXE_CONFIG_NO, 1);
879 if (err) { 879 if (err) {
880 aprint_error_dev(self, "failed to set configuration" 880 aprint_error_dev(self, "failed to set configuration"
881 ", err=%s\n", usbd_errstr(err)); 881 ", err=%s\n", usbd_errstr(err));
882 return; 882 return;
883 } 883 }
884 884
885 un->un_flags = axe_lookup(uaa->uaa_vendor, uaa->uaa_product)->axe_flags; 885 un->un_flags = axe_lookup(uaa->uaa_vendor, uaa->uaa_product)->axe_flags;
886 886
887 err = usbd_device2interface_handle(dev, AXE_IFACE_IDX, &un->un_iface); 887 err = usbd_device2interface_handle(dev, AXE_IFACE_IDX, &un->un_iface);
888 if (err) { 888 if (err) {
889 aprint_error_dev(self, "getting interface handle failed\n"); 889 aprint_error_dev(self, "getting interface handle failed\n");
890 return; 890 return;
891 } 891 }
892 892
893 id = usbd_get_interface_descriptor(un->un_iface); 893 id = usbd_get_interface_descriptor(un->un_iface);
894 894
895 /* decide on what our bufsize will be */ 895 /* decide on what our bufsize will be */
896 if (AXE_IS_172(un)) 896 if (AXE_IS_172(un))
897 bufsz = AXE_172_BUFSZ; 897 bufsz = AXE_172_BUFSZ;
898 else 898 else
899 bufsz = (un->un_udev->ud_speed == USB_SPEED_HIGH) ? 899 bufsz = (un->un_udev->ud_speed == USB_SPEED_HIGH) ?
900 AXE_178_MAX_BUFSZ : AXE_178_MIN_BUFSZ; 900 AXE_178_MAX_BUFSZ : AXE_178_MIN_BUFSZ;
901 un->un_rx_bufsz = un->un_tx_bufsz = bufsz; 901 un->un_rx_bufsz = un->un_tx_bufsz = bufsz;
902 902
903 un->un_ed[USBNET_ENDPT_RX] = 0; 903 un->un_ed[USBNET_ENDPT_RX] = 0;
904 un->un_ed[USBNET_ENDPT_TX] = 0; 904 un->un_ed[USBNET_ENDPT_TX] = 0;
905 un->un_ed[USBNET_ENDPT_INTR] = 0; 905 un->un_ed[USBNET_ENDPT_INTR] = 0;
906 906
907 /* Find endpoints. */ 907 /* Find endpoints. */
908 for (i = 0; i < id->bNumEndpoints; i++) { 908 for (i = 0; i < id->bNumEndpoints; i++) {
909 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 909 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
910 if (ed == NULL) { 910 if (ed == NULL) {
911 aprint_error_dev(self, "couldn't get ep %d\n", i); 911 aprint_error_dev(self, "couldn't get ep %d\n", i);
912 return; 912 return;
913 } 913 }
914 const uint8_t xt = UE_GET_XFERTYPE(ed->bmAttributes); 914 const uint8_t xt = UE_GET_XFERTYPE(ed->bmAttributes);
915 const uint8_t dir = UE_GET_DIR(ed->bEndpointAddress); 915 const uint8_t dir = UE_GET_DIR(ed->bEndpointAddress);
916 916
917 if (dir == UE_DIR_IN && xt == UE_BULK && 917 if (dir == UE_DIR_IN && xt == UE_BULK &&
918 un->un_ed[USBNET_ENDPT_RX] == 0) { 918 un->un_ed[USBNET_ENDPT_RX] == 0) {
919 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 919 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
920 } else if (dir == UE_DIR_OUT && xt == UE_BULK && 920 } else if (dir == UE_DIR_OUT && xt == UE_BULK &&
921 un->un_ed[USBNET_ENDPT_TX] == 0) { 921 un->un_ed[USBNET_ENDPT_TX] == 0) {
922 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 922 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
923 } else if (dir == UE_DIR_IN && xt == UE_INTERRUPT) { 923 } else if (dir == UE_DIR_IN && xt == UE_INTERRUPT) {
924 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 924 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
925 } 925 }
926 } 926 }
927 927
928 /* Set these up now for axe_cmd(). */ 928 /* Set these up now for axe_cmd(). */
929 usbnet_attach(un, "axedet"); 929 usbnet_attach(un, "axedet");
930 930
931 /* We need the PHYID for init dance in some cases */ 931 /* We need the PHYID for init dance in some cases */
932 usbnet_lock_core(un); 932 usbnet_lock_core(un);
933 usbnet_busy(un); 933 usbnet_busy(un);
934 if (axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, &sc->axe_phyaddrs)) { 934 if (axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, &sc->axe_phyaddrs)) {
935 aprint_error_dev(self, "failed to read phyaddrs\n"); 935 aprint_error_dev(self, "failed to read phyaddrs\n");
936 usbnet_unbusy(un); 936 usbnet_unbusy(un);
937 usbnet_unlock_core(un); 937 usbnet_unlock_core(un);
938 return; 938 return;
939 } 939 }
940 940
941 DPRINTF(" phyaddrs[0]: %jx phyaddrs[1]: %jx", 941 DPRINTF(" phyaddrs[0]: %jx phyaddrs[1]: %jx",
942 sc->axe_phyaddrs[0], sc->axe_phyaddrs[1], 0, 0); 942 sc->axe_phyaddrs[0], sc->axe_phyaddrs[1], 0, 0);
943 un->un_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI); 943 un->un_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI);
944 if (un->un_phyno == -1) 944 if (un->un_phyno == -1)
945 un->un_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC); 945 un->un_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC);
946 if (un->un_phyno == -1) { 946 if (un->un_phyno == -1) {
947 DPRINTF(" no valid PHY address found, assuming PHY address 0", 947 DPRINTF(" no valid PHY address found, assuming PHY address 0",
948 0, 0, 0, 0); 948 0, 0, 0, 0);
949 un->un_phyno = 0; 949 un->un_phyno = 0;
950 } 950 }
951 951
952 /* Initialize controller and get station address. */ 952 /* Initialize controller and get station address. */
953 953
954 axe_ax_init(un); 954 axe_ax_init(un);
955 955
956 /* 956 /*
957 * Fetch IPG values. 957 * Fetch IPG values.
958 */ 958 */
959 if (un->un_flags & (AX772A | AX772B)) { 959 if (un->un_flags & (AX772A | AX772B)) {
960 /* Set IPG values. */ 960 /* Set IPG values. */
961 sc->axe_ipgs[0] = AXE_IPG0_DEFAULT; 961 sc->axe_ipgs[0] = AXE_IPG0_DEFAULT;
962 sc->axe_ipgs[1] = AXE_IPG1_DEFAULT; 962 sc->axe_ipgs[1] = AXE_IPG1_DEFAULT;
963 sc->axe_ipgs[2] = AXE_IPG2_DEFAULT; 963 sc->axe_ipgs[2] = AXE_IPG2_DEFAULT;
964 } else { 964 } else {
965 if (axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->axe_ipgs)) { 965 if (axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->axe_ipgs)) {
966 aprint_error_dev(self, "failed to read ipg\n"); 966 aprint_error_dev(self, "failed to read ipg\n");
967 usbnet_unbusy(un); 967 usbnet_unbusy(un);
968 usbnet_unlock_core(un); 968 usbnet_unlock_core(un);
969 return; 969 return;
970 } 970 }
971 } 971 }
972 972
973 usbnet_unbusy(un); 973 usbnet_unbusy(un);
974 usbnet_unlock_core(un); 974 usbnet_unlock_core(un);
975 975
976 if (!AXE_IS_172(un)) 976 if (!AXE_IS_172(un))
977 usbnet_ec(un)->ec_capabilities = ETHERCAP_VLAN_MTU; 977 usbnet_ec(un)->ec_capabilities = ETHERCAP_VLAN_MTU;
978 if (un->un_flags & AX772B) { 978 if (un->un_flags & AX772B) {
979 struct ifnet *ifp = usbnet_ifp(un); 979 struct ifnet *ifp = usbnet_ifp(un);
980 980
981 ifp->if_capabilities = 981 ifp->if_capabilities =
982 IFCAP_CSUM_IPv4_Rx | 982 IFCAP_CSUM_IPv4_Rx |
983 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | 983 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |
984 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx; 984 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx;
985 /* 985 /*
986 * Checksum offloading of AX88772B also works with VLAN 986 * Checksum offloading of AX88772B also works with VLAN
987 * tagged frames but there is no way to take advantage 987 * tagged frames but there is no way to take advantage
988 * of the feature because vlan(4) assumes 988 * of the feature because vlan(4) assumes
989 * IFCAP_VLAN_HWTAGGING is prerequisite condition to 989 * IFCAP_VLAN_HWTAGGING is prerequisite condition to
990 * support checksum offloading with VLAN. VLAN hardware 990 * support checksum offloading with VLAN. VLAN hardware
991 * tagging support of AX88772B is very limited so it's 991 * tagging support of AX88772B is very limited so it's
992 * not possible to announce IFCAP_VLAN_HWTAGGING. 992 * not possible to announce IFCAP_VLAN_HWTAGGING.
993 */ 993 */
994 } 994 }
995 if (un->un_flags & (AX772A | AX772B | AX178)) 995 if (un->un_flags & (AX772A | AX772B | AX178))
996 unm.un_mii_flags = MIIF_DOPAUSE; 996 unm.un_mii_flags = MIIF_DOPAUSE;
997 997
998 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 998 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
999 0, &unm); 999 0, &unm);
1000} 1000}
1001 1001
1002static void 1002static void
1003axe_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len) 1003axe_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
1004{ 1004{
1005 AXEHIST_FUNC(); AXEHIST_CALLED(); 1005 AXEHIST_FUNC(); AXEHIST_CALLED();
1006 struct axe_softc * const sc = usbnet_softc(un); 1006 struct axe_softc * const sc = usbnet_softc(un);
1007 struct ifnet *ifp = usbnet_ifp(un); 1007 struct ifnet *ifp = usbnet_ifp(un);
1008 uint8_t *buf = c->unc_buf; 1008 uint8_t *buf = c->unc_buf;
1009 1009
1010 do { 1010 do {
1011 u_int pktlen = 0; 1011 u_int pktlen = 0;
1012 u_int rxlen = 0; 1012 u_int rxlen = 0;
1013 int flags = 0; 1013 int flags = 0;
1014 1014
1015 if ((un->un_flags & AXSTD_FRAME) != 0) { 1015 if ((un->un_flags & AXSTD_FRAME) != 0) {
1016 struct axe_sframe_hdr hdr; 1016 struct axe_sframe_hdr hdr;
1017 1017
1018 if (total_len < sizeof(hdr)) { 1018 if (total_len < sizeof(hdr)) {
1019 if_statinc(ifp, if_ierrors); 1019 if_statinc(ifp, if_ierrors);
1020 break; 1020 break;
1021 } 1021 }
1022 1022
1023 memcpy(&hdr, buf, sizeof(hdr)); 1023 memcpy(&hdr, buf, sizeof(hdr));
1024 1024
1025 DPRINTFN(20, "total_len %#jx len %#jx ilen %#jx", 1025 DPRINTFN(20, "total_len %#jx len %#jx ilen %#jx",
1026 total_len, 1026 total_len,
1027 (le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK), 1027 (le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK),
1028 (le16toh(hdr.ilen) & AXE_RH1M_RXLEN_MASK), 0); 1028 (le16toh(hdr.ilen) & AXE_RH1M_RXLEN_MASK), 0);
1029 1029
1030 total_len -= sizeof(hdr); 1030 total_len -= sizeof(hdr);
1031 buf += sizeof(hdr); 1031 buf += sizeof(hdr);
1032 1032
1033 if (((le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK) ^ 1033 if (((le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK) ^
1034 (le16toh(hdr.ilen) & AXE_RH1M_RXLEN_MASK)) != 1034 (le16toh(hdr.ilen) & AXE_RH1M_RXLEN_MASK)) !=
1035 AXE_RH1M_RXLEN_MASK) { 1035 AXE_RH1M_RXLEN_MASK) {
1036 if_statinc(ifp, if_ierrors); 1036 if_statinc(ifp, if_ierrors);
1037 break; 1037 break;
1038 } 1038 }
1039 1039
1040 rxlen = le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK; 1040 rxlen = le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK;
1041 if (total_len < rxlen) { 1041 if (total_len < rxlen) {
1042 pktlen = total_len; 1042 pktlen = total_len;
1043 total_len = 0; 1043 total_len = 0;
1044 } else { 1044 } else {
1045 pktlen = rxlen; 1045 pktlen = rxlen;
1046 rxlen = roundup2(rxlen, 2); 1046 rxlen = roundup2(rxlen, 2);
1047 total_len -= rxlen; 1047 total_len -= rxlen;
1048 } 1048 }
1049 1049
1050 } else if ((un->un_flags & AXCSUM_FRAME) != 0) { 1050 } else if ((un->un_flags & AXCSUM_FRAME) != 0) {
1051 struct axe_csum_hdr csum_hdr; 1051 struct axe_csum_hdr csum_hdr;
1052 1052
1053 if (total_len < sizeof(csum_hdr)) { 1053 if (total_len < sizeof(csum_hdr)) {
1054 if_statinc(ifp, if_ierrors); 1054 if_statinc(ifp, if_ierrors);
1055 break; 1055 break;
1056 } 1056 }
1057 1057
1058 memcpy(&csum_hdr, buf, sizeof(csum_hdr)); 1058 memcpy(&csum_hdr, buf, sizeof(csum_hdr));
1059 1059
1060 csum_hdr.len = le16toh(csum_hdr.len); 1060 csum_hdr.len = le16toh(csum_hdr.len);
1061 csum_hdr.ilen = le16toh(csum_hdr.ilen); 1061 csum_hdr.ilen = le16toh(csum_hdr.ilen);
1062 csum_hdr.cstatus = le16toh(csum_hdr.cstatus); 1062 csum_hdr.cstatus = le16toh(csum_hdr.cstatus);
1063 1063
1064 DPRINTFN(20, "total_len %#jx len %#jx ilen %#jx" 1064 DPRINTFN(20, "total_len %#jx len %#jx ilen %#jx"
1065 " cstatus %#jx", total_len, 1065 " cstatus %#jx", total_len,
1066 csum_hdr.len, csum_hdr.ilen, csum_hdr.cstatus); 1066 csum_hdr.len, csum_hdr.ilen, csum_hdr.cstatus);
1067 1067
1068 if ((AXE_CSUM_RXBYTES(csum_hdr.len) ^ 1068 if ((AXE_CSUM_RXBYTES(csum_hdr.len) ^
1069 AXE_CSUM_RXBYTES(csum_hdr.ilen)) != 1069 AXE_CSUM_RXBYTES(csum_hdr.ilen)) !=
1070 sc->sc_lenmask) { 1070 sc->sc_lenmask) {
1071 /* we lost sync */ 1071 /* we lost sync */
1072 if_statinc(ifp, if_ierrors); 1072 if_statinc(ifp, if_ierrors);
1073 DPRINTFN(20, "len %#jx ilen %#jx lenmask %#jx " 1073 DPRINTFN(20, "len %#jx ilen %#jx lenmask %#jx "
1074 "err", 1074 "err",
1075 AXE_CSUM_RXBYTES(csum_hdr.len), 1075 AXE_CSUM_RXBYTES(csum_hdr.len),
1076 AXE_CSUM_RXBYTES(csum_hdr.ilen), 1076 AXE_CSUM_RXBYTES(csum_hdr.ilen),
1077 sc->sc_lenmask, 0); 1077 sc->sc_lenmask, 0);
1078 break; 1078 break;
1079 } 1079 }
1080 /* 1080 /*
1081 * Get total transferred frame length including 1081 * Get total transferred frame length including
1082 * checksum header. The length should be multiple 1082 * checksum header. The length should be multiple
1083 * of 4. 1083 * of 4.
1084 */ 1084 */
1085 pktlen = AXE_CSUM_RXBYTES(csum_hdr.len); 1085 pktlen = AXE_CSUM_RXBYTES(csum_hdr.len);
1086 u_int len = sizeof(csum_hdr) + pktlen; 1086 u_int len = sizeof(csum_hdr) + pktlen;
1087 len = (len + 3) & ~3; 1087 len = (len + 3) & ~3;
1088 if (total_len < len) { 1088 if (total_len < len) {
1089 DPRINTFN(20, "total_len %#jx < len %#jx", 1089 DPRINTFN(20, "total_len %#jx < len %#jx",
1090 total_len, len, 0, 0); 1090 total_len, len, 0, 0);
1091 /* invalid length */ 1091 /* invalid length */
1092 if_statinc(ifp, if_ierrors); 1092 if_statinc(ifp, if_ierrors);
1093 break; 1093 break;
1094 } 1094 }
1095 buf += sizeof(csum_hdr); 1095 buf += sizeof(csum_hdr);
1096 1096
1097 const uint16_t cstatus = csum_hdr.cstatus; 1097 const uint16_t cstatus = csum_hdr.cstatus;
1098 1098
1099 if (cstatus & AXE_CSUM_HDR_L3_TYPE_IPV4) { 1099 if (cstatus & AXE_CSUM_HDR_L3_TYPE_IPV4) {
1100 if (cstatus & AXE_CSUM_HDR_L4_CSUM_ERR) 1100 if (cstatus & AXE_CSUM_HDR_L4_CSUM_ERR)
1101 flags |= M_CSUM_TCP_UDP_BAD; 1101 flags |= M_CSUM_TCP_UDP_BAD;
1102 if (cstatus & AXE_CSUM_HDR_L3_CSUM_ERR) 1102 if (cstatus & AXE_CSUM_HDR_L3_CSUM_ERR)
1103 flags |= M_CSUM_IPv4_BAD; 1103 flags |= M_CSUM_IPv4_BAD;
1104 1104
1105 const uint16_t l4type = 1105 const uint16_t l4type =
1106 cstatus & AXE_CSUM_HDR_L4_TYPE_MASK; 1106 cstatus & AXE_CSUM_HDR_L4_TYPE_MASK;
1107 1107
1108 if (l4type == AXE_CSUM_HDR_L4_TYPE_TCP) 1108 if (l4type == AXE_CSUM_HDR_L4_TYPE_TCP)
1109 flags |= M_CSUM_TCPv4; 1109 flags |= M_CSUM_TCPv4;
1110 if (l4type == AXE_CSUM_HDR_L4_TYPE_UDP) 1110 if (l4type == AXE_CSUM_HDR_L4_TYPE_UDP)
1111 flags |= M_CSUM_UDPv4; 1111 flags |= M_CSUM_UDPv4;
1112 } 1112 }
1113 if (total_len < len) { 1113 if (total_len < len) {
1114 pktlen = total_len; 1114 pktlen = total_len;
1115 total_len = 0; 1115 total_len = 0;
1116 } else { 1116 } else {
1117 total_len -= len; 1117 total_len -= len;
1118 rxlen = len - sizeof(csum_hdr); 1118 rxlen = len - sizeof(csum_hdr);
1119 } 1119 }
1120 DPRINTFN(20, "total_len %#jx len %#jx pktlen %#jx" 1120 DPRINTFN(20, "total_len %#jx len %#jx pktlen %#jx"
1121 " rxlen %#jx", total_len, len, pktlen, rxlen); 1121 " rxlen %#jx", total_len, len, pktlen, rxlen);
1122 } else { /* AX172 */ 1122 } else { /* AX172 */
1123 pktlen = rxlen = total_len; 1123 pktlen = rxlen = total_len;
1124 total_len = 0; 1124 total_len = 0;
1125 } 1125 }
1126 1126
1127 usbnet_enqueue(un, buf, pktlen, flags, 0, 0); 1127 usbnet_enqueue(un, buf, pktlen, flags, 0, 0);
1128 buf += rxlen; 1128 buf += rxlen;
1129 1129
1130 } while (total_len > 0); 1130 } while (total_len > 0);
1131 1131
1132 DPRINTFN(10, "start rx", 0, 0, 0, 0); 1132 DPRINTFN(10, "start rx", 0, 0, 0, 0);
1133} 1133}
1134 1134
1135static unsigned 1135static unsigned
1136axe_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 1136axe_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
1137{ 1137{
1138 AXEHIST_FUNC(); AXEHIST_CALLED(); 1138 AXEHIST_FUNC(); AXEHIST_CALLED();
1139 struct axe_sframe_hdr hdr, tlr; 1139 struct axe_sframe_hdr hdr, tlr;
1140 size_t hdr_len = 0, tlr_len = 0; 1140 size_t hdr_len = 0, tlr_len = 0;
1141 int length, boundary; 1141 int length, boundary;
1142 1142
1143 usbnet_isowned_tx(un); 1143 usbnet_isowned_tx(un);
1144 1144
1145 if (!AXE_IS_172(un)) { 1145 if (!AXE_IS_172(un)) {
1146 /* 1146 /*
1147 * Copy the mbuf data into a contiguous buffer, leaving two 1147 * Copy the mbuf data into a contiguous buffer, leaving two
1148 * bytes at the beginning to hold the frame length. 1148 * bytes at the beginning to hold the frame length.
1149 */ 1149 */
1150 boundary = (un->un_udev->ud_speed == USB_SPEED_HIGH) ? 512 : 64; 1150 boundary = (un->un_udev->ud_speed == USB_SPEED_HIGH) ? 512 : 64;
1151 1151
1152 hdr.len = htole16(m->m_pkthdr.len); 1152 hdr.len = htole16(m->m_pkthdr.len);
1153 hdr.ilen = ~hdr.len; 1153 hdr.ilen = ~hdr.len;
1154 hdr_len = sizeof(hdr); 1154 hdr_len = sizeof(hdr);
1155 1155
1156 length = hdr_len + m->m_pkthdr.len; 1156 length = hdr_len + m->m_pkthdr.len;
1157 1157
1158 if ((length % boundary) == 0) { 1158 if ((length % boundary) == 0) {
1159 tlr.len = 0x0000; 1159 tlr.len = 0x0000;
1160 tlr.ilen = 0xffff; 1160 tlr.ilen = 0xffff;
1161 tlr_len = sizeof(tlr); 1161 tlr_len = sizeof(tlr);
1162 } 1162 }
1163 DPRINTFN(20, "length %jx m_pkthdr.len %jx hdrsize %#jx", 1163 DPRINTFN(20, "length %jx m_pkthdr.len %jx hdrsize %#jx",
1164 length, m->m_pkthdr.len, sizeof(hdr), 0); 1164 length, m->m_pkthdr.len, sizeof(hdr), 0);
1165 } 1165 }
1166 1166
1167 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdr_len - tlr_len) 1167 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdr_len - tlr_len)
1168 return 0; 1168 return 0;
1169 length = hdr_len + m->m_pkthdr.len + tlr_len; 1169 length = hdr_len + m->m_pkthdr.len + tlr_len;
1170 1170
1171 if (hdr_len) 1171 if (hdr_len)
1172 memcpy(c->unc_buf, &hdr, hdr_len); 1172 memcpy(c->unc_buf, &hdr, hdr_len);
1173 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + hdr_len); 1173 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + hdr_len);
1174 if (tlr_len) 1174 if (tlr_len)
1175 memcpy(c->unc_buf + length - tlr_len, &tlr, tlr_len); 1175 memcpy(c->unc_buf + length - tlr_len, &tlr, tlr_len);
1176 1176
1177 return length; 1177 return length;
1178} 1178}
1179 1179
1180static void 1180static void
1181axe_csum_cfg(struct axe_softc *sc) 1181axe_csum_cfg(struct axe_softc *sc)
1182{ 1182{
1183 struct usbnet * const un = &sc->axe_un; 1183 struct usbnet * const un = &sc->axe_un;
1184 struct ifnet * const ifp = usbnet_ifp(un); 1184 struct ifnet * const ifp = usbnet_ifp(un);
1185 uint16_t csum1, csum2; 1185 uint16_t csum1, csum2;
1186 1186
1187 if ((un->un_flags & AX772B) != 0) { 1187 if ((un->un_flags & AX772B) != 0) {
1188 csum1 = 0; 1188 csum1 = 0;
1189 csum2 = 0; 1189 csum2 = 0;
1190 if ((ifp->if_capenable & IFCAP_CSUM_IPv4_Tx) != 0) 1190 if ((ifp->if_capenable & IFCAP_CSUM_IPv4_Tx) != 0)
1191 csum1 |= AXE_TXCSUM_IP; 1191 csum1 |= AXE_TXCSUM_IP;
1192 if ((ifp->if_capenable & IFCAP_CSUM_TCPv4_Tx) != 0) 1192 if ((ifp->if_capenable & IFCAP_CSUM_TCPv4_Tx) != 0)
1193 csum1 |= AXE_TXCSUM_TCP; 1193 csum1 |= AXE_TXCSUM_TCP;
1194 if ((ifp->if_capenable & IFCAP_CSUM_UDPv4_Tx) != 0) 1194 if ((ifp->if_capenable & IFCAP_CSUM_UDPv4_Tx) != 0)
1195 csum1 |= AXE_TXCSUM_UDP; 1195 csum1 |= AXE_TXCSUM_UDP;
1196 if ((ifp->if_capenable & IFCAP_CSUM_TCPv6_Tx) != 0) 1196 if ((ifp->if_capenable & IFCAP_CSUM_TCPv6_Tx) != 0)
1197 csum1 |= AXE_TXCSUM_TCPV6; 1197 csum1 |= AXE_TXCSUM_TCPV6;
1198 if ((ifp->if_capenable & IFCAP_CSUM_UDPv6_Tx) != 0) 1198 if ((ifp->if_capenable & IFCAP_CSUM_UDPv6_Tx) != 0)
1199 csum1 |= AXE_TXCSUM_UDPV6; 1199 csum1 |= AXE_TXCSUM_UDPV6;
1200 axe_cmd(sc, AXE_772B_CMD_WRITE_TXCSUM, csum2, csum1, NULL); 1200 axe_cmd(sc, AXE_772B_CMD_WRITE_TXCSUM, csum2, csum1, NULL);
1201 csum1 = 0; 1201 csum1 = 0;
1202 csum2 = 0; 1202 csum2 = 0;
1203 1203
1204 if ((ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) != 0) 1204 if ((ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) != 0)
1205 csum1 |= AXE_RXCSUM_IP; 1205 csum1 |= AXE_RXCSUM_IP;
1206 if ((ifp->if_capenable & IFCAP_CSUM_TCPv4_Rx) != 0) 1206 if ((ifp->if_capenable & IFCAP_CSUM_TCPv4_Rx) != 0)
1207 csum1 |= AXE_RXCSUM_TCP; 1207 csum1 |= AXE_RXCSUM_TCP;
1208 if ((ifp->if_capenable & IFCAP_CSUM_UDPv4_Rx) != 0) 1208 if ((ifp->if_capenable & IFCAP_CSUM_UDPv4_Rx) != 0)
1209 csum1 |= AXE_RXCSUM_UDP; 1209 csum1 |= AXE_RXCSUM_UDP;
1210 if ((ifp->if_capenable & IFCAP_CSUM_TCPv6_Rx) != 0) 1210 if ((ifp->if_capenable & IFCAP_CSUM_TCPv6_Rx) != 0)
1211 csum1 |= AXE_RXCSUM_TCPV6; 1211 csum1 |= AXE_RXCSUM_TCPV6;
1212 if ((ifp->if_capenable & IFCAP_CSUM_UDPv6_Rx) != 0) 1212 if ((ifp->if_capenable & IFCAP_CSUM_UDPv6_Rx) != 0)
1213 csum1 |= AXE_RXCSUM_UDPV6; 1213 csum1 |= AXE_RXCSUM_UDPV6;
1214 axe_cmd(sc, AXE_772B_CMD_WRITE_RXCSUM, csum2, csum1, NULL); 1214 axe_cmd(sc, AXE_772B_CMD_WRITE_RXCSUM, csum2, csum1, NULL);
1215 } 1215 }
1216} 1216}
1217 1217
1218static int 1218static int
1219axe_init_locked(struct ifnet *ifp) 1219axe_init_locked(struct ifnet *ifp)
1220{ 1220{
1221 AXEHIST_FUNC(); AXEHIST_CALLED(); 1221 AXEHIST_FUNC(); AXEHIST_CALLED();
1222 struct usbnet * const un = ifp->if_softc; 1222 struct usbnet * const un = ifp->if_softc;
1223 struct axe_softc * const sc = usbnet_softc(un); 1223 struct axe_softc * const sc = usbnet_softc(un);
1224 int rxmode; 1224 int rxmode;
1225 1225
1226 usbnet_isowned_core(un); 1226 usbnet_isowned_core(un);
1227 1227
1228 if (usbnet_isdying(un)) 1228 if (usbnet_isdying(un))
1229 return EIO; 1229 return EIO;
1230 1230
1231 /* Cancel pending I/O */ 1231 /* Cancel pending I/O */
1232 usbnet_stop(un, ifp, 1); 1232 usbnet_stop(un, ifp, 1);
1233 1233
1234 /* Reset the ethernet interface. */ 1234 /* Reset the ethernet interface. */
1235 axe_reset(un); 1235 axe_reset(un);
1236 1236
1237#if 0 1237#if 0
1238 ret = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 | 1238 ret = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 |
1239 AX_GPIO_GPO2EN, 5, in_pm); 1239 AX_GPIO_GPO2EN, 5, in_pm);
1240#endif 1240#endif
1241 /* Set MAC address and transmitter IPG values. */ 1241 /* Set MAC address and transmitter IPG values. */
1242 if (AXE_IS_172(un)) { 1242 if (AXE_IS_172(un)) {
1243 axe_cmd(sc, AXE_172_CMD_WRITE_NODEID, 0, 0, un->un_eaddr); 1243 axe_cmd(sc, AXE_172_CMD_WRITE_NODEID, 0, 0, un->un_eaddr);
1244 axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL); 1244 axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL);
1245 axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL); 1245 axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL);
1246 axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL); 1246 axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
1247 } else { 1247 } else {
1248 axe_cmd(sc, AXE_178_CMD_WRITE_NODEID, 0, 0, un->un_eaddr); 1248 axe_cmd(sc, AXE_178_CMD_WRITE_NODEID, 0, 0, un->un_eaddr);
1249 axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2], 1249 axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2],
1250 (sc->axe_ipgs[1] << 8) | (sc->axe_ipgs[0]), NULL); 1250 (sc->axe_ipgs[1] << 8) | (sc->axe_ipgs[0]), NULL);
1251 1251
1252 un->un_flags &= ~(AXSTD_FRAME | AXCSUM_FRAME); 1252 un->un_flags &= ~(AXSTD_FRAME | AXCSUM_FRAME);
1253 if ((un->un_flags & AX772B) != 0 && 1253 if ((un->un_flags & AX772B) != 0 &&
1254 (ifp->if_capenable & AX_RXCSUM) != 0) { 1254 (ifp->if_capenable & AX_RXCSUM) != 0) {
1255 sc->sc_lenmask = AXE_CSUM_HDR_LEN_MASK; 1255 sc->sc_lenmask = AXE_CSUM_HDR_LEN_MASK;
1256 un->un_flags |= AXCSUM_FRAME; 1256 un->un_flags |= AXCSUM_FRAME;
1257 } else { 1257 } else {
1258 sc->sc_lenmask = AXE_HDR_LEN_MASK; 1258 sc->sc_lenmask = AXE_HDR_LEN_MASK;
1259 un->un_flags |= AXSTD_FRAME; 1259 un->un_flags |= AXSTD_FRAME;
1260 } 1260 }
1261 } 1261 }
1262 1262
1263 /* Configure TX/RX checksum offloading. */ 1263 /* Configure TX/RX checksum offloading. */
1264 axe_csum_cfg(sc); 1264 axe_csum_cfg(sc);
1265 1265
1266 if (un->un_flags & AX772B) { 1266 if (un->un_flags & AX772B) {
1267 /* AX88772B uses different maximum frame burst configuration. */ 1267 /* AX88772B uses different maximum frame burst configuration. */
1268 axe_cmd(sc, AXE_772B_CMD_RXCTL_WRITE_CFG, 1268 axe_cmd(sc, AXE_772B_CMD_RXCTL_WRITE_CFG,
1269 ax88772b_mfb_table[AX88772B_MFB_16K].threshold, 1269 ax88772b_mfb_table[AX88772B_MFB_16K].threshold,
1270 ax88772b_mfb_table[AX88772B_MFB_16K].byte_cnt, NULL); 1270 ax88772b_mfb_table[AX88772B_MFB_16K].byte_cnt, NULL);
1271 } 1271 }
1272 /* Enable receiver, set RX mode */ 1272 /* Enable receiver, set RX mode */
1273 rxmode = (AXE_RXCMD_BROADCAST | AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE); 1273 rxmode = (AXE_RXCMD_BROADCAST | AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE);
1274 if (AXE_IS_172(un)) 1274 if (AXE_IS_172(un))
1275 rxmode |= AXE_172_RXCMD_UNICAST; 1275 rxmode |= AXE_172_RXCMD_UNICAST;
1276 else { 1276 else {
1277 if (un->un_flags & AX772B) { 1277 if (un->un_flags & AX772B) {
1278 /* 1278 /*
1279 * Select RX header format type 1. Aligning IP 1279 * Select RX header format type 1. Aligning IP
1280 * header on 4 byte boundary is not needed when 1280 * header on 4 byte boundary is not needed when
1281 * checksum offloading feature is not used 1281 * checksum offloading feature is not used
1282 * because we always copy the received frame in 1282 * because we always copy the received frame in
1283 * RX handler. When RX checksum offloading is 1283 * RX handler. When RX checksum offloading is
1284 * active, aligning IP header is required to 1284 * active, aligning IP header is required to
1285 * reflect actual frame length including RX 1285 * reflect actual frame length including RX
1286 * header size. 1286 * header size.
1287 */ 1287 */
1288 rxmode |= AXE_772B_RXCMD_HDR_TYPE_1; 1288 rxmode |= AXE_772B_RXCMD_HDR_TYPE_1;
1289 if (un->un_flags & AXCSUM_FRAME) 1289 if (un->un_flags & AXCSUM_FRAME)
1290 rxmode |= AXE_772B_RXCMD_IPHDR_ALIGN; 1290 rxmode |= AXE_772B_RXCMD_IPHDR_ALIGN;
1291 } else { 1291 } else {
1292 /* 1292 /*
1293 * Default Rx buffer size is too small to get 1293 * Default Rx buffer size is too small to get
1294 * maximum performance. 1294 * maximum performance.
1295 */ 1295 */
1296#if 0 1296#if 0
1297 if (un->un_udev->ud_speed == USB_SPEED_HIGH) { 1297 if (un->un_udev->ud_speed == USB_SPEED_HIGH) {
1298 /* Largest possible USB buffer size for AX88178 */ 1298 /* Largest possible USB buffer size for AX88178 */
1299 } 1299 }
1300#endif 1300#endif
1301 rxmode |= AXE_178_RXCMD_MFB_16384; 1301 rxmode |= AXE_178_RXCMD_MFB_16384;
1302 } 1302 }
1303 } 1303 }
1304 1304
1305 DPRINTF("rxmode %#jx", rxmode, 0, 0, 0); 1305 DPRINTF("rxmode %#jx", rxmode, 0, 0, 0);
1306 1306
1307 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 1307 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
1308 1308
1309 /* Accept multicast frame or run promisc. mode */ 1309 /* Accept multicast frame or run promisc. mode */
1310 axe_rcvfilt_locked(un); 1310 axe_rcvfilt_locked(un);
1311 1311
1312 return usbnet_init_rx_tx(un); 1312 return usbnet_init_rx_tx(un);
1313} 1313}
1314 1314
1315static int 1315static int
1316axe_uno_init(struct ifnet *ifp) 1316axe_uno_init(struct ifnet *ifp)
1317{ 1317{
1318 int ret = axe_init_locked(ifp); 1318 int ret = axe_init_locked(ifp);
1319 1319
1320 return ret; 1320 return ret;
1321} 1321}
1322 1322
1323static void 1323static void
1324axe_uno_mcast(struct ifnet *ifp) 1324axe_uno_mcast(struct ifnet *ifp)
1325{ 1325{
1326 struct usbnet * const un = ifp->if_softc; 1326 struct usbnet * const un = ifp->if_softc;
1327 1327
1328 usbnet_lock_core(un); 1328 usbnet_lock_core(un);
1329 usbnet_busy(un); 
1330 1329
1331 axe_rcvfilt_locked(un); 1330 axe_rcvfilt_locked(un);
1332 1331
1333 usbnet_unbusy(un); 
1334 usbnet_unlock_core(un); 1332 usbnet_unlock_core(un);
1335} 1333}
1336 1334
1337static void 1335static void
1338axe_uno_stop(struct ifnet *ifp, int disable) 1336axe_uno_stop(struct ifnet *ifp, int disable)
1339{ 1337{
1340 struct usbnet * const un = ifp->if_softc; 1338 struct usbnet * const un = ifp->if_softc;
1341 1339
1342 axe_reset(un); 1340 axe_reset(un);
1343} 1341}
1344 1342
1345#ifdef _MODULE 1343#ifdef _MODULE
1346#include "ioconf.c" 1344#include "ioconf.c"
1347#endif 1345#endif
1348 1346
1349USBNET_MODULE(axe) 1347USBNET_MODULE(axe)

cvs diff -r1.77 -r1.78 src/sys/dev/usb/if_axen.c (switch to unified diff)

--- src/sys/dev/usb/if_axen.c 2022/03/03 05:51:17 1.77
+++ src/sys/dev/usb/if_axen.c 2022/03/03 05:51:27 1.78
@@ -1,973 +1,971 @@ @@ -1,973 +1,971 @@
1/* $NetBSD: if_axen.c,v 1.77 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_axen.c,v 1.78 2022/03/03 05:51:27 riastradh Exp $ */
2/* $OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $ */ 2/* $OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2013 Yojiro UO <yuo@openbsd.org> 5 * Copyright (c) 2013 Yojiro UO <yuo@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/* 20/*
21 * ASIX Electronics AX88178a USB 2.0 ethernet and AX88179 USB 3.0 Ethernet 21 * ASIX Electronics AX88178a USB 2.0 ethernet and AX88179 USB 3.0 Ethernet
22 * driver. 22 * driver.
23 */ 23 */
24 24
25#include <sys/cdefs.h> 25#include <sys/cdefs.h>
26__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.77 2022/03/03 05:51:17 riastradh Exp $"); 26__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.78 2022/03/03 05:51:27 riastradh Exp $");
27 27
28#ifdef _KERNEL_OPT 28#ifdef _KERNEL_OPT
29#include "opt_usb.h" 29#include "opt_usb.h"
30#endif 30#endif
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33 33
34#include <netinet/in.h> /* XXX for netinet/ip.h */ 34#include <netinet/in.h> /* XXX for netinet/ip.h */
35#include <netinet/ip.h> /* XXX for IP_MAXPACKET */ 35#include <netinet/ip.h> /* XXX for IP_MAXPACKET */
36 36
37#include <dev/usb/usbnet.h> 37#include <dev/usb/usbnet.h>
38 38
39#include <dev/usb/if_axenreg.h> 39#include <dev/usb/if_axenreg.h>
40 40
41#ifdef AXEN_DEBUG 41#ifdef AXEN_DEBUG
42#define DPRINTF(x) do { if (axendebug) printf x; } while (/*CONSTCOND*/0) 42#define DPRINTF(x) do { if (axendebug) printf x; } while (/*CONSTCOND*/0)
43#define DPRINTFN(n, x) do { if (axendebug >= (n)) printf x; } while (/*CONSTCOND*/0) 43#define DPRINTFN(n, x) do { if (axendebug >= (n)) printf x; } while (/*CONSTCOND*/0)
44int axendebug = 0; 44int axendebug = 0;
45#else 45#else
46#define DPRINTF(x) 46#define DPRINTF(x)
47#define DPRINTFN(n, x) 47#define DPRINTFN(n, x)
48#endif 48#endif
49 49
50struct axen_type { 50struct axen_type {
51 struct usb_devno axen_devno; 51 struct usb_devno axen_devno;
52 uint16_t axen_flags; 52 uint16_t axen_flags;
53#define AX178A 0x0001 /* AX88178a */ 53#define AX178A 0x0001 /* AX88178a */
54#define AX179 0x0002 /* AX88179 */ 54#define AX179 0x0002 /* AX88179 */
55}; 55};
56 56
57/* 57/*
58 * Various supported device vendors/products. 58 * Various supported device vendors/products.
59 */ 59 */
60static const struct axen_type axen_devs[] = { 60static const struct axen_type axen_devs[] = {
61#if 0 /* not tested */ 61#if 0 /* not tested */
62 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178A}, AX178A }, 62 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178A}, AX178A },
63#endif 63#endif
64 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88179}, AX179 }, 64 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88179}, AX179 },
65 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUB1312}, AX179 } 65 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUB1312}, AX179 }
66}; 66};
67 67
68#define axen_lookup(v, p) ((const struct axen_type *)usb_lookup(axen_devs, v, p)) 68#define axen_lookup(v, p) ((const struct axen_type *)usb_lookup(axen_devs, v, p))
69 69
70static int axen_match(device_t, cfdata_t, void *); 70static int axen_match(device_t, cfdata_t, void *);
71static void axen_attach(device_t, device_t, void *); 71static void axen_attach(device_t, device_t, void *);
72 72
73CFATTACH_DECL_NEW(axen, sizeof(struct usbnet), 73CFATTACH_DECL_NEW(axen, sizeof(struct usbnet),
74 axen_match, axen_attach, usbnet_detach, usbnet_activate); 74 axen_match, axen_attach, usbnet_detach, usbnet_activate);
75 75
76static int axen_cmd(struct usbnet *, int, int, int, void *); 76static int axen_cmd(struct usbnet *, int, int, int, void *);
77static void axen_reset(struct usbnet *); 77static void axen_reset(struct usbnet *);
78static int axen_get_eaddr(struct usbnet *, void *); 78static int axen_get_eaddr(struct usbnet *, void *);
79static void axen_ax88179_init(struct usbnet *); 79static void axen_ax88179_init(struct usbnet *);
80 80
81static void axen_uno_stop(struct ifnet *, int); 81static void axen_uno_stop(struct ifnet *, int);
82static int axen_uno_ioctl(struct ifnet *, u_long, void *); 82static int axen_uno_ioctl(struct ifnet *, u_long, void *);
83static void axen_uno_mcast(struct ifnet *); 83static void axen_uno_mcast(struct ifnet *);
84static int axen_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 84static int axen_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
85static int axen_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 85static int axen_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
86static void axen_uno_mii_statchg(struct ifnet *); 86static void axen_uno_mii_statchg(struct ifnet *);
87static void axen_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 87static void axen_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
88 uint32_t); 88 uint32_t);
89static unsigned axen_uno_tx_prepare(struct usbnet *, struct mbuf *, 89static unsigned axen_uno_tx_prepare(struct usbnet *, struct mbuf *,
90 struct usbnet_chain *); 90 struct usbnet_chain *);
91static int axen_uno_init(struct ifnet *); 91static int axen_uno_init(struct ifnet *);
92 92
93static const struct usbnet_ops axen_ops = { 93static const struct usbnet_ops axen_ops = {
94 .uno_stop = axen_uno_stop, 94 .uno_stop = axen_uno_stop,
95 .uno_ioctl = axen_uno_ioctl, 95 .uno_ioctl = axen_uno_ioctl,
96 .uno_mcast = axen_uno_mcast, 96 .uno_mcast = axen_uno_mcast,
97 .uno_read_reg = axen_uno_mii_read_reg, 97 .uno_read_reg = axen_uno_mii_read_reg,
98 .uno_write_reg = axen_uno_mii_write_reg, 98 .uno_write_reg = axen_uno_mii_write_reg,
99 .uno_statchg = axen_uno_mii_statchg, 99 .uno_statchg = axen_uno_mii_statchg,
100 .uno_tx_prepare = axen_uno_tx_prepare, 100 .uno_tx_prepare = axen_uno_tx_prepare,
101 .uno_rx_loop = axen_uno_rx_loop, 101 .uno_rx_loop = axen_uno_rx_loop,
102 .uno_init = axen_uno_init, 102 .uno_init = axen_uno_init,
103}; 103};
104 104
105static int 105static int
106axen_cmd(struct usbnet *un, int cmd, int index, int val, void *buf) 106axen_cmd(struct usbnet *un, int cmd, int index, int val, void *buf)
107{ 107{
108 usb_device_request_t req; 108 usb_device_request_t req;
109 usbd_status err; 109 usbd_status err;
110 110
111 usbnet_isowned_core(un); 111 usbnet_isowned_core(un);
112 112
113 if (usbnet_isdying(un)) 113 if (usbnet_isdying(un))
114 return 0; 114 return 0;
115 115
116 if (AXEN_CMD_DIR(cmd)) 116 if (AXEN_CMD_DIR(cmd))
117 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 117 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
118 else 118 else
119 req.bmRequestType = UT_READ_VENDOR_DEVICE; 119 req.bmRequestType = UT_READ_VENDOR_DEVICE;
120 req.bRequest = AXEN_CMD_CMD(cmd); 120 req.bRequest = AXEN_CMD_CMD(cmd);
121 USETW(req.wValue, val); 121 USETW(req.wValue, val);
122 USETW(req.wIndex, index); 122 USETW(req.wIndex, index);
123 USETW(req.wLength, AXEN_CMD_LEN(cmd)); 123 USETW(req.wLength, AXEN_CMD_LEN(cmd));
124 124
125 err = usbd_do_request(un->un_udev, &req, buf); 125 err = usbd_do_request(un->un_udev, &req, buf);
126 DPRINTFN(5, ("axen_cmd: cmd 0x%04x val 0x%04x len %d\n", 126 DPRINTFN(5, ("axen_cmd: cmd 0x%04x val 0x%04x len %d\n",
127 cmd, val, AXEN_CMD_LEN(cmd))); 127 cmd, val, AXEN_CMD_LEN(cmd)));
128 128
129 if (err) { 129 if (err) {
130 DPRINTF(("%s: cmd: %d, error: %d\n", __func__, cmd, err)); 130 DPRINTF(("%s: cmd: %d, error: %d\n", __func__, cmd, err));
131 return -1; 131 return -1;
132 } 132 }
133 133
134 return 0; 134 return 0;
135} 135}
136 136
137static int 137static int
138axen_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 138axen_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
139{ 139{
140 uint16_t data; 140 uint16_t data;
141 141
142 if (un->un_phyno != phy) 142 if (un->un_phyno != phy)
143 return EINVAL; 143 return EINVAL;
144 144
145 usbd_status err = axen_cmd(un, AXEN_CMD_MII_READ_REG, reg, phy, &data); 145 usbd_status err = axen_cmd(un, AXEN_CMD_MII_READ_REG, reg, phy, &data);
146 if (err) 146 if (err)
147 return EIO; 147 return EIO;
148 148
149 *val = le16toh(data); 149 *val = le16toh(data);
150 if (reg == MII_BMSR) 150 if (reg == MII_BMSR)
151 *val &= ~BMSR_EXTCAP; 151 *val &= ~BMSR_EXTCAP;
152 152
153 return 0; 153 return 0;
154} 154}
155 155
156static int 156static int
157axen_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 157axen_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
158{ 158{
159 uint16_t uval = htole16(val); 159 uint16_t uval = htole16(val);
160 160
161 if (un->un_phyno != phy) 161 if (un->un_phyno != phy)
162 return EINVAL; 162 return EINVAL;
163 163
164 usbd_status err = axen_cmd(un, AXEN_CMD_MII_WRITE_REG, reg, phy, &uval); 164 usbd_status err = axen_cmd(un, AXEN_CMD_MII_WRITE_REG, reg, phy, &uval);
165 if (err) 165 if (err)
166 return EIO; 166 return EIO;
167 167
168 return 0; 168 return 0;
169} 169}
170 170
171static void 171static void
172axen_uno_mii_statchg(struct ifnet *ifp) 172axen_uno_mii_statchg(struct ifnet *ifp)
173{ 173{
174 struct usbnet * const un = ifp->if_softc; 174 struct usbnet * const un = ifp->if_softc;
175 struct mii_data * const mii = usbnet_mii(un); 175 struct mii_data * const mii = usbnet_mii(un);
176 int err; 176 int err;
177 uint16_t val; 177 uint16_t val;
178 uint16_t wval; 178 uint16_t wval;
179 179
180 if (usbnet_isdying(un)) 180 if (usbnet_isdying(un))
181 return; 181 return;
182 182
183 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 183 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
184 (IFM_ACTIVE | IFM_AVALID)) { 184 (IFM_ACTIVE | IFM_AVALID)) {
185 switch (IFM_SUBTYPE(mii->mii_media_active)) { 185 switch (IFM_SUBTYPE(mii->mii_media_active)) {
186 case IFM_10_T: 186 case IFM_10_T:
187 case IFM_100_TX: 187 case IFM_100_TX:
188 usbnet_set_link(un, true); 188 usbnet_set_link(un, true);
189 break; 189 break;
190 case IFM_1000_T: 190 case IFM_1000_T:
191 usbnet_set_link(un, true); 191 usbnet_set_link(un, true);
192 break; 192 break;
193 default: 193 default:
194 break; 194 break;
195 } 195 }
196 } 196 }
197 197
198 /* Lost link, do nothing. */ 198 /* Lost link, do nothing. */
199 if (!usbnet_havelink(un)) 199 if (!usbnet_havelink(un))
200 return; 200 return;
201 201
202 val = 0; 202 val = 0;
203 if ((mii->mii_media_active & IFM_FDX) != 0) 203 if ((mii->mii_media_active & IFM_FDX) != 0)
204 val |= AXEN_MEDIUM_FDX; 204 val |= AXEN_MEDIUM_FDX;
205 205
206 val |= AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN | 206 val |= AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN |
207 AXEN_MEDIUM_RECV_EN; 207 AXEN_MEDIUM_RECV_EN;
208 switch (IFM_SUBTYPE(mii->mii_media_active)) { 208 switch (IFM_SUBTYPE(mii->mii_media_active)) {
209 case IFM_1000_T: 209 case IFM_1000_T:
210 val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ; 210 val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
211 break; 211 break;
212 case IFM_100_TX: 212 case IFM_100_TX:
213 val |= AXEN_MEDIUM_PS; 213 val |= AXEN_MEDIUM_PS;
214 break; 214 break;
215 case IFM_10_T: 215 case IFM_10_T:
216 /* doesn't need to be handled */ 216 /* doesn't need to be handled */
217 break; 217 break;
218 } 218 }
219 219
220 DPRINTF(("%s: val=%#x\n", __func__, val)); 220 DPRINTF(("%s: val=%#x\n", __func__, val));
221 wval = htole16(val); 221 wval = htole16(val);
222 err = axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval); 222 err = axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
223 if (err) 223 if (err)
224 aprint_error_dev(un->un_dev, "media change failed\n"); 224 aprint_error_dev(un->un_dev, "media change failed\n");
225} 225}
226 226
227static void 227static void
228axen_setiff_locked(struct usbnet *un) 228axen_setiff_locked(struct usbnet *un)
229{ 229{
230 struct ifnet * const ifp = usbnet_ifp(un); 230 struct ifnet * const ifp = usbnet_ifp(un);
231 struct ethercom *ec = usbnet_ec(un); 231 struct ethercom *ec = usbnet_ec(un);
232 struct ether_multi *enm; 232 struct ether_multi *enm;
233 struct ether_multistep step; 233 struct ether_multistep step;
234 uint32_t h = 0; 234 uint32_t h = 0;
235 uint16_t rxmode; 235 uint16_t rxmode;
236 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 236 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
237 uint16_t wval; 237 uint16_t wval;
238 238
239 if (usbnet_isdying(un)) 239 if (usbnet_isdying(un))
240 return; 240 return;
241 241
242 usbnet_isowned_core(un); 242 usbnet_isowned_core(un);
243 243
244 rxmode = 0; 244 rxmode = 0;
245 245
246 /* Enable receiver, set RX mode */ 246 /* Enable receiver, set RX mode */
247 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); 247 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval);
248 rxmode = le16toh(wval); 248 rxmode = le16toh(wval);
249 rxmode &= ~(AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_PROMISC | 249 rxmode &= ~(AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_PROMISC |
250 AXEN_RXCTL_ACPT_MCAST); 250 AXEN_RXCTL_ACPT_MCAST);
251 251
252 if (ifp->if_flags & IFF_PROMISC) { 252 if (ifp->if_flags & IFF_PROMISC) {
253 DPRINTF(("%s: promisc\n", device_xname(un->un_dev))); 253 DPRINTF(("%s: promisc\n", device_xname(un->un_dev)));
254 rxmode |= AXEN_RXCTL_PROMISC; 254 rxmode |= AXEN_RXCTL_PROMISC;
255allmulti: 255allmulti:
256 ETHER_LOCK(ec); 256 ETHER_LOCK(ec);
257 ec->ec_flags |= ETHER_F_ALLMULTI; 257 ec->ec_flags |= ETHER_F_ALLMULTI;
258 ETHER_UNLOCK(ec); 258 ETHER_UNLOCK(ec);
259 rxmode |= AXEN_RXCTL_ACPT_ALL_MCAST 259 rxmode |= AXEN_RXCTL_ACPT_ALL_MCAST
260 /* | AXEN_RXCTL_ACPT_PHY_MCAST */; 260 /* | AXEN_RXCTL_ACPT_PHY_MCAST */;
261 } else { 261 } else {
262 /* now program new ones */ 262 /* now program new ones */
263 DPRINTF(("%s: initializing hash table\n", 263 DPRINTF(("%s: initializing hash table\n",
264 device_xname(un->un_dev))); 264 device_xname(un->un_dev)));
265 ETHER_LOCK(ec); 265 ETHER_LOCK(ec);
266 ec->ec_flags &= ~ETHER_F_ALLMULTI; 266 ec->ec_flags &= ~ETHER_F_ALLMULTI;
267 267
268 ETHER_FIRST_MULTI(step, ec, enm); 268 ETHER_FIRST_MULTI(step, ec, enm);
269 while (enm != NULL) { 269 while (enm != NULL) {
270 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 270 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
271 ETHER_ADDR_LEN)) { 271 ETHER_ADDR_LEN)) {
272 DPRINTF(("%s: allmulti\n", 272 DPRINTF(("%s: allmulti\n",
273 device_xname(un->un_dev))); 273 device_xname(un->un_dev)));
274 memset(hashtbl, 0, sizeof(hashtbl)); 274 memset(hashtbl, 0, sizeof(hashtbl));
275 ETHER_UNLOCK(ec); 275 ETHER_UNLOCK(ec);
276 goto allmulti; 276 goto allmulti;
277 } 277 }
278 h = ether_crc32_be(enm->enm_addrlo, 278 h = ether_crc32_be(enm->enm_addrlo,
279 ETHER_ADDR_LEN) >> 26; 279 ETHER_ADDR_LEN) >> 26;
280 hashtbl[h / 8] |= 1 << (h % 8); 280 hashtbl[h / 8] |= 1 << (h % 8);
281 DPRINTF(("%s: %s added\n", 281 DPRINTF(("%s: %s added\n",
282 device_xname(un->un_dev), 282 device_xname(un->un_dev),
283 ether_sprintf(enm->enm_addrlo))); 283 ether_sprintf(enm->enm_addrlo)));
284 ETHER_NEXT_MULTI(step, enm); 284 ETHER_NEXT_MULTI(step, enm);
285 } 285 }
286 ETHER_UNLOCK(ec); 286 ETHER_UNLOCK(ec);
287 rxmode |= AXEN_RXCTL_ACPT_MCAST; 287 rxmode |= AXEN_RXCTL_ACPT_MCAST;
288 } 288 }
289 289
290 axen_cmd(un, AXEN_CMD_MAC_WRITE_FILTER, 8, AXEN_FILTER_MULTI, hashtbl); 290 axen_cmd(un, AXEN_CMD_MAC_WRITE_FILTER, 8, AXEN_FILTER_MULTI, hashtbl);
291 wval = htole16(rxmode); 291 wval = htole16(rxmode);
292 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 292 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval);
293} 293}
294 294
295static void 295static void
296axen_reset(struct usbnet *un) 296axen_reset(struct usbnet *un)
297{ 297{
298 usbnet_isowned_core(un); 298 usbnet_isowned_core(un);
299 if (usbnet_isdying(un)) 299 if (usbnet_isdying(un))
300 return; 300 return;
301 /* XXX What to reset? */ 301 /* XXX What to reset? */
302 302
303 /* Wait a little while for the chip to get its brains in order. */ 303 /* Wait a little while for the chip to get its brains in order. */
304 DELAY(1000); 304 DELAY(1000);
305} 305}
306 306
307static int 307static int
308axen_get_eaddr(struct usbnet *un, void *addr) 308axen_get_eaddr(struct usbnet *un, void *addr)
309{ 309{
310#if 1 310#if 1
311 return axen_cmd(un, AXEN_CMD_MAC_READ_ETHER, 6, AXEN_CMD_MAC_NODE_ID, 311 return axen_cmd(un, AXEN_CMD_MAC_READ_ETHER, 6, AXEN_CMD_MAC_NODE_ID,
312 addr); 312 addr);
313#else 313#else
314 int i, retry; 314 int i, retry;
315 uint8_t eeprom[20]; 315 uint8_t eeprom[20];
316 uint16_t csum; 316 uint16_t csum;
317 uint16_t buf; 317 uint16_t buf;
318 318
319 for (i = 0; i < 6; i++) { 319 for (i = 0; i < 6; i++) {
320 /* set eeprom address */ 320 /* set eeprom address */
321 buf = htole16(i); 321 buf = htole16(i);
322 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MAC_EEPROM_ADDR, &buf); 322 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MAC_EEPROM_ADDR, &buf);
323 323
324 /* set eeprom command */ 324 /* set eeprom command */
325 buf = htole16(AXEN_EEPROM_READ); 325 buf = htole16(AXEN_EEPROM_READ);
326 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MAC_EEPROM_CMD, &buf); 326 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MAC_EEPROM_CMD, &buf);
327 327
328 /* check the value is ready */ 328 /* check the value is ready */
329 retry = 3; 329 retry = 3;
330 do { 330 do {
331 buf = htole16(AXEN_EEPROM_READ); 331 buf = htole16(AXEN_EEPROM_READ);
332 usbd_delay_ms(un->un_udev, 10); 332 usbd_delay_ms(un->un_udev, 10);
333 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_MAC_EEPROM_CMD, 333 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_MAC_EEPROM_CMD,
334 &buf); 334 &buf);
335 retry--; 335 retry--;
336 if (retry < 0) 336 if (retry < 0)
337 return EINVAL; 337 return EINVAL;
338 } while ((le16toh(buf) & 0xff) & AXEN_EEPROM_BUSY); 338 } while ((le16toh(buf) & 0xff) & AXEN_EEPROM_BUSY);
339 339
340 /* read data */ 340 /* read data */
341 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_EEPROM_READ, 341 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_EEPROM_READ,
342 &eeprom[i * 2]); 342 &eeprom[i * 2]);
343 343
344 /* sanity check */ 344 /* sanity check */
345 if ((i == 0) && (eeprom[0] == 0xff)) 345 if ((i == 0) && (eeprom[0] == 0xff))
346 return EINVAL; 346 return EINVAL;
347 } 347 }
348 348
349 /* check checksum */ 349 /* check checksum */
350 csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9]; 350 csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9];
351 csum = (csum >> 8) + (csum & 0xff) + eeprom[10]; 351 csum = (csum >> 8) + (csum & 0xff) + eeprom[10];
352 if (csum != 0xff) { 352 if (csum != 0xff) {
353 printf("eeprom checksum mismatch(0x%02x)\n", csum); 353 printf("eeprom checksum mismatch(0x%02x)\n", csum);
354 return EINVAL; 354 return EINVAL;
355 } 355 }
356 356
357 memcpy(addr, eeprom, ETHER_ADDR_LEN); 357 memcpy(addr, eeprom, ETHER_ADDR_LEN);
358 return 0; 358 return 0;
359#endif 359#endif
360} 360}
361 361
362static void 362static void
363axen_ax88179_init(struct usbnet *un) 363axen_ax88179_init(struct usbnet *un)
364{ 364{
365 struct axen_qctrl qctrl; 365 struct axen_qctrl qctrl;
366 uint16_t ctl, temp; 366 uint16_t ctl, temp;
367 uint16_t wval; 367 uint16_t wval;
368 uint8_t val; 368 uint8_t val;
369 369
370 usbnet_lock_core(un); 370 usbnet_lock_core(un);
371 usbnet_busy(un); 371 usbnet_busy(un);
372 372
373 /* XXX: ? */ 373 /* XXX: ? */
374 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_UNK_05, &val); 374 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_UNK_05, &val);
375 DPRINTFN(5, ("AXEN_CMD_MAC_READ(0x05): 0x%02x\n", val)); 375 DPRINTFN(5, ("AXEN_CMD_MAC_READ(0x05): 0x%02x\n", val));
376 376
377 /* check AX88179 version, UA1 / UA2 */ 377 /* check AX88179 version, UA1 / UA2 */
378 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_GENERAL_STATUS, &val); 378 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_GENERAL_STATUS, &val);
379 /* UA1 */ 379 /* UA1 */
380 if (!(val & AXEN_GENERAL_STATUS_MASK)) { 380 if (!(val & AXEN_GENERAL_STATUS_MASK)) {
381 DPRINTF(("AX88179 ver. UA1\n")); 381 DPRINTF(("AX88179 ver. UA1\n"));
382 } else { 382 } else {
383 DPRINTF(("AX88179 ver. UA2\n")); 383 DPRINTF(("AX88179 ver. UA2\n"));
384 } 384 }
385 385
386 /* power up ethernet PHY */ 386 /* power up ethernet PHY */
387 wval = htole16(0); 387 wval = htole16(0);
388 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval); 388 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval);
389 389
390 wval = htole16(AXEN_PHYPWR_RSTCTL_IPRL); 390 wval = htole16(AXEN_PHYPWR_RSTCTL_IPRL);
391 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval); 391 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval);
392 usbd_delay_ms(un->un_udev, 200); 392 usbd_delay_ms(un->un_udev, 200);
393 393
394 /* set clock mode */ 394 /* set clock mode */
395 val = AXEN_PHYCLK_ACS | AXEN_PHYCLK_BCS; 395 val = AXEN_PHYCLK_ACS | AXEN_PHYCLK_BCS;
396 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val); 396 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val);
397 usbd_delay_ms(un->un_udev, 100); 397 usbd_delay_ms(un->un_udev, 100);
398 398
399 /* set monitor mode (disable) */ 399 /* set monitor mode (disable) */
400 val = AXEN_MONITOR_NONE; 400 val = AXEN_MONITOR_NONE;
401 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MONITOR_MODE, &val); 401 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MONITOR_MODE, &val);
402 402
403 /* enable auto detach */ 403 /* enable auto detach */
404 axen_cmd(un, AXEN_CMD_EEPROM_READ, 2, AXEN_EEPROM_STAT, &wval); 404 axen_cmd(un, AXEN_CMD_EEPROM_READ, 2, AXEN_EEPROM_STAT, &wval);
405 temp = le16toh(wval); 405 temp = le16toh(wval);
406 DPRINTFN(2,("EEPROM0x43 = 0x%04x\n", temp)); 406 DPRINTFN(2,("EEPROM0x43 = 0x%04x\n", temp));
407 if (!(temp == 0xffff) && !(temp & 0x0100)) { 407 if (!(temp == 0xffff) && !(temp & 0x0100)) {
408 /* Enable auto detach bit */ 408 /* Enable auto detach bit */
409 val = 0; 409 val = 0;
410 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val); 410 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val);
411 val = AXEN_PHYCLK_ULR; 411 val = AXEN_PHYCLK_ULR;
412 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val); 412 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val);
413 usbd_delay_ms(un->un_udev, 100); 413 usbd_delay_ms(un->un_udev, 100);
414 414
415 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_PHYPWR_RSTCTL, &wval); 415 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_PHYPWR_RSTCTL, &wval);
416 ctl = le16toh(wval); 416 ctl = le16toh(wval);
417 ctl |= AXEN_PHYPWR_RSTCTL_AUTODETACH; 417 ctl |= AXEN_PHYPWR_RSTCTL_AUTODETACH;
418 wval = htole16(ctl); 418 wval = htole16(ctl);
419 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval); 419 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval);
420 usbd_delay_ms(un->un_udev, 200); 420 usbd_delay_ms(un->un_udev, 200);
421 aprint_error_dev(un->un_dev, "enable auto detach (0x%04x)\n", 421 aprint_error_dev(un->un_dev, "enable auto detach (0x%04x)\n",
422 ctl); 422 ctl);
423 } 423 }
424 424
425 /* bulkin queue setting */ 425 /* bulkin queue setting */
426 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &val); 426 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &val);
427 switch (val) { 427 switch (val) {
428 case AXEN_USB_FS: 428 case AXEN_USB_FS:
429 DPRINTF(("uplink: USB1.1\n")); 429 DPRINTF(("uplink: USB1.1\n"));
430 qctrl.ctrl = 0x07; 430 qctrl.ctrl = 0x07;
431 qctrl.timer_low = 0xcc; 431 qctrl.timer_low = 0xcc;
432 qctrl.timer_high = 0x4c; 432 qctrl.timer_high = 0x4c;
433 qctrl.bufsize = AXEN_BUFSZ_LS - 1; 433 qctrl.bufsize = AXEN_BUFSZ_LS - 1;
434 qctrl.ifg = 0x08; 434 qctrl.ifg = 0x08;
435 break; 435 break;
436 case AXEN_USB_HS: 436 case AXEN_USB_HS:
437 DPRINTF(("uplink: USB2.0\n")); 437 DPRINTF(("uplink: USB2.0\n"));
438 qctrl.ctrl = 0x07; 438 qctrl.ctrl = 0x07;
439 qctrl.timer_low = 0x02; 439 qctrl.timer_low = 0x02;
440 qctrl.timer_high = 0xa0; 440 qctrl.timer_high = 0xa0;
441 qctrl.bufsize = AXEN_BUFSZ_HS - 1; 441 qctrl.bufsize = AXEN_BUFSZ_HS - 1;
442 qctrl.ifg = 0xff; 442 qctrl.ifg = 0xff;
443 break; 443 break;
444 case AXEN_USB_SS: 444 case AXEN_USB_SS:
445 DPRINTF(("uplink: USB3.0\n")); 445 DPRINTF(("uplink: USB3.0\n"));
446 qctrl.ctrl = 0x07; 446 qctrl.ctrl = 0x07;
447 qctrl.timer_low = 0x4f; 447 qctrl.timer_low = 0x4f;
448 qctrl.timer_high = 0x00; 448 qctrl.timer_high = 0x00;
449 qctrl.bufsize = AXEN_BUFSZ_SS - 1; 449 qctrl.bufsize = AXEN_BUFSZ_SS - 1;
450 qctrl.ifg = 0xff; 450 qctrl.ifg = 0xff;
451 break; 451 break;
452 default: 452 default:
453 aprint_error_dev(un->un_dev, "unknown uplink bus:0x%02x\n", 453 aprint_error_dev(un->un_dev, "unknown uplink bus:0x%02x\n",
454 val); 454 val);
455 usbnet_unbusy(un); 455 usbnet_unbusy(un);
456 usbnet_unlock_core(un); 456 usbnet_unlock_core(un);
457 return; 457 return;
458 } 458 }
459 axen_cmd(un, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl); 459 axen_cmd(un, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
460 460
461 /* 461 /*
462 * set buffer high/low watermark to pause/resume. 462 * set buffer high/low watermark to pause/resume.
463 * write 2byte will set high/log simultaneous with AXEN_PAUSE_HIGH. 463 * write 2byte will set high/log simultaneous with AXEN_PAUSE_HIGH.
464 * XXX: what is the best value? OSX driver uses 0x3c-0x4c as LOW-HIGH 464 * XXX: what is the best value? OSX driver uses 0x3c-0x4c as LOW-HIGH
465 * watermark parameters. 465 * watermark parameters.
466 */ 466 */
467 val = 0x34; 467 val = 0x34;
468 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PAUSE_LOW_WATERMARK, &val); 468 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PAUSE_LOW_WATERMARK, &val);
469 val = 0x52; 469 val = 0x52;
470 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PAUSE_HIGH_WATERMARK, &val); 470 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PAUSE_HIGH_WATERMARK, &val);
471 471
472 /* Set RX/TX configuration. */ 472 /* Set RX/TX configuration. */
473 /* Set RX control register */ 473 /* Set RX control register */
474 ctl = AXEN_RXCTL_IPE | AXEN_RXCTL_DROPCRCERR | AXEN_RXCTL_AUTOB; 474 ctl = AXEN_RXCTL_IPE | AXEN_RXCTL_DROPCRCERR | AXEN_RXCTL_AUTOB;
475 wval = htole16(ctl); 475 wval = htole16(ctl);
476 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 476 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval);
477 477
478 /* set monitor mode (enable) */ 478 /* set monitor mode (enable) */
479 val = AXEN_MONITOR_PMETYPE | AXEN_MONITOR_PMEPOL | AXEN_MONITOR_RWMP; 479 val = AXEN_MONITOR_PMETYPE | AXEN_MONITOR_PMEPOL | AXEN_MONITOR_RWMP;
480 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MONITOR_MODE, &val); 480 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MONITOR_MODE, &val);
481 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_MONITOR_MODE, &val); 481 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_MONITOR_MODE, &val);
482 DPRINTF(("axen: Monitor mode = 0x%02x\n", val)); 482 DPRINTF(("axen: Monitor mode = 0x%02x\n", val));
483 483
484 /* set medium type */ 484 /* set medium type */
485 ctl = AXEN_MEDIUM_GIGA | AXEN_MEDIUM_FDX | AXEN_MEDIUM_EN_125MHZ | 485 ctl = AXEN_MEDIUM_GIGA | AXEN_MEDIUM_FDX | AXEN_MEDIUM_EN_125MHZ |
486 AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN | 486 AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN |
487 AXEN_MEDIUM_RECV_EN; 487 AXEN_MEDIUM_RECV_EN;
488 wval = htole16(ctl); 488 wval = htole16(ctl);
489 DPRINTF(("axen: set to medium mode: 0x%04x\n", ctl)); 489 DPRINTF(("axen: set to medium mode: 0x%04x\n", ctl));
490 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval); 490 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
491 usbd_delay_ms(un->un_udev, 100); 491 usbd_delay_ms(un->un_udev, 100);
492 492
493 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MEDIUM_STATUS, &wval); 493 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MEDIUM_STATUS, &wval);
494 DPRINTF(("axen: current medium mode: 0x%04x\n", le16toh(wval))); 494 DPRINTF(("axen: current medium mode: 0x%04x\n", le16toh(wval)));
495 495
496#if 0 /* XXX: TBD.... */ 496#if 0 /* XXX: TBD.... */
497#define GMII_LED_ACTIVE 0x1a 497#define GMII_LED_ACTIVE 0x1a
498#define GMII_PHY_PAGE_SEL 0x1e 498#define GMII_PHY_PAGE_SEL 0x1e
499#define GMII_PHY_PAGE_SEL 0x1f 499#define GMII_PHY_PAGE_SEL 0x1f
500#define GMII_PAGE_EXT 0x0007 500#define GMII_PAGE_EXT 0x0007
501 usbnet_mii_writereg(un->un_dev, un->un_phyno, GMII_PHY_PAGE_SEL, 501 usbnet_mii_writereg(un->un_dev, un->un_phyno, GMII_PHY_PAGE_SEL,
502 GMII_PAGE_EXT); 502 GMII_PAGE_EXT);
503 usbnet_mii_writereg(un->un_dev, un->un_phyno, GMII_PHY_PAGE, 503 usbnet_mii_writereg(un->un_dev, un->un_phyno, GMII_PHY_PAGE,
504 0x002c); 504 0x002c);
505#endif 505#endif
506 506
507#if 1 /* XXX: phy hack ? */ 507#if 1 /* XXX: phy hack ? */
508 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x1F, 0x0005); 508 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x1F, 0x0005);
509 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x0C, 0x0000); 509 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x0C, 0x0000);
510 usbnet_mii_readreg(un->un_dev, un->un_phyno, 0x0001, &wval); 510 usbnet_mii_readreg(un->un_dev, un->un_phyno, 0x0001, &wval);
511 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x01, wval | 0x0080); 511 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x01, wval | 0x0080);
512 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x1F, 0x0000); 512 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x1F, 0x0000);
513#endif 513#endif
514 514
515 usbnet_unbusy(un); 515 usbnet_unbusy(un);
516 usbnet_unlock_core(un); 516 usbnet_unlock_core(un);
517} 517}
518 518
519static void 519static void
520axen_setoe_locked(struct usbnet *un) 520axen_setoe_locked(struct usbnet *un)
521{ 521{
522 struct ifnet * const ifp = usbnet_ifp(un); 522 struct ifnet * const ifp = usbnet_ifp(un);
523 uint64_t enabled = ifp->if_capenable; 523 uint64_t enabled = ifp->if_capenable;
524 uint8_t val; 524 uint8_t val;
525 525
526 usbnet_isowned_core(un); 526 usbnet_isowned_core(un);
527 527
528 val = AXEN_RXCOE_OFF; 528 val = AXEN_RXCOE_OFF;
529 if (enabled & IFCAP_CSUM_IPv4_Rx) 529 if (enabled & IFCAP_CSUM_IPv4_Rx)
530 val |= AXEN_RXCOE_IPv4; 530 val |= AXEN_RXCOE_IPv4;
531 if (enabled & IFCAP_CSUM_TCPv4_Rx) 531 if (enabled & IFCAP_CSUM_TCPv4_Rx)
532 val |= AXEN_RXCOE_TCPv4; 532 val |= AXEN_RXCOE_TCPv4;
533 if (enabled & IFCAP_CSUM_UDPv4_Rx) 533 if (enabled & IFCAP_CSUM_UDPv4_Rx)
534 val |= AXEN_RXCOE_UDPv4; 534 val |= AXEN_RXCOE_UDPv4;
535 if (enabled & IFCAP_CSUM_TCPv6_Rx) 535 if (enabled & IFCAP_CSUM_TCPv6_Rx)
536 val |= AXEN_RXCOE_TCPv6; 536 val |= AXEN_RXCOE_TCPv6;
537 if (enabled & IFCAP_CSUM_UDPv6_Rx) 537 if (enabled & IFCAP_CSUM_UDPv6_Rx)
538 val |= AXEN_RXCOE_UDPv6; 538 val |= AXEN_RXCOE_UDPv6;
539 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_RX_COE, &val); 539 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_RX_COE, &val);
540 540
541 val = AXEN_TXCOE_OFF; 541 val = AXEN_TXCOE_OFF;
542 if (enabled & IFCAP_CSUM_IPv4_Tx) 542 if (enabled & IFCAP_CSUM_IPv4_Tx)
543 val |= AXEN_TXCOE_IPv4; 543 val |= AXEN_TXCOE_IPv4;
544 if (enabled & IFCAP_CSUM_TCPv4_Tx) 544 if (enabled & IFCAP_CSUM_TCPv4_Tx)
545 val |= AXEN_TXCOE_TCPv4; 545 val |= AXEN_TXCOE_TCPv4;
546 if (enabled & IFCAP_CSUM_UDPv4_Tx) 546 if (enabled & IFCAP_CSUM_UDPv4_Tx)
547 val |= AXEN_TXCOE_UDPv4; 547 val |= AXEN_TXCOE_UDPv4;
548 if (enabled & IFCAP_CSUM_TCPv6_Tx) 548 if (enabled & IFCAP_CSUM_TCPv6_Tx)
549 val |= AXEN_TXCOE_TCPv6; 549 val |= AXEN_TXCOE_TCPv6;
550 if (enabled & IFCAP_CSUM_UDPv6_Tx) 550 if (enabled & IFCAP_CSUM_UDPv6_Tx)
551 val |= AXEN_TXCOE_UDPv6; 551 val |= AXEN_TXCOE_UDPv6;
552 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_TX_COE, &val); 552 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_TX_COE, &val);
553} 553}
554 554
555static int 555static int
556axen_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 556axen_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
557{ 557{
558 struct usbnet * const un = ifp->if_softc; 558 struct usbnet * const un = ifp->if_softc;
559 559
560 usbnet_lock_core(un); 560 usbnet_lock_core(un);
561 usbnet_busy(un); 561 usbnet_busy(un);
562 562
563 switch (cmd) { 563 switch (cmd) {
564 case SIOCSIFCAP: 564 case SIOCSIFCAP:
565 axen_setoe_locked(un); 565 axen_setoe_locked(un);
566 break; 566 break;
567 default: 567 default:
568 break; 568 break;
569 } 569 }
570 570
571 usbnet_unbusy(un); 571 usbnet_unbusy(un);
572 usbnet_unlock_core(un); 572 usbnet_unlock_core(un);
573 573
574 return 0; 574 return 0;
575} 575}
576 576
577static void 577static void
578axen_uno_mcast(struct ifnet *ifp) 578axen_uno_mcast(struct ifnet *ifp)
579{ 579{
580 struct usbnet * const un = ifp->if_softc; 580 struct usbnet * const un = ifp->if_softc;
581 581
582 usbnet_lock_core(un); 582 usbnet_lock_core(un);
583 usbnet_busy(un); 
584 583
585 axen_setiff_locked(un); 584 axen_setiff_locked(un);
586 585
587 usbnet_unbusy(un); 
588 usbnet_unlock_core(un); 586 usbnet_unlock_core(un);
589} 587}
590 588
591static int 589static int
592axen_match(device_t parent, cfdata_t match, void *aux) 590axen_match(device_t parent, cfdata_t match, void *aux)
593{ 591{
594 struct usb_attach_arg *uaa = aux; 592 struct usb_attach_arg *uaa = aux;
595 593
596 return axen_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 594 return axen_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
597 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 595 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
598} 596}
599 597
600static void 598static void
601axen_attach(device_t parent, device_t self, void *aux) 599axen_attach(device_t parent, device_t self, void *aux)
602{ 600{
603 USBNET_MII_DECL_DEFAULT(unm); 601 USBNET_MII_DECL_DEFAULT(unm);
604 struct usbnet * const un = device_private(self); 602 struct usbnet * const un = device_private(self);
605 struct usb_attach_arg *uaa = aux; 603 struct usb_attach_arg *uaa = aux;
606 struct usbd_device *dev = uaa->uaa_device; 604 struct usbd_device *dev = uaa->uaa_device;
607 usbd_status err; 605 usbd_status err;
608 usb_interface_descriptor_t *id; 606 usb_interface_descriptor_t *id;
609 usb_endpoint_descriptor_t *ed; 607 usb_endpoint_descriptor_t *ed;
610 char *devinfop; 608 char *devinfop;
611 uint16_t axen_flags; 609 uint16_t axen_flags;
612 int i; 610 int i;
613 611
614 aprint_naive("\n"); 612 aprint_naive("\n");
615 aprint_normal("\n"); 613 aprint_normal("\n");
616 devinfop = usbd_devinfo_alloc(dev, 0); 614 devinfop = usbd_devinfo_alloc(dev, 0);
617 aprint_normal_dev(self, "%s\n", devinfop); 615 aprint_normal_dev(self, "%s\n", devinfop);
618 usbd_devinfo_free(devinfop); 616 usbd_devinfo_free(devinfop);
619 617
620 un->un_dev = self; 618 un->un_dev = self;
621 un->un_udev = dev; 619 un->un_udev = dev;
622 un->un_sc = un; 620 un->un_sc = un;
623 un->un_ops = &axen_ops; 621 un->un_ops = &axen_ops;
624 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 622 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
625 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 623 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
626 un->un_rx_list_cnt = AXEN_RX_LIST_CNT; 624 un->un_rx_list_cnt = AXEN_RX_LIST_CNT;
627 un->un_tx_list_cnt = AXEN_TX_LIST_CNT; 625 un->un_tx_list_cnt = AXEN_TX_LIST_CNT;
628 626
629 err = usbd_set_config_no(dev, AXEN_CONFIG_NO, 1); 627 err = usbd_set_config_no(dev, AXEN_CONFIG_NO, 1);
630 if (err) { 628 if (err) {
631 aprint_error_dev(self, "failed to set configuration" 629 aprint_error_dev(self, "failed to set configuration"
632 ", err=%s\n", usbd_errstr(err)); 630 ", err=%s\n", usbd_errstr(err));
633 return; 631 return;
634 } 632 }
635 633
636 axen_flags = axen_lookup(uaa->uaa_vendor, uaa->uaa_product)->axen_flags; 634 axen_flags = axen_lookup(uaa->uaa_vendor, uaa->uaa_product)->axen_flags;
637 635
638 err = usbd_device2interface_handle(dev, AXEN_IFACE_IDX, &un->un_iface); 636 err = usbd_device2interface_handle(dev, AXEN_IFACE_IDX, &un->un_iface);
639 if (err) { 637 if (err) {
640 aprint_error_dev(self, "getting interface handle failed\n"); 638 aprint_error_dev(self, "getting interface handle failed\n");
641 return; 639 return;
642 } 640 }
643 641
644 /* decide on what our bufsize will be */ 642 /* decide on what our bufsize will be */
645 switch (dev->ud_speed) { 643 switch (dev->ud_speed) {
646 case USB_SPEED_SUPER: 644 case USB_SPEED_SUPER:
647 un->un_rx_bufsz = AXEN_BUFSZ_SS * 1024; 645 un->un_rx_bufsz = AXEN_BUFSZ_SS * 1024;
648 break; 646 break;
649 case USB_SPEED_HIGH: 647 case USB_SPEED_HIGH:
650 un->un_rx_bufsz = AXEN_BUFSZ_HS * 1024; 648 un->un_rx_bufsz = AXEN_BUFSZ_HS * 1024;
651 break; 649 break;
652 default: 650 default:
653 un->un_rx_bufsz = AXEN_BUFSZ_LS * 1024; 651 un->un_rx_bufsz = AXEN_BUFSZ_LS * 1024;
654 break; 652 break;
655 } 653 }
656 un->un_tx_bufsz = IP_MAXPACKET + ETHER_HDR_LEN + ETHER_CRC_LEN + 654 un->un_tx_bufsz = IP_MAXPACKET + ETHER_HDR_LEN + ETHER_CRC_LEN +
657 ETHER_VLAN_ENCAP_LEN + sizeof(struct axen_sframe_hdr); 655 ETHER_VLAN_ENCAP_LEN + sizeof(struct axen_sframe_hdr);
658 656
659 /* Find endpoints. */ 657 /* Find endpoints. */
660 id = usbd_get_interface_descriptor(un->un_iface); 658 id = usbd_get_interface_descriptor(un->un_iface);
661 for (i = 0; i < id->bNumEndpoints; i++) { 659 for (i = 0; i < id->bNumEndpoints; i++) {
662 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 660 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
663 if (!ed) { 661 if (!ed) {
664 aprint_error_dev(self, "couldn't get ep %d\n", i); 662 aprint_error_dev(self, "couldn't get ep %d\n", i);
665 return; 663 return;
666 } 664 }
667 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 665 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
668 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 666 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
669 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 667 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
670 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 668 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
671 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 669 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
672 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 670 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
673#if 0 /* not used yet */ 671#if 0 /* not used yet */
674 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 672 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
675 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 673 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
676 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 674 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
677#endif 675#endif
678 } 676 }
679 } 677 }
680 678
681 /* Set these up now for axen_cmd(). */ 679 /* Set these up now for axen_cmd(). */
682 usbnet_attach(un, "axendet"); 680 usbnet_attach(un, "axendet");
683 681
684 un->un_phyno = AXEN_PHY_ID; 682 un->un_phyno = AXEN_PHY_ID;
685 DPRINTF(("%s: phyno %d\n", device_xname(self), un->un_phyno)); 683 DPRINTF(("%s: phyno %d\n", device_xname(self), un->un_phyno));
686 684
687 /* Get station address. */ 685 /* Get station address. */
688 usbnet_lock_core(un); 686 usbnet_lock_core(un);
689 usbnet_busy(un); 687 usbnet_busy(un);
690 if (axen_get_eaddr(un, &un->un_eaddr)) { 688 if (axen_get_eaddr(un, &un->un_eaddr)) {
691 usbnet_unbusy(un); 689 usbnet_unbusy(un);
692 usbnet_unlock_core(un); 690 usbnet_unlock_core(un);
693 printf("EEPROM checksum error\n"); 691 printf("EEPROM checksum error\n");
694 return; 692 return;
695 } 693 }
696 usbnet_unbusy(un); 694 usbnet_unbusy(un);
697 usbnet_unlock_core(un); 695 usbnet_unlock_core(un);
698 696
699 axen_ax88179_init(un); 697 axen_ax88179_init(un);
700 698
701 /* An ASIX chip was detected. Inform the world. */ 699 /* An ASIX chip was detected. Inform the world. */
702 if (axen_flags & AX178A) 700 if (axen_flags & AX178A)
703 aprint_normal_dev(self, "AX88178a\n"); 701 aprint_normal_dev(self, "AX88178a\n");
704 else if (axen_flags & AX179) 702 else if (axen_flags & AX179)
705 aprint_normal_dev(self, "AX88179\n"); 703 aprint_normal_dev(self, "AX88179\n");
706 else 704 else
707 aprint_normal_dev(self, "(unknown)\n"); 705 aprint_normal_dev(self, "(unknown)\n");
708 706
709 struct ethercom *ec = usbnet_ec(un); 707 struct ethercom *ec = usbnet_ec(un);
710 ec->ec_capabilities = ETHERCAP_VLAN_MTU; 708 ec->ec_capabilities = ETHERCAP_VLAN_MTU;
711 709
712 /* Adapter does not support TSOv6 (They call it LSOv2). */ 710 /* Adapter does not support TSOv6 (They call it LSOv2). */
713 struct ifnet *ifp = usbnet_ifp(un); 711 struct ifnet *ifp = usbnet_ifp(un);
714 ifp->if_capabilities |= IFCAP_TSOv4 | 712 ifp->if_capabilities |= IFCAP_TSOv4 |
715 IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_IPv4_Tx | 713 IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_IPv4_Tx |
716 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_TCPv4_Tx | 714 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_TCPv4_Tx |
717 IFCAP_CSUM_UDPv4_Rx | IFCAP_CSUM_UDPv4_Tx | 715 IFCAP_CSUM_UDPv4_Rx | IFCAP_CSUM_UDPv4_Tx |
718 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_TCPv6_Tx | 716 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_TCPv6_Tx |
719 IFCAP_CSUM_UDPv6_Rx | IFCAP_CSUM_UDPv6_Tx; 717 IFCAP_CSUM_UDPv6_Rx | IFCAP_CSUM_UDPv6_Tx;
720 718
721 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 719 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
722 0, &unm); 720 0, &unm);
723} 721}
724 722
725static int 723static int
726axen_csum_flags_rx(struct ifnet *ifp, uint32_t pkt_hdr) 724axen_csum_flags_rx(struct ifnet *ifp, uint32_t pkt_hdr)
727{ 725{
728 int enabled_flags = ifp->if_csum_flags_rx; 726 int enabled_flags = ifp->if_csum_flags_rx;
729 int csum_flags = 0; 727 int csum_flags = 0;
730 int l3_type, l4_type; 728 int l3_type, l4_type;
731 729
732 if (enabled_flags == 0) 730 if (enabled_flags == 0)
733 return 0; 731 return 0;
734 732
735 l3_type = (pkt_hdr & AXEN_RXHDR_L3_TYPE_MASK) >> 733 l3_type = (pkt_hdr & AXEN_RXHDR_L3_TYPE_MASK) >>
736 AXEN_RXHDR_L3_TYPE_OFFSET; 734 AXEN_RXHDR_L3_TYPE_OFFSET;
737 735
738 if (l3_type == AXEN_RXHDR_L3_TYPE_IPV4) 736 if (l3_type == AXEN_RXHDR_L3_TYPE_IPV4)
739 csum_flags |= M_CSUM_IPv4; 737 csum_flags |= M_CSUM_IPv4;
740 738
741 l4_type = (pkt_hdr & AXEN_RXHDR_L4_TYPE_MASK) >> 739 l4_type = (pkt_hdr & AXEN_RXHDR_L4_TYPE_MASK) >>
742 AXEN_RXHDR_L4_TYPE_OFFSET; 740 AXEN_RXHDR_L4_TYPE_OFFSET;
743 741
744 switch (l4_type) { 742 switch (l4_type) {
745 case AXEN_RXHDR_L4_TYPE_TCP: 743 case AXEN_RXHDR_L4_TYPE_TCP:
746 if (l3_type == AXEN_RXHDR_L3_TYPE_IPV4) 744 if (l3_type == AXEN_RXHDR_L3_TYPE_IPV4)
747 csum_flags |= M_CSUM_TCPv4; 745 csum_flags |= M_CSUM_TCPv4;
748 else 746 else
749 csum_flags |= M_CSUM_TCPv6; 747 csum_flags |= M_CSUM_TCPv6;
750 break; 748 break;
751 case AXEN_RXHDR_L4_TYPE_UDP: 749 case AXEN_RXHDR_L4_TYPE_UDP:
752 if (l3_type == AXEN_RXHDR_L3_TYPE_IPV4) 750 if (l3_type == AXEN_RXHDR_L3_TYPE_IPV4)
753 csum_flags |= M_CSUM_UDPv4; 751 csum_flags |= M_CSUM_UDPv4;
754 else 752 else
755 csum_flags |= M_CSUM_UDPv6; 753 csum_flags |= M_CSUM_UDPv6;
756 break; 754 break;
757 default: 755 default:
758 break; 756 break;
759 } 757 }
760 758
761 csum_flags &= enabled_flags; 759 csum_flags &= enabled_flags;
762 if ((csum_flags & M_CSUM_IPv4) && (pkt_hdr & AXEN_RXHDR_L3CSUM_ERR)) 760 if ((csum_flags & M_CSUM_IPv4) && (pkt_hdr & AXEN_RXHDR_L3CSUM_ERR))
763 csum_flags |= M_CSUM_IPv4_BAD; 761 csum_flags |= M_CSUM_IPv4_BAD;
764 if ((csum_flags & ~M_CSUM_IPv4) && (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) 762 if ((csum_flags & ~M_CSUM_IPv4) && (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR))
765 csum_flags |= M_CSUM_TCP_UDP_BAD; 763 csum_flags |= M_CSUM_TCP_UDP_BAD;
766 764
767 return csum_flags; 765 return csum_flags;
768} 766}
769 767
770static void 768static void
771axen_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 769axen_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
772{ 770{
773 struct ifnet *ifp = usbnet_ifp(un); 771 struct ifnet *ifp = usbnet_ifp(un);
774 uint8_t *buf = c->unc_buf; 772 uint8_t *buf = c->unc_buf;
775 uint32_t rx_hdr, pkt_hdr; 773 uint32_t rx_hdr, pkt_hdr;
776 uint32_t *hdr_p; 774 uint32_t *hdr_p;
777 uint16_t hdr_offset, pkt_count; 775 uint16_t hdr_offset, pkt_count;
778 size_t pkt_len; 776 size_t pkt_len;
779 size_t temp; 777 size_t temp;
780 778
781 if (total_len < sizeof(pkt_hdr)) { 779 if (total_len < sizeof(pkt_hdr)) {
782 aprint_error_dev(un->un_dev, "rxeof: too short transfer\n"); 780 aprint_error_dev(un->un_dev, "rxeof: too short transfer\n");
783 if_statinc(ifp, if_ierrors); 781 if_statinc(ifp, if_ierrors);
784 return; 782 return;
785 } 783 }
786 784
787 /* 785 /*
788 * buffer map 786 * buffer map
789 * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr] 787 * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr]
790 * each packet has 0xeeee as psuedo header.. 788 * each packet has 0xeeee as psuedo header..
791 */ 789 */
792 hdr_p = (uint32_t *)(buf + total_len - sizeof(uint32_t)); 790 hdr_p = (uint32_t *)(buf + total_len - sizeof(uint32_t));
793 rx_hdr = le32toh(*hdr_p); 791 rx_hdr = le32toh(*hdr_p);
794 hdr_offset = (uint16_t)(rx_hdr >> 16); 792 hdr_offset = (uint16_t)(rx_hdr >> 16);
795 pkt_count = (uint16_t)(rx_hdr & 0xffff); 793 pkt_count = (uint16_t)(rx_hdr & 0xffff);
796 794
797 /* sanity check */ 795 /* sanity check */
798 if (hdr_offset > total_len) { 796 if (hdr_offset > total_len) {
799 aprint_error_dev(un->un_dev, 797 aprint_error_dev(un->un_dev,
800 "rxeof: invalid hdr offset (%u > %u)\n", 798 "rxeof: invalid hdr offset (%u > %u)\n",
801 hdr_offset, total_len); 799 hdr_offset, total_len);
802 if_statinc(ifp, if_ierrors); 800 if_statinc(ifp, if_ierrors);
803 usbd_delay_ms(un->un_udev, 100); 801 usbd_delay_ms(un->un_udev, 100);
804 return; 802 return;
805 } 803 }
806 804
807 /* point first packet header */ 805 /* point first packet header */
808 hdr_p = (uint32_t *)(buf + hdr_offset); 806 hdr_p = (uint32_t *)(buf + hdr_offset);
809 807
810 /* 808 /*
811 * ax88179 will pack multiple ip packet to a USB transaction. 809 * ax88179 will pack multiple ip packet to a USB transaction.
812 * process all of packets in the buffer 810 * process all of packets in the buffer
813 */ 811 */
814 812
815#if 1 /* XXX: paranoiac check. need to remove later */ 813#if 1 /* XXX: paranoiac check. need to remove later */
816#define AXEN_MAX_PACKED_PACKET 200 814#define AXEN_MAX_PACKED_PACKET 200
817 if (pkt_count > AXEN_MAX_PACKED_PACKET) { 815 if (pkt_count > AXEN_MAX_PACKED_PACKET) {
818 DPRINTF(("%s: Too many packets (%d) in a transaction, discard.\n", 816 DPRINTF(("%s: Too many packets (%d) in a transaction, discard.\n",
819 device_xname(un->un_dev), pkt_count)); 817 device_xname(un->un_dev), pkt_count));
820 return; 818 return;
821 } 819 }
822#endif 820#endif
823 821
824 if (pkt_count) 822 if (pkt_count)
825 rnd_add_uint32(usbnet_rndsrc(un), pkt_count); 823 rnd_add_uint32(usbnet_rndsrc(un), pkt_count);
826 824
827 do { 825 do {
828 if ((buf[0] != 0xee) || (buf[1] != 0xee)) { 826 if ((buf[0] != 0xee) || (buf[1] != 0xee)) {
829 aprint_error_dev(un->un_dev, 827 aprint_error_dev(un->un_dev,
830 "invalid buffer(pkt#%d), continue\n", pkt_count); 828 "invalid buffer(pkt#%d), continue\n", pkt_count);
831 if_statadd(ifp, if_ierrors, pkt_count); 829 if_statadd(ifp, if_ierrors, pkt_count);
832 return; 830 return;
833 } 831 }
834 832
835 pkt_hdr = le32toh(*hdr_p); 833 pkt_hdr = le32toh(*hdr_p);
836 pkt_len = (pkt_hdr >> 16) & 0x1fff; 834 pkt_len = (pkt_hdr >> 16) & 0x1fff;
837 DPRINTFN(10, 835 DPRINTFN(10,
838 ("%s: rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n", 836 ("%s: rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
839 device_xname(un->un_dev), pkt_count, pkt_hdr, pkt_len)); 837 device_xname(un->un_dev), pkt_count, pkt_hdr, pkt_len));
840 838
841 if (pkt_hdr & (AXEN_RXHDR_CRC_ERR | AXEN_RXHDR_DROP_ERR)) { 839 if (pkt_hdr & (AXEN_RXHDR_CRC_ERR | AXEN_RXHDR_DROP_ERR)) {
842 if_statinc(ifp, if_ierrors); 840 if_statinc(ifp, if_ierrors);
843 /* move to next pkt header */ 841 /* move to next pkt header */
844 DPRINTF(("%s: %s err (pkt#%d)\n", 842 DPRINTF(("%s: %s err (pkt#%d)\n",
845 device_xname(un->un_dev), 843 device_xname(un->un_dev),
846 (pkt_hdr & AXEN_RXHDR_CRC_ERR) ? "crc" : "drop", 844 (pkt_hdr & AXEN_RXHDR_CRC_ERR) ? "crc" : "drop",
847 pkt_count)); 845 pkt_count));
848 goto nextpkt; 846 goto nextpkt;
849 } 847 }
850 848
851 usbnet_enqueue(un, buf + ETHER_ALIGN, pkt_len - 6, 849 usbnet_enqueue(un, buf + ETHER_ALIGN, pkt_len - 6,
852 axen_csum_flags_rx(ifp, pkt_hdr), 0, 0); 850 axen_csum_flags_rx(ifp, pkt_hdr), 0, 0);
853 851
854nextpkt: 852nextpkt:
855 /* 853 /*
856 * prepare next packet 854 * prepare next packet
857 * as each packet will be aligned 8byte boundary, 855 * as each packet will be aligned 8byte boundary,
858 * need to fix up the start point of the buffer. 856 * need to fix up the start point of the buffer.
859 */ 857 */
860 temp = ((pkt_len + 7) & 0xfff8); 858 temp = ((pkt_len + 7) & 0xfff8);
861 buf = buf + temp; 859 buf = buf + temp;
862 hdr_p++; 860 hdr_p++;
863 pkt_count--; 861 pkt_count--;
864 } while (pkt_count > 0); 862 } while (pkt_count > 0);
865} 863}
866 864
867static unsigned 865static unsigned
868axen_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 866axen_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
869{ 867{
870 struct axen_sframe_hdr hdr; 868 struct axen_sframe_hdr hdr;
871 u_int length, boundary; 869 u_int length, boundary;
872 870
873 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(hdr)) 871 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(hdr))
874 return 0; 872 return 0;
875 length = m->m_pkthdr.len + sizeof(hdr); 873 length = m->m_pkthdr.len + sizeof(hdr);
876 874
877 /* XXX Is this needed? wMaxPacketSize? */ 875 /* XXX Is this needed? wMaxPacketSize? */
878 switch (un->un_udev->ud_speed) { 876 switch (un->un_udev->ud_speed) {
879 case USB_SPEED_SUPER: 877 case USB_SPEED_SUPER:
880 boundary = 4096; 878 boundary = 4096;
881 break; 879 break;
882 case USB_SPEED_HIGH: 880 case USB_SPEED_HIGH:
883 boundary = 512; 881 boundary = 512;
884 break; 882 break;
885 default: 883 default:
886 boundary = 64; 884 boundary = 64;
887 break; 885 break;
888 } 886 }
889 887
890 hdr.plen = htole32(m->m_pkthdr.len); 888 hdr.plen = htole32(m->m_pkthdr.len);
891 889
892 hdr.gso = (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) ? 890 hdr.gso = (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) ?
893 m->m_pkthdr.segsz : 0; 891 m->m_pkthdr.segsz : 0;
894 if ((length % boundary) == 0) { 892 if ((length % boundary) == 0) {
895 DPRINTF(("%s: boundary hit\n", device_xname(un->un_dev))); 893 DPRINTF(("%s: boundary hit\n", device_xname(un->un_dev)));
896 hdr.gso |= 0x80008000; /* XXX enable padding */ 894 hdr.gso |= 0x80008000; /* XXX enable padding */
897 } 895 }
898 hdr.gso = htole32(hdr.gso); 896 hdr.gso = htole32(hdr.gso);
899 897
900 memcpy(c->unc_buf, &hdr, sizeof(hdr)); 898 memcpy(c->unc_buf, &hdr, sizeof(hdr));
901 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + sizeof(hdr)); 899 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + sizeof(hdr));
902 900
903 return length; 901 return length;
904} 902}
905 903
906static int 904static int
907axen_init_locked(struct ifnet *ifp) 905axen_init_locked(struct ifnet *ifp)
908{ 906{
909 struct usbnet * const un = ifp->if_softc; 907 struct usbnet * const un = ifp->if_softc;
910 uint16_t rxmode; 908 uint16_t rxmode;
911 uint16_t wval; 909 uint16_t wval;
912 uint8_t bval; 910 uint8_t bval;
913 911
914 usbnet_isowned_core(un); 912 usbnet_isowned_core(un);
915 913
916 if (usbnet_isdying(un)) 914 if (usbnet_isdying(un))
917 return EIO; 915 return EIO;
918 916
919 /* Cancel pending I/O */ 917 /* Cancel pending I/O */
920 usbnet_stop(un, ifp, 1); 918 usbnet_stop(un, ifp, 1);
921 919
922 /* Reset the ethernet interface. */ 920 /* Reset the ethernet interface. */
923 axen_reset(un); 921 axen_reset(un);
924 922
925 /* XXX: ? */ 923 /* XXX: ? */
926 bval = 0x01; 924 bval = 0x01;
927 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_UNK_28, &bval); 925 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_UNK_28, &bval);
928 926
929 /* Configure offloading engine. */ 927 /* Configure offloading engine. */
930 axen_setoe_locked(un); 928 axen_setoe_locked(un);
931 929
932 /* Program promiscuous mode and multicast filters. */ 930 /* Program promiscuous mode and multicast filters. */
933 axen_setiff_locked(un); 931 axen_setiff_locked(un);
934 932
935 /* Enable receiver, set RX mode */ 933 /* Enable receiver, set RX mode */
936 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); 934 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval);
937 rxmode = le16toh(wval); 935 rxmode = le16toh(wval);
938 rxmode |= AXEN_RXCTL_START; 936 rxmode |= AXEN_RXCTL_START;
939 wval = htole16(rxmode); 937 wval = htole16(rxmode);
940 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 938 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval);
941 939
942 return usbnet_init_rx_tx(un); 940 return usbnet_init_rx_tx(un);
943} 941}
944 942
945static int 943static int
946axen_uno_init(struct ifnet *ifp) 944axen_uno_init(struct ifnet *ifp)
947{ 945{
948 int ret = axen_init_locked(ifp); 946 int ret = axen_init_locked(ifp);
949 947
950 return ret; 948 return ret;
951} 949}
952 950
953static void 951static void
954axen_uno_stop(struct ifnet *ifp, int disable) 952axen_uno_stop(struct ifnet *ifp, int disable)
955{ 953{
956 struct usbnet * const un = ifp->if_softc; 954 struct usbnet * const un = ifp->if_softc;
957 uint16_t rxmode, wval; 955 uint16_t rxmode, wval;
958 956
959 axen_reset(un); 957 axen_reset(un);
960 958
961 /* Disable receiver, set RX mode */ 959 /* Disable receiver, set RX mode */
962 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); 960 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval);
963 rxmode = le16toh(wval); 961 rxmode = le16toh(wval);
964 rxmode &= ~AXEN_RXCTL_START; 962 rxmode &= ~AXEN_RXCTL_START;
965 wval = htole16(rxmode); 963 wval = htole16(rxmode);
966 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 964 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval);
967} 965}
968 966
969#ifdef _MODULE 967#ifdef _MODULE
970#include "ioconf.c" 968#include "ioconf.c"
971#endif 969#endif
972 970
973USBNET_MODULE(axen) 971USBNET_MODULE(axen)

cvs diff -r1.95 -r1.96 src/sys/dev/usb/if_cue.c (switch to unified diff)

--- src/sys/dev/usb/if_cue.c 2022/03/03 05:51:17 1.95
+++ src/sys/dev/usb/if_cue.c 2022/03/03 05:51:27 1.96
@@ -1,710 +1,708 @@ @@ -1,710 +1,708 @@
1/* $NetBSD: if_cue.c,v 1.95 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_cue.c,v 1.96 2022/03/03 05:51:27 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997, 1998, 1999, 2000 4 * Copyright (c) 1997, 1998, 1999, 2000
5 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. 5 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Bill Paul. 17 * This product includes software developed by Bill Paul.
18 * 4. Neither the name of the author nor the names of any co-contributors 18 * 4. Neither the name of the author nor the names of any co-contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE. 32 * THE POSSIBILITY OF SUCH DAMAGE.
33 * 33 *
34 * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.4 2000/01/16 22:45:06 wpaul Exp $ 34 * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.4 2000/01/16 22:45:06 wpaul Exp $
35 */ 35 */
36 36
37/* 37/*
38 * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate 38 * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate
39 * adapters and others. 39 * adapters and others.
40 * 40 *
41 * Written by Bill Paul <wpaul@ee.columbia.edu> 41 * Written by Bill Paul <wpaul@ee.columbia.edu>
42 * Electrical Engineering Department 42 * Electrical Engineering Department
43 * Columbia University, New York City 43 * Columbia University, New York City
44 */ 44 */
45 45
46/* 46/*
47 * The CATC USB-EL1210A provides USB ethernet support at 10Mbps. The 47 * The CATC USB-EL1210A provides USB ethernet support at 10Mbps. The
48 * RX filter uses a 512-bit multicast hash table, single perfect entry 48 * RX filter uses a 512-bit multicast hash table, single perfect entry
49 * for the station address, and promiscuous mode. Unlike the ADMtek 49 * for the station address, and promiscuous mode. Unlike the ADMtek
50 * and KLSI chips, the CATC ASIC supports read and write combining 50 * and KLSI chips, the CATC ASIC supports read and write combining
51 * mode where multiple packets can be transferred using a single bulk 51 * mode where multiple packets can be transferred using a single bulk
52 * transaction, which helps performance a great deal. 52 * transaction, which helps performance a great deal.
53 */ 53 */
54 54
55/* 55/*
56 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. 56 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson.
57 */ 57 */
58 58
59#include <sys/cdefs.h> 59#include <sys/cdefs.h>
60__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.95 2022/03/03 05:51:17 riastradh Exp $"); 60__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.96 2022/03/03 05:51:27 riastradh Exp $");
61 61
62#ifdef _KERNEL_OPT 62#ifdef _KERNEL_OPT
63#include "opt_inet.h" 63#include "opt_inet.h"
64#include "opt_usb.h" 64#include "opt_usb.h"
65#endif 65#endif
66 66
67#include <sys/param.h> 67#include <sys/param.h>
68 68
69#include <dev/usb/usbnet.h> 69#include <dev/usb/usbnet.h>
70#include <dev/usb/if_cuereg.h> 70#include <dev/usb/if_cuereg.h>
71 71
72#ifdef INET 72#ifdef INET
73#include <netinet/in.h> 73#include <netinet/in.h>
74#include <netinet/if_inarp.h> 74#include <netinet/if_inarp.h>
75#endif 75#endif
76 76
77#ifdef CUE_DEBUG 77#ifdef CUE_DEBUG
78#define DPRINTF(x) if (cuedebug) printf x 78#define DPRINTF(x) if (cuedebug) printf x
79#define DPRINTFN(n, x) if (cuedebug >= (n)) printf x 79#define DPRINTFN(n, x) if (cuedebug >= (n)) printf x
80int cuedebug = 0; 80int cuedebug = 0;
81#else 81#else
82#define DPRINTF(x) 82#define DPRINTF(x)
83#define DPRINTFN(n, x) 83#define DPRINTFN(n, x)
84#endif 84#endif
85 85
86#define CUE_BUFSZ 1536 86#define CUE_BUFSZ 1536
87#define CUE_MIN_FRAMELEN 60 87#define CUE_MIN_FRAMELEN 60
88#define CUE_RX_FRAMES 1 88#define CUE_RX_FRAMES 1
89#define CUE_TX_FRAMES 1 89#define CUE_TX_FRAMES 1
90 90
91#define CUE_CONFIG_NO 1 91#define CUE_CONFIG_NO 1
92#define CUE_IFACE_IDX 0 92#define CUE_IFACE_IDX 0
93 93
94#define CUE_RX_LIST_CNT 1 94#define CUE_RX_LIST_CNT 1
95#define CUE_TX_LIST_CNT 1 95#define CUE_TX_LIST_CNT 1
96 96
97struct cue_type { 97struct cue_type {
98 uint16_t cue_vid; 98 uint16_t cue_vid;
99 uint16_t cue_did; 99 uint16_t cue_did;
100}; 100};
101 101
102struct cue_softc; 102struct cue_softc;
103 103
104struct cue_chain { 104struct cue_chain {
105 struct cue_softc *cue_sc; 105 struct cue_softc *cue_sc;
106 struct usbd_xfer *cue_xfer; 106 struct usbd_xfer *cue_xfer;
107 char *cue_buf; 107 char *cue_buf;
108 struct mbuf *cue_mbuf; 108 struct mbuf *cue_mbuf;
109 int cue_idx; 109 int cue_idx;
110}; 110};
111 111
112struct cue_cdata { 112struct cue_cdata {
113 struct cue_chain cue_tx_chain[CUE_TX_LIST_CNT]; 113 struct cue_chain cue_tx_chain[CUE_TX_LIST_CNT];
114 struct cue_chain cue_rx_chain[CUE_RX_LIST_CNT]; 114 struct cue_chain cue_rx_chain[CUE_RX_LIST_CNT];
115 int cue_tx_prod; 115 int cue_tx_prod;
116 int cue_tx_cnt; 116 int cue_tx_cnt;
117}; 117};
118 118
119struct cue_softc { 119struct cue_softc {
120 struct usbnet cue_un; 120 struct usbnet cue_un;
121 uint8_t cue_mctab[CUE_MCAST_TABLE_LEN]; 121 uint8_t cue_mctab[CUE_MCAST_TABLE_LEN];
122}; 122};
123 123
124/* 124/*
125 * Various supported device vendors/products. 125 * Various supported device vendors/products.
126 */ 126 */
127static const struct usb_devno cue_devs[] = { 127static const struct usb_devno cue_devs[] = {
128 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE }, 128 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE },
129 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2 }, 129 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2 },
130 { USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK }, 130 { USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK },
131 /* Belkin F5U111 adapter covered by NETMATE entry */ 131 /* Belkin F5U111 adapter covered by NETMATE entry */
132}; 132};
133#define cue_lookup(v, p) (usb_lookup(cue_devs, v, p)) 133#define cue_lookup(v, p) (usb_lookup(cue_devs, v, p))
134 134
135static int cue_match(device_t, cfdata_t, void *); 135static int cue_match(device_t, cfdata_t, void *);
136static void cue_attach(device_t, device_t, void *); 136static void cue_attach(device_t, device_t, void *);
137 137
138CFATTACH_DECL_NEW(cue, sizeof(struct cue_softc), cue_match, cue_attach, 138CFATTACH_DECL_NEW(cue, sizeof(struct cue_softc), cue_match, cue_attach,
139 usbnet_detach, usbnet_activate); 139 usbnet_detach, usbnet_activate);
140 140
141static unsigned cue_uno_tx_prepare(struct usbnet *, struct mbuf *, 141static unsigned cue_uno_tx_prepare(struct usbnet *, struct mbuf *,
142 struct usbnet_chain *); 142 struct usbnet_chain *);
143static void cue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 143static void cue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
144static void cue_uno_mcast(struct ifnet *); 144static void cue_uno_mcast(struct ifnet *);
145static void cue_uno_stop(struct ifnet *, int); 145static void cue_uno_stop(struct ifnet *, int);
146static int cue_uno_init(struct ifnet *); 146static int cue_uno_init(struct ifnet *);
147static void cue_uno_tick(struct usbnet *); 147static void cue_uno_tick(struct usbnet *);
148 148
149static const struct usbnet_ops cue_ops = { 149static const struct usbnet_ops cue_ops = {
150 .uno_stop = cue_uno_stop, 150 .uno_stop = cue_uno_stop,
151 .uno_mcast = cue_uno_mcast, 151 .uno_mcast = cue_uno_mcast,
152 .uno_tx_prepare = cue_uno_tx_prepare, 152 .uno_tx_prepare = cue_uno_tx_prepare,
153 .uno_rx_loop = cue_uno_rx_loop, 153 .uno_rx_loop = cue_uno_rx_loop,
154 .uno_init = cue_uno_init, 154 .uno_init = cue_uno_init,
155 .uno_tick = cue_uno_tick, 155 .uno_tick = cue_uno_tick,
156}; 156};
157 157
158#ifdef CUE_DEBUG 158#ifdef CUE_DEBUG
159static int 159static int
160cue_csr_read_1(struct usbnet *un, int reg) 160cue_csr_read_1(struct usbnet *un, int reg)
161{ 161{
162 usb_device_request_t req; 162 usb_device_request_t req;
163 usbd_status err; 163 usbd_status err;
164 uint8_t val = 0; 164 uint8_t val = 0;
165 165
166 if (usbnet_isdying(un)) 166 if (usbnet_isdying(un))
167 return 0; 167 return 0;
168 168
169 req.bmRequestType = UT_READ_VENDOR_DEVICE; 169 req.bmRequestType = UT_READ_VENDOR_DEVICE;
170 req.bRequest = CUE_CMD_READREG; 170 req.bRequest = CUE_CMD_READREG;
171 USETW(req.wValue, 0); 171 USETW(req.wValue, 0);
172 USETW(req.wIndex, reg); 172 USETW(req.wIndex, reg);
173 USETW(req.wLength, 1); 173 USETW(req.wLength, 1);
174 174
175 err = usbd_do_request(un->un_udev, &req, &val); 175 err = usbd_do_request(un->un_udev, &req, &val);
176 176
177 if (err) { 177 if (err) {
178 DPRINTF(("%s: cue_csr_read_1: reg=%#x err=%s\n", 178 DPRINTF(("%s: cue_csr_read_1: reg=%#x err=%s\n",
179 device_xname(un->un_dev), reg, usbd_errstr(err))); 179 device_xname(un->un_dev), reg, usbd_errstr(err)));
180 return 0; 180 return 0;
181 } 181 }
182 182
183 DPRINTFN(10,("%s: cue_csr_read_1 reg=%#x val=%#x\n", 183 DPRINTFN(10,("%s: cue_csr_read_1 reg=%#x val=%#x\n",
184 device_xname(un->un_dev), reg, val)); 184 device_xname(un->un_dev), reg, val));
185 185
186 return val; 186 return val;
187} 187}
188#endif 188#endif
189 189
190static int 190static int
191cue_csr_read_2(struct usbnet *un, int reg) 191cue_csr_read_2(struct usbnet *un, int reg)
192{ 192{
193 usb_device_request_t req; 193 usb_device_request_t req;
194 usbd_status err; 194 usbd_status err;
195 uWord val; 195 uWord val;
196 196
197 if (usbnet_isdying(un)) 197 if (usbnet_isdying(un))
198 return 0; 198 return 0;
199 199
200 req.bmRequestType = UT_READ_VENDOR_DEVICE; 200 req.bmRequestType = UT_READ_VENDOR_DEVICE;
201 req.bRequest = CUE_CMD_READREG; 201 req.bRequest = CUE_CMD_READREG;
202 USETW(req.wValue, 0); 202 USETW(req.wValue, 0);
203 USETW(req.wIndex, reg); 203 USETW(req.wIndex, reg);
204 USETW(req.wLength, 2); 204 USETW(req.wLength, 2);
205 205
206 err = usbd_do_request(un->un_udev, &req, &val); 206 err = usbd_do_request(un->un_udev, &req, &val);
207 207
208 DPRINTFN(10,("%s: cue_csr_read_2 reg=%#x val=%#x\n", 208 DPRINTFN(10,("%s: cue_csr_read_2 reg=%#x val=%#x\n",
209 device_xname(un->un_dev), reg, UGETW(val))); 209 device_xname(un->un_dev), reg, UGETW(val)));
210 210
211 if (err) { 211 if (err) {
212 DPRINTF(("%s: cue_csr_read_2: reg=%#x err=%s\n", 212 DPRINTF(("%s: cue_csr_read_2: reg=%#x err=%s\n",
213 device_xname(un->un_dev), reg, usbd_errstr(err))); 213 device_xname(un->un_dev), reg, usbd_errstr(err)));
214 return 0; 214 return 0;
215 } 215 }
216 216
217 return UGETW(val); 217 return UGETW(val);
218} 218}
219 219
220static int 220static int
221cue_csr_write_1(struct usbnet *un, int reg, int val) 221cue_csr_write_1(struct usbnet *un, int reg, int val)
222{ 222{
223 usb_device_request_t req; 223 usb_device_request_t req;
224 usbd_status err; 224 usbd_status err;
225 225
226 if (usbnet_isdying(un)) 226 if (usbnet_isdying(un))
227 return 0; 227 return 0;
228 228
229 DPRINTFN(10,("%s: cue_csr_write_1 reg=%#x val=%#x\n", 229 DPRINTFN(10,("%s: cue_csr_write_1 reg=%#x val=%#x\n",
230 device_xname(un->un_dev), reg, val)); 230 device_xname(un->un_dev), reg, val));
231 231
232 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 232 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
233 req.bRequest = CUE_CMD_WRITEREG; 233 req.bRequest = CUE_CMD_WRITEREG;
234 USETW(req.wValue, val); 234 USETW(req.wValue, val);
235 USETW(req.wIndex, reg); 235 USETW(req.wIndex, reg);
236 USETW(req.wLength, 0); 236 USETW(req.wLength, 0);
237 237
238 err = usbd_do_request(un->un_udev, &req, NULL); 238 err = usbd_do_request(un->un_udev, &req, NULL);
239 239
240 if (err) { 240 if (err) {
241 DPRINTF(("%s: cue_csr_write_1: reg=%#x err=%s\n", 241 DPRINTF(("%s: cue_csr_write_1: reg=%#x err=%s\n",
242 device_xname(un->un_dev), reg, usbd_errstr(err))); 242 device_xname(un->un_dev), reg, usbd_errstr(err)));
243 return -1; 243 return -1;
244 } 244 }
245 245
246 DPRINTFN(20,("%s: cue_csr_write_1, after reg=%#x val=%#x\n", 246 DPRINTFN(20,("%s: cue_csr_write_1, after reg=%#x val=%#x\n",
247 device_xname(un->un_dev), reg, cue_csr_read_1(un, reg))); 247 device_xname(un->un_dev), reg, cue_csr_read_1(un, reg)));
248 248
249 return 0; 249 return 0;
250} 250}
251 251
252#if 0 252#if 0
253static int 253static int
254cue_csr_write_2(struct usbnet *un, int reg, int aval) 254cue_csr_write_2(struct usbnet *un, int reg, int aval)
255{ 255{
256 usb_device_request_t req; 256 usb_device_request_t req;
257 usbd_status err; 257 usbd_status err;
258 uWord val; 258 uWord val;
259 int s; 259 int s;
260 260
261 if (usbnet_isdying(un)) 261 if (usbnet_isdying(un))
262 return 0; 262 return 0;
263 263
264 DPRINTFN(10,("%s: cue_csr_write_2 reg=%#x val=%#x\n", 264 DPRINTFN(10,("%s: cue_csr_write_2 reg=%#x val=%#x\n",
265 device_xname(un->un_dev), reg, aval)); 265 device_xname(un->un_dev), reg, aval));
266 266
267 USETW(val, aval); 267 USETW(val, aval);
268 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 268 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
269 req.bRequest = CUE_CMD_WRITEREG; 269 req.bRequest = CUE_CMD_WRITEREG;
270 USETW(req.wValue, val); 270 USETW(req.wValue, val);
271 USETW(req.wIndex, reg); 271 USETW(req.wIndex, reg);
272 USETW(req.wLength, 0); 272 USETW(req.wLength, 0);
273 273
274 err = usbd_do_request(un->un_udev, &req, NULL); 274 err = usbd_do_request(un->un_udev, &req, NULL);
275 275
276 if (err) { 276 if (err) {
277 DPRINTF(("%s: cue_csr_write_2: reg=%#x err=%s\n", 277 DPRINTF(("%s: cue_csr_write_2: reg=%#x err=%s\n",
278 device_xname(un->un_dev), reg, usbd_errstr(err))); 278 device_xname(un->un_dev), reg, usbd_errstr(err)));
279 return -1; 279 return -1;
280 } 280 }
281 281
282 return 0; 282 return 0;
283} 283}
284#endif 284#endif
285 285
286static int 286static int
287cue_mem(struct usbnet *un, int cmd, int addr, void *buf, int len) 287cue_mem(struct usbnet *un, int cmd, int addr, void *buf, int len)
288{ 288{
289 usb_device_request_t req; 289 usb_device_request_t req;
290 usbd_status err; 290 usbd_status err;
291 291
292 DPRINTFN(10,("%s: cue_mem cmd=%#x addr=%#x len=%d\n", 292 DPRINTFN(10,("%s: cue_mem cmd=%#x addr=%#x len=%d\n",
293 device_xname(un->un_dev), cmd, addr, len)); 293 device_xname(un->un_dev), cmd, addr, len));
294 294
295 if (cmd == CUE_CMD_READSRAM) 295 if (cmd == CUE_CMD_READSRAM)
296 req.bmRequestType = UT_READ_VENDOR_DEVICE; 296 req.bmRequestType = UT_READ_VENDOR_DEVICE;
297 else 297 else
298 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 298 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
299 req.bRequest = cmd; 299 req.bRequest = cmd;
300 USETW(req.wValue, 0); 300 USETW(req.wValue, 0);
301 USETW(req.wIndex, addr); 301 USETW(req.wIndex, addr);
302 USETW(req.wLength, len); 302 USETW(req.wLength, len);
303 303
304 err = usbd_do_request(un->un_udev, &req, buf); 304 err = usbd_do_request(un->un_udev, &req, buf);
305 305
306 if (err) { 306 if (err) {
307 DPRINTF(("%s: cue_csr_mem: addr=%#x err=%s\n", 307 DPRINTF(("%s: cue_csr_mem: addr=%#x err=%s\n",
308 device_xname(un->un_dev), addr, usbd_errstr(err))); 308 device_xname(un->un_dev), addr, usbd_errstr(err)));
309 return -1; 309 return -1;
310 } 310 }
311 311
312 return 0; 312 return 0;
313} 313}
314 314
315static int 315static int
316cue_getmac(struct usbnet *un) 316cue_getmac(struct usbnet *un)
317{ 317{
318 usb_device_request_t req; 318 usb_device_request_t req;
319 usbd_status err; 319 usbd_status err;
320 320
321 DPRINTFN(10,("%s: cue_getmac\n", device_xname(un->un_dev))); 321 DPRINTFN(10,("%s: cue_getmac\n", device_xname(un->un_dev)));
322 322
323 req.bmRequestType = UT_READ_VENDOR_DEVICE; 323 req.bmRequestType = UT_READ_VENDOR_DEVICE;
324 req.bRequest = CUE_CMD_GET_MACADDR; 324 req.bRequest = CUE_CMD_GET_MACADDR;
325 USETW(req.wValue, 0); 325 USETW(req.wValue, 0);
326 USETW(req.wIndex, 0); 326 USETW(req.wIndex, 0);
327 USETW(req.wLength, ETHER_ADDR_LEN); 327 USETW(req.wLength, ETHER_ADDR_LEN);
328 328
329 err = usbd_do_request(un->un_udev, &req, un->un_eaddr); 329 err = usbd_do_request(un->un_udev, &req, un->un_eaddr);
330 330
331 if (err) { 331 if (err) {
332 printf("%s: read MAC address failed\n", 332 printf("%s: read MAC address failed\n",
333 device_xname(un->un_dev)); 333 device_xname(un->un_dev));
334 return -1; 334 return -1;
335 } 335 }
336 336
337 return 0; 337 return 0;
338} 338}
339 339
340#define CUE_POLY 0xEDB88320 340#define CUE_POLY 0xEDB88320
341#define CUE_BITS 9 341#define CUE_BITS 9
342 342
343static uint32_t 343static uint32_t
344cue_crc(const char *addr) 344cue_crc(const char *addr)
345{ 345{
346 uint32_t idx, bit, data, crc; 346 uint32_t idx, bit, data, crc;
347 347
348 /* Compute CRC for the address value. */ 348 /* Compute CRC for the address value. */
349 crc = 0xFFFFFFFF; /* initial value */ 349 crc = 0xFFFFFFFF; /* initial value */
350 350
351 for (idx = 0; idx < 6; idx++) { 351 for (idx = 0; idx < 6; idx++) {
352 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) 352 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
353 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CUE_POLY : 0); 353 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CUE_POLY : 0);
354 } 354 }
355 355
356 return crc & ((1 << CUE_BITS) - 1); 356 return crc & ((1 << CUE_BITS) - 1);
357} 357}
358 358
359static void 359static void
360cue_setiff_locked(struct usbnet *un) 360cue_setiff_locked(struct usbnet *un)
361{ 361{
362 struct cue_softc *sc = usbnet_softc(un); 362 struct cue_softc *sc = usbnet_softc(un);
363 struct ethercom *ec = usbnet_ec(un); 363 struct ethercom *ec = usbnet_ec(un);
364 struct ifnet *ifp = usbnet_ifp(un); 364 struct ifnet *ifp = usbnet_ifp(un);
365 struct ether_multi *enm; 365 struct ether_multi *enm;
366 struct ether_multistep step; 366 struct ether_multistep step;
367 uint32_t h, i; 367 uint32_t h, i;
368 368
369 DPRINTFN(2,("%s: cue_setiff if_flags=%#x\n", 369 DPRINTFN(2,("%s: cue_setiff if_flags=%#x\n",
370 device_xname(un->un_dev), ifp->if_flags)); 370 device_xname(un->un_dev), ifp->if_flags));
371 371
372 if (ifp->if_flags & IFF_PROMISC) { 372 if (ifp->if_flags & IFF_PROMISC) {
373allmulti: 373allmulti:
374 ifp->if_flags |= IFF_ALLMULTI; 374 ifp->if_flags |= IFF_ALLMULTI;
375 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) 375 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
376 sc->cue_mctab[i] = 0xFF; 376 sc->cue_mctab[i] = 0xFF;
377 cue_mem(un, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, 377 cue_mem(un, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
378 &sc->cue_mctab, CUE_MCAST_TABLE_LEN); 378 &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
379 return; 379 return;
380 } 380 }
381 381
382 /* first, zot all the existing hash bits */ 382 /* first, zot all the existing hash bits */
383 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) 383 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
384 sc->cue_mctab[i] = 0; 384 sc->cue_mctab[i] = 0;
385 385
386 /* now program new ones */ 386 /* now program new ones */
387 ETHER_LOCK(ec); 387 ETHER_LOCK(ec);
388 ETHER_FIRST_MULTI(step, ec, enm); 388 ETHER_FIRST_MULTI(step, ec, enm);
389 while (enm != NULL) { 389 while (enm != NULL) {
390 if (memcmp(enm->enm_addrlo, 390 if (memcmp(enm->enm_addrlo,
391 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) { 391 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
392 ETHER_UNLOCK(ec); 392 ETHER_UNLOCK(ec);
393 goto allmulti; 393 goto allmulti;
394 } 394 }
395 395
396 h = cue_crc(enm->enm_addrlo); 396 h = cue_crc(enm->enm_addrlo);
397 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); 397 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
398 ETHER_NEXT_MULTI(step, enm); 398 ETHER_NEXT_MULTI(step, enm);
399 } 399 }
400 ETHER_UNLOCK(ec); 400 ETHER_UNLOCK(ec);
401 401
402 ifp->if_flags &= ~IFF_ALLMULTI; 402 ifp->if_flags &= ~IFF_ALLMULTI;
403 403
404 /* 404 /*
405 * Also include the broadcast address in the filter 405 * Also include the broadcast address in the filter
406 * so we can receive broadcast frames. 406 * so we can receive broadcast frames.
407 */ 407 */
408 if (ifp->if_flags & IFF_BROADCAST) { 408 if (ifp->if_flags & IFF_BROADCAST) {
409 h = cue_crc(etherbroadcastaddr); 409 h = cue_crc(etherbroadcastaddr);
410 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); 410 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
411 } 411 }
412 412
413 cue_mem(un, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, 413 cue_mem(un, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
414 &sc->cue_mctab, CUE_MCAST_TABLE_LEN); 414 &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
415} 415}
416 416
417static void 417static void
418cue_reset(struct usbnet *un) 418cue_reset(struct usbnet *un)
419{ 419{
420 usb_device_request_t req; 420 usb_device_request_t req;
421 usbd_status err; 421 usbd_status err;
422 422
423 DPRINTFN(2,("%s: cue_reset\n", device_xname(un->un_dev))); 423 DPRINTFN(2,("%s: cue_reset\n", device_xname(un->un_dev)));
424 424
425 if (usbnet_isdying(un)) 425 if (usbnet_isdying(un))
426 return; 426 return;
427 427
428 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 428 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
429 req.bRequest = CUE_CMD_RESET; 429 req.bRequest = CUE_CMD_RESET;
430 USETW(req.wValue, 0); 430 USETW(req.wValue, 0);
431 USETW(req.wIndex, 0); 431 USETW(req.wIndex, 0);
432 USETW(req.wLength, 0); 432 USETW(req.wLength, 0);
433 433
434 err = usbd_do_request(un->un_udev, &req, NULL); 434 err = usbd_do_request(un->un_udev, &req, NULL);
435 435
436 if (err) 436 if (err)
437 printf("%s: reset failed\n", device_xname(un->un_dev)); 437 printf("%s: reset failed\n", device_xname(un->un_dev));
438 438
439 /* Wait a little while for the chip to get its brains in order. */ 439 /* Wait a little while for the chip to get its brains in order. */
440 usbd_delay_ms(un->un_udev, 1); 440 usbd_delay_ms(un->un_udev, 1);
441} 441}
442 442
443/* 443/*
444 * Probe for a CATC chip. 444 * Probe for a CATC chip.
445 */ 445 */
446static int 446static int
447cue_match(device_t parent, cfdata_t match, void *aux) 447cue_match(device_t parent, cfdata_t match, void *aux)
448{ 448{
449 struct usb_attach_arg *uaa = aux; 449 struct usb_attach_arg *uaa = aux;
450 450
451 return cue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 451 return cue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
452 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 452 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
453} 453}
454 454
455/* 455/*
456 * Attach the interface. Allocate softc structures, do ifmedia 456 * Attach the interface. Allocate softc structures, do ifmedia
457 * setup and ethernet/BPF attach. 457 * setup and ethernet/BPF attach.
458 */ 458 */
459static void 459static void
460cue_attach(device_t parent, device_t self, void *aux) 460cue_attach(device_t parent, device_t self, void *aux)
461{ 461{
462 struct cue_softc *sc = device_private(self); 462 struct cue_softc *sc = device_private(self);
463 struct usbnet * const un = &sc->cue_un; 463 struct usbnet * const un = &sc->cue_un;
464 struct usb_attach_arg *uaa = aux; 464 struct usb_attach_arg *uaa = aux;
465 char *devinfop; 465 char *devinfop;
466 struct usbd_device * dev = uaa->uaa_device; 466 struct usbd_device * dev = uaa->uaa_device;
467 usbd_status err; 467 usbd_status err;
468 usb_interface_descriptor_t *id; 468 usb_interface_descriptor_t *id;
469 usb_endpoint_descriptor_t *ed; 469 usb_endpoint_descriptor_t *ed;
470 int i; 470 int i;
471 471
472 KASSERT((void *)sc == un); 472 KASSERT((void *)sc == un);
473 473
474 DPRINTFN(5,(" : cue_attach: sc=%p, dev=%p", sc, dev)); 474 DPRINTFN(5,(" : cue_attach: sc=%p, dev=%p", sc, dev));
475 475
476 aprint_naive("\n"); 476 aprint_naive("\n");
477 aprint_normal("\n"); 477 aprint_normal("\n");
478 devinfop = usbd_devinfo_alloc(dev, 0); 478 devinfop = usbd_devinfo_alloc(dev, 0);
479 aprint_normal_dev(self, "%s\n", devinfop); 479 aprint_normal_dev(self, "%s\n", devinfop);
480 usbd_devinfo_free(devinfop); 480 usbd_devinfo_free(devinfop);
481 481
482 err = usbd_set_config_no(dev, CUE_CONFIG_NO, 1); 482 err = usbd_set_config_no(dev, CUE_CONFIG_NO, 1);
483 if (err) { 483 if (err) {
484 aprint_error_dev(self, "failed to set configuration" 484 aprint_error_dev(self, "failed to set configuration"
485 ", err=%s\n", usbd_errstr(err)); 485 ", err=%s\n", usbd_errstr(err));
486 return; 486 return;
487 } 487 }
488 488
489 un->un_dev = self; 489 un->un_dev = self;
490 un->un_udev = dev; 490 un->un_udev = dev;
491 un->un_sc = sc; 491 un->un_sc = sc;
492 un->un_ops = &cue_ops; 492 un->un_ops = &cue_ops;
493 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 493 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
494 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 494 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
495 un->un_rx_list_cnt = CUE_RX_LIST_CNT; 495 un->un_rx_list_cnt = CUE_RX_LIST_CNT;
496 un->un_tx_list_cnt = CUE_TX_LIST_CNT; 496 un->un_tx_list_cnt = CUE_TX_LIST_CNT;
497 un->un_rx_bufsz = CUE_BUFSZ; 497 un->un_rx_bufsz = CUE_BUFSZ;
498 un->un_tx_bufsz = CUE_BUFSZ; 498 un->un_tx_bufsz = CUE_BUFSZ;
499 499
500 err = usbd_device2interface_handle(dev, CUE_IFACE_IDX, &un->un_iface); 500 err = usbd_device2interface_handle(dev, CUE_IFACE_IDX, &un->un_iface);
501 if (err) { 501 if (err) {
502 aprint_error_dev(self, "getting interface handle failed\n"); 502 aprint_error_dev(self, "getting interface handle failed\n");
503 return; 503 return;
504 } 504 }
505 505
506 id = usbd_get_interface_descriptor(un->un_iface); 506 id = usbd_get_interface_descriptor(un->un_iface);
507 507
508 /* Find endpoints. */ 508 /* Find endpoints. */
509 for (i = 0; i < id->bNumEndpoints; i++) { 509 for (i = 0; i < id->bNumEndpoints; i++) {
510 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 510 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
511 if (ed == NULL) { 511 if (ed == NULL) {
512 aprint_error_dev(self, "couldn't get ep %d\n", i); 512 aprint_error_dev(self, "couldn't get ep %d\n", i);
513 return; 513 return;
514 } 514 }
515 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 515 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
516 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 516 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
517 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 517 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
518 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 518 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
519 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 519 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
520 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 520 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
521 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 521 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
522 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 522 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
523 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 523 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
524 } 524 }
525 } 525 }
526 526
527 /* First level attach. */ 527 /* First level attach. */
528 usbnet_attach(un, "cuedet"); 528 usbnet_attach(un, "cuedet");
529 529
530#if 0 530#if 0
531 /* Reset the adapter. */ 531 /* Reset the adapter. */
532 cue_reset(un); 532 cue_reset(un);
533#endif 533#endif
534 /* 534 /*
535 * Get station address. 535 * Get station address.
536 */ 536 */
537 cue_getmac(un); 537 cue_getmac(un);
538 538
539 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 539 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
540 0, NULL); 540 0, NULL);
541} 541}
542 542
543static void 543static void
544cue_uno_tick(struct usbnet *un) 544cue_uno_tick(struct usbnet *un)
545{ 545{
546 struct ifnet *ifp = usbnet_ifp(un); 546 struct ifnet *ifp = usbnet_ifp(un);
547 547
548 usbnet_lock_core(un); 548 usbnet_lock_core(un);
549 549
550 net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 550 net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
551 if (cue_csr_read_2(un, CUE_RX_FRAMEERR)) 551 if (cue_csr_read_2(un, CUE_RX_FRAMEERR))
552 if_statinc_ref(nsr, if_ierrors); 552 if_statinc_ref(nsr, if_ierrors);
553 553
554 if_statadd_ref(nsr, if_collisions, 554 if_statadd_ref(nsr, if_collisions,
555 cue_csr_read_2(un, CUE_TX_SINGLECOLL)); 555 cue_csr_read_2(un, CUE_TX_SINGLECOLL));
556 if_statadd_ref(nsr, if_collisions, 556 if_statadd_ref(nsr, if_collisions,
557 cue_csr_read_2(un, CUE_TX_MULTICOLL)); 557 cue_csr_read_2(un, CUE_TX_MULTICOLL));
558 if_statadd_ref(nsr, if_collisions, 558 if_statadd_ref(nsr, if_collisions,
559 cue_csr_read_2(un, CUE_TX_EXCESSCOLL)); 559 cue_csr_read_2(un, CUE_TX_EXCESSCOLL));
560 IF_STAT_PUTREF(ifp); 560 IF_STAT_PUTREF(ifp);
561 561
562 usbnet_unlock_core(un); 562 usbnet_unlock_core(un);
563} 563}
564 564
565static void 565static void
566cue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 566cue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
567{ 567{
568 struct ifnet *ifp = usbnet_ifp(un); 568 struct ifnet *ifp = usbnet_ifp(un);
569 uint8_t *buf = c->unc_buf; 569 uint8_t *buf = c->unc_buf;
570 uint16_t len; 570 uint16_t len;
571 571
572 DPRINTFN(5,("%s: %s: total_len=%d len=%d\n", 572 DPRINTFN(5,("%s: %s: total_len=%d len=%d\n",
573 device_xname(un->un_dev), __func__, 573 device_xname(un->un_dev), __func__,
574 total_len, le16dec(buf))); 574 total_len, le16dec(buf)));
575 575
576 len = UGETW(buf); 576 len = UGETW(buf);
577 if (total_len < 2 || 577 if (total_len < 2 ||
578 len > total_len - 2 || 578 len > total_len - 2 ||
579 len < sizeof(struct ether_header)) { 579 len < sizeof(struct ether_header)) {
580 if_statinc(ifp, if_ierrors); 580 if_statinc(ifp, if_ierrors);
581 return; 581 return;
582 } 582 }
583 583
584 /* No errors; receive the packet. */ 584 /* No errors; receive the packet. */
585 usbnet_enqueue(un, buf + 2, len, 0, 0, 0); 585 usbnet_enqueue(un, buf + 2, len, 0, 0, 0);
586} 586}
587 587
588static unsigned 588static unsigned
589cue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 589cue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
590{ 590{
591 unsigned total_len; 591 unsigned total_len;
592 592
593 DPRINTFN(5,("%s: %s: mbuf len=%d\n", 593 DPRINTFN(5,("%s: %s: mbuf len=%d\n",
594 device_xname(un->un_dev), __func__, 594 device_xname(un->un_dev), __func__,
595 m->m_pkthdr.len)); 595 m->m_pkthdr.len));
596 596
597 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2) 597 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2)
598 return 0; 598 return 0;
599 599
600 /* 600 /*
601 * Copy the mbuf data into a contiguous buffer, leaving two 601 * Copy the mbuf data into a contiguous buffer, leaving two
602 * bytes at the beginning to hold the frame length. 602 * bytes at the beginning to hold the frame length.
603 */ 603 */
604 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + 2); 604 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + 2);
605 605
606 total_len = m->m_pkthdr.len + 2; 606 total_len = m->m_pkthdr.len + 2;
607 607
608 /* The first two bytes are the frame length */ 608 /* The first two bytes are the frame length */
609 c->unc_buf[0] = (uint8_t)m->m_pkthdr.len; 609 c->unc_buf[0] = (uint8_t)m->m_pkthdr.len;
610 c->unc_buf[1] = (uint8_t)(m->m_pkthdr.len >> 8); 610 c->unc_buf[1] = (uint8_t)(m->m_pkthdr.len >> 8);
611 611
612 return total_len; 612 return total_len;
613} 613}
614 614
615static int 615static int
616cue_init_locked(struct ifnet *ifp) 616cue_init_locked(struct ifnet *ifp)
617{ 617{
618 struct usbnet * const un = ifp->if_softc; 618 struct usbnet * const un = ifp->if_softc;
619 int i, ctl; 619 int i, ctl;
620 const u_char *eaddr; 620 const u_char *eaddr;
621 621
622 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev),__func__)); 622 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev),__func__));
623 623
624 if (usbnet_isdying(un)) 624 if (usbnet_isdying(un))
625 return ENXIO; 625 return ENXIO;
626 626
627 /* Cancel pending I/O */ 627 /* Cancel pending I/O */
628 usbnet_stop(un, ifp, 1); 628 usbnet_stop(un, ifp, 1);
629 629
630 /* Reset the interface. */ 630 /* Reset the interface. */
631#if 1 631#if 1
632 cue_reset(un); 632 cue_reset(un);
633#endif 633#endif
634 634
635 /* Set advanced operation modes. */ 635 /* Set advanced operation modes. */
636 cue_csr_write_1(un, CUE_ADVANCED_OPMODES, 636 cue_csr_write_1(un, CUE_ADVANCED_OPMODES,
637 CUE_AOP_EMBED_RXLEN | 0x03); /* 1 wait state */ 637 CUE_AOP_EMBED_RXLEN | 0x03); /* 1 wait state */
638 638
639 eaddr = CLLADDR(ifp->if_sadl); 639 eaddr = CLLADDR(ifp->if_sadl);
640 /* Set MAC address */ 640 /* Set MAC address */
641 for (i = 0; i < ETHER_ADDR_LEN; i++) 641 for (i = 0; i < ETHER_ADDR_LEN; i++)
642 cue_csr_write_1(un, CUE_PAR0 - i, eaddr[i]); 642 cue_csr_write_1(un, CUE_PAR0 - i, eaddr[i]);
643 643
644 /* Enable RX logic. */ 644 /* Enable RX logic. */
645 ctl = CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON; 645 ctl = CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON;
646 if (ifp->if_flags & IFF_PROMISC) 646 if (ifp->if_flags & IFF_PROMISC)
647 ctl |= CUE_ETHCTL_PROMISC; 647 ctl |= CUE_ETHCTL_PROMISC;
648 cue_csr_write_1(un, CUE_ETHCTL, ctl); 648 cue_csr_write_1(un, CUE_ETHCTL, ctl);
649 649
650 /* Load the multicast filter. */ 650 /* Load the multicast filter. */
651 cue_setiff_locked(un); 651 cue_setiff_locked(un);
652 652
653 /* 653 /*
654 * Set the number of RX and TX buffers that we want 654 * Set the number of RX and TX buffers that we want
655 * to reserve inside the ASIC. 655 * to reserve inside the ASIC.
656 */ 656 */
657 cue_csr_write_1(un, CUE_RX_BUFPKTS, CUE_RX_FRAMES); 657 cue_csr_write_1(un, CUE_RX_BUFPKTS, CUE_RX_FRAMES);
658 cue_csr_write_1(un, CUE_TX_BUFPKTS, CUE_TX_FRAMES); 658 cue_csr_write_1(un, CUE_TX_BUFPKTS, CUE_TX_FRAMES);
659 659
660 /* Set advanced operation modes. */ 660 /* Set advanced operation modes. */
661 cue_csr_write_1(un, CUE_ADVANCED_OPMODES, 661 cue_csr_write_1(un, CUE_ADVANCED_OPMODES,
662 CUE_AOP_EMBED_RXLEN | 0x01); /* 1 wait state */ 662 CUE_AOP_EMBED_RXLEN | 0x01); /* 1 wait state */
663 663
664 /* Program the LED operation. */ 664 /* Program the LED operation. */
665 cue_csr_write_1(un, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK); 665 cue_csr_write_1(un, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);
666 666
667 return usbnet_init_rx_tx(un); 667 return usbnet_init_rx_tx(un);
668} 668}
669 669
670static int 670static int
671cue_uno_init(struct ifnet *ifp) 671cue_uno_init(struct ifnet *ifp)
672{ 672{
673 int rv; 673 int rv;
674 674
675 rv = cue_init_locked(ifp); 675 rv = cue_init_locked(ifp);
676 676
677 return rv; 677 return rv;
678} 678}
679 679
680static void 680static void
681cue_uno_mcast(struct ifnet *ifp) 681cue_uno_mcast(struct ifnet *ifp)
682{ 682{
683 struct usbnet * const un = ifp->if_softc; 683 struct usbnet * const un = ifp->if_softc;
684 684
685 usbnet_lock_core(un); 685 usbnet_lock_core(un);
686 usbnet_busy(un); 
687 686
688 cue_setiff_locked(un); 687 cue_setiff_locked(un);
689 688
690 usbnet_unbusy(un); 
691 usbnet_unlock_core(un); 689 usbnet_unlock_core(un);
692} 690}
693 691
694/* Stop and reset the adapter. */ 692/* Stop and reset the adapter. */
695static void 693static void
696cue_uno_stop(struct ifnet *ifp, int disable) 694cue_uno_stop(struct ifnet *ifp, int disable)
697{ 695{
698 struct usbnet * const un = ifp->if_softc; 696 struct usbnet * const un = ifp->if_softc;
699 697
700 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 698 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev), __func__));
701 699
702 cue_csr_write_1(un, CUE_ETHCTL, 0); 700 cue_csr_write_1(un, CUE_ETHCTL, 0);
703 cue_reset(un); 701 cue_reset(un);
704} 702}
705 703
706#ifdef _MODULE 704#ifdef _MODULE
707#include "ioconf.c" 705#include "ioconf.c"
708#endif 706#endif
709 707
710USBNET_MODULE(cue) 708USBNET_MODULE(cue)

cvs diff -r1.108 -r1.109 src/sys/dev/usb/if_kue.c (switch to unified diff)

--- src/sys/dev/usb/if_kue.c 2022/03/03 05:51:17 1.108
+++ src/sys/dev/usb/if_kue.c 2022/03/03 05:51:27 1.109
@@ -1,658 +1,656 @@ @@ -1,658 +1,656 @@
1/* $NetBSD: if_kue.c,v 1.108 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_kue.c,v 1.109 2022/03/03 05:51:27 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997, 1998, 1999, 2000 4 * Copyright (c) 1997, 1998, 1999, 2000
5 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. 5 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Bill Paul. 17 * This product includes software developed by Bill Paul.
18 * 4. Neither the name of the author nor the names of any co-contributors 18 * 4. Neither the name of the author nor the names of any co-contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE. 32 * THE POSSIBILITY OF SUCH DAMAGE.
33 * 33 *
34 * $FreeBSD: src/sys/dev/usb/if_kue.c,v 1.14 2000/01/14 01:36:15 wpaul Exp $ 34 * $FreeBSD: src/sys/dev/usb/if_kue.c,v 1.14 2000/01/14 01:36:15 wpaul Exp $
35 */ 35 */
36 36
37/* 37/*
38 * Kawasaki LSI KL5KUSB101B USB to ethernet adapter driver. 38 * Kawasaki LSI KL5KUSB101B USB to ethernet adapter driver.
39 * 39 *
40 * Written by Bill Paul <wpaul@ee.columbia.edu> 40 * Written by Bill Paul <wpaul@ee.columbia.edu>
41 * Electrical Engineering Department 41 * Electrical Engineering Department
42 * Columbia University, New York City 42 * Columbia University, New York City
43 */ 43 */
44 44
45/* 45/*
46 * The KLSI USB to ethernet adapter chip contains an USB serial interface, 46 * The KLSI USB to ethernet adapter chip contains an USB serial interface,
47 * ethernet MAC and embedded microcontroller (called the QT Engine). 47 * ethernet MAC and embedded microcontroller (called the QT Engine).
48 * The chip must have firmware loaded into it before it will operate. 48 * The chip must have firmware loaded into it before it will operate.
49 * Packets are passed between the chip and host via bulk transfers. 49 * Packets are passed between the chip and host via bulk transfers.
50 * There is an interrupt endpoint mentioned in the software spec, however 50 * There is an interrupt endpoint mentioned in the software spec, however
51 * it's currently unused. This device is 10Mbps half-duplex only, hence 51 * it's currently unused. This device is 10Mbps half-duplex only, hence
52 * there is no media selection logic. The MAC supports a 128 entry 52 * there is no media selection logic. The MAC supports a 128 entry
53 * multicast filter, though the exact size of the filter can depend 53 * multicast filter, though the exact size of the filter can depend
54 * on the firmware. Curiously, while the software spec describes various 54 * on the firmware. Curiously, while the software spec describes various
55 * ethernet statistics counters, my sample adapter and firmware combination 55 * ethernet statistics counters, my sample adapter and firmware combination
56 * claims not to support any statistics counters at all. 56 * claims not to support any statistics counters at all.
57 * 57 *
58 * Note that once we load the firmware in the device, we have to be 58 * Note that once we load the firmware in the device, we have to be
59 * careful not to load it again: if you restart your computer but 59 * careful not to load it again: if you restart your computer but
60 * leave the adapter attached to the USB controller, it may remain 60 * leave the adapter attached to the USB controller, it may remain
61 * powered on and retain its firmware. In this case, we don't need 61 * powered on and retain its firmware. In this case, we don't need
62 * to load the firmware a second time. 62 * to load the firmware a second time.
63 * 63 *
64 * Special thanks to Rob Furr for providing an ADS Technologies 64 * Special thanks to Rob Furr for providing an ADS Technologies
65 * adapter for development and testing. No monkeys were harmed during 65 * adapter for development and testing. No monkeys were harmed during
66 * the development of this driver. 66 * the development of this driver.
67 */ 67 */
68 68
69/* 69/*
70 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. 70 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson.
71 */ 71 */
72 72
73#include <sys/cdefs.h> 73#include <sys/cdefs.h>
74__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.108 2022/03/03 05:51:17 riastradh Exp $"); 74__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.109 2022/03/03 05:51:27 riastradh Exp $");
75 75
76#ifdef _KERNEL_OPT 76#ifdef _KERNEL_OPT
77#include "opt_inet.h" 77#include "opt_inet.h"
78#include "opt_usb.h" 78#include "opt_usb.h"
79#endif 79#endif
80 80
81#include <sys/param.h> 81#include <sys/param.h>
82#include <sys/kmem.h> 82#include <sys/kmem.h>
83 83
84#include <dev/usb/usbnet.h> 84#include <dev/usb/usbnet.h>
85 85
86#ifdef INET 86#ifdef INET
87#include <netinet/in.h> 87#include <netinet/in.h>
88#include <netinet/if_inarp.h> 88#include <netinet/if_inarp.h>
89#endif 89#endif
90 90
91#include <dev/usb/if_kuereg.h> 91#include <dev/usb/if_kuereg.h>
92#include <dev/usb/kue_fw.h> 92#include <dev/usb/kue_fw.h>
93 93
94#ifdef KUE_DEBUG 94#ifdef KUE_DEBUG
95#define DPRINTF(x) if (kuedebug) printf x 95#define DPRINTF(x) if (kuedebug) printf x
96#define DPRINTFN(n, x) if (kuedebug >= (n)) printf x 96#define DPRINTFN(n, x) if (kuedebug >= (n)) printf x
97int kuedebug = 0; 97int kuedebug = 0;
98#else 98#else
99#define DPRINTF(x) 99#define DPRINTF(x)
100#define DPRINTFN(n, x) 100#define DPRINTFN(n, x)
101#endif 101#endif
102 102
103struct kue_type { 103struct kue_type {
104 uint16_t kue_vid; 104 uint16_t kue_vid;
105 uint16_t kue_did; 105 uint16_t kue_did;
106}; 106};
107 107
108struct kue_softc { 108struct kue_softc {
109 struct usbnet kue_un; 109 struct usbnet kue_un;
110 110
111 struct kue_ether_desc kue_desc; 111 struct kue_ether_desc kue_desc;
112 uint16_t kue_rxfilt; 112 uint16_t kue_rxfilt;
113 uint8_t *kue_mcfilters; 113 uint8_t *kue_mcfilters;
114}; 114};
115 115
116#define KUE_MCFILT(x, y) \ 116#define KUE_MCFILT(x, y) \
117 (uint8_t *)&(sc->kue_mcfilters[y * ETHER_ADDR_LEN]) 117 (uint8_t *)&(sc->kue_mcfilters[y * ETHER_ADDR_LEN])
118 118
119#define KUE_BUFSZ 1536 119#define KUE_BUFSZ 1536
120#define KUE_MIN_FRAMELEN 60 120#define KUE_MIN_FRAMELEN 60
121 121
122#define KUE_RX_LIST_CNT 1 122#define KUE_RX_LIST_CNT 1
123#define KUE_TX_LIST_CNT 1 123#define KUE_TX_LIST_CNT 1
124 124
125/* 125/*
126 * Various supported device vendors/products. 126 * Various supported device vendors/products.
127 */ 127 */
128static const struct usb_devno kue_devs[] = { 128static const struct usb_devno kue_devs[] = {
129 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 }, 129 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 },
130 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 }, 130 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 },
131 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450 }, 131 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450 },
132 { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT }, 132 { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT },
133 { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX }, 133 { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX },
134 { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287 }, 134 { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287 },
135 { USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_AT_USB10 }, 135 { USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_AT_USB10 },
136 { USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101 }, 136 { USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101 },
137 { USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA }, 137 { USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA },
138 { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T }, 138 { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T },
139 { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C }, 139 { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C },
140 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T }, 140 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T },
141 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C }, 141 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C },
142 { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 }, 142 { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 },
143 { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1 }, 143 { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1 },
144 { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2 }, 144 { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2 },
145 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT }, 145 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT },
146 { USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA }, 146 { USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA },
147 { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1 }, 147 { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1 },
148 { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT }, 148 { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT },
149 { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN }, 149 { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN },
150 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T }, 150 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T },
151 { USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA }, 151 { USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA },
152 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 }, 152 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 },
153 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X }, 153 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X },
154 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET }, 154 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET },
155 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 }, 155 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 },
156 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3 }, 156 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3 },
157 { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8 }, 157 { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8 },
158 { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9 }, 158 { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9 },
159 { USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA }, 159 { USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA },
160 { USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA }, 160 { USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA },
161 { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E }, 161 { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E },
162 { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_GPE }, 162 { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_GPE },
163 { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB }, 163 { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB },
164}; 164};
165#define kue_lookup(v, p) (usb_lookup(kue_devs, v, p)) 165#define kue_lookup(v, p) (usb_lookup(kue_devs, v, p))
166 166
167static int kue_match(device_t, cfdata_t, void *); 167static int kue_match(device_t, cfdata_t, void *);
168static void kue_attach(device_t, device_t, void *); 168static void kue_attach(device_t, device_t, void *);
169static int kue_detach(device_t, int); 169static int kue_detach(device_t, int);
170 170
171CFATTACH_DECL_NEW(kue, sizeof(struct kue_softc), kue_match, kue_attach, 171CFATTACH_DECL_NEW(kue, sizeof(struct kue_softc), kue_match, kue_attach,
172 kue_detach, usbnet_activate); 172 kue_detach, usbnet_activate);
173 173
174static void kue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 174static void kue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
175static unsigned kue_uno_tx_prepare(struct usbnet *, struct mbuf *, 175static unsigned kue_uno_tx_prepare(struct usbnet *, struct mbuf *,
176 struct usbnet_chain *); 176 struct usbnet_chain *);
177static void kue_uno_mcast(struct ifnet *); 177static void kue_uno_mcast(struct ifnet *);
178static int kue_uno_init(struct ifnet *); 178static int kue_uno_init(struct ifnet *);
179 179
180static const struct usbnet_ops kue_ops = { 180static const struct usbnet_ops kue_ops = {
181 .uno_mcast = kue_uno_mcast, 181 .uno_mcast = kue_uno_mcast,
182 .uno_tx_prepare = kue_uno_tx_prepare, 182 .uno_tx_prepare = kue_uno_tx_prepare,
183 .uno_rx_loop = kue_uno_rx_loop, 183 .uno_rx_loop = kue_uno_rx_loop,
184 .uno_init = kue_uno_init, 184 .uno_init = kue_uno_init,
185}; 185};
186 186
187static void kue_reset(struct usbnet *); 187static void kue_reset(struct usbnet *);
188 188
189static usbd_status kue_ctl(struct usbnet *, int, uint8_t, 189static usbd_status kue_ctl(struct usbnet *, int, uint8_t,
190 uint16_t, void *, uint32_t); 190 uint16_t, void *, uint32_t);
191static int kue_load_fw(struct usbnet *); 191static int kue_load_fw(struct usbnet *);
192 192
193static usbd_status 193static usbd_status
194kue_setword(struct usbnet *un, uint8_t breq, uint16_t word) 194kue_setword(struct usbnet *un, uint8_t breq, uint16_t word)
195{ 195{
196 usb_device_request_t req; 196 usb_device_request_t req;
197 197
198 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev),__func__)); 198 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev),__func__));
199 199
200 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 200 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
201 req.bRequest = breq; 201 req.bRequest = breq;
202 USETW(req.wValue, word); 202 USETW(req.wValue, word);
203 USETW(req.wIndex, 0); 203 USETW(req.wIndex, 0);
204 USETW(req.wLength, 0); 204 USETW(req.wLength, 0);
205 205
206 return usbd_do_request(un->un_udev, &req, NULL); 206 return usbd_do_request(un->un_udev, &req, NULL);
207} 207}
208 208
209static usbd_status 209static usbd_status
210kue_ctl(struct usbnet *un, int rw, uint8_t breq, uint16_t val, 210kue_ctl(struct usbnet *un, int rw, uint8_t breq, uint16_t val,
211 void *data, uint32_t len) 211 void *data, uint32_t len)
212{ 212{
213 usb_device_request_t req; 213 usb_device_request_t req;
214 214
215 DPRINTFN(10,("%s: %s: enter, len=%d\n", device_xname(un->un_dev), 215 DPRINTFN(10,("%s: %s: enter, len=%d\n", device_xname(un->un_dev),
216 __func__, len)); 216 __func__, len));
217 217
218 if (rw == KUE_CTL_WRITE) 218 if (rw == KUE_CTL_WRITE)
219 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 219 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
220 else 220 else
221 req.bmRequestType = UT_READ_VENDOR_DEVICE; 221 req.bmRequestType = UT_READ_VENDOR_DEVICE;
222 222
223 req.bRequest = breq; 223 req.bRequest = breq;
224 USETW(req.wValue, val); 224 USETW(req.wValue, val);
225 USETW(req.wIndex, 0); 225 USETW(req.wIndex, 0);
226 USETW(req.wLength, len); 226 USETW(req.wLength, len);
227 227
228 return usbd_do_request(un->un_udev, &req, data); 228 return usbd_do_request(un->un_udev, &req, data);
229} 229}
230 230
231static int 231static int
232kue_load_fw(struct usbnet *un) 232kue_load_fw(struct usbnet *un)
233{ 233{
234 usb_device_descriptor_t dd; 234 usb_device_descriptor_t dd;
235 usbd_status err; 235 usbd_status err;
236 236
237 DPRINTFN(1,("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 237 DPRINTFN(1,("%s: %s: enter\n", device_xname(un->un_dev), __func__));
238 238
239 /* 239 /*
240 * First, check if we even need to load the firmware. 240 * First, check if we even need to load the firmware.
241 * If the device was still attached when the system was 241 * If the device was still attached when the system was
242 * rebooted, it may already have firmware loaded in it. 242 * rebooted, it may already have firmware loaded in it.
243 * If this is the case, we don't need to do it again. 243 * If this is the case, we don't need to do it again.
244 * And in fact, if we try to load it again, we'll hang, 244 * And in fact, if we try to load it again, we'll hang,
245 * so we have to avoid this condition if we don't want 245 * so we have to avoid this condition if we don't want
246 * to look stupid. 246 * to look stupid.
247 * 247 *
248 * We can test this quickly by checking the bcdRevision 248 * We can test this quickly by checking the bcdRevision
249 * code. The NIC will return a different revision code if 249 * code. The NIC will return a different revision code if
250 * it's probed while the firmware is still loaded and 250 * it's probed while the firmware is still loaded and
251 * running. 251 * running.
252 */ 252 */
253 if (usbd_get_device_desc(un->un_udev, &dd)) 253 if (usbd_get_device_desc(un->un_udev, &dd))
254 return EIO; 254 return EIO;
255 if (UGETW(dd.bcdDevice) == KUE_WARM_REV) { 255 if (UGETW(dd.bcdDevice) == KUE_WARM_REV) {
256 printf("%s: warm boot, no firmware download\n", 256 printf("%s: warm boot, no firmware download\n",
257 device_xname(un->un_dev)); 257 device_xname(un->un_dev));
258 return 0; 258 return 0;
259 } 259 }
260 260
261 printf("%s: cold boot, downloading firmware\n", 261 printf("%s: cold boot, downloading firmware\n",
262 device_xname(un->un_dev)); 262 device_xname(un->un_dev));
263 263
264 /* Load code segment */ 264 /* Load code segment */
265 DPRINTFN(1,("%s: kue_load_fw: download code_seg\n", 265 DPRINTFN(1,("%s: kue_load_fw: download code_seg\n",
266 device_xname(un->un_dev))); 266 device_xname(un->un_dev)));
267 /*XXXUNCONST*/ 267 /*XXXUNCONST*/
268 err = kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 268 err = kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
269 0, __UNCONST(kue_code_seg), sizeof(kue_code_seg)); 269 0, __UNCONST(kue_code_seg), sizeof(kue_code_seg));
270 if (err) { 270 if (err) {
271 printf("%s: failed to load code segment: %s\n", 271 printf("%s: failed to load code segment: %s\n",
272 device_xname(un->un_dev), usbd_errstr(err)); 272 device_xname(un->un_dev), usbd_errstr(err));
273 return EIO; 273 return EIO;
274 } 274 }
275 275
276 /* Load fixup segment */ 276 /* Load fixup segment */
277 DPRINTFN(1,("%s: kue_load_fw: download fix_seg\n", 277 DPRINTFN(1,("%s: kue_load_fw: download fix_seg\n",
278 device_xname(un->un_dev))); 278 device_xname(un->un_dev)));
279 /*XXXUNCONST*/ 279 /*XXXUNCONST*/
280 err = kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 280 err = kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
281 0, __UNCONST(kue_fix_seg), sizeof(kue_fix_seg)); 281 0, __UNCONST(kue_fix_seg), sizeof(kue_fix_seg));
282 if (err) { 282 if (err) {
283 printf("%s: failed to load fixup segment: %s\n", 283 printf("%s: failed to load fixup segment: %s\n",
284 device_xname(un->un_dev), usbd_errstr(err)); 284 device_xname(un->un_dev), usbd_errstr(err));
285 return EIO; 285 return EIO;
286 } 286 }
287 287
288 /* Send trigger command. */ 288 /* Send trigger command. */
289 DPRINTFN(1,("%s: kue_load_fw: download trig_seg\n", 289 DPRINTFN(1,("%s: kue_load_fw: download trig_seg\n",
290 device_xname(un->un_dev))); 290 device_xname(un->un_dev)));
291 /*XXXUNCONST*/ 291 /*XXXUNCONST*/
292 err = kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 292 err = kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
293 0, __UNCONST(kue_trig_seg), sizeof(kue_trig_seg)); 293 0, __UNCONST(kue_trig_seg), sizeof(kue_trig_seg));
294 if (err) { 294 if (err) {
295 printf("%s: failed to load trigger segment: %s\n", 295 printf("%s: failed to load trigger segment: %s\n",
296 device_xname(un->un_dev), usbd_errstr(err)); 296 device_xname(un->un_dev), usbd_errstr(err));
297 return EIO; 297 return EIO;
298 } 298 }
299 299
300 usbd_delay_ms(un->un_udev, 10); 300 usbd_delay_ms(un->un_udev, 10);
301 301
302 /* 302 /*
303 * Reload device descriptor. 303 * Reload device descriptor.
304 * Why? The chip without the firmware loaded returns 304 * Why? The chip without the firmware loaded returns
305 * one revision code. The chip with the firmware 305 * one revision code. The chip with the firmware
306 * loaded and running returns a *different* revision 306 * loaded and running returns a *different* revision
307 * code. This confuses the quirk mechanism, which is 307 * code. This confuses the quirk mechanism, which is
308 * dependent on the revision data. 308 * dependent on the revision data.
309 */ 309 */
310 (void)usbd_reload_device_desc(un->un_udev); 310 (void)usbd_reload_device_desc(un->un_udev);
311 311
312 DPRINTFN(1,("%s: %s: done\n", device_xname(un->un_dev), __func__)); 312 DPRINTFN(1,("%s: %s: done\n", device_xname(un->un_dev), __func__));
313 313
314 /* Reset the adapter. */ 314 /* Reset the adapter. */
315 kue_reset(un); 315 kue_reset(un);
316 316
317 return 0; 317 return 0;
318} 318}
319 319
320static void 320static void
321kue_setiff_locked(struct usbnet *un) 321kue_setiff_locked(struct usbnet *un)
322{ 322{
323 struct ethercom * ec = usbnet_ec(un); 323 struct ethercom * ec = usbnet_ec(un);
324 struct kue_softc * sc = usbnet_softc(un); 324 struct kue_softc * sc = usbnet_softc(un);
325 struct ifnet * const ifp = usbnet_ifp(un); 325 struct ifnet * const ifp = usbnet_ifp(un);
326 struct ether_multi *enm; 326 struct ether_multi *enm;
327 struct ether_multistep step; 327 struct ether_multistep step;
328 int i; 328 int i;
329 329
330 DPRINTFN(5,("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 330 DPRINTFN(5,("%s: %s: enter\n", device_xname(un->un_dev), __func__));
331 331
332 /* If we want promiscuous mode, set the allframes bit. */ 332 /* If we want promiscuous mode, set the allframes bit. */
333 if (ifp->if_flags & IFF_PROMISC) 333 if (ifp->if_flags & IFF_PROMISC)
334 sc->kue_rxfilt |= KUE_RXFILT_PROMISC; 334 sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
335 else 335 else
336 sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC; 336 sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC;
337 337
338 if (ifp->if_flags & IFF_PROMISC) { 338 if (ifp->if_flags & IFF_PROMISC) {
339allmulti: 339allmulti:
340 ifp->if_flags |= IFF_ALLMULTI; 340 ifp->if_flags |= IFF_ALLMULTI;
341 sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI|KUE_RXFILT_PROMISC; 341 sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI|KUE_RXFILT_PROMISC;
342 sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST; 342 sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST;
343 kue_setword(un, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt); 343 kue_setword(un, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
344 return; 344 return;
345 } 345 }
346 346
347 sc->kue_rxfilt &= ~(KUE_RXFILT_ALLMULTI|KUE_RXFILT_PROMISC); 347 sc->kue_rxfilt &= ~(KUE_RXFILT_ALLMULTI|KUE_RXFILT_PROMISC);
348 348
349 i = 0; 349 i = 0;
350 ETHER_LOCK(ec); 350 ETHER_LOCK(ec);
351 ETHER_FIRST_MULTI(step, ec, enm); 351 ETHER_FIRST_MULTI(step, ec, enm);
352 while (enm != NULL) { 352 while (enm != NULL) {
353 if (i == KUE_MCFILTCNT(sc) || 353 if (i == KUE_MCFILTCNT(sc) ||
354 memcmp(enm->enm_addrlo, enm->enm_addrhi, 354 memcmp(enm->enm_addrlo, enm->enm_addrhi,
355 ETHER_ADDR_LEN) != 0) { 355 ETHER_ADDR_LEN) != 0) {
356 ETHER_UNLOCK(ec); 356 ETHER_UNLOCK(ec);
357 goto allmulti; 357 goto allmulti;
358 } 358 }
359 359
360 memcpy(KUE_MCFILT(sc, i), enm->enm_addrlo, ETHER_ADDR_LEN); 360 memcpy(KUE_MCFILT(sc, i), enm->enm_addrlo, ETHER_ADDR_LEN);
361 ETHER_NEXT_MULTI(step, enm); 361 ETHER_NEXT_MULTI(step, enm);
362 i++; 362 i++;
363 } 363 }
364 ETHER_UNLOCK(ec); 364 ETHER_UNLOCK(ec);
365 365
366 ifp->if_flags &= ~IFF_ALLMULTI; 366 ifp->if_flags &= ~IFF_ALLMULTI;
367 367
368 sc->kue_rxfilt |= KUE_RXFILT_MULTICAST; 368 sc->kue_rxfilt |= KUE_RXFILT_MULTICAST;
369 kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS, 369 kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS,
370 i, sc->kue_mcfilters, i * ETHER_ADDR_LEN); 370 i, sc->kue_mcfilters, i * ETHER_ADDR_LEN);
371 371
372 kue_setword(un, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt); 372 kue_setword(un, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
373} 373}
374 374
375/* 375/*
376 * Issue a SET_CONFIGURATION command to reset the MAC. This should be 376 * Issue a SET_CONFIGURATION command to reset the MAC. This should be
377 * done after the firmware is loaded into the adapter in order to 377 * done after the firmware is loaded into the adapter in order to
378 * bring it into proper operation. 378 * bring it into proper operation.
379 */ 379 */
380static void 380static void
381kue_reset(struct usbnet *un) 381kue_reset(struct usbnet *un)
382{ 382{
383 DPRINTFN(5,("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 383 DPRINTFN(5,("%s: %s: enter\n", device_xname(un->un_dev), __func__));
384 384
385 if (usbd_set_config_no(un->un_udev, KUE_CONFIG_NO, 1) || 385 if (usbd_set_config_no(un->un_udev, KUE_CONFIG_NO, 1) ||
386 usbd_device2interface_handle(un->un_udev, KUE_IFACE_IDX, 386 usbd_device2interface_handle(un->un_udev, KUE_IFACE_IDX,
387 &un->un_iface)) 387 &un->un_iface))
388 printf("%s: reset failed\n", device_xname(un->un_dev)); 388 printf("%s: reset failed\n", device_xname(un->un_dev));
389 389
390 /* Wait a little while for the chip to get its brains in order. */ 390 /* Wait a little while for the chip to get its brains in order. */
391 usbd_delay_ms(un->un_udev, 10); 391 usbd_delay_ms(un->un_udev, 10);
392} 392}
393 393
394/* 394/*
395 * Probe for a KLSI chip. 395 * Probe for a KLSI chip.
396 */ 396 */
397static int 397static int
398kue_match(device_t parent, cfdata_t match, void *aux) 398kue_match(device_t parent, cfdata_t match, void *aux)
399{ 399{
400 struct usb_attach_arg *uaa = aux; 400 struct usb_attach_arg *uaa = aux;
401 401
402 DPRINTFN(25,("kue_match: enter\n")); 402 DPRINTFN(25,("kue_match: enter\n"));
403 403
404 return kue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 404 return kue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
405 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 405 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
406} 406}
407 407
408/* 408/*
409 * Attach the interface. Allocate softc structures, do 409 * Attach the interface. Allocate softc structures, do
410 * setup and ethernet/BPF attach. 410 * setup and ethernet/BPF attach.
411 */ 411 */
412static void 412static void
413kue_attach(device_t parent, device_t self, void *aux) 413kue_attach(device_t parent, device_t self, void *aux)
414{ 414{
415 struct kue_softc *sc = device_private(self); 415 struct kue_softc *sc = device_private(self);
416 struct usbnet * const un = &sc->kue_un; 416 struct usbnet * const un = &sc->kue_un;
417 struct usb_attach_arg *uaa = aux; 417 struct usb_attach_arg *uaa = aux;
418 char *devinfop; 418 char *devinfop;
419 struct usbd_device * dev = uaa->uaa_device; 419 struct usbd_device * dev = uaa->uaa_device;
420 usbd_status err; 420 usbd_status err;
421 usb_interface_descriptor_t *id; 421 usb_interface_descriptor_t *id;
422 usb_endpoint_descriptor_t *ed; 422 usb_endpoint_descriptor_t *ed;
423 int i; 423 int i;
424 424
425 KASSERT((void *)sc == un); 425 KASSERT((void *)sc == un);
426 426
427 DPRINTFN(5,(" : kue_attach: sc=%p, dev=%p", sc, dev)); 427 DPRINTFN(5,(" : kue_attach: sc=%p, dev=%p", sc, dev));
428 428
429 aprint_naive("\n"); 429 aprint_naive("\n");
430 aprint_normal("\n"); 430 aprint_normal("\n");
431 devinfop = usbd_devinfo_alloc(dev, 0); 431 devinfop = usbd_devinfo_alloc(dev, 0);
432 aprint_normal_dev(self, "%s\n", devinfop); 432 aprint_normal_dev(self, "%s\n", devinfop);
433 usbd_devinfo_free(devinfop); 433 usbd_devinfo_free(devinfop);
434 434
435 un->un_dev = self; 435 un->un_dev = self;
436 un->un_udev = dev; 436 un->un_udev = dev;
437 un->un_sc = sc; 437 un->un_sc = sc;
438 un->un_ops = &kue_ops; 438 un->un_ops = &kue_ops;
439 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 439 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
440 un->un_tx_xfer_flags = 0; 440 un->un_tx_xfer_flags = 0;
441 un->un_rx_list_cnt = KUE_RX_LIST_CNT; 441 un->un_rx_list_cnt = KUE_RX_LIST_CNT;
442 un->un_tx_list_cnt = KUE_TX_LIST_CNT; 442 un->un_tx_list_cnt = KUE_TX_LIST_CNT;
443 un->un_rx_bufsz = KUE_BUFSZ; 443 un->un_rx_bufsz = KUE_BUFSZ;
444 un->un_tx_bufsz = KUE_BUFSZ; 444 un->un_tx_bufsz = KUE_BUFSZ;
445 445
446 err = usbd_set_config_no(dev, KUE_CONFIG_NO, 1); 446 err = usbd_set_config_no(dev, KUE_CONFIG_NO, 1);
447 if (err) { 447 if (err) {
448 aprint_error_dev(self, "failed to set configuration" 448 aprint_error_dev(self, "failed to set configuration"
449 ", err=%s\n", usbd_errstr(err)); 449 ", err=%s\n", usbd_errstr(err));
450 return; 450 return;
451 } 451 }
452 452
453 /* Load the firmware into the NIC. */ 453 /* Load the firmware into the NIC. */
454 if (kue_load_fw(un)) { 454 if (kue_load_fw(un)) {
455 aprint_error_dev(self, "loading firmware failed\n"); 455 aprint_error_dev(self, "loading firmware failed\n");
456 return; 456 return;
457 } 457 }
458 458
459 err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &un->un_iface); 459 err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &un->un_iface);
460 if (err) { 460 if (err) {
461 aprint_error_dev(self, "getting interface handle failed\n"); 461 aprint_error_dev(self, "getting interface handle failed\n");
462 return; 462 return;
463 } 463 }
464 464
465 id = usbd_get_interface_descriptor(un->un_iface); 465 id = usbd_get_interface_descriptor(un->un_iface);
466 466
467 /* Find endpoints. */ 467 /* Find endpoints. */
468 for (i = 0; i < id->bNumEndpoints; i++) { 468 for (i = 0; i < id->bNumEndpoints; i++) {
469 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 469 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
470 if (ed == NULL) { 470 if (ed == NULL) {
471 aprint_error_dev(self, "couldn't get ep %d\n", i); 471 aprint_error_dev(self, "couldn't get ep %d\n", i);
472 return; 472 return;
473 } 473 }
474 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 474 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
475 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 475 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
476 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 476 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
477 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 477 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
478 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 478 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
479 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 479 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
480 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 480 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
481 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 481 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
482 /* 482 /*
483 * The interrupt endpoint is currently unused by the 483 * The interrupt endpoint is currently unused by the
484 * KLSI part. 484 * KLSI part.
485 */ 485 */
486 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 486 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
487 } 487 }
488 } 488 }
489 489
490 if (un->un_ed[USBNET_ENDPT_RX] == 0 || 490 if (un->un_ed[USBNET_ENDPT_RX] == 0 ||
491 un->un_ed[USBNET_ENDPT_TX] == 0) { 491 un->un_ed[USBNET_ENDPT_TX] == 0) {
492 aprint_error_dev(self, "missing endpoint\n"); 492 aprint_error_dev(self, "missing endpoint\n");
493 return; 493 return;
494 } 494 }
495 495
496 /* First level attach, so kue_ctl() works. */ 496 /* First level attach, so kue_ctl() works. */
497 usbnet_attach(un, "kuedet"); 497 usbnet_attach(un, "kuedet");
498 498
499 /* Read ethernet descriptor */ 499 /* Read ethernet descriptor */
500 err = kue_ctl(un, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR, 500 err = kue_ctl(un, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
501 0, &sc->kue_desc, sizeof(sc->kue_desc)); 501 0, &sc->kue_desc, sizeof(sc->kue_desc));
502 if (err) { 502 if (err) {
503 aprint_error_dev(self, "could not read Ethernet descriptor\n"); 503 aprint_error_dev(self, "could not read Ethernet descriptor\n");
504 return; 504 return;
505 } 505 }
506 memcpy(un->un_eaddr, sc->kue_desc.kue_macaddr, sizeof(un->un_eaddr)); 506 memcpy(un->un_eaddr, sc->kue_desc.kue_macaddr, sizeof(un->un_eaddr));
507 507
508 sc->kue_mcfilters = kmem_alloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, 508 sc->kue_mcfilters = kmem_alloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
509 KM_SLEEP); 509 KM_SLEEP);
510 510
511 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 511 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
512 0, NULL); 512 0, NULL);
513} 513}
514 514
515static int 515static int
516kue_detach(device_t self, int flags) 516kue_detach(device_t self, int flags)
517{ 517{
518 struct kue_softc *sc = device_private(self); 518 struct kue_softc *sc = device_private(self);
519 519
520 if (sc->kue_mcfilters != NULL) { 520 if (sc->kue_mcfilters != NULL) {
521 kmem_free(sc->kue_mcfilters, 521 kmem_free(sc->kue_mcfilters,
522 KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN); 522 KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN);
523 sc->kue_mcfilters = NULL; 523 sc->kue_mcfilters = NULL;
524 } 524 }
525 525
526 return usbnet_detach(self, flags); 526 return usbnet_detach(self, flags);
527} 527}
528 528
529/* 529/*
530 * A frame has been uploaded: pass the resulting mbuf chain up to 530 * A frame has been uploaded: pass the resulting mbuf chain up to
531 * the higher level protocols. 531 * the higher level protocols.
532 */ 532 */
533static void 533static void
534kue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 534kue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
535{ 535{
536 struct ifnet *ifp = usbnet_ifp(un); 536 struct ifnet *ifp = usbnet_ifp(un);
537 uint8_t *buf = c->unc_buf; 537 uint8_t *buf = c->unc_buf;
538 unsigned pktlen; 538 unsigned pktlen;
539 539
540 if (total_len <= 1) 540 if (total_len <= 1)
541 return; 541 return;
542 542
543 DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", 543 DPRINTFN(10,("%s: %s: total_len=%d len=%d\n",
544 device_xname(un->un_dev), __func__, 544 device_xname(un->un_dev), __func__,
545 total_len, le16dec(buf))); 545 total_len, le16dec(buf)));
546 546
547 pktlen = le16dec(buf); 547 pktlen = le16dec(buf);
548 if (pktlen > total_len - ETHER_ALIGN) 548 if (pktlen > total_len - ETHER_ALIGN)
549 pktlen = total_len - ETHER_ALIGN; 549 pktlen = total_len - ETHER_ALIGN;
550 550
551 if (pktlen < ETHER_MIN_LEN - ETHER_CRC_LEN || 551 if (pktlen < ETHER_MIN_LEN - ETHER_CRC_LEN ||
552 pktlen > MCLBYTES - ETHER_ALIGN) { 552 pktlen > MCLBYTES - ETHER_ALIGN) {
553 if_statinc(ifp, if_ierrors); 553 if_statinc(ifp, if_ierrors);
554 return; 554 return;
555 } 555 }
556 556
557 DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(un->un_dev), 557 DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(un->un_dev),
558 __func__, pktlen)); 558 __func__, pktlen));
559 usbnet_enqueue(un, buf + 2, pktlen, 0, 0, 0); 559 usbnet_enqueue(un, buf + 2, pktlen, 0, 0, 0);
560} 560}
561 561
562static unsigned 562static unsigned
563kue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 563kue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
564{ 564{
565 unsigned total_len, pkt_len; 565 unsigned total_len, pkt_len;
566 566
567 pkt_len = m->m_pkthdr.len + 2; 567 pkt_len = m->m_pkthdr.len + 2;
568 total_len = roundup2(pkt_len, 64); 568 total_len = roundup2(pkt_len, 64);
569 569
570 if ((unsigned)total_len > un->un_tx_bufsz) { 570 if ((unsigned)total_len > un->un_tx_bufsz) {
571 DPRINTFN(10,("%s: %s: too big pktlen %u total %u\n", 571 DPRINTFN(10,("%s: %s: too big pktlen %u total %u\n",
572 device_xname(un->un_dev), __func__, pkt_len, total_len)); 572 device_xname(un->un_dev), __func__, pkt_len, total_len));
573 return 0; 573 return 0;
574 } 574 }
575 575
576 /* Frame length is specified in the first 2 bytes of the buffer. */ 576 /* Frame length is specified in the first 2 bytes of the buffer. */
577 le16enc(c->unc_buf, (uint16_t)m->m_pkthdr.len); 577 le16enc(c->unc_buf, (uint16_t)m->m_pkthdr.len);
578 578
579 /* 579 /*
580 * Copy the mbuf data into a contiguous buffer after the frame length, 580 * Copy the mbuf data into a contiguous buffer after the frame length,
581 * possibly zeroing the rest of the buffer. 581 * possibly zeroing the rest of the buffer.
582 */ 582 */
583 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + 2); 583 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + 2);
584 if (total_len - pkt_len > 0) 584 if (total_len - pkt_len > 0)
585 memset(c->unc_buf + pkt_len, 0, total_len - pkt_len); 585 memset(c->unc_buf + pkt_len, 0, total_len - pkt_len);
586 586
587 DPRINTFN(10,("%s: %s: enter pktlen %u total %u\n", 587 DPRINTFN(10,("%s: %s: enter pktlen %u total %u\n",
588 device_xname(un->un_dev), __func__, pkt_len, total_len)); 588 device_xname(un->un_dev), __func__, pkt_len, total_len));
589 589
590 return total_len; 590 return total_len;
591} 591}
592 592
593static int 593static int
594kue_init_locked(struct ifnet *ifp) 594kue_init_locked(struct ifnet *ifp)
595{ 595{
596 struct usbnet * const un = ifp->if_softc; 596 struct usbnet * const un = ifp->if_softc;
597 struct kue_softc *sc = usbnet_softc(un); 597 struct kue_softc *sc = usbnet_softc(un);
598 uint8_t eaddr[ETHER_ADDR_LEN]; 598 uint8_t eaddr[ETHER_ADDR_LEN];
599 599
600 DPRINTFN(5,("%s: %s: enter\n", device_xname(un->un_dev),__func__)); 600 DPRINTFN(5,("%s: %s: enter\n", device_xname(un->un_dev),__func__));
601 601
602 if (usbnet_isdying(un)) 602 if (usbnet_isdying(un))
603 return EIO; 603 return EIO;
604 604
605 /* Cancel pending I/O */ 605 /* Cancel pending I/O */
606 usbnet_stop(un, ifp, 1); 606 usbnet_stop(un, ifp, 1);
607 607
608 memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr)); 608 memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr));
609 /* Set MAC address */ 609 /* Set MAC address */
610 kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SET_MAC, 0, eaddr, ETHER_ADDR_LEN); 610 kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SET_MAC, 0, eaddr, ETHER_ADDR_LEN);
611 611
612 sc->kue_rxfilt = KUE_RXFILT_UNICAST | KUE_RXFILT_BROADCAST; 612 sc->kue_rxfilt = KUE_RXFILT_UNICAST | KUE_RXFILT_BROADCAST;
613 613
614 /* I'm not sure how to tune these. */ 614 /* I'm not sure how to tune these. */
615#if 0 615#if 0
616 /* 616 /*
617 * Leave this one alone for now; setting it 617 * Leave this one alone for now; setting it
618 * wrong causes lockups on some machines/controllers. 618 * wrong causes lockups on some machines/controllers.
619 */ 619 */
620 kue_setword(un, KUE_CMD_SET_SOFS, 1); 620 kue_setword(un, KUE_CMD_SET_SOFS, 1);
621#endif 621#endif
622 kue_setword(un, KUE_CMD_SET_URB_SIZE, 64); 622 kue_setword(un, KUE_CMD_SET_URB_SIZE, 64);
623 623
624 /* Load the multicast filter. */ 624 /* Load the multicast filter. */
625 kue_setiff_locked(un); 625 kue_setiff_locked(un);
626 626
627 return usbnet_init_rx_tx(un); 627 return usbnet_init_rx_tx(un);
628} 628}
629 629
630static int 630static int
631kue_uno_init(struct ifnet *ifp) 631kue_uno_init(struct ifnet *ifp)
632{ 632{
633 int rv; 633 int rv;
634 634
635 rv = kue_init_locked(ifp); 635 rv = kue_init_locked(ifp);
636 636
637 return rv; 637 return rv;
638} 638}
639 639
640static void 640static void
641kue_uno_mcast(struct ifnet *ifp) 641kue_uno_mcast(struct ifnet *ifp)
642{ 642{
643 struct usbnet * const un = ifp->if_softc; 643 struct usbnet * const un = ifp->if_softc;
644 644
645 usbnet_lock_core(un); 645 usbnet_lock_core(un);
646 usbnet_busy(un); 
647 646
648 kue_setiff_locked(un); 647 kue_setiff_locked(un);
649 648
650 usbnet_unbusy(un); 
651 usbnet_unlock_core(un); 649 usbnet_unlock_core(un);
652} 650}
653 651
654#ifdef _MODULE 652#ifdef _MODULE
655#include "ioconf.c" 653#include "ioconf.c"
656#endif 654#endif
657 655
658USBNET_MODULE(kue) 656USBNET_MODULE(kue)

cvs diff -r1.11 -r1.12 src/sys/dev/usb/if_mos.c (switch to unified diff)

--- src/sys/dev/usb/if_mos.c 2022/03/03 05:51:17 1.11
+++ src/sys/dev/usb/if_mos.c 2022/03/03 05:51:27 1.12
@@ -1,790 +1,788 @@ @@ -1,790 +1,788 @@
1/* $NetBSD: if_mos.c,v 1.11 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_mos.c,v 1.12 2022/03/03 05:51:27 riastradh Exp $ */
2/* $OpenBSD: if_mos.c,v 1.40 2019/07/07 06:40:10 kevlo Exp $ */ 2/* $OpenBSD: if_mos.c,v 1.40 2019/07/07 06:40:10 kevlo Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2008 Johann Christian Rode <jcrode@gmx.net> 5 * Copyright (c) 2008 Johann Christian Rode <jcrode@gmx.net>
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/* 20/*
21 * Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg@openbsd.org> 21 * Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg@openbsd.org>
22 * 22 *
23 * Permission to use, copy, modify, and distribute this software for any 23 * Permission to use, copy, modify, and distribute this software for any
24 * purpose with or without fee is hereby granted, provided that the above 24 * purpose with or without fee is hereby granted, provided that the above
25 * copyright notice and this permission notice appear in all copies. 25 * copyright notice and this permission notice appear in all copies.
26 * 26 *
27 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 27 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
28 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 28 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
29 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 29 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
30 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 30 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
31 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 31 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
32 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 32 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
33 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 33 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
34 */ 34 */
35 35
36/* 36/*
37 * Copyright (c) 1997, 1998, 1999, 2000-2003 37 * Copyright (c) 1997, 1998, 1999, 2000-2003
38 * Bill Paul <wpaul@windriver.com>. All rights reserved. 38 * Bill Paul <wpaul@windriver.com>. All rights reserved.
39 * 39 *
40 * Redistribution and use in source and binary forms, with or without 40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions 41 * modification, are permitted provided that the following conditions
42 * are met: 42 * are met:
43 * 1. Redistributions of source code must retain the above copyright 43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer. 44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright 45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the 46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution. 47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software 48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement: 49 * must display the following acknowledgement:
50 * This product includes software developed by Bill Paul. 50 * This product includes software developed by Bill Paul.
51 * 4. Neither the name of the author nor the names of any co-contributors 51 * 4. Neither the name of the author nor the names of any co-contributors
52 * may be used to endorse or promote products derived from this software 52 * may be used to endorse or promote products derived from this software
53 * without specific prior written permission. 53 * without specific prior written permission.
54 * 54 *
55 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 55 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 58 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
59 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 59 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
60 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 60 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
61 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 61 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
62 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 62 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
63 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 63 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
64 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 64 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
65 * THE POSSIBILITY OF SUCH DAMAGE. 65 * THE POSSIBILITY OF SUCH DAMAGE.
66 */ 66 */
67 67
68/* 68/*
69 * Moschip MCS7730/MCS7830/MCS7832 USB to Ethernet controller  69 * Moschip MCS7730/MCS7830/MCS7832 USB to Ethernet controller
70 * The datasheet is available at the following URL:  70 * The datasheet is available at the following URL:
71 * http://www.moschip.com/data/products/MCS7830/Data%20Sheet_7830.pdf 71 * http://www.moschip.com/data/products/MCS7830/Data%20Sheet_7830.pdf
72 */ 72 */
73 73
74#include <sys/cdefs.h> 74#include <sys/cdefs.h>
75__KERNEL_RCSID(0, "$NetBSD: if_mos.c,v 1.11 2022/03/03 05:51:17 riastradh Exp $"); 75__KERNEL_RCSID(0, "$NetBSD: if_mos.c,v 1.12 2022/03/03 05:51:27 riastradh Exp $");
76 76
77#include <sys/param.h> 77#include <sys/param.h>
78 78
79#include <dev/usb/usbnet.h> 79#include <dev/usb/usbnet.h>
80#include <dev/usb/if_mosreg.h> 80#include <dev/usb/if_mosreg.h>
81 81
82#define MOS_PAUSE_REWRITES 3 82#define MOS_PAUSE_REWRITES 3
83 83
84#define MOS_TIMEOUT 1000 84#define MOS_TIMEOUT 1000
85 85
86#define MOS_RX_LIST_CNT 1 86#define MOS_RX_LIST_CNT 1
87#define MOS_TX_LIST_CNT 1 87#define MOS_TX_LIST_CNT 1
88 88
89/* Maximum size of a fast ethernet frame plus one byte for the status */ 89/* Maximum size of a fast ethernet frame plus one byte for the status */
90#define MOS_BUFSZ (ETHER_MAX_LEN+1) 90#define MOS_BUFSZ (ETHER_MAX_LEN+1)
91 91
92/* 92/*
93 * USB endpoints. 93 * USB endpoints.
94 */ 94 */
95#define MOS_ENDPT_RX 0 95#define MOS_ENDPT_RX 0
96#define MOS_ENDPT_TX 1 96#define MOS_ENDPT_TX 1
97#define MOS_ENDPT_INTR 2 97#define MOS_ENDPT_INTR 2
98#define MOS_ENDPT_MAX 3 98#define MOS_ENDPT_MAX 3
99 99
100/* 100/*
101 * USB vendor requests. 101 * USB vendor requests.
102 */ 102 */
103#define MOS_UR_READREG 0x0e 103#define MOS_UR_READREG 0x0e
104#define MOS_UR_WRITEREG 0x0d 104#define MOS_UR_WRITEREG 0x0d
105 105
106#define MOS_CONFIG_NO 1 106#define MOS_CONFIG_NO 1
107#define MOS_IFACE_IDX 0 107#define MOS_IFACE_IDX 0
108 108
109struct mos_type { 109struct mos_type {
110 struct usb_devno mos_dev; 110 struct usb_devno mos_dev;
111 u_int16_t mos_flags; 111 u_int16_t mos_flags;
112#define MCS7730 0x0001 /* MCS7730 */ 112#define MCS7730 0x0001 /* MCS7730 */
113#define MCS7830 0x0002 /* MCS7830 */ 113#define MCS7830 0x0002 /* MCS7830 */
114#define MCS7832 0x0004 /* MCS7832 */ 114#define MCS7832 0x0004 /* MCS7832 */
115}; 115};
116 116
117#define MOS_INC(x, y) (x) = (x + 1) % y 117#define MOS_INC(x, y) (x) = (x + 1) % y
118 118
119#ifdef MOS_DEBUG 119#ifdef MOS_DEBUG
120#define DPRINTF(x) do { if (mosdebug) printf x; } while (0) 120#define DPRINTF(x) do { if (mosdebug) printf x; } while (0)
121#define DPRINTFN(n,x) do { if (mosdebug >= (n)) printf x; } while (0) 121#define DPRINTFN(n,x) do { if (mosdebug >= (n)) printf x; } while (0)
122int mosdebug = 0; 122int mosdebug = 0;
123#else 123#else
124#define DPRINTF(x) __nothing 124#define DPRINTF(x) __nothing
125#define DPRINTFN(n,x) __nothing 125#define DPRINTFN(n,x) __nothing
126#endif 126#endif
127 127
128/* 128/*
129 * Various supported device vendors/products. 129 * Various supported device vendors/products.
130 */ 130 */
131static const struct mos_type mos_devs[] = { 131static const struct mos_type mos_devs[] = {
132 { { USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7730 }, MCS7730 }, 132 { { USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7730 }, MCS7730 },
133 { { USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7830 }, MCS7830 }, 133 { { USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7830 }, MCS7830 },
134 { { USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7832 }, MCS7832 }, 134 { { USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7832 }, MCS7832 },
135 { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN030 }, MCS7830 }, 135 { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN030 }, MCS7830 },
136}; 136};
137#define mos_lookup(v, p) ((const struct mos_type *)usb_lookup(mos_devs, v, p)) 137#define mos_lookup(v, p) ((const struct mos_type *)usb_lookup(mos_devs, v, p))
138 138
139static int mos_match(device_t, cfdata_t, void *); 139static int mos_match(device_t, cfdata_t, void *);
140static void mos_attach(device_t, device_t, void *); 140static void mos_attach(device_t, device_t, void *);
141 141
142CFATTACH_DECL_NEW(mos, sizeof(struct usbnet), 142CFATTACH_DECL_NEW(mos, sizeof(struct usbnet),
143 mos_match, mos_attach, usbnet_detach, usbnet_activate); 143 mos_match, mos_attach, usbnet_detach, usbnet_activate);
144 144
145static void mos_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 145static void mos_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
146static unsigned mos_uno_tx_prepare(struct usbnet *, struct mbuf *, 146static unsigned mos_uno_tx_prepare(struct usbnet *, struct mbuf *,
147 struct usbnet_chain *); 147 struct usbnet_chain *);
148static void mos_uno_mcast(struct ifnet *); 148static void mos_uno_mcast(struct ifnet *);
149static int mos_uno_init(struct ifnet *); 149static int mos_uno_init(struct ifnet *);
150static void mos_chip_init(struct usbnet *); 150static void mos_chip_init(struct usbnet *);
151static void mos_uno_stop(struct ifnet *ifp, int disable); 151static void mos_uno_stop(struct ifnet *ifp, int disable);
152static int mos_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 152static int mos_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
153static int mos_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 153static int mos_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
154static void mos_uno_mii_statchg(struct ifnet *); 154static void mos_uno_mii_statchg(struct ifnet *);
155static void mos_reset(struct usbnet *); 155static void mos_reset(struct usbnet *);
156 156
157static int mos_reg_read_1(struct usbnet *, int); 157static int mos_reg_read_1(struct usbnet *, int);
158static int mos_reg_read_2(struct usbnet *, int); 158static int mos_reg_read_2(struct usbnet *, int);
159static int mos_reg_write_1(struct usbnet *, int, int); 159static int mos_reg_write_1(struct usbnet *, int, int);
160static int mos_reg_write_2(struct usbnet *, int, int); 160static int mos_reg_write_2(struct usbnet *, int, int);
161static int mos_readmac(struct usbnet *); 161static int mos_readmac(struct usbnet *);
162static int mos_writemac(struct usbnet *); 162static int mos_writemac(struct usbnet *);
163static int mos_write_mcast(struct usbnet *, uint8_t *); 163static int mos_write_mcast(struct usbnet *, uint8_t *);
164 164
165static const struct usbnet_ops mos_ops = { 165static const struct usbnet_ops mos_ops = {
166 .uno_stop = mos_uno_stop, 166 .uno_stop = mos_uno_stop,
167 .uno_mcast = mos_uno_mcast, 167 .uno_mcast = mos_uno_mcast,
168 .uno_read_reg = mos_uno_mii_read_reg, 168 .uno_read_reg = mos_uno_mii_read_reg,
169 .uno_write_reg = mos_uno_mii_write_reg, 169 .uno_write_reg = mos_uno_mii_write_reg,
170 .uno_statchg = mos_uno_mii_statchg, 170 .uno_statchg = mos_uno_mii_statchg,
171 .uno_tx_prepare = mos_uno_tx_prepare, 171 .uno_tx_prepare = mos_uno_tx_prepare,
172 .uno_rx_loop = mos_uno_rx_loop, 172 .uno_rx_loop = mos_uno_rx_loop,
173 .uno_init = mos_uno_init, 173 .uno_init = mos_uno_init,
174}; 174};
175 175
176static int 176static int
177mos_reg_read_1(struct usbnet *un, int reg) 177mos_reg_read_1(struct usbnet *un, int reg)
178{ 178{
179 usb_device_request_t req; 179 usb_device_request_t req;
180 usbd_status err; 180 usbd_status err;
181 uByte val = 0; 181 uByte val = 0;
182 182
183 if (usbnet_isdying(un)) 183 if (usbnet_isdying(un))
184 return 0; 184 return 0;
185 185
186 req.bmRequestType = UT_READ_VENDOR_DEVICE; 186 req.bmRequestType = UT_READ_VENDOR_DEVICE;
187 req.bRequest = MOS_UR_READREG; 187 req.bRequest = MOS_UR_READREG;
188 USETW(req.wValue, 0); 188 USETW(req.wValue, 0);
189 USETW(req.wIndex, reg); 189 USETW(req.wIndex, reg);
190 USETW(req.wLength, 1); 190 USETW(req.wLength, 1);
191 191
192 err = usbd_do_request(un->un_udev, &req, &val); 192 err = usbd_do_request(un->un_udev, &req, &val);
193 193
194 if (err) { 194 if (err) {
195 aprint_error_dev(un->un_dev, "read reg %x\n", reg); 195 aprint_error_dev(un->un_dev, "read reg %x\n", reg);
196 return 0; 196 return 0;
197 } 197 }
198 198
199 return val; 199 return val;
200} 200}
201 201
202static int 202static int
203mos_reg_read_2(struct usbnet *un, int reg) 203mos_reg_read_2(struct usbnet *un, int reg)
204{ 204{
205 usb_device_request_t req; 205 usb_device_request_t req;
206 usbd_status err; 206 usbd_status err;
207 uWord val; 207 uWord val;
208 208
209 if (usbnet_isdying(un)) 209 if (usbnet_isdying(un))
210 return 0; 210 return 0;
211 211
212 USETW(val,0); 212 USETW(val,0);
213 213
214 req.bmRequestType = UT_READ_VENDOR_DEVICE; 214 req.bmRequestType = UT_READ_VENDOR_DEVICE;
215 req.bRequest = MOS_UR_READREG; 215 req.bRequest = MOS_UR_READREG;
216 USETW(req.wValue, 0); 216 USETW(req.wValue, 0);
217 USETW(req.wIndex, reg); 217 USETW(req.wIndex, reg);
218 USETW(req.wLength, 2); 218 USETW(req.wLength, 2);
219 219
220 err = usbd_do_request(un->un_udev, &req, &val); 220 err = usbd_do_request(un->un_udev, &req, &val);
221 221
222 if (err) { 222 if (err) {
223 aprint_error_dev(un->un_dev, "read reg2 %x\n", reg); 223 aprint_error_dev(un->un_dev, "read reg2 %x\n", reg);
224 return 0; 224 return 0;
225 } 225 }
226 226
227 return UGETW(val); 227 return UGETW(val);
228} 228}
229 229
230static int 230static int
231mos_reg_write_1(struct usbnet *un, int reg, int aval) 231mos_reg_write_1(struct usbnet *un, int reg, int aval)
232{ 232{
233 usb_device_request_t req; 233 usb_device_request_t req;
234 usbd_status err; 234 usbd_status err;
235 uByte val; 235 uByte val;
236 236
237 if (usbnet_isdying(un)) 237 if (usbnet_isdying(un))
238 return 0; 238 return 0;
239 239
240 val = aval; 240 val = aval;
241 241
242 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 242 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
243 req.bRequest = MOS_UR_WRITEREG; 243 req.bRequest = MOS_UR_WRITEREG;
244 USETW(req.wValue, 0); 244 USETW(req.wValue, 0);
245 USETW(req.wIndex, reg); 245 USETW(req.wIndex, reg);
246 USETW(req.wLength, 1); 246 USETW(req.wLength, 1);
247 247
248 err = usbd_do_request(un->un_udev, &req, &val); 248 err = usbd_do_request(un->un_udev, &req, &val);
249 249
250 if (err) 250 if (err)
251 aprint_error_dev(un->un_dev, "write reg %x <- %x\n",  251 aprint_error_dev(un->un_dev, "write reg %x <- %x\n",
252 reg, aval); 252 reg, aval);
253 253
254 return 0; 254 return 0;
255} 255}
256 256
257static int 257static int
258mos_reg_write_2(struct usbnet *un, int reg, int aval) 258mos_reg_write_2(struct usbnet *un, int reg, int aval)
259{ 259{
260 usb_device_request_t req; 260 usb_device_request_t req;
261 usbd_status err; 261 usbd_status err;
262 uWord val; 262 uWord val;
263 263
264 USETW(val, aval); 264 USETW(val, aval);
265 265
266 if (usbnet_isdying(un)) 266 if (usbnet_isdying(un))
267 return EIO; 267 return EIO;
268 268
269 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 269 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
270 req.bRequest = MOS_UR_WRITEREG; 270 req.bRequest = MOS_UR_WRITEREG;
271 USETW(req.wValue, 0); 271 USETW(req.wValue, 0);
272 USETW(req.wIndex, reg); 272 USETW(req.wIndex, reg);
273 USETW(req.wLength, 2); 273 USETW(req.wLength, 2);
274 274
275 err = usbd_do_request(un->un_udev, &req, &val); 275 err = usbd_do_request(un->un_udev, &req, &val);
276 276
277 if (err) 277 if (err)
278 aprint_error_dev(un->un_dev, "write reg2 %x <- %x\n",  278 aprint_error_dev(un->un_dev, "write reg2 %x <- %x\n",
279 reg, aval); 279 reg, aval);
280 280
281 return 0; 281 return 0;
282} 282}
283 283
284static int 284static int
285mos_readmac(struct usbnet *un) 285mos_readmac(struct usbnet *un)
286{ 286{
287 usb_device_request_t req; 287 usb_device_request_t req;
288 usbd_status err; 288 usbd_status err;
289 289
290 if (usbnet_isdying(un)) 290 if (usbnet_isdying(un))
291 return 0; 291 return 0;
292 292
293 req.bmRequestType = UT_READ_VENDOR_DEVICE; 293 req.bmRequestType = UT_READ_VENDOR_DEVICE;
294 req.bRequest = MOS_UR_READREG; 294 req.bRequest = MOS_UR_READREG;
295 USETW(req.wValue, 0); 295 USETW(req.wValue, 0);
296 USETW(req.wIndex, MOS_MAC); 296 USETW(req.wIndex, MOS_MAC);
297 USETW(req.wLength, ETHER_ADDR_LEN); 297 USETW(req.wLength, ETHER_ADDR_LEN);
298 298
299 err = usbd_do_request(un->un_udev, &req, un->un_eaddr); 299 err = usbd_do_request(un->un_udev, &req, un->un_eaddr);
300 300
301 if (err) 301 if (err)
302 aprint_error_dev(un->un_dev, "%s: failed", __func__); 302 aprint_error_dev(un->un_dev, "%s: failed", __func__);
303 303
304 return err; 304 return err;
305} 305}
306 306
307static int 307static int
308mos_writemac(struct usbnet *un) 308mos_writemac(struct usbnet *un)
309{ 309{
310 usb_device_request_t req; 310 usb_device_request_t req;
311 usbd_status err; 311 usbd_status err;
312 312
313 if (usbnet_isdying(un)) 313 if (usbnet_isdying(un))
314 return 0; 314 return 0;
315 315
316 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 316 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
317 req.bRequest = MOS_UR_WRITEREG; 317 req.bRequest = MOS_UR_WRITEREG;
318 USETW(req.wValue, 0); 318 USETW(req.wValue, 0);
319 USETW(req.wIndex, MOS_MAC); 319 USETW(req.wIndex, MOS_MAC);
320 USETW(req.wLength, ETHER_ADDR_LEN); 320 USETW(req.wLength, ETHER_ADDR_LEN);
321 321
322 err = usbd_do_request(un->un_udev, &req, un->un_eaddr); 322 err = usbd_do_request(un->un_udev, &req, un->un_eaddr);
323 323
324 if (err) 324 if (err)
325 aprint_error_dev(un->un_dev, "%s: failed", __func__); 325 aprint_error_dev(un->un_dev, "%s: failed", __func__);
326 326
327 return 0; 327 return 0;
328} 328}
329 329
330static int 330static int
331mos_write_mcast(struct usbnet *un, uint8_t *hashtbl) 331mos_write_mcast(struct usbnet *un, uint8_t *hashtbl)
332{ 332{
333 usb_device_request_t req; 333 usb_device_request_t req;
334 usbd_status err; 334 usbd_status err;
335 335
336 if (usbnet_isdying(un)) 336 if (usbnet_isdying(un))
337 return EIO; 337 return EIO;
338 338
339 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 339 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
340 req.bRequest = MOS_UR_WRITEREG; 340 req.bRequest = MOS_UR_WRITEREG;
341 USETW(req.wValue, 0); 341 USETW(req.wValue, 0);
342 USETW(req.wIndex, MOS_MCAST_TABLE); 342 USETW(req.wIndex, MOS_MCAST_TABLE);
343 USETW(req.wLength, 8); 343 USETW(req.wLength, 8);
344 344
345 err = usbd_do_request(un->un_udev, &req, hashtbl); 345 err = usbd_do_request(un->un_udev, &req, hashtbl);
346 346
347 if (err) { 347 if (err) {
348 aprint_error_dev(un->un_dev, "%s: failed", __func__); 348 aprint_error_dev(un->un_dev, "%s: failed", __func__);
349 return(-1); 349 return(-1);
350 } 350 }
351 351
352 return 0; 352 return 0;
353} 353}
354 354
355static int 355static int
356mos_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 356mos_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
357{ 357{
358 int i, res; 358 int i, res;
359 359
360 mos_reg_write_2(un, MOS_PHY_DATA, 0); 360 mos_reg_write_2(un, MOS_PHY_DATA, 0);
361 mos_reg_write_1(un, MOS_PHY_CTL, (phy & MOS_PHYCTL_PHYADDR) | 361 mos_reg_write_1(un, MOS_PHY_CTL, (phy & MOS_PHYCTL_PHYADDR) |
362 MOS_PHYCTL_READ); 362 MOS_PHYCTL_READ);
363 mos_reg_write_1(un, MOS_PHY_STS, (reg & MOS_PHYSTS_PHYREG) | 363 mos_reg_write_1(un, MOS_PHY_STS, (reg & MOS_PHYSTS_PHYREG) |
364 MOS_PHYSTS_PENDING); 364 MOS_PHYSTS_PENDING);
365 365
366 for (i = 0; i < MOS_TIMEOUT; i++) { 366 for (i = 0; i < MOS_TIMEOUT; i++) {
367 if (usbnet_isdying(un)) 367 if (usbnet_isdying(un))
368 return ENXIO; 368 return ENXIO;
369 if (mos_reg_read_1(un, MOS_PHY_STS) & MOS_PHYSTS_READY) 369 if (mos_reg_read_1(un, MOS_PHY_STS) & MOS_PHYSTS_READY)
370 break; 370 break;
371 } 371 }
372 if (i == MOS_TIMEOUT) { 372 if (i == MOS_TIMEOUT) {
373 aprint_error_dev(un->un_dev, "read PHY failed\n"); 373 aprint_error_dev(un->un_dev, "read PHY failed\n");
374 return EIO; 374 return EIO;
375 } 375 }
376 376
377 res = mos_reg_read_2(un, MOS_PHY_DATA); 377 res = mos_reg_read_2(un, MOS_PHY_DATA);
378 *val = res; 378 *val = res;
379 379
380 DPRINTFN(10,("%s: %s: phy %d reg %d val %u\n", 380 DPRINTFN(10,("%s: %s: phy %d reg %d val %u\n",
381 device_xname(un->un_dev), __func__, phy, reg, res)); 381 device_xname(un->un_dev), __func__, phy, reg, res));
382 382
383 return 0; 383 return 0;
384} 384}
385 385
386static int 386static int
387mos_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 387mos_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
388{ 388{
389 int i; 389 int i;
390 390
391 DPRINTFN(10,("%s: %s: phy %d reg %d val %u\n", 391 DPRINTFN(10,("%s: %s: phy %d reg %d val %u\n",
392 device_xname(un->un_dev), __func__, phy, reg, val)); 392 device_xname(un->un_dev), __func__, phy, reg, val));
393 393
394 mos_reg_write_2(un, MOS_PHY_DATA, val); 394 mos_reg_write_2(un, MOS_PHY_DATA, val);
395 mos_reg_write_1(un, MOS_PHY_CTL, (phy & MOS_PHYCTL_PHYADDR) | 395 mos_reg_write_1(un, MOS_PHY_CTL, (phy & MOS_PHYCTL_PHYADDR) |
396 MOS_PHYCTL_WRITE); 396 MOS_PHYCTL_WRITE);
397 mos_reg_write_1(un, MOS_PHY_STS, (reg & MOS_PHYSTS_PHYREG) | 397 mos_reg_write_1(un, MOS_PHY_STS, (reg & MOS_PHYSTS_PHYREG) |
398 MOS_PHYSTS_PENDING); 398 MOS_PHYSTS_PENDING);
399 399
400 for (i = 0; i < MOS_TIMEOUT; i++) { 400 for (i = 0; i < MOS_TIMEOUT; i++) {
401 if (usbnet_isdying(un)) 401 if (usbnet_isdying(un))
402 return ENXIO; 402 return ENXIO;
403 if (mos_reg_read_1(un, MOS_PHY_STS) & MOS_PHYSTS_READY) 403 if (mos_reg_read_1(un, MOS_PHY_STS) & MOS_PHYSTS_READY)
404 break; 404 break;
405 } 405 }
406 if (i == MOS_TIMEOUT) { 406 if (i == MOS_TIMEOUT) {
407 aprint_error_dev(un->un_dev, "write PHY failed\n"); 407 aprint_error_dev(un->un_dev, "write PHY failed\n");
408 return EIO; 408 return EIO;
409 } 409 }
410 410
411 return 0; 411 return 0;
412} 412}
413 413
414void 414void
415mos_uno_mii_statchg(struct ifnet *ifp) 415mos_uno_mii_statchg(struct ifnet *ifp)
416{ 416{
417 struct usbnet * const un = ifp->if_softc; 417 struct usbnet * const un = ifp->if_softc;
418 struct mii_data * const mii = usbnet_mii(un); 418 struct mii_data * const mii = usbnet_mii(un);
419 int val, err; 419 int val, err;
420 420
421 if (usbnet_isdying(un)) 421 if (usbnet_isdying(un))
422 return; 422 return;
423 423
424 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 424 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev), __func__));
425 425
426 /* disable RX, TX prior to changing FDX, SPEEDSEL */ 426 /* disable RX, TX prior to changing FDX, SPEEDSEL */
427 val = mos_reg_read_1(un, MOS_CTL); 427 val = mos_reg_read_1(un, MOS_CTL);
428 val &= ~(MOS_CTL_TX_ENB | MOS_CTL_RX_ENB); 428 val &= ~(MOS_CTL_TX_ENB | MOS_CTL_RX_ENB);
429 mos_reg_write_1(un, MOS_CTL, val); 429 mos_reg_write_1(un, MOS_CTL, val);
430 430
431 /* reset register which counts dropped frames */ 431 /* reset register which counts dropped frames */
432 mos_reg_write_1(un, MOS_FRAME_DROP_CNT, 0); 432 mos_reg_write_1(un, MOS_FRAME_DROP_CNT, 0);
433 433
434 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) 434 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
435 val |= MOS_CTL_FDX_ENB; 435 val |= MOS_CTL_FDX_ENB;
436 else 436 else
437 val &= ~(MOS_CTL_FDX_ENB); 437 val &= ~(MOS_CTL_FDX_ENB);
438 438
439 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 439 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
440 (IFM_ACTIVE | IFM_AVALID)) { 440 (IFM_ACTIVE | IFM_AVALID)) {
441 switch (IFM_SUBTYPE(mii->mii_media_active)) { 441 switch (IFM_SUBTYPE(mii->mii_media_active)) {
442 case IFM_100_TX: 442 case IFM_100_TX:
443 val |= MOS_CTL_SPEEDSEL; 443 val |= MOS_CTL_SPEEDSEL;
444 break; 444 break;
445 case IFM_10_T: 445 case IFM_10_T:
446 val &= ~(MOS_CTL_SPEEDSEL); 446 val &= ~(MOS_CTL_SPEEDSEL);
447 break; 447 break;
448 } 448 }
449 usbnet_set_link(un, true); 449 usbnet_set_link(un, true);
450 } 450 }
451 451
452 /* re-enable TX, RX */ 452 /* re-enable TX, RX */
453 val |= (MOS_CTL_TX_ENB | MOS_CTL_RX_ENB); 453 val |= (MOS_CTL_TX_ENB | MOS_CTL_RX_ENB);
454 err = mos_reg_write_1(un, MOS_CTL, val); 454 err = mos_reg_write_1(un, MOS_CTL, val);
455 455
456 if (err) 456 if (err)
457 aprint_error_dev(un->un_dev, "media change failed\n"); 457 aprint_error_dev(un->un_dev, "media change failed\n");
458} 458}
459 459
460static void 460static void
461mos_rcvfilt_locked(struct usbnet *un) 461mos_rcvfilt_locked(struct usbnet *un)
462{ 462{
463 struct ifnet *ifp = usbnet_ifp(un); 463 struct ifnet *ifp = usbnet_ifp(un);
464 struct ethercom *ec = usbnet_ec(un); 464 struct ethercom *ec = usbnet_ec(un);
465 struct ether_multi *enm; 465 struct ether_multi *enm;
466 struct ether_multistep step; 466 struct ether_multistep step;
467 u_int32_t h = 0; 467 u_int32_t h = 0;
468 u_int8_t rxmode, mchash[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 468 u_int8_t rxmode, mchash[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
469 469
470 if (usbnet_isdying(un)) 470 if (usbnet_isdying(un))
471 return; 471 return;
472 472
473 rxmode = mos_reg_read_1(un, MOS_CTL); 473 rxmode = mos_reg_read_1(un, MOS_CTL);
474 rxmode &= ~(MOS_CTL_ALLMULTI | MOS_CTL_RX_PROMISC); 474 rxmode &= ~(MOS_CTL_ALLMULTI | MOS_CTL_RX_PROMISC);
475 475
476 ETHER_LOCK(ec); 476 ETHER_LOCK(ec);
477 if (ifp->if_flags & IFF_PROMISC) { 477 if (ifp->if_flags & IFF_PROMISC) {
478 ec->ec_flags |= ETHER_F_ALLMULTI; 478 ec->ec_flags |= ETHER_F_ALLMULTI;
479 ETHER_UNLOCK(ec); 479 ETHER_UNLOCK(ec);
480 /* run promisc. mode */ 480 /* run promisc. mode */
481 rxmode |= MOS_CTL_ALLMULTI; /* ??? */ 481 rxmode |= MOS_CTL_ALLMULTI; /* ??? */
482 rxmode |= MOS_CTL_RX_PROMISC; 482 rxmode |= MOS_CTL_RX_PROMISC;
483 goto update; 483 goto update;
484 } 484 }
485 ec->ec_flags &= ~ETHER_F_ALLMULTI; 485 ec->ec_flags &= ~ETHER_F_ALLMULTI;
486 ETHER_FIRST_MULTI(step, ec, enm); 486 ETHER_FIRST_MULTI(step, ec, enm);
487 while (enm != NULL) { 487 while (enm != NULL) {
488 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 488 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
489 ec->ec_flags |= ETHER_F_ALLMULTI; 489 ec->ec_flags |= ETHER_F_ALLMULTI;
490 ETHER_UNLOCK(ec); 490 ETHER_UNLOCK(ec);
491 memset(mchash, 0, sizeof(mchash)); /* correct ??? */ 491 memset(mchash, 0, sizeof(mchash)); /* correct ??? */
492 /* accept all multicast frame */ 492 /* accept all multicast frame */
493 rxmode |= MOS_CTL_ALLMULTI; 493 rxmode |= MOS_CTL_ALLMULTI;
494 goto update; 494 goto update;
495 } 495 }
496 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 496 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
497 /* 3(31:29) and 3(28:26) sampling to have uint8_t[8] */ 497 /* 3(31:29) and 3(28:26) sampling to have uint8_t[8] */
498 mchash[h >> 29] |= 1 << ((h >> 26) % 8); 498 mchash[h >> 29] |= 1 << ((h >> 26) % 8);
499 ETHER_NEXT_MULTI(step, enm); 499 ETHER_NEXT_MULTI(step, enm);
500 } 500 }
501 ETHER_UNLOCK(ec); 501 ETHER_UNLOCK(ec);
502 /* MOS receive filter is always on */ 502 /* MOS receive filter is always on */
503 update: 503 update:
504 /*  504 /*
505 * The datasheet claims broadcast frames were always accepted 505 * The datasheet claims broadcast frames were always accepted
506 * regardless of filter settings. But the hardware seems to 506 * regardless of filter settings. But the hardware seems to
507 * filter broadcast frames, so pass them explicitly. 507 * filter broadcast frames, so pass them explicitly.
508 */ 508 */
509 mchash[7] |= 0x80; 509 mchash[7] |= 0x80;
510 mos_write_mcast(un, mchash); 510 mos_write_mcast(un, mchash);
511 mos_reg_write_1(un, MOS_CTL, rxmode); 511 mos_reg_write_1(un, MOS_CTL, rxmode);
512} 512}
513 513
514static void 514static void
515mos_reset(struct usbnet *un) 515mos_reset(struct usbnet *un)
516{ 516{
517 u_int8_t ctl; 517 u_int8_t ctl;
518 518
519 if (usbnet_isdying(un)) 519 if (usbnet_isdying(un))
520 return; 520 return;
521 521
522 ctl = mos_reg_read_1(un, MOS_CTL); 522 ctl = mos_reg_read_1(un, MOS_CTL);
523 ctl &= ~(MOS_CTL_RX_PROMISC | MOS_CTL_ALLMULTI | MOS_CTL_TX_ENB | 523 ctl &= ~(MOS_CTL_RX_PROMISC | MOS_CTL_ALLMULTI | MOS_CTL_TX_ENB |
524 MOS_CTL_RX_ENB); 524 MOS_CTL_RX_ENB);
525 /* Disable RX, TX, promiscuous and allmulticast mode */ 525 /* Disable RX, TX, promiscuous and allmulticast mode */
526 mos_reg_write_1(un, MOS_CTL, ctl); 526 mos_reg_write_1(un, MOS_CTL, ctl);
527 527
528 /* Reset frame drop counter register to zero */ 528 /* Reset frame drop counter register to zero */
529 mos_reg_write_1(un, MOS_FRAME_DROP_CNT, 0); 529 mos_reg_write_1(un, MOS_FRAME_DROP_CNT, 0);
530 530
531 /* Wait a little while for the chip to get its brains in order. */ 531 /* Wait a little while for the chip to get its brains in order. */
532 DELAY(1000); 532 DELAY(1000);
533} 533}
534 534
535void 535void
536mos_chip_init(struct usbnet *un) 536mos_chip_init(struct usbnet *un)
537{ 537{
538 int i; 538 int i;
539 539
540 /* 540 /*
541 * Rev.C devices have a pause threshold register which needs to be set 541 * Rev.C devices have a pause threshold register which needs to be set
542 * at startup. 542 * at startup.
543 */ 543 */
544 if (mos_reg_read_1(un, MOS_PAUSE_TRHD) != -1) { 544 if (mos_reg_read_1(un, MOS_PAUSE_TRHD) != -1) {
545 for (i = 0; i < MOS_PAUSE_REWRITES; i++) 545 for (i = 0; i < MOS_PAUSE_REWRITES; i++)
546 mos_reg_write_1(un, MOS_PAUSE_TRHD, 0); 546 mos_reg_write_1(un, MOS_PAUSE_TRHD, 0);
547 } 547 }
548} 548}
549 549
550/* 550/*
551 * Probe for a MCS7x30 chip. 551 * Probe for a MCS7x30 chip.
552 */ 552 */
553static int 553static int
554mos_match(device_t parent, cfdata_t match, void *aux) 554mos_match(device_t parent, cfdata_t match, void *aux)
555{ 555{
556 struct usb_attach_arg *uaa = aux; 556 struct usb_attach_arg *uaa = aux;
557 557
558 return (mos_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 558 return (mos_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
559 UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 559 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
560} 560}
561 561
562/* 562/*
563 * Attach the interface. 563 * Attach the interface.
564 */ 564 */
565static void 565static void
566mos_attach(device_t parent, device_t self, void *aux) 566mos_attach(device_t parent, device_t self, void *aux)
567{ 567{
568 USBNET_MII_DECL_DEFAULT(unm); 568 USBNET_MII_DECL_DEFAULT(unm);
569 struct usbnet * un = device_private(self); 569 struct usbnet * un = device_private(self);
570 struct usb_attach_arg *uaa = aux; 570 struct usb_attach_arg *uaa = aux;
571 struct usbd_device *dev = uaa->uaa_device; 571 struct usbd_device *dev = uaa->uaa_device;
572 usbd_status err; 572 usbd_status err;
573 usb_interface_descriptor_t *id; 573 usb_interface_descriptor_t *id;
574 usb_endpoint_descriptor_t *ed; 574 usb_endpoint_descriptor_t *ed;
575 char *devinfop; 575 char *devinfop;
576 int i; 576 int i;
577 577
578 aprint_naive("\n"); 578 aprint_naive("\n");
579 aprint_normal("\n"); 579 aprint_normal("\n");
580 devinfop = usbd_devinfo_alloc(dev, 0); 580 devinfop = usbd_devinfo_alloc(dev, 0);
581 aprint_normal_dev(self, "%s\n", devinfop); 581 aprint_normal_dev(self, "%s\n", devinfop);
582 usbd_devinfo_free(devinfop); 582 usbd_devinfo_free(devinfop);
583 583
584 un->un_dev = self; 584 un->un_dev = self;
585 un->un_udev = dev; 585 un->un_udev = dev;
586 un->un_sc = un; 586 un->un_sc = un;
587 un->un_ops = &mos_ops; 587 un->un_ops = &mos_ops;
588 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 588 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
589 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 589 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
590 un->un_rx_list_cnt = MOS_RX_LIST_CNT; 590 un->un_rx_list_cnt = MOS_RX_LIST_CNT;
591 un->un_tx_list_cnt = MOS_TX_LIST_CNT; 591 un->un_tx_list_cnt = MOS_TX_LIST_CNT;
592 un->un_rx_bufsz = un->un_tx_bufsz = MOS_BUFSZ; 592 un->un_rx_bufsz = un->un_tx_bufsz = MOS_BUFSZ;
593 593
594 err = usbd_set_config_no(dev, MOS_CONFIG_NO, 1); 594 err = usbd_set_config_no(dev, MOS_CONFIG_NO, 1);
595 if (err) { 595 if (err) {
596 aprint_error_dev(self, "failed to set configuration" 596 aprint_error_dev(self, "failed to set configuration"
597 ", err=%s\n", usbd_errstr(err)); 597 ", err=%s\n", usbd_errstr(err));
598 return; 598 return;
599 } 599 }
600 600
601 err = usbd_device2interface_handle(dev, MOS_IFACE_IDX, &un->un_iface); 601 err = usbd_device2interface_handle(dev, MOS_IFACE_IDX, &un->un_iface);
602 if (err) { 602 if (err) {
603 aprint_error_dev(self, "failed getting interface handle" 603 aprint_error_dev(self, "failed getting interface handle"
604 ", err=%s\n", usbd_errstr(err)); 604 ", err=%s\n", usbd_errstr(err));
605 return; 605 return;
606 } 606 }
607 607
608 un->un_flags = mos_lookup(uaa->uaa_vendor, uaa->uaa_product)->mos_flags; 608 un->un_flags = mos_lookup(uaa->uaa_vendor, uaa->uaa_product)->mos_flags;
609 609
610 id = usbd_get_interface_descriptor(un->un_iface); 610 id = usbd_get_interface_descriptor(un->un_iface);
611 611
612 /* Find endpoints. */ 612 /* Find endpoints. */
613 for (i = 0; i < id->bNumEndpoints; i++) { 613 for (i = 0; i < id->bNumEndpoints; i++) {
614 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 614 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
615 if (!ed) { 615 if (!ed) {
616 aprint_error_dev(self, "couldn't get ep %d\n", i); 616 aprint_error_dev(self, "couldn't get ep %d\n", i);
617 return; 617 return;
618 } 618 }
619 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 619 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
620 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 620 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
621 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 621 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
622 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 622 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
623 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 623 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
624 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 624 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
625 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 625 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
626 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 626 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
627 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 627 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
628 } 628 }
629 } 629 }
630 630
631 if (un->un_flags & MCS7730) 631 if (un->un_flags & MCS7730)
632 aprint_normal_dev(self, "MCS7730\n"); 632 aprint_normal_dev(self, "MCS7730\n");
633 else if (un->un_flags & MCS7830) 633 else if (un->un_flags & MCS7830)
634 aprint_normal_dev(self, "MCS7830\n"); 634 aprint_normal_dev(self, "MCS7830\n");
635 else if (un->un_flags & MCS7832) 635 else if (un->un_flags & MCS7832)
636 aprint_normal_dev(self, "MCS7832\n"); 636 aprint_normal_dev(self, "MCS7832\n");
637 637
638 /* Set these up now for register access. */ 638 /* Set these up now for register access. */
639 usbnet_attach(un, "mosdet"); 639 usbnet_attach(un, "mosdet");
640 640
641 mos_chip_init(un); 641 mos_chip_init(un);
642 642
643 /* 643 /*
644 * Read MAC address, inform the world. 644 * Read MAC address, inform the world.
645 */ 645 */
646 err = mos_readmac(un); 646 err = mos_readmac(un);
647 if (err) { 647 if (err) {
648 aprint_error_dev(self, "couldn't read MAC address\n"); 648 aprint_error_dev(self, "couldn't read MAC address\n");
649 return; 649 return;
650 } 650 }
651 651
652 struct ifnet *ifp = usbnet_ifp(un); 652 struct ifnet *ifp = usbnet_ifp(un);
653 ifp->if_capabilities = ETHERCAP_VLAN_MTU; 653 ifp->if_capabilities = ETHERCAP_VLAN_MTU;
654 654
655 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 655 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
656 0, &unm); 656 0, &unm);
657} 657}
658 658
659/* 659/*
660 * A frame has been uploaded: pass the resulting mbuf chain up to 660 * A frame has been uploaded: pass the resulting mbuf chain up to
661 * the higher level protocols. 661 * the higher level protocols.
662 */ 662 */
663void 663void
664mos_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len) 664mos_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
665{ 665{
666 struct ifnet *ifp = usbnet_ifp(un); 666 struct ifnet *ifp = usbnet_ifp(un);
667 uint8_t *buf = c->unc_buf; 667 uint8_t *buf = c->unc_buf;
668 u_int8_t rxstat; 668 u_int8_t rxstat;
669 u_int16_t pktlen = 0; 669 u_int16_t pktlen = 0;
670 670
671 DPRINTFN(5,("%s: %s: enter len %u\n", 671 DPRINTFN(5,("%s: %s: enter len %u\n",
672 device_xname(un->un_dev), __func__, total_len)); 672 device_xname(un->un_dev), __func__, total_len));
673 673
674 if (total_len <= 1) 674 if (total_len <= 1)
675 return; 675 return;
676 676
677 /* evaluate status byte at the end */ 677 /* evaluate status byte at the end */
678 pktlen = total_len - 1; 678 pktlen = total_len - 1;
679 if (pktlen > un->un_rx_bufsz) { 679 if (pktlen > un->un_rx_bufsz) {
680 if_statinc(ifp, if_ierrors); 680 if_statinc(ifp, if_ierrors);
681 return; 681 return;
682 } 682 }
683 rxstat = buf[pktlen] & MOS_RXSTS_MASK; 683 rxstat = buf[pktlen] & MOS_RXSTS_MASK;
684 684
685 if (rxstat != MOS_RXSTS_VALID) { 685 if (rxstat != MOS_RXSTS_VALID) {
686 DPRINTF(("%s: erroneous frame received: ", 686 DPRINTF(("%s: erroneous frame received: ",
687 device_xname(un->un_dev))); 687 device_xname(un->un_dev)));
688 if (rxstat & MOS_RXSTS_SHORT_FRAME) 688 if (rxstat & MOS_RXSTS_SHORT_FRAME)
689 DPRINTF(("frame size less than 64 bytes\n")); 689 DPRINTF(("frame size less than 64 bytes\n"));
690 if (rxstat & MOS_RXSTS_LARGE_FRAME) 690 if (rxstat & MOS_RXSTS_LARGE_FRAME)
691 DPRINTF(("frame size larger than 1532 bytes\n")); 691 DPRINTF(("frame size larger than 1532 bytes\n"));
692 if (rxstat & MOS_RXSTS_CRC_ERROR) 692 if (rxstat & MOS_RXSTS_CRC_ERROR)
693 DPRINTF(("CRC error\n")); 693 DPRINTF(("CRC error\n"));
694 if (rxstat & MOS_RXSTS_ALIGN_ERROR) 694 if (rxstat & MOS_RXSTS_ALIGN_ERROR)
695 DPRINTF(("alignment error\n")); 695 DPRINTF(("alignment error\n"));
696 if_statinc(ifp, if_ierrors); 696 if_statinc(ifp, if_ierrors);
697 return; 697 return;
698 } 698 }
699 699
700 if (pktlen < sizeof(struct ether_header) ) { 700 if (pktlen < sizeof(struct ether_header) ) {
701 if_statinc(ifp, if_ierrors); 701 if_statinc(ifp, if_ierrors);
702 return; 702 return;
703 } 703 }
704 704
705 usbnet_enqueue(un, c->unc_buf, pktlen, 0, 0, 0); 705 usbnet_enqueue(un, c->unc_buf, pktlen, 0, 0, 0);
706} 706}
707 707
708static unsigned 708static unsigned
709mos_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 709mos_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
710{ 710{
711 int length; 711 int length;
712 712
713 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz) 713 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz)
714 return 0; 714 return 0;
715 715
716 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf); 716 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf);
717 length = m->m_pkthdr.len; 717 length = m->m_pkthdr.len;
718 718
719 DPRINTFN(5,("%s: %s: len %u\n", 719 DPRINTFN(5,("%s: %s: len %u\n",
720 device_xname(un->un_dev), __func__, length)); 720 device_xname(un->un_dev), __func__, length));
721 721
722 return length; 722 return length;
723} 723}
724 724
725static int 725static int
726mos_init_locked(struct ifnet *ifp) 726mos_init_locked(struct ifnet *ifp)
727{ 727{
728 struct usbnet * const un = ifp->if_softc; 728 struct usbnet * const un = ifp->if_softc;
729 u_int8_t rxmode; 729 u_int8_t rxmode;
730 unsigned char ipgs[2]; 730 unsigned char ipgs[2];
731 731
732 if (usbnet_isdying(un)) 732 if (usbnet_isdying(un))
733 return EIO; 733 return EIO;
734 734
735 /* Cancel pending I/O */ 735 /* Cancel pending I/O */
736 usbnet_stop(un, ifp, 1); 736 usbnet_stop(un, ifp, 1);
737 737
738 /* Reset the ethernet interface. */ 738 /* Reset the ethernet interface. */
739 mos_reset(un); 739 mos_reset(un);
740 740
741 /* Write MAC address. */ 741 /* Write MAC address. */
742 mos_writemac(un); 742 mos_writemac(un);
743 743
744 /* Read and set transmitter IPG values */ 744 /* Read and set transmitter IPG values */
745 ipgs[0] = mos_reg_read_1(un, MOS_IPG0); 745 ipgs[0] = mos_reg_read_1(un, MOS_IPG0);
746 ipgs[1] = mos_reg_read_1(un, MOS_IPG1); 746 ipgs[1] = mos_reg_read_1(un, MOS_IPG1);
747 mos_reg_write_1(un, MOS_IPG0, ipgs[0]); 747 mos_reg_write_1(un, MOS_IPG0, ipgs[0]);
748 mos_reg_write_1(un, MOS_IPG1, ipgs[1]); 748 mos_reg_write_1(un, MOS_IPG1, ipgs[1]);
749 749
750 /* Accept multicast frame or run promisc. mode */ 750 /* Accept multicast frame or run promisc. mode */
751 mos_rcvfilt_locked(un); 751 mos_rcvfilt_locked(un);
752 752
753 /* Enable receiver and transmitter, bridge controls speed/duplex mode */ 753 /* Enable receiver and transmitter, bridge controls speed/duplex mode */
754 rxmode = mos_reg_read_1(un, MOS_CTL); 754 rxmode = mos_reg_read_1(un, MOS_CTL);
755 rxmode |= MOS_CTL_RX_ENB | MOS_CTL_TX_ENB | MOS_CTL_BS_ENB; 755 rxmode |= MOS_CTL_RX_ENB | MOS_CTL_TX_ENB | MOS_CTL_BS_ENB;
756 rxmode &= ~(MOS_CTL_SLEEP); 756 rxmode &= ~(MOS_CTL_SLEEP);
757 mos_reg_write_1(un, MOS_CTL, rxmode); 757 mos_reg_write_1(un, MOS_CTL, rxmode);
758 758
759 return usbnet_init_rx_tx(un); 759 return usbnet_init_rx_tx(un);
760} 760}
761 761
762static int 762static int
763mos_uno_init(struct ifnet *ifp) 763mos_uno_init(struct ifnet *ifp)
764{ 764{
765 int ret = mos_init_locked(ifp); 765 int ret = mos_init_locked(ifp);
766 766
767 return ret; 767 return ret;
768} 768}
769 769
770static void 770static void
771mos_uno_mcast(struct ifnet *ifp) 771mos_uno_mcast(struct ifnet *ifp)
772{ 772{
773 struct usbnet * const un = ifp->if_softc; 773 struct usbnet * const un = ifp->if_softc;
774 774
775 usbnet_lock_core(un); 775 usbnet_lock_core(un);
776 usbnet_busy(un); 
777 776
778 mos_rcvfilt_locked(un); 777 mos_rcvfilt_locked(un);
779 778
780 usbnet_unbusy(un); 
781 usbnet_unlock_core(un); 779 usbnet_unlock_core(un);
782} 780}
783 781
784void 782void
785mos_uno_stop(struct ifnet *ifp, int disable) 783mos_uno_stop(struct ifnet *ifp, int disable)
786{ 784{
787 struct usbnet * const un = ifp->if_softc; 785 struct usbnet * const un = ifp->if_softc;
788 786
789 mos_reset(un); 787 mos_reset(un);
790} 788}

cvs diff -r1.67 -r1.68 src/sys/dev/usb/if_mue.c (switch to unified diff)

--- src/sys/dev/usb/if_mue.c 2022/03/03 05:51:17 1.67
+++ src/sys/dev/usb/if_mue.c 2022/03/03 05:51:27 1.68
@@ -1,1329 +1,1327 @@ @@ -1,1329 +1,1327 @@
1/* $NetBSD: if_mue.c,v 1.67 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_mue.c,v 1.68 2022/03/03 05:51:27 riastradh 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.67 2022/03/03 05:51:17 riastradh Exp $"); 23__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.68 2022/03/03 05:51:27 riastradh 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
37#define MUE_PRINTF(un, fmt, args...) \ 37#define MUE_PRINTF(un, fmt, args...) \
38 device_printf((un)->un_dev, "%s: " fmt, __func__, ##args); 38 device_printf((un)->un_dev, "%s: " fmt, __func__, ##args);
39 39
40#ifdef USB_DEBUG 40#ifdef USB_DEBUG
41int muedebug = 0; 41int muedebug = 0;
42#define DPRINTF(un, fmt, args...) \ 42#define DPRINTF(un, fmt, args...) \
43 do { \ 43 do { \
44 if (muedebug) \ 44 if (muedebug) \
45 MUE_PRINTF(un, fmt, ##args); \ 45 MUE_PRINTF(un, fmt, ##args); \
46 } while (0 /* CONSTCOND */) 46 } while (0 /* CONSTCOND */)
47#else 47#else
48#define DPRINTF(un, fmt, args...) __nothing 48#define DPRINTF(un, fmt, args...) __nothing
49#endif 49#endif
50 50
51/* 51/*
52 * Various supported device vendors/products. 52 * Various supported device vendors/products.
53 */ 53 */
54struct mue_type { 54struct mue_type {
55 struct usb_devno mue_dev; 55 struct usb_devno mue_dev;
56 uint16_t mue_flags; 56 uint16_t mue_flags;
57#define LAN7500 0x0001 /* LAN7500 */ 57#define LAN7500 0x0001 /* LAN7500 */
58#define LAN7800 0x0002 /* LAN7800 */ 58#define LAN7800 0x0002 /* LAN7800 */
59#define LAN7801 0x0004 /* LAN7801 */ 59#define LAN7801 0x0004 /* LAN7801 */
60#define LAN7850 0x0008 /* LAN7850 */ 60#define LAN7850 0x0008 /* LAN7850 */
61}; 61};
62 62
63static const struct mue_type mue_devs[] = { 63static const struct mue_type mue_devs[] = {
64 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7500 }, LAN7500 }, 64 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7500 }, LAN7500 },
65 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7505 }, LAN7500 }, 65 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7505 }, LAN7500 },
66 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7800 }, LAN7800 }, 66 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7800 }, LAN7800 },
67 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7801 }, LAN7801 }, 67 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7801 }, LAN7801 },
68 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7850 }, LAN7850 } 68 { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7850 }, LAN7850 }
69}; 69};
70 70
71#define MUE_LOOKUP(uaa) ((const struct mue_type *)usb_lookup(mue_devs, \ 71#define MUE_LOOKUP(uaa) ((const struct mue_type *)usb_lookup(mue_devs, \
72 uaa->uaa_vendor, uaa->uaa_product)) 72 uaa->uaa_vendor, uaa->uaa_product))
73 73
74#define MUE_ENADDR_LO(enaddr) \ 74#define MUE_ENADDR_LO(enaddr) \
75 ((enaddr[3] << 24) | (enaddr[2] << 16) | (enaddr[1] << 8) | enaddr[0]) 75 ((enaddr[3] << 24) | (enaddr[2] << 16) | (enaddr[1] << 8) | enaddr[0])
76#define MUE_ENADDR_HI(enaddr) \ 76#define MUE_ENADDR_HI(enaddr) \
77 ((enaddr[5] << 8) | enaddr[4]) 77 ((enaddr[5] << 8) | enaddr[4])
78 78
79static int mue_match(device_t, cfdata_t, void *); 79static int mue_match(device_t, cfdata_t, void *);
80static void mue_attach(device_t, device_t, void *); 80static void mue_attach(device_t, device_t, void *);
81 81
82static uint32_t mue_csr_read(struct usbnet *, uint32_t); 82static uint32_t mue_csr_read(struct usbnet *, uint32_t);
83static int mue_csr_write(struct usbnet *, uint32_t, uint32_t); 83static int mue_csr_write(struct usbnet *, uint32_t, uint32_t);
84static int mue_wait_for_bits(struct usbnet *, uint32_t, uint32_t, 84static int mue_wait_for_bits(struct usbnet *, uint32_t, uint32_t,
85 uint32_t, uint32_t); 85 uint32_t, uint32_t);
86static uint8_t mue_eeprom_getbyte(struct usbnet *, int, uint8_t *); 86static uint8_t mue_eeprom_getbyte(struct usbnet *, int, uint8_t *);
87static bool mue_eeprom_present(struct usbnet *); 87static bool mue_eeprom_present(struct usbnet *);
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_ioctl(struct ifnet *, u_long, void *);
102static void mue_uno_mcast(struct ifnet *); 102static void mue_uno_mcast(struct ifnet *);
103static int mue_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 103static int mue_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
104static int mue_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 104static int mue_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
105static void mue_uno_mii_statchg(struct ifnet *); 105static void mue_uno_mii_statchg(struct ifnet *);
106static void mue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 106static void mue_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
107 uint32_t); 107 uint32_t);
108static unsigned mue_uno_tx_prepare(struct usbnet *, struct mbuf *, 108static unsigned mue_uno_tx_prepare(struct usbnet *, struct mbuf *,
109 struct usbnet_chain *); 109 struct usbnet_chain *);
110static int mue_uno_init(struct ifnet *); 110static int mue_uno_init(struct ifnet *);
111 111
112static const struct usbnet_ops mue_ops = { 112static const struct usbnet_ops mue_ops = {
113 .uno_stop = mue_uno_stop, 113 .uno_stop = mue_uno_stop,
114 .uno_ioctl = mue_uno_ioctl, 114 .uno_ioctl = mue_uno_ioctl,
115 .uno_mcast = mue_uno_mcast, 115 .uno_mcast = mue_uno_mcast,
116 .uno_read_reg = mue_uno_mii_read_reg, 116 .uno_read_reg = mue_uno_mii_read_reg,
117 .uno_write_reg = mue_uno_mii_write_reg, 117 .uno_write_reg = mue_uno_mii_write_reg,
118 .uno_statchg = mue_uno_mii_statchg, 118 .uno_statchg = mue_uno_mii_statchg,
119 .uno_tx_prepare = mue_uno_tx_prepare, 119 .uno_tx_prepare = mue_uno_tx_prepare,
120 .uno_rx_loop = mue_uno_rx_loop, 120 .uno_rx_loop = mue_uno_rx_loop,
121 .uno_init = mue_uno_init, 121 .uno_init = mue_uno_init,
122}; 122};
123 123
124#define MUE_SETBIT(un, reg, x) \ 124#define MUE_SETBIT(un, reg, x) \
125 mue_csr_write(un, reg, mue_csr_read(un, reg) | (x)) 125 mue_csr_write(un, reg, mue_csr_read(un, reg) | (x))
126 126
127#define MUE_CLRBIT(un, reg, x) \ 127#define MUE_CLRBIT(un, reg, x) \
128 mue_csr_write(un, reg, mue_csr_read(un, reg) & ~(x)) 128 mue_csr_write(un, reg, mue_csr_read(un, reg) & ~(x))
129 129
130#define MUE_WAIT_SET(un, reg, set, fail) \ 130#define MUE_WAIT_SET(un, reg, set, fail) \
131 mue_wait_for_bits(un, reg, set, ~0, fail) 131 mue_wait_for_bits(un, reg, set, ~0, fail)
132 132
133#define MUE_WAIT_CLR(un, reg, clear, fail) \ 133#define MUE_WAIT_CLR(un, reg, clear, fail) \
134 mue_wait_for_bits(un, reg, 0, clear, fail) 134 mue_wait_for_bits(un, reg, 0, clear, fail)
135 135
136#define ETHER_IS_VALID(addr) \ 136#define ETHER_IS_VALID(addr) \
137 (!ETHER_IS_MULTICAST(addr) && !ETHER_IS_ZERO(addr)) 137 (!ETHER_IS_MULTICAST(addr) && !ETHER_IS_ZERO(addr))
138 138
139#define ETHER_IS_ZERO(addr) \ 139#define ETHER_IS_ZERO(addr) \
140 (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) 140 (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]))
141 141
142CFATTACH_DECL_NEW(mue, sizeof(struct usbnet), mue_match, mue_attach, 142CFATTACH_DECL_NEW(mue, sizeof(struct usbnet), mue_match, mue_attach,
143 usbnet_detach, usbnet_activate); 143 usbnet_detach, usbnet_activate);
144 144
145static uint32_t 145static uint32_t
146mue_csr_read(struct usbnet *un, uint32_t reg) 146mue_csr_read(struct usbnet *un, uint32_t reg)
147{ 147{
148 usb_device_request_t req; 148 usb_device_request_t req;
149 usbd_status err; 149 usbd_status err;
150 uDWord val; 150 uDWord val;
151 151
152 if (usbnet_isdying(un)) 152 if (usbnet_isdying(un))
153 return 0; 153 return 0;
154 154
155 USETDW(val, 0); 155 USETDW(val, 0);
156 req.bmRequestType = UT_READ_VENDOR_DEVICE; 156 req.bmRequestType = UT_READ_VENDOR_DEVICE;
157 req.bRequest = MUE_UR_READREG; 157 req.bRequest = MUE_UR_READREG;
158 USETW(req.wValue, 0); 158 USETW(req.wValue, 0);
159 USETW(req.wIndex, reg); 159 USETW(req.wIndex, reg);
160 USETW(req.wLength, 4); 160 USETW(req.wLength, 4);
161 161
162 err = usbd_do_request(un->un_udev, &req, &val); 162 err = usbd_do_request(un->un_udev, &req, &val);
163 if (err) { 163 if (err) {
164 MUE_PRINTF(un, "reg = %#x: %s\n", reg, usbd_errstr(err)); 164 MUE_PRINTF(un, "reg = %#x: %s\n", reg, usbd_errstr(err));
165 return 0; 165 return 0;
166 } 166 }
167 167
168 return UGETDW(val); 168 return UGETDW(val);
169} 169}
170 170
171static int 171static int
172mue_csr_write(struct usbnet *un, uint32_t reg, uint32_t aval) 172mue_csr_write(struct usbnet *un, uint32_t reg, uint32_t aval)
173{ 173{
174 usb_device_request_t req; 174 usb_device_request_t req;
175 usbd_status err; 175 usbd_status err;
176 uDWord val; 176 uDWord val;
177 177
178 if (usbnet_isdying(un)) 178 if (usbnet_isdying(un))
179 return 0; 179 return 0;
180 180
181 USETDW(val, aval); 181 USETDW(val, aval);
182 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 182 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
183 req.bRequest = MUE_UR_WRITEREG; 183 req.bRequest = MUE_UR_WRITEREG;
184 USETW(req.wValue, 0); 184 USETW(req.wValue, 0);
185 USETW(req.wIndex, reg); 185 USETW(req.wIndex, reg);
186 USETW(req.wLength, 4); 186 USETW(req.wLength, 4);
187 187
188 err = usbd_do_request(un->un_udev, &req, &val); 188 err = usbd_do_request(un->un_udev, &req, &val);
189 if (err) { 189 if (err) {
190 MUE_PRINTF(un, "reg = %#x: %s\n", reg, usbd_errstr(err)); 190 MUE_PRINTF(un, "reg = %#x: %s\n", reg, usbd_errstr(err));
191 return -1; 191 return -1;
192 } 192 }
193 193
194 return 0; 194 return 0;
195} 195}
196 196
197static int 197static int
198mue_wait_for_bits(struct usbnet *un, uint32_t reg, 198mue_wait_for_bits(struct usbnet *un, uint32_t reg,
199 uint32_t set, uint32_t clear, uint32_t fail) 199 uint32_t set, uint32_t clear, uint32_t fail)
200{ 200{
201 uint32_t val; 201 uint32_t val;
202 int ntries; 202 int ntries;
203 203
204 for (ntries = 0; ntries < 1000; ntries++) { 204 for (ntries = 0; ntries < 1000; ntries++) {
205 if (usbnet_isdying(un)) 205 if (usbnet_isdying(un))
206 return 1; 206 return 1;
207 val = mue_csr_read(un, reg); 207 val = mue_csr_read(un, reg);
208 if ((val & set) || !(val & clear)) 208 if ((val & set) || !(val & clear))
209 return 0; 209 return 0;
210 if (val & fail) 210 if (val & fail)
211 return 1; 211 return 1;
212 usbd_delay_ms(un->un_udev, 1); 212 usbd_delay_ms(un->un_udev, 1);
213 } 213 }
214 214
215 return 1; 215 return 1;
216} 216}
217 217
218static int 218static int
219mue_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 219mue_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
220{ 220{
221 uint32_t data; 221 uint32_t data;
222 222
223 if (un->un_phyno != phy) 223 if (un->un_phyno != phy)
224 return EINVAL; 224 return EINVAL;
225 225
226 if (MUE_WAIT_CLR(un, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) { 226 if (MUE_WAIT_CLR(un, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) {
227 MUE_PRINTF(un, "not ready\n"); 227 MUE_PRINTF(un, "not ready\n");
228 return EBUSY; 228 return EBUSY;
229 } 229 }
230 230
231 mue_csr_write(un, MUE_MII_ACCESS, MUE_MII_ACCESS_READ | 231 mue_csr_write(un, MUE_MII_ACCESS, MUE_MII_ACCESS_READ |
232 MUE_MII_ACCESS_BUSY | MUE_MII_ACCESS_REGADDR(reg) | 232 MUE_MII_ACCESS_BUSY | MUE_MII_ACCESS_REGADDR(reg) |
233 MUE_MII_ACCESS_PHYADDR(phy)); 233 MUE_MII_ACCESS_PHYADDR(phy));
234 234
235 if (MUE_WAIT_CLR(un, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) { 235 if (MUE_WAIT_CLR(un, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) {
236 MUE_PRINTF(un, "timed out\n"); 236 MUE_PRINTF(un, "timed out\n");
237 return ETIMEDOUT; 237 return ETIMEDOUT;
238 } 238 }
239 239
240 data = mue_csr_read(un, MUE_MII_DATA); 240 data = mue_csr_read(un, MUE_MII_DATA);
241 *val = data & 0xffff; 241 *val = data & 0xffff;
242 242
243 return 0; 243 return 0;
244} 244}
245 245
246static int 246static int
247mue_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 247mue_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
248{ 248{
249 249
250 if (un->un_phyno != phy) 250 if (un->un_phyno != phy)
251 return EINVAL; 251 return EINVAL;
252 252
253 if (MUE_WAIT_CLR(un, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) { 253 if (MUE_WAIT_CLR(un, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) {
254 MUE_PRINTF(un, "not ready\n"); 254 MUE_PRINTF(un, "not ready\n");
255 return EBUSY; 255 return EBUSY;
256 } 256 }
257 257
258 mue_csr_write(un, MUE_MII_DATA, val); 258 mue_csr_write(un, MUE_MII_DATA, val);
259 mue_csr_write(un, MUE_MII_ACCESS, MUE_MII_ACCESS_WRITE | 259 mue_csr_write(un, MUE_MII_ACCESS, MUE_MII_ACCESS_WRITE |
260 MUE_MII_ACCESS_BUSY | MUE_MII_ACCESS_REGADDR(reg) | 260 MUE_MII_ACCESS_BUSY | MUE_MII_ACCESS_REGADDR(reg) |
261 MUE_MII_ACCESS_PHYADDR(phy)); 261 MUE_MII_ACCESS_PHYADDR(phy));
262 262
263 if (MUE_WAIT_CLR(un, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) { 263 if (MUE_WAIT_CLR(un, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) {
264 MUE_PRINTF(un, "timed out\n"); 264 MUE_PRINTF(un, "timed out\n");
265 return ETIMEDOUT; 265 return ETIMEDOUT;
266 } 266 }
267 267
268 return 0; 268 return 0;
269} 269}
270 270
271static void 271static void
272mue_uno_mii_statchg(struct ifnet *ifp) 272mue_uno_mii_statchg(struct ifnet *ifp)
273{ 273{
274 struct usbnet * const un = ifp->if_softc; 274 struct usbnet * const un = ifp->if_softc;
275 struct mii_data * const mii = usbnet_mii(un); 275 struct mii_data * const mii = usbnet_mii(un);
276 uint32_t flow, threshold; 276 uint32_t flow, threshold;
277 277
278 if (usbnet_isdying(un)) 278 if (usbnet_isdying(un))
279 return; 279 return;
280 280
281 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 281 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
282 (IFM_ACTIVE | IFM_AVALID)) { 282 (IFM_ACTIVE | IFM_AVALID)) {
283 switch (IFM_SUBTYPE(mii->mii_media_active)) { 283 switch (IFM_SUBTYPE(mii->mii_media_active)) {
284 case IFM_10_T: 284 case IFM_10_T:
285 case IFM_100_TX: 285 case IFM_100_TX:
286 case IFM_1000_T: 286 case IFM_1000_T:
287 usbnet_set_link(un, true); 287 usbnet_set_link(un, true);
288 break; 288 break;
289 default: 289 default:
290 break; 290 break;
291 } 291 }
292 } 292 }
293 293
294 /* Lost link, do nothing. */ 294 /* Lost link, do nothing. */
295 if (!usbnet_havelink(un)) { 295 if (!usbnet_havelink(un)) {
296 DPRINTF(un, "mii_media_status = %#x\n", mii->mii_media_status); 296 DPRINTF(un, "mii_media_status = %#x\n", mii->mii_media_status);
297 return; 297 return;
298 } 298 }
299 299
300 if (!(un->un_flags & LAN7500)) { 300 if (!(un->un_flags & LAN7500)) {
301 if (un->un_udev->ud_speed == USB_SPEED_SUPER) { 301 if (un->un_udev->ud_speed == USB_SPEED_SUPER) {
302 if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) { 302 if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
303 /* Disable U2 and enable U1. */ 303 /* Disable U2 and enable U1. */
304 MUE_CLRBIT(un, MUE_USB_CFG1, 304 MUE_CLRBIT(un, MUE_USB_CFG1,
305 MUE_USB_CFG1_DEV_U2_INIT_EN); 305 MUE_USB_CFG1_DEV_U2_INIT_EN);
306 MUE_SETBIT(un, MUE_USB_CFG1, 306 MUE_SETBIT(un, MUE_USB_CFG1,
307 MUE_USB_CFG1_DEV_U1_INIT_EN); 307 MUE_USB_CFG1_DEV_U1_INIT_EN);
308 } else { 308 } else {
309 /* Enable U1 and U2. */ 309 /* Enable U1 and U2. */
310 MUE_SETBIT(un, MUE_USB_CFG1, 310 MUE_SETBIT(un, MUE_USB_CFG1,
311 MUE_USB_CFG1_DEV_U1_INIT_EN | 311 MUE_USB_CFG1_DEV_U1_INIT_EN |
312 MUE_USB_CFG1_DEV_U2_INIT_EN); 312 MUE_USB_CFG1_DEV_U2_INIT_EN);
313 } 313 }
314 } 314 }
315 } 315 }
316 316
317 flow = 0; 317 flow = 0;
318 /* XXX Linux does not check IFM_FDX flag for 7800. */ 318 /* XXX Linux does not check IFM_FDX flag for 7800. */
319 if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) { 319 if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) {
320 if (IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) 320 if (IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE)
321 flow |= MUE_FLOW_TX_FCEN | MUE_FLOW_PAUSE_TIME; 321 flow |= MUE_FLOW_TX_FCEN | MUE_FLOW_PAUSE_TIME;
322 if (IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) 322 if (IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE)
323 flow |= MUE_FLOW_RX_FCEN; 323 flow |= MUE_FLOW_RX_FCEN;
324 } 324 }
325 325
326 /* XXX Magic numbers taken from Linux driver. */ 326 /* XXX Magic numbers taken from Linux driver. */
327 if (un->un_flags & LAN7500) 327 if (un->un_flags & LAN7500)
328 threshold = 0x820; 328 threshold = 0x820;
329 else 329 else
330 switch (un->un_udev->ud_speed) { 330 switch (un->un_udev->ud_speed) {
331 case USB_SPEED_SUPER: 331 case USB_SPEED_SUPER:
332 threshold = 0x817; 332 threshold = 0x817;
333 break; 333 break;
334 case USB_SPEED_HIGH: 334 case USB_SPEED_HIGH:
335 threshold = 0x211; 335 threshold = 0x211;
336 break; 336 break;
337 default: 337 default:
338 threshold = 0; 338 threshold = 0;
339 break; 339 break;
340 } 340 }
341 341
342 /* Threshold value should be set before enabling flow. */ 342 /* Threshold value should be set before enabling flow. */
343 mue_csr_write(un, (un->un_flags & LAN7500) ? 343 mue_csr_write(un, (un->un_flags & LAN7500) ?
344 MUE_7500_FCT_FLOW : MUE_7800_FCT_FLOW, threshold); 344 MUE_7500_FCT_FLOW : MUE_7800_FCT_FLOW, threshold);
345 mue_csr_write(un, MUE_FLOW, flow); 345 mue_csr_write(un, MUE_FLOW, flow);
346 346
347 DPRINTF(un, "done\n"); 347 DPRINTF(un, "done\n");
348} 348}
349 349
350static uint8_t 350static uint8_t
351mue_eeprom_getbyte(struct usbnet *un, int off, uint8_t *dest) 351mue_eeprom_getbyte(struct usbnet *un, int off, uint8_t *dest)
352{ 352{
353 uint32_t val; 353 uint32_t val;
354 354
355 if (MUE_WAIT_CLR(un, MUE_E2P_CMD, MUE_E2P_CMD_BUSY, 0)) { 355 if (MUE_WAIT_CLR(un, MUE_E2P_CMD, MUE_E2P_CMD_BUSY, 0)) {
356 MUE_PRINTF(un, "not ready\n"); 356 MUE_PRINTF(un, "not ready\n");
357 return ETIMEDOUT; 357 return ETIMEDOUT;
358 } 358 }
359 359
360 KASSERT((off & ~MUE_E2P_CMD_ADDR_MASK) == 0); 360 KASSERT((off & ~MUE_E2P_CMD_ADDR_MASK) == 0);
361 mue_csr_write(un, MUE_E2P_CMD, MUE_E2P_CMD_READ | MUE_E2P_CMD_BUSY | 361 mue_csr_write(un, MUE_E2P_CMD, MUE_E2P_CMD_READ | MUE_E2P_CMD_BUSY |
362 off); 362 off);
363 363
364 if (MUE_WAIT_CLR(un, MUE_E2P_CMD, MUE_E2P_CMD_BUSY, 364 if (MUE_WAIT_CLR(un, MUE_E2P_CMD, MUE_E2P_CMD_BUSY,
365 MUE_E2P_CMD_TIMEOUT)) { 365 MUE_E2P_CMD_TIMEOUT)) {
366 MUE_PRINTF(un, "timed out\n"); 366 MUE_PRINTF(un, "timed out\n");
367 return ETIMEDOUT; 367 return ETIMEDOUT;
368 } 368 }
369 369
370 val = mue_csr_read(un, MUE_E2P_DATA); 370 val = mue_csr_read(un, MUE_E2P_DATA);
371 *dest = val & 0xff; 371 *dest = val & 0xff;
372 372
373 return 0; 373 return 0;
374} 374}
375 375
376static int 376static int
377mue_read_eeprom(struct usbnet *un, uint8_t *dest, int off, int cnt) 377mue_read_eeprom(struct usbnet *un, uint8_t *dest, int off, int cnt)
378{ 378{
379 uint32_t val = 0; /* XXX gcc */ 379 uint32_t val = 0; /* XXX gcc */
380 uint8_t byte; 380 uint8_t byte;
381 int i, err = 0; 381 int i, err = 0;
382 382
383 /*  383 /*
384 * EEPROM pins are muxed with the LED function on LAN7800 device. 384 * EEPROM pins are muxed with the LED function on LAN7800 device.
385 */ 385 */
386 if (un->un_flags & LAN7800) { 386 if (un->un_flags & LAN7800) {
387 val = mue_csr_read(un, MUE_HW_CFG); 387 val = mue_csr_read(un, MUE_HW_CFG);
388 mue_csr_write(un, MUE_HW_CFG, 388 mue_csr_write(un, MUE_HW_CFG,
389 val & ~(MUE_HW_CFG_LED0_EN | MUE_HW_CFG_LED1_EN)); 389 val & ~(MUE_HW_CFG_LED0_EN | MUE_HW_CFG_LED1_EN));
390 } 390 }
391 391
392 for (i = 0; i < cnt; i++) { 392 for (i = 0; i < cnt; i++) {
393 err = mue_eeprom_getbyte(un, off + i, &byte); 393 err = mue_eeprom_getbyte(un, off + i, &byte);
394 if (err) 394 if (err)
395 break; 395 break;
396 *(dest + i) = byte; 396 *(dest + i) = byte;
397 } 397 }
398 398
399 if (un->un_flags & LAN7800) 399 if (un->un_flags & LAN7800)
400 mue_csr_write(un, MUE_HW_CFG, val); 400 mue_csr_write(un, MUE_HW_CFG, val);
401 401
402 return err ? 1 : 0; 402 return err ? 1 : 0;
403} 403}
404 404
405static bool 405static bool
406mue_eeprom_present(struct usbnet *un) 406mue_eeprom_present(struct usbnet *un)
407{ 407{
408 uint32_t val; 408 uint32_t val;
409 uint8_t sig; 409 uint8_t sig;
410 int ret; 410 int ret;
411 411
412 if (un->un_flags & LAN7500) { 412 if (un->un_flags & LAN7500) {
413 val = mue_csr_read(un, MUE_E2P_CMD); 413 val = mue_csr_read(un, MUE_E2P_CMD);
414 return val & MUE_E2P_CMD_LOADED; 414 return val & MUE_E2P_CMD_LOADED;
415 } else { 415 } else {
416 ret = mue_read_eeprom(un, &sig, MUE_E2P_IND_OFFSET, 1); 416 ret = mue_read_eeprom(un, &sig, MUE_E2P_IND_OFFSET, 1);
417 return (ret == 0) && (sig == MUE_E2P_IND); 417 return (ret == 0) && (sig == MUE_E2P_IND);
418 } 418 }
419} 419}
420 420
421static int 421static int
422mue_read_otp_raw(struct usbnet *un, uint8_t *dest, int off, int cnt) 422mue_read_otp_raw(struct usbnet *un, uint8_t *dest, int off, int cnt)
423{ 423{
424 uint32_t val; 424 uint32_t val;
425 int i, err; 425 int i, err;
426 426
427 val = mue_csr_read(un, MUE_OTP_PWR_DN); 427 val = mue_csr_read(un, MUE_OTP_PWR_DN);
428 428
429 /* Checking if bit is set. */ 429 /* Checking if bit is set. */
430 if (val & MUE_OTP_PWR_DN_PWRDN_N) { 430 if (val & MUE_OTP_PWR_DN_PWRDN_N) {
431 /* Clear it, then wait for it to be cleared. */ 431 /* Clear it, then wait for it to be cleared. */
432 mue_csr_write(un, MUE_OTP_PWR_DN, 0); 432 mue_csr_write(un, MUE_OTP_PWR_DN, 0);
433 err = MUE_WAIT_CLR(un, MUE_OTP_PWR_DN, MUE_OTP_PWR_DN_PWRDN_N, 433 err = MUE_WAIT_CLR(un, MUE_OTP_PWR_DN, MUE_OTP_PWR_DN_PWRDN_N,
434 0); 434 0);
435 if (err) { 435 if (err) {
436 MUE_PRINTF(un, "not ready\n"); 436 MUE_PRINTF(un, "not ready\n");
437 return 1; 437 return 1;
438 } 438 }
439 } 439 }
440 440
441 /* Start reading the bytes, one at a time. */ 441 /* Start reading the bytes, one at a time. */
442 for (i = 0; i < cnt; i++) { 442 for (i = 0; i < cnt; i++) {
443 mue_csr_write(un, MUE_OTP_ADDR1, 443 mue_csr_write(un, MUE_OTP_ADDR1,
444 ((off + i) >> 8) & MUE_OTP_ADDR1_MASK); 444 ((off + i) >> 8) & MUE_OTP_ADDR1_MASK);
445 mue_csr_write(un, MUE_OTP_ADDR2, 445 mue_csr_write(un, MUE_OTP_ADDR2,
446 ((off + i) & MUE_OTP_ADDR2_MASK)); 446 ((off + i) & MUE_OTP_ADDR2_MASK));
447 mue_csr_write(un, MUE_OTP_FUNC_CMD, MUE_OTP_FUNC_CMD_READ); 447 mue_csr_write(un, MUE_OTP_FUNC_CMD, MUE_OTP_FUNC_CMD_READ);
448 mue_csr_write(un, MUE_OTP_CMD_GO, MUE_OTP_CMD_GO_GO); 448 mue_csr_write(un, MUE_OTP_CMD_GO, MUE_OTP_CMD_GO_GO);
449 449
450 err = MUE_WAIT_CLR(un, MUE_OTP_STATUS, MUE_OTP_STATUS_BUSY, 0); 450 err = MUE_WAIT_CLR(un, MUE_OTP_STATUS, MUE_OTP_STATUS_BUSY, 0);
451 if (err) { 451 if (err) {
452 MUE_PRINTF(un, "timed out\n"); 452 MUE_PRINTF(un, "timed out\n");
453 return 1; 453 return 1;
454 } 454 }
455 val = mue_csr_read(un, MUE_OTP_RD_DATA); 455 val = mue_csr_read(un, MUE_OTP_RD_DATA);
456 *(dest + i) = (uint8_t)(val & 0xff); 456 *(dest + i) = (uint8_t)(val & 0xff);
457 } 457 }
458 458
459 return 0; 459 return 0;
460} 460}
461 461
462static int 462static int
463mue_read_otp(struct usbnet *un, uint8_t *dest, int off, int cnt) 463mue_read_otp(struct usbnet *un, uint8_t *dest, int off, int cnt)
464{ 464{
465 uint8_t sig; 465 uint8_t sig;
466 int err; 466 int err;
467 467
468 if (un->un_flags & LAN7500) 468 if (un->un_flags & LAN7500)
469 return 1; 469 return 1;
470 470
471 err = mue_read_otp_raw(un, &sig, MUE_OTP_IND_OFFSET, 1); 471 err = mue_read_otp_raw(un, &sig, MUE_OTP_IND_OFFSET, 1);
472 if (err) 472 if (err)
473 return 1; 473 return 1;
474 switch (sig) { 474 switch (sig) {
475 case MUE_OTP_IND_1: 475 case MUE_OTP_IND_1:
476 break; 476 break;
477 case MUE_OTP_IND_2: 477 case MUE_OTP_IND_2:
478 off += 0x100; 478 off += 0x100;
479 break; 479 break;
480 default: 480 default:
481 DPRINTF(un, "OTP not found\n"); 481 DPRINTF(un, "OTP not found\n");
482 return 1; 482 return 1;
483 } 483 }
484 err = mue_read_otp_raw(un, dest, off, cnt); 484 err = mue_read_otp_raw(un, dest, off, cnt);
485 return err; 485 return err;
486} 486}
487 487
488static void 488static void
489mue_dataport_write(struct usbnet *un, uint32_t sel, uint32_t addr, 489mue_dataport_write(struct usbnet *un, uint32_t sel, uint32_t addr,
490 uint32_t cnt, uint32_t *data) 490 uint32_t cnt, uint32_t *data)
491{ 491{
492 uint32_t i; 492 uint32_t i;
493 493
494 if (MUE_WAIT_SET(un, MUE_DP_SEL, MUE_DP_SEL_DPRDY, 0)) { 494 if (MUE_WAIT_SET(un, MUE_DP_SEL, MUE_DP_SEL_DPRDY, 0)) {
495 MUE_PRINTF(un, "not ready\n"); 495 MUE_PRINTF(un, "not ready\n");
496 return; 496 return;
497 } 497 }
498 498
499 mue_csr_write(un, MUE_DP_SEL, 499 mue_csr_write(un, MUE_DP_SEL,
500 (mue_csr_read(un, MUE_DP_SEL) & ~MUE_DP_SEL_RSEL_MASK) | sel); 500 (mue_csr_read(un, MUE_DP_SEL) & ~MUE_DP_SEL_RSEL_MASK) | sel);
501 501
502 for (i = 0; i < cnt; i++) { 502 for (i = 0; i < cnt; i++) {
503 mue_csr_write(un, MUE_DP_ADDR, addr + i); 503 mue_csr_write(un, MUE_DP_ADDR, addr + i);
504 mue_csr_write(un, MUE_DP_DATA, data[i]); 504 mue_csr_write(un, MUE_DP_DATA, data[i]);
505 mue_csr_write(un, MUE_DP_CMD, MUE_DP_CMD_WRITE); 505 mue_csr_write(un, MUE_DP_CMD, MUE_DP_CMD_WRITE);
506 if (MUE_WAIT_SET(un, MUE_DP_SEL, MUE_DP_SEL_DPRDY, 0)) { 506 if (MUE_WAIT_SET(un, MUE_DP_SEL, MUE_DP_SEL_DPRDY, 0)) {
507 MUE_PRINTF(un, "timed out\n"); 507 MUE_PRINTF(un, "timed out\n");
508 return; 508 return;
509 } 509 }
510 } 510 }
511} 511}
512 512
513static void 513static void
514mue_init_ltm(struct usbnet *un) 514mue_init_ltm(struct usbnet *un)
515{ 515{
516 uint32_t idx[MUE_NUM_LTM_INDEX] = { 0, 0, 0, 0, 0, 0 }; 516 uint32_t idx[MUE_NUM_LTM_INDEX] = { 0, 0, 0, 0, 0, 0 };
517 uint8_t temp[2]; 517 uint8_t temp[2];
518 size_t i; 518 size_t i;
519 519
520 if (mue_csr_read(un, MUE_USB_CFG1) & MUE_USB_CFG1_LTM_ENABLE) { 520 if (mue_csr_read(un, MUE_USB_CFG1) & MUE_USB_CFG1_LTM_ENABLE) {
521 if (mue_eeprom_present(un) && 521 if (mue_eeprom_present(un) &&
522 (mue_read_eeprom(un, temp, MUE_E2P_LTM_OFFSET, 2) == 0)) { 522 (mue_read_eeprom(un, temp, MUE_E2P_LTM_OFFSET, 2) == 0)) {
523 if (temp[0] != sizeof(idx)) { 523 if (temp[0] != sizeof(idx)) {
524 DPRINTF(un, "EEPROM: unexpected size\n"); 524 DPRINTF(un, "EEPROM: unexpected size\n");
525 goto done; 525 goto done;
526 } 526 }
527 if (mue_read_eeprom(un, (uint8_t *)idx, temp[1] << 1, 527 if (mue_read_eeprom(un, (uint8_t *)idx, temp[1] << 1,
528 sizeof(idx))) { 528 sizeof(idx))) {
529 DPRINTF(un, "EEPROM: failed to read\n"); 529 DPRINTF(un, "EEPROM: failed to read\n");
530 goto done; 530 goto done;
531 } 531 }
532 DPRINTF(un, "success\n"); 532 DPRINTF(un, "success\n");
533 } else if (mue_read_otp(un, temp, MUE_E2P_LTM_OFFSET, 2) == 0) { 533 } else if (mue_read_otp(un, temp, MUE_E2P_LTM_OFFSET, 2) == 0) {
534 if (temp[0] != sizeof(idx)) { 534 if (temp[0] != sizeof(idx)) {
535 DPRINTF(un, "OTP: unexpected size\n"); 535 DPRINTF(un, "OTP: unexpected size\n");
536 goto done; 536 goto done;
537 } 537 }
538 if (mue_read_otp(un, (uint8_t *)idx, temp[1] << 1, 538 if (mue_read_otp(un, (uint8_t *)idx, temp[1] << 1,
539 sizeof(idx))) { 539 sizeof(idx))) {
540 DPRINTF(un, "OTP: failed to read\n"); 540 DPRINTF(un, "OTP: failed to read\n");
541 goto done; 541 goto done;
542 } 542 }
543 DPRINTF(un, "success\n"); 543 DPRINTF(un, "success\n");
544 } else 544 } else
545 DPRINTF(un, "nothing to do\n"); 545 DPRINTF(un, "nothing to do\n");
546 } else 546 } else
547 DPRINTF(un, "nothing to do\n"); 547 DPRINTF(un, "nothing to do\n");
548done: 548done:
549 for (i = 0; i < __arraycount(idx); i++) 549 for (i = 0; i < __arraycount(idx); i++)
550 mue_csr_write(un, MUE_LTM_INDEX(i), idx[i]); 550 mue_csr_write(un, MUE_LTM_INDEX(i), idx[i]);
551} 551}
552 552
553static int 553static int
554mue_chip_init(struct usbnet *un) 554mue_chip_init(struct usbnet *un)
555{ 555{
556 uint32_t val; 556 uint32_t val;
557 557
558 if ((un->un_flags & LAN7500) && 558 if ((un->un_flags & LAN7500) &&
559 MUE_WAIT_SET(un, MUE_PMT_CTL, MUE_PMT_CTL_READY, 0)) { 559 MUE_WAIT_SET(un, MUE_PMT_CTL, MUE_PMT_CTL_READY, 0)) {
560 MUE_PRINTF(un, "not ready\n"); 560 MUE_PRINTF(un, "not ready\n");
561 return ETIMEDOUT; 561 return ETIMEDOUT;
562 } 562 }
563 563
564 MUE_SETBIT(un, MUE_HW_CFG, MUE_HW_CFG_LRST); 564 MUE_SETBIT(un, MUE_HW_CFG, MUE_HW_CFG_LRST);
565 if (MUE_WAIT_CLR(un, MUE_HW_CFG, MUE_HW_CFG_LRST, 0)) { 565 if (MUE_WAIT_CLR(un, MUE_HW_CFG, MUE_HW_CFG_LRST, 0)) {
566 MUE_PRINTF(un, "timed out\n"); 566 MUE_PRINTF(un, "timed out\n");
567 return ETIMEDOUT; 567 return ETIMEDOUT;
568 } 568 }
569 569
570 /* Respond to the IN token with a NAK. */ 570 /* Respond to the IN token with a NAK. */
571 if (un->un_flags & LAN7500) 571 if (un->un_flags & LAN7500)
572 MUE_SETBIT(un, MUE_HW_CFG, MUE_HW_CFG_BIR); 572 MUE_SETBIT(un, MUE_HW_CFG, MUE_HW_CFG_BIR);
573 else 573 else
574 MUE_SETBIT(un, MUE_USB_CFG0, MUE_USB_CFG0_BIR); 574 MUE_SETBIT(un, MUE_USB_CFG0, MUE_USB_CFG0_BIR);
575 575
576 if (un->un_flags & LAN7500) { 576 if (un->un_flags & LAN7500) {
577 if (un->un_udev->ud_speed == USB_SPEED_HIGH) 577 if (un->un_udev->ud_speed == USB_SPEED_HIGH)
578 val = MUE_7500_HS_RX_BUFSIZE / 578 val = MUE_7500_HS_RX_BUFSIZE /
579 MUE_HS_USB_PKT_SIZE; 579 MUE_HS_USB_PKT_SIZE;
580 else 580 else
581 val = MUE_7500_FS_RX_BUFSIZE / 581 val = MUE_7500_FS_RX_BUFSIZE /
582 MUE_FS_USB_PKT_SIZE; 582 MUE_FS_USB_PKT_SIZE;
583 mue_csr_write(un, MUE_7500_BURST_CAP, val); 583 mue_csr_write(un, MUE_7500_BURST_CAP, val);
584 mue_csr_write(un, MUE_7500_BULKIN_DELAY, 584 mue_csr_write(un, MUE_7500_BULKIN_DELAY,
585 MUE_7500_DEFAULT_BULKIN_DELAY); 585 MUE_7500_DEFAULT_BULKIN_DELAY);
586 586
587 MUE_SETBIT(un, MUE_HW_CFG, MUE_HW_CFG_BCE | MUE_HW_CFG_MEF); 587 MUE_SETBIT(un, MUE_HW_CFG, MUE_HW_CFG_BCE | MUE_HW_CFG_MEF);
588 588
589 /* Set FIFO sizes. */ 589 /* Set FIFO sizes. */
590 val = (MUE_7500_MAX_RX_FIFO_SIZE - 512) / 512; 590 val = (MUE_7500_MAX_RX_FIFO_SIZE - 512) / 512;
591 mue_csr_write(un, MUE_7500_FCT_RX_FIFO_END, val); 591 mue_csr_write(un, MUE_7500_FCT_RX_FIFO_END, val);
592 val = (MUE_7500_MAX_TX_FIFO_SIZE - 512) / 512; 592 val = (MUE_7500_MAX_TX_FIFO_SIZE - 512) / 512;
593 mue_csr_write(un, MUE_7500_FCT_TX_FIFO_END, val); 593 mue_csr_write(un, MUE_7500_FCT_TX_FIFO_END, val);
594 } else { 594 } else {
595 /* Init LTM. */ 595 /* Init LTM. */
596 mue_init_ltm(un); 596 mue_init_ltm(un);
597 597
598 val = MUE_7800_RX_BUFSIZE; 598 val = MUE_7800_RX_BUFSIZE;
599 switch (un->un_udev->ud_speed) { 599 switch (un->un_udev->ud_speed) {
600 case USB_SPEED_SUPER: 600 case USB_SPEED_SUPER:
601 val /= MUE_SS_USB_PKT_SIZE; 601 val /= MUE_SS_USB_PKT_SIZE;
602 break; 602 break;
603 case USB_SPEED_HIGH: 603 case USB_SPEED_HIGH:
604 val /= MUE_HS_USB_PKT_SIZE; 604 val /= MUE_HS_USB_PKT_SIZE;
605 break; 605 break;
606 default: 606 default:
607 val /= MUE_FS_USB_PKT_SIZE; 607 val /= MUE_FS_USB_PKT_SIZE;
608 break; 608 break;
609 } 609 }
610 mue_csr_write(un, MUE_7800_BURST_CAP, val); 610 mue_csr_write(un, MUE_7800_BURST_CAP, val);
611 mue_csr_write(un, MUE_7800_BULKIN_DELAY, 611 mue_csr_write(un, MUE_7800_BULKIN_DELAY,
612 MUE_7800_DEFAULT_BULKIN_DELAY); 612 MUE_7800_DEFAULT_BULKIN_DELAY);
613 613
614 MUE_SETBIT(un, MUE_HW_CFG, MUE_HW_CFG_MEF); 614 MUE_SETBIT(un, MUE_HW_CFG, MUE_HW_CFG_MEF);
615 MUE_SETBIT(un, MUE_USB_CFG0, MUE_USB_CFG0_BCE); 615 MUE_SETBIT(un, MUE_USB_CFG0, MUE_USB_CFG0_BCE);
616 616
617 /* 617 /*
618 * Set FCL's RX and TX FIFO sizes: according to data sheet this 618 * Set FCL's RX and TX FIFO sizes: according to data sheet this
619 * is already the default value. But we initialize it to the 619 * is already the default value. But we initialize it to the
620 * same value anyways, as that's what the Linux driver does. 620 * same value anyways, as that's what the Linux driver does.
621 */ 621 */
622 val = (MUE_7800_MAX_RX_FIFO_SIZE - 512) / 512; 622 val = (MUE_7800_MAX_RX_FIFO_SIZE - 512) / 512;
623 mue_csr_write(un, MUE_7800_FCT_RX_FIFO_END, val); 623 mue_csr_write(un, MUE_7800_FCT_RX_FIFO_END, val);
624 val = (MUE_7800_MAX_TX_FIFO_SIZE - 512) / 512; 624 val = (MUE_7800_MAX_TX_FIFO_SIZE - 512) / 512;
625 mue_csr_write(un, MUE_7800_FCT_TX_FIFO_END, val); 625 mue_csr_write(un, MUE_7800_FCT_TX_FIFO_END, val);
626 } 626 }
627 627
628 /* Enabling interrupts. */ 628 /* Enabling interrupts. */
629 mue_csr_write(un, MUE_INT_STATUS, ~0); 629 mue_csr_write(un, MUE_INT_STATUS, ~0);
630 630
631 mue_csr_write(un, (un->un_flags & LAN7500) ? 631 mue_csr_write(un, (un->un_flags & LAN7500) ?
632 MUE_7500_FCT_FLOW : MUE_7800_FCT_FLOW, 0); 632 MUE_7500_FCT_FLOW : MUE_7800_FCT_FLOW, 0);
633 mue_csr_write(un, MUE_FLOW, 0); 633 mue_csr_write(un, MUE_FLOW, 0);
634 634
635 /* Reset PHY. */ 635 /* Reset PHY. */
636 MUE_SETBIT(un, MUE_PMT_CTL, MUE_PMT_CTL_PHY_RST); 636 MUE_SETBIT(un, MUE_PMT_CTL, MUE_PMT_CTL_PHY_RST);
637 if (MUE_WAIT_CLR(un, MUE_PMT_CTL, MUE_PMT_CTL_PHY_RST, 0)) { 637 if (MUE_WAIT_CLR(un, MUE_PMT_CTL, MUE_PMT_CTL_PHY_RST, 0)) {
638 MUE_PRINTF(un, "PHY not ready\n"); 638 MUE_PRINTF(un, "PHY not ready\n");
639 return ETIMEDOUT; 639 return ETIMEDOUT;
640 } 640 }
641 641
642 /* LAN7801 only has RGMII mode. */ 642 /* LAN7801 only has RGMII mode. */
643 if (un->un_flags & LAN7801) 643 if (un->un_flags & LAN7801)
644 MUE_CLRBIT(un, MUE_MAC_CR, MUE_MAC_CR_GMII_EN); 644 MUE_CLRBIT(un, MUE_MAC_CR, MUE_MAC_CR_GMII_EN);
645 645
646 if ((un->un_flags & (LAN7500 | LAN7800)) || 646 if ((un->un_flags & (LAN7500 | LAN7800)) ||
647 !mue_eeprom_present(un)) { 647 !mue_eeprom_present(un)) {
648 /* Allow MAC to detect speed and duplex from PHY. */ 648 /* Allow MAC to detect speed and duplex from PHY. */
649 MUE_SETBIT(un, MUE_MAC_CR, MUE_MAC_CR_AUTO_SPEED | 649 MUE_SETBIT(un, MUE_MAC_CR, MUE_MAC_CR_AUTO_SPEED |
650 MUE_MAC_CR_AUTO_DUPLEX); 650 MUE_MAC_CR_AUTO_DUPLEX);
651 } 651 }
652 652
653 MUE_SETBIT(un, MUE_MAC_TX, MUE_MAC_TX_TXEN); 653 MUE_SETBIT(un, MUE_MAC_TX, MUE_MAC_TX_TXEN);
654 MUE_SETBIT(un, (un->un_flags & LAN7500) ? 654 MUE_SETBIT(un, (un->un_flags & LAN7500) ?
655 MUE_7500_FCT_TX_CTL : MUE_7800_FCT_TX_CTL, MUE_FCT_TX_CTL_EN); 655 MUE_7500_FCT_TX_CTL : MUE_7800_FCT_TX_CTL, MUE_FCT_TX_CTL_EN);
656 656
657 MUE_SETBIT(un, (un->un_flags & LAN7500) ? 657 MUE_SETBIT(un, (un->un_flags & LAN7500) ?
658 MUE_7500_FCT_RX_CTL : MUE_7800_FCT_RX_CTL, MUE_FCT_RX_CTL_EN); 658 MUE_7500_FCT_RX_CTL : MUE_7800_FCT_RX_CTL, MUE_FCT_RX_CTL_EN);
659 659
660 /* Set default GPIO/LED settings only if no EEPROM is detected. */ 660 /* Set default GPIO/LED settings only if no EEPROM is detected. */
661 if ((un->un_flags & LAN7500) && !mue_eeprom_present(un)) { 661 if ((un->un_flags & LAN7500) && !mue_eeprom_present(un)) {
662 MUE_CLRBIT(un, MUE_LED_CFG, MUE_LED_CFG_LED10_FUN_SEL); 662 MUE_CLRBIT(un, MUE_LED_CFG, MUE_LED_CFG_LED10_FUN_SEL);
663 MUE_SETBIT(un, MUE_LED_CFG, 663 MUE_SETBIT(un, MUE_LED_CFG,
664 MUE_LED_CFG_LEDGPIO_EN | MUE_LED_CFG_LED2_FUN_SEL); 664 MUE_LED_CFG_LEDGPIO_EN | MUE_LED_CFG_LED2_FUN_SEL);
665 } 665 }
666 666
667 /* XXX We assume two LEDs at least when EEPROM is missing. */ 667 /* XXX We assume two LEDs at least when EEPROM is missing. */
668 if (un->un_flags & LAN7800 && 668 if (un->un_flags & LAN7800 &&
669 !mue_eeprom_present(un)) 669 !mue_eeprom_present(un))
670 MUE_SETBIT(un, MUE_HW_CFG, 670 MUE_SETBIT(un, MUE_HW_CFG,
671 MUE_HW_CFG_LED0_EN | MUE_HW_CFG_LED1_EN); 671 MUE_HW_CFG_LED0_EN | MUE_HW_CFG_LED1_EN);
672 672
673 return 0; 673 return 0;
674} 674}
675 675
676static void 676static void
677mue_set_macaddr(struct usbnet *un) 677mue_set_macaddr(struct usbnet *un)
678{ 678{
679 struct ifnet * const ifp = usbnet_ifp(un); 679 struct ifnet * const ifp = usbnet_ifp(un);
680 const uint8_t *enaddr = CLLADDR(ifp->if_sadl); 680 const uint8_t *enaddr = CLLADDR(ifp->if_sadl);
681 uint32_t lo, hi; 681 uint32_t lo, hi;
682 682
683 lo = MUE_ENADDR_LO(enaddr); 683 lo = MUE_ENADDR_LO(enaddr);
684 hi = MUE_ENADDR_HI(enaddr); 684 hi = MUE_ENADDR_HI(enaddr);
685 685
686 mue_csr_write(un, MUE_RX_ADDRL, lo); 686 mue_csr_write(un, MUE_RX_ADDRL, lo);
687 mue_csr_write(un, MUE_RX_ADDRH, hi); 687 mue_csr_write(un, MUE_RX_ADDRH, hi);
688} 688}
689 689
690static int 690static int
691mue_get_macaddr(struct usbnet *un, prop_dictionary_t dict) 691mue_get_macaddr(struct usbnet *un, prop_dictionary_t dict)
692{ 692{
693 prop_data_t eaprop; 693 prop_data_t eaprop;
694 uint32_t low, high; 694 uint32_t low, high;
695 695
696 if (!(un->un_flags & LAN7500)) { 696 if (!(un->un_flags & LAN7500)) {
697 low = mue_csr_read(un, MUE_RX_ADDRL); 697 low = mue_csr_read(un, MUE_RX_ADDRL);
698 high = mue_csr_read(un, MUE_RX_ADDRH); 698 high = mue_csr_read(un, MUE_RX_ADDRH);
699 un->un_eaddr[5] = (uint8_t)((high >> 8) & 0xff); 699 un->un_eaddr[5] = (uint8_t)((high >> 8) & 0xff);
700 un->un_eaddr[4] = (uint8_t)((high) & 0xff); 700 un->un_eaddr[4] = (uint8_t)((high) & 0xff);
701 un->un_eaddr[3] = (uint8_t)((low >> 24) & 0xff); 701 un->un_eaddr[3] = (uint8_t)((low >> 24) & 0xff);
702 un->un_eaddr[2] = (uint8_t)((low >> 16) & 0xff); 702 un->un_eaddr[2] = (uint8_t)((low >> 16) & 0xff);
703 un->un_eaddr[1] = (uint8_t)((low >> 8) & 0xff); 703 un->un_eaddr[1] = (uint8_t)((low >> 8) & 0xff);
704 un->un_eaddr[0] = (uint8_t)((low) & 0xff); 704 un->un_eaddr[0] = (uint8_t)((low) & 0xff);
705 if (ETHER_IS_VALID(un->un_eaddr)) 705 if (ETHER_IS_VALID(un->un_eaddr))
706 return 0; 706 return 0;
707 else 707 else
708 DPRINTF(un, "registers: %s\n", 708 DPRINTF(un, "registers: %s\n",
709 ether_sprintf(un->un_eaddr)); 709 ether_sprintf(un->un_eaddr));
710 } 710 }
711 711
712 if (mue_eeprom_present(un) && !mue_read_eeprom(un, un->un_eaddr, 712 if (mue_eeprom_present(un) && !mue_read_eeprom(un, un->un_eaddr,
713 MUE_E2P_MAC_OFFSET, ETHER_ADDR_LEN)) { 713 MUE_E2P_MAC_OFFSET, ETHER_ADDR_LEN)) {
714 if (ETHER_IS_VALID(un->un_eaddr)) 714 if (ETHER_IS_VALID(un->un_eaddr))
715 return 0; 715 return 0;
716 else 716 else
717 DPRINTF(un, "EEPROM: %s\n", 717 DPRINTF(un, "EEPROM: %s\n",
718 ether_sprintf(un->un_eaddr)); 718 ether_sprintf(un->un_eaddr));
719 } 719 }
720 720
721 if (mue_read_otp(un, un->un_eaddr, MUE_OTP_MAC_OFFSET, 721 if (mue_read_otp(un, un->un_eaddr, MUE_OTP_MAC_OFFSET,
722 ETHER_ADDR_LEN) == 0) { 722 ETHER_ADDR_LEN) == 0) {
723 if (ETHER_IS_VALID(un->un_eaddr)) 723 if (ETHER_IS_VALID(un->un_eaddr))
724 return 0; 724 return 0;
725 else 725 else
726 DPRINTF(un, "OTP: %s\n", 726 DPRINTF(un, "OTP: %s\n",
727 ether_sprintf(un->un_eaddr)); 727 ether_sprintf(un->un_eaddr));
728 } 728 }
729 729
730 /* 730 /*
731 * Other MD methods. This should be tried only if other methods fail. 731 * Other MD methods. This should be tried only if other methods fail.
732 * Otherwise, MAC address for internal device can be assinged to 732 * Otherwise, MAC address for internal device can be assinged to
733 * external devices on Raspberry Pi, for example. 733 * external devices on Raspberry Pi, for example.
734 */ 734 */
735 eaprop = prop_dictionary_get(dict, "mac-address"); 735 eaprop = prop_dictionary_get(dict, "mac-address");
736 if (eaprop != NULL) { 736 if (eaprop != NULL) {
737 KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA); 737 KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA);
738 KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN); 738 KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN);
739 memcpy(un->un_eaddr, prop_data_value(eaprop), 739 memcpy(un->un_eaddr, prop_data_value(eaprop),
740 ETHER_ADDR_LEN); 740 ETHER_ADDR_LEN);
741 if (ETHER_IS_VALID(un->un_eaddr)) 741 if (ETHER_IS_VALID(un->un_eaddr))
742 return 0; 742 return 0;
743 else 743 else
744 DPRINTF(un, "prop_dictionary_get: %s\n", 744 DPRINTF(un, "prop_dictionary_get: %s\n",
745 ether_sprintf(un->un_eaddr)); 745 ether_sprintf(un->un_eaddr));
746 } 746 }
747 747
748 return 1; 748 return 1;
749} 749}
750 750
751 751
752/*  752/*
753 * Probe for a Microchip chip. 753 * Probe for a Microchip chip.
754 */ 754 */
755static int 755static int
756mue_match(device_t parent, cfdata_t match, void *aux) 756mue_match(device_t parent, cfdata_t match, void *aux)
757{ 757{
758 struct usb_attach_arg *uaa = aux; 758 struct usb_attach_arg *uaa = aux;
759 759
760 return (MUE_LOOKUP(uaa) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 760 return (MUE_LOOKUP(uaa) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
761} 761}
762 762
763static void 763static void
764mue_attach(device_t parent, device_t self, void *aux) 764mue_attach(device_t parent, device_t self, void *aux)
765{ 765{
766 USBNET_MII_DECL_DEFAULT(unm); 766 USBNET_MII_DECL_DEFAULT(unm);
767 struct usbnet * const un = device_private(self); 767 struct usbnet * const un = device_private(self);
768 prop_dictionary_t dict = device_properties(self); 768 prop_dictionary_t dict = device_properties(self);
769 struct usb_attach_arg *uaa = aux; 769 struct usb_attach_arg *uaa = aux;
770 struct usbd_device *dev = uaa->uaa_device; 770 struct usbd_device *dev = uaa->uaa_device;
771 usb_interface_descriptor_t *id; 771 usb_interface_descriptor_t *id;
772 usb_endpoint_descriptor_t *ed; 772 usb_endpoint_descriptor_t *ed;
773 char *devinfop; 773 char *devinfop;
774 usbd_status err; 774 usbd_status err;
775 const char *descr; 775 const char *descr;
776 uint32_t id_rev; 776 uint32_t id_rev;
777 uint8_t i; 777 uint8_t i;
778 unsigned rx_list_cnt, tx_list_cnt; 778 unsigned rx_list_cnt, tx_list_cnt;
779 unsigned rx_bufsz; 779 unsigned rx_bufsz;
780 780
781 aprint_naive("\n"); 781 aprint_naive("\n");
782 aprint_normal("\n"); 782 aprint_normal("\n");
783 devinfop = usbd_devinfo_alloc(dev, 0); 783 devinfop = usbd_devinfo_alloc(dev, 0);
784 aprint_normal_dev(self, "%s\n", devinfop); 784 aprint_normal_dev(self, "%s\n", devinfop);
785 usbd_devinfo_free(devinfop); 785 usbd_devinfo_free(devinfop);
786 786
787 un->un_dev = self; 787 un->un_dev = self;
788 un->un_udev = dev; 788 un->un_udev = dev;
789 un->un_sc = un; 789 un->un_sc = un;
790 un->un_ops = &mue_ops; 790 un->un_ops = &mue_ops;
791 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 791 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
792 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 792 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
793 793
794#define MUE_CONFIG_NO 1 794#define MUE_CONFIG_NO 1
795 err = usbd_set_config_no(dev, MUE_CONFIG_NO, 1); 795 err = usbd_set_config_no(dev, MUE_CONFIG_NO, 1);
796 if (err) { 796 if (err) {
797 aprint_error_dev(self, "failed to set configuration: %s\n", 797 aprint_error_dev(self, "failed to set configuration: %s\n",
798 usbd_errstr(err)); 798 usbd_errstr(err));
799 return; 799 return;
800 } 800 }
801 801
802#define MUE_IFACE_IDX 0 802#define MUE_IFACE_IDX 0
803 err = usbd_device2interface_handle(dev, MUE_IFACE_IDX, &un->un_iface); 803 err = usbd_device2interface_handle(dev, MUE_IFACE_IDX, &un->un_iface);
804 if (err) { 804 if (err) {
805 aprint_error_dev(self, "failed to get interface handle: %s\n", 805 aprint_error_dev(self, "failed to get interface handle: %s\n",
806 usbd_errstr(err)); 806 usbd_errstr(err));
807 return; 807 return;
808 } 808 }
809 809
810 un->un_flags = MUE_LOOKUP(uaa)->mue_flags; 810 un->un_flags = MUE_LOOKUP(uaa)->mue_flags;
811 811
812 /* Decide on what our bufsize will be. */ 812 /* Decide on what our bufsize will be. */
813 if (un->un_flags & LAN7500) { 813 if (un->un_flags & LAN7500) {
814 rx_bufsz = (un->un_udev->ud_speed == USB_SPEED_HIGH) ? 814 rx_bufsz = (un->un_udev->ud_speed == USB_SPEED_HIGH) ?
815 MUE_7500_HS_RX_BUFSIZE : MUE_7500_FS_RX_BUFSIZE; 815 MUE_7500_HS_RX_BUFSIZE : MUE_7500_FS_RX_BUFSIZE;
816 rx_list_cnt = 1; 816 rx_list_cnt = 1;
817 tx_list_cnt = 1; 817 tx_list_cnt = 1;
818 } else { 818 } else {
819 rx_bufsz = MUE_7800_RX_BUFSIZE; 819 rx_bufsz = MUE_7800_RX_BUFSIZE;
820 rx_list_cnt = MUE_RX_LIST_CNT; 820 rx_list_cnt = MUE_RX_LIST_CNT;
821 tx_list_cnt = MUE_TX_LIST_CNT; 821 tx_list_cnt = MUE_TX_LIST_CNT;
822 } 822 }
823 823
824 un->un_rx_list_cnt = rx_list_cnt; 824 un->un_rx_list_cnt = rx_list_cnt;
825 un->un_tx_list_cnt = tx_list_cnt; 825 un->un_tx_list_cnt = tx_list_cnt;
826 un->un_rx_bufsz = rx_bufsz; 826 un->un_rx_bufsz = rx_bufsz;
827 un->un_tx_bufsz = MUE_TX_BUFSIZE; 827 un->un_tx_bufsz = MUE_TX_BUFSIZE;
828 828
829 /* Find endpoints. */ 829 /* Find endpoints. */
830 id = usbd_get_interface_descriptor(un->un_iface); 830 id = usbd_get_interface_descriptor(un->un_iface);
831 for (i = 0; i < id->bNumEndpoints; i++) { 831 for (i = 0; i < id->bNumEndpoints; i++) {
832 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 832 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
833 if (ed == NULL) { 833 if (ed == NULL) {
834 aprint_error_dev(self, "failed to get ep %hhd\n", i); 834 aprint_error_dev(self, "failed to get ep %hhd\n", i);
835 return; 835 return;
836 } 836 }
837 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 837 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
838 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 838 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
839 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 839 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
840 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 840 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
841 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 841 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
842 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 842 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
843 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 843 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
844 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 844 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
845 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 845 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
846 } 846 }
847 } 847 }
848 if (un->un_ed[USBNET_ENDPT_RX] == 0 || 848 if (un->un_ed[USBNET_ENDPT_RX] == 0 ||
849 un->un_ed[USBNET_ENDPT_TX] == 0 || 849 un->un_ed[USBNET_ENDPT_TX] == 0 ||
850 un->un_ed[USBNET_ENDPT_INTR] == 0) { 850 un->un_ed[USBNET_ENDPT_INTR] == 0) {
851 aprint_error_dev(self, "failed to find endpoints\n"); 851 aprint_error_dev(self, "failed to find endpoints\n");
852 return; 852 return;
853 } 853 }
854 854
855 /* Set these up now for mue_cmd(). */ 855 /* Set these up now for mue_cmd(). */
856 usbnet_attach(un, "muedet"); 856 usbnet_attach(un, "muedet");
857 857
858 un->un_phyno = 1; 858 un->un_phyno = 1;
859 859
860 if (mue_chip_init(un)) { 860 if (mue_chip_init(un)) {
861 aprint_error_dev(self, "failed to initialize chip\n"); 861 aprint_error_dev(self, "failed to initialize chip\n");
862 return; 862 return;
863 } 863 }
864 864
865 /* A Microchip chip was detected. Inform the world. */ 865 /* A Microchip chip was detected. Inform the world. */
866 id_rev = mue_csr_read(un, MUE_ID_REV); 866 id_rev = mue_csr_read(un, MUE_ID_REV);
867 descr = (un->un_flags & LAN7500) ? "LAN7500" : "LAN7800"; 867 descr = (un->un_flags & LAN7500) ? "LAN7500" : "LAN7800";
868 aprint_normal_dev(self, "%s id %#x rev %#x\n", descr, 868 aprint_normal_dev(self, "%s id %#x rev %#x\n", descr,
869 (unsigned)__SHIFTOUT(id_rev, MUE_ID_REV_ID), 869 (unsigned)__SHIFTOUT(id_rev, MUE_ID_REV_ID),
870 (unsigned)__SHIFTOUT(id_rev, MUE_ID_REV_REV)); 870 (unsigned)__SHIFTOUT(id_rev, MUE_ID_REV_REV));
871 871
872 if (mue_get_macaddr(un, dict)) { 872 if (mue_get_macaddr(un, dict)) {
873 aprint_error_dev(self, "failed to read MAC address\n"); 873 aprint_error_dev(self, "failed to read MAC address\n");
874 return; 874 return;
875 } 875 }
876 876
877 struct ifnet *ifp = usbnet_ifp(un); 877 struct ifnet *ifp = usbnet_ifp(un);
878 ifp->if_capabilities = IFCAP_TSOv4 | IFCAP_TSOv6 | 878 ifp->if_capabilities = IFCAP_TSOv4 | IFCAP_TSOv6 |
879 IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx | 879 IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
880 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx | 880 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
881 IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx | 881 IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
882 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx | 882 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx |
883 IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx; 883 IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx;
884 884
885 struct ethercom *ec = usbnet_ec(un); 885 struct ethercom *ec = usbnet_ec(un);
886 ec->ec_capabilities = ETHERCAP_VLAN_MTU; 886 ec->ec_capabilities = ETHERCAP_VLAN_MTU;
887#if 0 /* XXX not yet */ 887#if 0 /* XXX not yet */
888 ec->ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU; 888 ec->ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU;
889#endif 889#endif
890 890
891 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 891 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
892 0, &unm); 892 0, &unm);
893} 893}
894 894
895static unsigned 895static unsigned
896mue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 896mue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
897{ 897{
898 struct ifnet * const ifp = usbnet_ifp(un); 898 struct ifnet * const ifp = usbnet_ifp(un);
899 struct mue_txbuf_hdr hdr; 899 struct mue_txbuf_hdr hdr;
900 uint32_t tx_cmd_a, tx_cmd_b; 900 uint32_t tx_cmd_a, tx_cmd_b;
901 int csum, len, rv; 901 int csum, len, rv;
902 bool tso, ipe, tpe; 902 bool tso, ipe, tpe;
903 903
904 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(hdr)) 904 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(hdr))
905 return 0; 905 return 0;
906 906
907 csum = m->m_pkthdr.csum_flags; 907 csum = m->m_pkthdr.csum_flags;
908 tso = csum & (M_CSUM_TSOv4 | M_CSUM_TSOv6); 908 tso = csum & (M_CSUM_TSOv4 | M_CSUM_TSOv6);
909 ipe = csum & M_CSUM_IPv4; 909 ipe = csum & M_CSUM_IPv4;
910 tpe = csum & (M_CSUM_TCPv4 | M_CSUM_UDPv4 | 910 tpe = csum & (M_CSUM_TCPv4 | M_CSUM_UDPv4 |
911 M_CSUM_TCPv6 | M_CSUM_UDPv6); 911 M_CSUM_TCPv6 | M_CSUM_UDPv6);
912 912
913 len = m->m_pkthdr.len; 913 len = m->m_pkthdr.len;
914 if (__predict_false((!tso && len > (int)MUE_FRAME_LEN(ifp->if_mtu)) || 914 if (__predict_false((!tso && len > (int)MUE_FRAME_LEN(ifp->if_mtu)) ||
915 ( tso && len > MUE_TSO_FRAME_LEN))) { 915 ( tso && len > MUE_TSO_FRAME_LEN))) {
916 MUE_PRINTF(un, "packet length %d\n too long", len); 916 MUE_PRINTF(un, "packet length %d\n too long", len);
917 return 0; 917 return 0;
918 } 918 }
919 919
920 KASSERT((len & ~MUE_TX_CMD_A_LEN_MASK) == 0); 920 KASSERT((len & ~MUE_TX_CMD_A_LEN_MASK) == 0);
921 tx_cmd_a = len | MUE_TX_CMD_A_FCS; 921 tx_cmd_a = len | MUE_TX_CMD_A_FCS;
922 922
923 if (tso) { 923 if (tso) {
924 tx_cmd_a |= MUE_TX_CMD_A_LSO; 924 tx_cmd_a |= MUE_TX_CMD_A_LSO;
925 if (__predict_true(m->m_pkthdr.segsz > MUE_TX_MSS_MIN)) 925 if (__predict_true(m->m_pkthdr.segsz > MUE_TX_MSS_MIN))
926 tx_cmd_b = m->m_pkthdr.segsz; 926 tx_cmd_b = m->m_pkthdr.segsz;
927 else 927 else
928 tx_cmd_b = MUE_TX_MSS_MIN; 928 tx_cmd_b = MUE_TX_MSS_MIN;
929 tx_cmd_b <<= MUE_TX_CMD_B_MSS_SHIFT; 929 tx_cmd_b <<= MUE_TX_CMD_B_MSS_SHIFT;
930 KASSERT((tx_cmd_b & ~MUE_TX_CMD_B_MSS_MASK) == 0); 930 KASSERT((tx_cmd_b & ~MUE_TX_CMD_B_MSS_MASK) == 0);
931 rv = mue_prepare_tso(un, m); 931 rv = mue_prepare_tso(un, m);
932 if (__predict_false(rv)) 932 if (__predict_false(rv))
933 return 0; 933 return 0;
934 } else { 934 } else {
935 if (ipe) 935 if (ipe)
936 tx_cmd_a |= MUE_TX_CMD_A_IPE; 936 tx_cmd_a |= MUE_TX_CMD_A_IPE;
937 if (tpe) 937 if (tpe)
938 tx_cmd_a |= MUE_TX_CMD_A_TPE; 938 tx_cmd_a |= MUE_TX_CMD_A_TPE;
939 tx_cmd_b = 0; 939 tx_cmd_b = 0;
940 } 940 }
941 941
942 hdr.tx_cmd_a = htole32(tx_cmd_a); 942 hdr.tx_cmd_a = htole32(tx_cmd_a);
943 hdr.tx_cmd_b = htole32(tx_cmd_b); 943 hdr.tx_cmd_b = htole32(tx_cmd_b);
944 944
945 memcpy(c->unc_buf, &hdr, sizeof(hdr)); 945 memcpy(c->unc_buf, &hdr, sizeof(hdr));
946 m_copydata(m, 0, len, c->unc_buf + sizeof(hdr)); 946 m_copydata(m, 0, len, c->unc_buf + sizeof(hdr));
947 947
948 return len + sizeof(hdr); 948 return len + sizeof(hdr);
949} 949}
950 950
951/* 951/*
952 * L3 length field should be cleared. 952 * L3 length field should be cleared.
953 */ 953 */
954static int 954static int
955mue_prepare_tso(struct usbnet *un, struct mbuf *m) 955mue_prepare_tso(struct usbnet *un, struct mbuf *m)
956{ 956{
957 struct ether_header *eh; 957 struct ether_header *eh;
958 struct ip *ip; 958 struct ip *ip;
959 struct ip6_hdr *ip6; 959 struct ip6_hdr *ip6;
960 uint16_t type, len = 0; 960 uint16_t type, len = 0;
961 int off; 961 int off;
962 962
963 if (__predict_true(m->m_len >= (int)sizeof(*eh))) { 963 if (__predict_true(m->m_len >= (int)sizeof(*eh))) {
964 eh = mtod(m, struct ether_header *); 964 eh = mtod(m, struct ether_header *);
965 type = eh->ether_type; 965 type = eh->ether_type;
966 } else 966 } else
967 m_copydata(m, offsetof(struct ether_header, ether_type), 967 m_copydata(m, offsetof(struct ether_header, ether_type),
968 sizeof(type), &type); 968 sizeof(type), &type);
969 switch (type = htons(type)) { 969 switch (type = htons(type)) {
970 case ETHERTYPE_IP: 970 case ETHERTYPE_IP:
971 case ETHERTYPE_IPV6: 971 case ETHERTYPE_IPV6:
972 off = ETHER_HDR_LEN; 972 off = ETHER_HDR_LEN;
973 break; 973 break;
974 case ETHERTYPE_VLAN: 974 case ETHERTYPE_VLAN:
975 off = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 975 off = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
976 break; 976 break;
977 default: 977 default:
978 return EINVAL; 978 return EINVAL;
979 } 979 }
980 980
981 if (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) { 981 if (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) {
982 if (__predict_true(m->m_len >= off + (int)sizeof(*ip))) { 982 if (__predict_true(m->m_len >= off + (int)sizeof(*ip))) {
983 ip = (void *)(mtod(m, char *) + off); 983 ip = (void *)(mtod(m, char *) + off);
984 ip->ip_len = 0; 984 ip->ip_len = 0;
985 } else 985 } else
986 m_copyback(m, off + offsetof(struct ip, ip_len), 986 m_copyback(m, off + offsetof(struct ip, ip_len),
987 sizeof(len), &len); 987 sizeof(len), &len);
988 } else { 988 } else {
989 if (__predict_true(m->m_len >= off + (int)sizeof(*ip6))) { 989 if (__predict_true(m->m_len >= off + (int)sizeof(*ip6))) {
990 ip6 = (void *)(mtod(m, char *) + off); 990 ip6 = (void *)(mtod(m, char *) + off);
991 ip6->ip6_plen = 0; 991 ip6->ip6_plen = 0;
992 } else 992 } else
993 m_copyback(m, off + offsetof(struct ip6_hdr, ip6_plen), 993 m_copyback(m, off + offsetof(struct ip6_hdr, ip6_plen),
994 sizeof(len), &len); 994 sizeof(len), &len);
995 } 995 }
996 return 0; 996 return 0;
997} 997}
998 998
999static void 999static void
1000mue_setiff_locked(struct usbnet *un) 1000mue_setiff_locked(struct usbnet *un)
1001{ 1001{
1002 struct ethercom *ec = usbnet_ec(un); 1002 struct ethercom *ec = usbnet_ec(un);
1003 struct ifnet * const ifp = usbnet_ifp(un); 1003 struct ifnet * const ifp = usbnet_ifp(un);
1004 const uint8_t *enaddr = CLLADDR(ifp->if_sadl); 1004 const uint8_t *enaddr = CLLADDR(ifp->if_sadl);
1005 struct ether_multi *enm; 1005 struct ether_multi *enm;
1006 struct ether_multistep step; 1006 struct ether_multistep step;
1007 uint32_t pfiltbl[MUE_NUM_ADDR_FILTX][2]; 1007 uint32_t pfiltbl[MUE_NUM_ADDR_FILTX][2];
1008 uint32_t hashtbl[MUE_DP_SEL_VHF_HASH_LEN]; 1008 uint32_t hashtbl[MUE_DP_SEL_VHF_HASH_LEN];
1009 uint32_t reg, rxfilt, h, hireg, loreg; 1009 uint32_t reg, rxfilt, h, hireg, loreg;
1010 size_t i; 1010 size_t i;
1011 1011
1012 if (usbnet_isdying(un)) 1012 if (usbnet_isdying(un))
1013 return; 1013 return;
1014 1014
1015 /* Clear perfect filter and hash tables. */ 1015 /* Clear perfect filter and hash tables. */
1016 memset(pfiltbl, 0, sizeof(pfiltbl)); 1016 memset(pfiltbl, 0, sizeof(pfiltbl));
1017 memset(hashtbl, 0, sizeof(hashtbl)); 1017 memset(hashtbl, 0, sizeof(hashtbl));
1018 1018
1019 reg = (un->un_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL; 1019 reg = (un->un_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL;
1020 rxfilt = mue_csr_read(un, reg); 1020 rxfilt = mue_csr_read(un, reg);
1021 rxfilt &= ~(MUE_RFE_CTL_PERFECT | MUE_RFE_CTL_MULTICAST_HASH | 1021 rxfilt &= ~(MUE_RFE_CTL_PERFECT | MUE_RFE_CTL_MULTICAST_HASH |
1022 MUE_RFE_CTL_UNICAST | MUE_RFE_CTL_MULTICAST); 1022 MUE_RFE_CTL_UNICAST | MUE_RFE_CTL_MULTICAST);
1023 1023
1024 /* Always accept broadcast frames. */ 1024 /* Always accept broadcast frames. */
1025 rxfilt |= MUE_RFE_CTL_BROADCAST; 1025 rxfilt |= MUE_RFE_CTL_BROADCAST;
1026 1026
1027 if (ifp->if_flags & IFF_PROMISC) { 1027 if (ifp->if_flags & IFF_PROMISC) {
1028 rxfilt |= MUE_RFE_CTL_UNICAST; 1028 rxfilt |= MUE_RFE_CTL_UNICAST;
1029allmulti: rxfilt |= MUE_RFE_CTL_MULTICAST; 1029allmulti: rxfilt |= MUE_RFE_CTL_MULTICAST;
1030 ifp->if_flags |= IFF_ALLMULTI; 1030 ifp->if_flags |= IFF_ALLMULTI;
1031 if (ifp->if_flags & IFF_PROMISC) 1031 if (ifp->if_flags & IFF_PROMISC)
1032 DPRINTF(un, "promisc\n"); 1032 DPRINTF(un, "promisc\n");
1033 else 1033 else
1034 DPRINTF(un, "allmulti\n"); 1034 DPRINTF(un, "allmulti\n");
1035 } else { 1035 } else {
1036 /* Now program new ones. */ 1036 /* Now program new ones. */
1037 pfiltbl[0][0] = MUE_ENADDR_HI(enaddr) | MUE_ADDR_FILTX_VALID; 1037 pfiltbl[0][0] = MUE_ENADDR_HI(enaddr) | MUE_ADDR_FILTX_VALID;
1038 pfiltbl[0][1] = MUE_ENADDR_LO(enaddr); 1038 pfiltbl[0][1] = MUE_ENADDR_LO(enaddr);
1039 i = 1; 1039 i = 1;
1040 ETHER_LOCK(ec); 1040 ETHER_LOCK(ec);
1041 ETHER_FIRST_MULTI(step, ec, enm); 1041 ETHER_FIRST_MULTI(step, ec, enm);
1042 while (enm != NULL) { 1042 while (enm != NULL) {
1043 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1043 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1044 ETHER_ADDR_LEN)) { 1044 ETHER_ADDR_LEN)) {
1045 memset(pfiltbl, 0, sizeof(pfiltbl)); 1045 memset(pfiltbl, 0, sizeof(pfiltbl));
1046 memset(hashtbl, 0, sizeof(hashtbl)); 1046 memset(hashtbl, 0, sizeof(hashtbl));
1047 rxfilt &= ~MUE_RFE_CTL_MULTICAST_HASH; 1047 rxfilt &= ~MUE_RFE_CTL_MULTICAST_HASH;
1048 ETHER_UNLOCK(ec); 1048 ETHER_UNLOCK(ec);
1049 goto allmulti; 1049 goto allmulti;
1050 } 1050 }
1051 if (i < MUE_NUM_ADDR_FILTX) { 1051 if (i < MUE_NUM_ADDR_FILTX) {
1052 /* Use perfect address table if possible. */ 1052 /* Use perfect address table if possible. */
1053 pfiltbl[i][0] = MUE_ENADDR_HI(enm->enm_addrlo) | 1053 pfiltbl[i][0] = MUE_ENADDR_HI(enm->enm_addrlo) |
1054 MUE_ADDR_FILTX_VALID; 1054 MUE_ADDR_FILTX_VALID;
1055 pfiltbl[i][1] = MUE_ENADDR_LO(enm->enm_addrlo); 1055 pfiltbl[i][1] = MUE_ENADDR_LO(enm->enm_addrlo);
1056 } else { 1056 } else {
1057 /* Otherwise, use hash table. */ 1057 /* Otherwise, use hash table. */
1058 rxfilt |= MUE_RFE_CTL_MULTICAST_HASH; 1058 rxfilt |= MUE_RFE_CTL_MULTICAST_HASH;
1059 h = (ether_crc32_be(enm->enm_addrlo, 1059 h = (ether_crc32_be(enm->enm_addrlo,
1060 ETHER_ADDR_LEN) >> 23) & 0x1ff; 1060 ETHER_ADDR_LEN) >> 23) & 0x1ff;
1061 hashtbl[h / 32] |= 1 << (h % 32); 1061 hashtbl[h / 32] |= 1 << (h % 32);
1062 } 1062 }
1063 i++; 1063 i++;
1064 ETHER_NEXT_MULTI(step, enm); 1064 ETHER_NEXT_MULTI(step, enm);
1065 } 1065 }
1066 ETHER_UNLOCK(ec); 1066 ETHER_UNLOCK(ec);
1067 rxfilt |= MUE_RFE_CTL_PERFECT; 1067 rxfilt |= MUE_RFE_CTL_PERFECT;
1068 ifp->if_flags &= ~IFF_ALLMULTI; 1068 ifp->if_flags &= ~IFF_ALLMULTI;
1069 if (rxfilt & MUE_RFE_CTL_MULTICAST_HASH) 1069 if (rxfilt & MUE_RFE_CTL_MULTICAST_HASH)
1070 DPRINTF(un, "perfect filter and hash tables\n"); 1070 DPRINTF(un, "perfect filter and hash tables\n");
1071 else 1071 else
1072 DPRINTF(un, "perfect filter\n"); 1072 DPRINTF(un, "perfect filter\n");
1073 } 1073 }
1074 1074
1075 for (i = 0; i < MUE_NUM_ADDR_FILTX; i++) { 1075 for (i = 0; i < MUE_NUM_ADDR_FILTX; i++) {
1076 hireg = (un->un_flags & LAN7500) ? 1076 hireg = (un->un_flags & LAN7500) ?
1077 MUE_7500_ADDR_FILTX(i) : MUE_7800_ADDR_FILTX(i); 1077 MUE_7500_ADDR_FILTX(i) : MUE_7800_ADDR_FILTX(i);
1078 loreg = hireg + 4; 1078 loreg = hireg + 4;
1079 mue_csr_write(un, hireg, 0); 1079 mue_csr_write(un, hireg, 0);
1080 mue_csr_write(un, loreg, pfiltbl[i][1]); 1080 mue_csr_write(un, loreg, pfiltbl[i][1]);
1081 mue_csr_write(un, hireg, pfiltbl[i][0]); 1081 mue_csr_write(un, hireg, pfiltbl[i][0]);
1082 } 1082 }
1083 1083
1084 mue_dataport_write(un, MUE_DP_SEL_VHF, MUE_DP_SEL_VHF_VLAN_LEN, 1084 mue_dataport_write(un, MUE_DP_SEL_VHF, MUE_DP_SEL_VHF_VLAN_LEN,
1085 MUE_DP_SEL_VHF_HASH_LEN, hashtbl); 1085 MUE_DP_SEL_VHF_HASH_LEN, hashtbl);
1086 1086
1087 mue_csr_write(un, reg, rxfilt); 1087 mue_csr_write(un, reg, rxfilt);
1088} 1088}
1089 1089
1090static void 1090static void
1091mue_sethwcsum_locked(struct usbnet *un) 1091mue_sethwcsum_locked(struct usbnet *un)
1092{ 1092{
1093 struct ifnet * const ifp = usbnet_ifp(un); 1093 struct ifnet * const ifp = usbnet_ifp(un);
1094 uint32_t reg, val; 1094 uint32_t reg, val;
1095 1095
1096 reg = (un->un_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL; 1096 reg = (un->un_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL;
1097 val = mue_csr_read(un, reg); 1097 val = mue_csr_read(un, reg);
1098 1098
1099 if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) { 1099 if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) {
1100 DPRINTF(un, "RX IPv4 hwcsum enabled\n"); 1100 DPRINTF(un, "RX IPv4 hwcsum enabled\n");
1101 val |= MUE_RFE_CTL_IP_COE; 1101 val |= MUE_RFE_CTL_IP_COE;
1102 } else { 1102 } else {
1103 DPRINTF(un, "RX IPv4 hwcsum disabled\n"); 1103 DPRINTF(un, "RX IPv4 hwcsum disabled\n");
1104 val &= ~MUE_RFE_CTL_IP_COE; 1104 val &= ~MUE_RFE_CTL_IP_COE;
1105 } 1105 }
1106 1106
1107 if (ifp->if_capenable & 1107 if (ifp->if_capenable &
1108 (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | 1108 (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |
1109 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx)) { 1109 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx)) {
1110 DPRINTF(un, "RX L4 hwcsum enabled\n"); 1110 DPRINTF(un, "RX L4 hwcsum enabled\n");
1111 val |= MUE_RFE_CTL_TCPUDP_COE; 1111 val |= MUE_RFE_CTL_TCPUDP_COE;
1112 } else { 1112 } else {
1113 DPRINTF(un, "RX L4 hwcsum disabled\n"); 1113 DPRINTF(un, "RX L4 hwcsum disabled\n");
1114 val &= ~MUE_RFE_CTL_TCPUDP_COE; 1114 val &= ~MUE_RFE_CTL_TCPUDP_COE;
1115 } 1115 }
1116 1116
1117 val &= ~MUE_RFE_CTL_VLAN_FILTER; 1117 val &= ~MUE_RFE_CTL_VLAN_FILTER;
1118 1118
1119 mue_csr_write(un, reg, val); 1119 mue_csr_write(un, reg, val);
1120} 1120}
1121 1121
1122static void 1122static void
1123mue_setmtu_locked(struct usbnet *un) 1123mue_setmtu_locked(struct usbnet *un)
1124{ 1124{
1125 struct ifnet * const ifp = usbnet_ifp(un); 1125 struct ifnet * const ifp = usbnet_ifp(un);
1126 uint32_t val; 1126 uint32_t val;
1127 1127
1128 /* Set the maximum frame size. */ 1128 /* Set the maximum frame size. */
1129 MUE_CLRBIT(un, MUE_MAC_RX, MUE_MAC_RX_RXEN); 1129 MUE_CLRBIT(un, MUE_MAC_RX, MUE_MAC_RX_RXEN);
1130 val = mue_csr_read(un, MUE_MAC_RX); 1130 val = mue_csr_read(un, MUE_MAC_RX);
1131 val &= ~MUE_MAC_RX_MAX_SIZE_MASK; 1131 val &= ~MUE_MAC_RX_MAX_SIZE_MASK;
1132 val |= MUE_MAC_RX_MAX_LEN(MUE_FRAME_LEN(ifp->if_mtu)); 1132 val |= MUE_MAC_RX_MAX_LEN(MUE_FRAME_LEN(ifp->if_mtu));
1133 mue_csr_write(un, MUE_MAC_RX, val); 1133 mue_csr_write(un, MUE_MAC_RX, val);
1134 MUE_SETBIT(un, MUE_MAC_RX, MUE_MAC_RX_RXEN); 1134 MUE_SETBIT(un, MUE_MAC_RX, MUE_MAC_RX_RXEN);
1135} 1135}
1136 1136
1137static void 1137static void
1138mue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 1138mue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
1139{ 1139{
1140 struct ifnet * const ifp = usbnet_ifp(un); 1140 struct ifnet * const ifp = usbnet_ifp(un);
1141 struct mue_rxbuf_hdr *hdrp; 1141 struct mue_rxbuf_hdr *hdrp;
1142 uint32_t rx_cmd_a; 1142 uint32_t rx_cmd_a;
1143 uint16_t pktlen; 1143 uint16_t pktlen;
1144 int csum; 1144 int csum;
1145 uint8_t *buf = c->unc_buf; 1145 uint8_t *buf = c->unc_buf;
1146 bool v6; 1146 bool v6;
1147 1147
1148 KASSERTMSG(total_len <= un->un_rx_bufsz, "%u vs %u", 1148 KASSERTMSG(total_len <= un->un_rx_bufsz, "%u vs %u",
1149 total_len, un->un_rx_bufsz); 1149 total_len, un->un_rx_bufsz);
1150 1150
1151 do { 1151 do {
1152 if (__predict_false(total_len < sizeof(*hdrp))) { 1152 if (__predict_false(total_len < sizeof(*hdrp))) {
1153 MUE_PRINTF(un, "packet length %u too short\n", total_len); 1153 MUE_PRINTF(un, "packet length %u too short\n", total_len);
1154 if_statinc(ifp, if_ierrors); 1154 if_statinc(ifp, if_ierrors);
1155 return; 1155 return;
1156 } 1156 }
1157 1157
1158 hdrp = (struct mue_rxbuf_hdr *)buf; 1158 hdrp = (struct mue_rxbuf_hdr *)buf;
1159 rx_cmd_a = le32toh(hdrp->rx_cmd_a); 1159 rx_cmd_a = le32toh(hdrp->rx_cmd_a);
1160 1160
1161 if (__predict_false(rx_cmd_a & MUE_RX_CMD_A_ERRORS)) { 1161 if (__predict_false(rx_cmd_a & MUE_RX_CMD_A_ERRORS)) {
1162 /* 1162 /*
1163 * We cannot use MUE_RX_CMD_A_RED bit here; 1163 * We cannot use MUE_RX_CMD_A_RED bit here;
1164 * it is turned on in the cases of L3/L4 1164 * it is turned on in the cases of L3/L4
1165 * checksum errors which we handle below. 1165 * checksum errors which we handle below.
1166 */ 1166 */
1167 MUE_PRINTF(un, "rx_cmd_a: %#x\n", rx_cmd_a); 1167 MUE_PRINTF(un, "rx_cmd_a: %#x\n", rx_cmd_a);
1168 if_statinc(ifp, if_ierrors); 1168 if_statinc(ifp, if_ierrors);
1169 return; 1169 return;
1170 } 1170 }
1171 1171
1172 pktlen = (uint16_t)(rx_cmd_a & MUE_RX_CMD_A_LEN_MASK); 1172 pktlen = (uint16_t)(rx_cmd_a & MUE_RX_CMD_A_LEN_MASK);
1173 if (un->un_flags & LAN7500) 1173 if (un->un_flags & LAN7500)
1174 pktlen -= 2; 1174 pktlen -= 2;
1175 1175
1176 if (__predict_false(pktlen < ETHER_HDR_LEN + ETHER_CRC_LEN || 1176 if (__predict_false(pktlen < ETHER_HDR_LEN + ETHER_CRC_LEN ||
1177 pktlen > MCLBYTES - ETHER_ALIGN || /* XXX */ 1177 pktlen > MCLBYTES - ETHER_ALIGN || /* XXX */
1178 pktlen + sizeof(*hdrp) > total_len)) { 1178 pktlen + sizeof(*hdrp) > total_len)) {
1179 MUE_PRINTF(un, "invalid packet length %d\n", pktlen); 1179 MUE_PRINTF(un, "invalid packet length %d\n", pktlen);
1180 if_statinc(ifp, if_ierrors); 1180 if_statinc(ifp, if_ierrors);
1181 return; 1181 return;
1182 } 1182 }
1183 1183
1184 if (__predict_false(rx_cmd_a & MUE_RX_CMD_A_ICSM)) { 1184 if (__predict_false(rx_cmd_a & MUE_RX_CMD_A_ICSM)) {
1185 csum = 0; 1185 csum = 0;
1186 } else { 1186 } else {
1187 v6 = rx_cmd_a & MUE_RX_CMD_A_IPV; 1187 v6 = rx_cmd_a & MUE_RX_CMD_A_IPV;
1188 switch (rx_cmd_a & MUE_RX_CMD_A_PID) { 1188 switch (rx_cmd_a & MUE_RX_CMD_A_PID) {
1189 case MUE_RX_CMD_A_PID_TCP: 1189 case MUE_RX_CMD_A_PID_TCP:
1190 csum = v6 ? 1190 csum = v6 ?
1191 M_CSUM_TCPv6 : M_CSUM_IPv4 | M_CSUM_TCPv4; 1191 M_CSUM_TCPv6 : M_CSUM_IPv4 | M_CSUM_TCPv4;
1192 break; 1192 break;
1193 case MUE_RX_CMD_A_PID_UDP: 1193 case MUE_RX_CMD_A_PID_UDP:
1194 csum = v6 ? 1194 csum = v6 ?
1195 M_CSUM_UDPv6 : M_CSUM_IPv4 | M_CSUM_UDPv4; 1195 M_CSUM_UDPv6 : M_CSUM_IPv4 | M_CSUM_UDPv4;
1196 break; 1196 break;
1197 case MUE_RX_CMD_A_PID_IP: 1197 case MUE_RX_CMD_A_PID_IP:
1198 csum = v6 ? 0 : M_CSUM_IPv4; 1198 csum = v6 ? 0 : M_CSUM_IPv4;
1199 break; 1199 break;
1200 default: 1200 default:
1201 csum = 0; 1201 csum = 0;
1202 break; 1202 break;
1203 } 1203 }
1204 csum &= ifp->if_csum_flags_rx; 1204 csum &= ifp->if_csum_flags_rx;
1205 if (__predict_false((csum & M_CSUM_IPv4) && 1205 if (__predict_false((csum & M_CSUM_IPv4) &&
1206 (rx_cmd_a & MUE_RX_CMD_A_ICE))) 1206 (rx_cmd_a & MUE_RX_CMD_A_ICE)))
1207 csum |= M_CSUM_IPv4_BAD; 1207 csum |= M_CSUM_IPv4_BAD;
1208 if (__predict_false((csum & ~M_CSUM_IPv4) && 1208 if (__predict_false((csum & ~M_CSUM_IPv4) &&
1209 (rx_cmd_a & MUE_RX_CMD_A_TCE))) 1209 (rx_cmd_a & MUE_RX_CMD_A_TCE)))
1210 csum |= M_CSUM_TCP_UDP_BAD; 1210 csum |= M_CSUM_TCP_UDP_BAD;
1211 } 1211 }
1212 1212
1213 usbnet_enqueue(un, buf + sizeof(*hdrp), pktlen, csum, 1213 usbnet_enqueue(un, buf + sizeof(*hdrp), pktlen, csum,
1214 0, M_HASFCS); 1214 0, M_HASFCS);
1215 1215
1216 /* Attention: sizeof(hdr) = 10 */ 1216 /* Attention: sizeof(hdr) = 10 */
1217 pktlen = roundup(pktlen + sizeof(*hdrp), 4); 1217 pktlen = roundup(pktlen + sizeof(*hdrp), 4);
1218 if (pktlen > total_len) 1218 if (pktlen > total_len)
1219 pktlen = total_len; 1219 pktlen = total_len;
1220 total_len -= pktlen; 1220 total_len -= pktlen;
1221 buf += pktlen; 1221 buf += pktlen;
1222 } while (total_len > 0); 1222 } while (total_len > 0);
1223} 1223}
1224 1224
1225static int 1225static int
1226mue_init_locked(struct ifnet *ifp) 1226mue_init_locked(struct ifnet *ifp)
1227{ 1227{
1228 struct usbnet * const un = ifp->if_softc; 1228 struct usbnet * const un = ifp->if_softc;
1229 1229
1230 if (usbnet_isdying(un)) { 1230 if (usbnet_isdying(un)) {
1231 DPRINTF(un, "dying\n"); 1231 DPRINTF(un, "dying\n");
1232 return EIO; 1232 return EIO;
1233 } 1233 }
1234 1234
1235 /* Cancel pending I/O and free all TX/RX buffers. */ 1235 /* Cancel pending I/O and free all TX/RX buffers. */
1236 if (ifp->if_flags & IFF_RUNNING) 1236 if (ifp->if_flags & IFF_RUNNING)
1237 usbnet_stop(un, ifp, 1); 1237 usbnet_stop(un, ifp, 1);
1238 1238
1239 mue_reset(un); 1239 mue_reset(un);
1240 1240
1241 /* Set MAC address. */ 1241 /* Set MAC address. */
1242 mue_set_macaddr(un); 1242 mue_set_macaddr(un);
1243 1243
1244 /* Load the multicast filter. */ 1244 /* Load the multicast filter. */
1245 mue_setiff_locked(un); 1245 mue_setiff_locked(un);
1246 1246
1247 /* TCP/UDP checksum offload engines. */ 1247 /* TCP/UDP checksum offload engines. */
1248 mue_sethwcsum_locked(un); 1248 mue_sethwcsum_locked(un);
1249 1249
1250 /* Set MTU. */ 1250 /* Set MTU. */
1251 mue_setmtu_locked(un); 1251 mue_setmtu_locked(un);
1252 1252
1253 return usbnet_init_rx_tx(un); 1253 return usbnet_init_rx_tx(un);
1254} 1254}
1255 1255
1256static int 1256static int
1257mue_uno_init(struct ifnet *ifp) 1257mue_uno_init(struct ifnet *ifp)
1258{ 1258{
1259 int rv; 1259 int rv;
1260 1260
1261 rv = mue_init_locked(ifp); 1261 rv = mue_init_locked(ifp);
1262 1262
1263 return rv; 1263 return rv;
1264} 1264}
1265 1265
1266static int 1266static int
1267mue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1267mue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1268{ 1268{
1269 struct usbnet * const un = ifp->if_softc; 1269 struct usbnet * const un = ifp->if_softc;
1270 1270
1271 usbnet_lock_core(un); 1271 usbnet_lock_core(un);
1272 usbnet_busy(un); 1272 usbnet_busy(un);
1273 1273
1274 switch (cmd) { 1274 switch (cmd) {
1275 case SIOCSIFCAP: 1275 case SIOCSIFCAP:
1276 mue_sethwcsum_locked(un); 1276 mue_sethwcsum_locked(un);
1277 break; 1277 break;
1278 case SIOCSIFMTU: 1278 case SIOCSIFMTU:
1279 mue_setmtu_locked(un); 1279 mue_setmtu_locked(un);
1280 break; 1280 break;
1281 default: 1281 default:
1282 break; 1282 break;
1283 } 1283 }
1284 1284
1285 usbnet_unbusy(un); 1285 usbnet_unbusy(un);
1286 usbnet_unlock_core(un); 1286 usbnet_unlock_core(un);
1287 1287
1288 return 0; 1288 return 0;
1289} 1289}
1290 1290
1291static void 1291static void
1292mue_uno_mcast(struct ifnet *ifp) 1292mue_uno_mcast(struct ifnet *ifp)
1293{ 1293{
1294 struct usbnet * const un = ifp->if_softc; 1294 struct usbnet * const un = ifp->if_softc;
1295 1295
1296 usbnet_lock_core(un); 1296 usbnet_lock_core(un);
1297 usbnet_busy(un); 
1298 1297
1299 mue_setiff_locked(un); 1298 mue_setiff_locked(un);
1300 1299
1301 usbnet_unbusy(un); 
1302 usbnet_unlock_core(un); 1300 usbnet_unlock_core(un);
1303} 1301}
1304 1302
1305static void 1303static void
1306mue_reset(struct usbnet *un) 1304mue_reset(struct usbnet *un)
1307{ 1305{
1308 if (usbnet_isdying(un)) 1306 if (usbnet_isdying(un))
1309 return; 1307 return;
1310 1308
1311 /* Wait a little while for the chip to get its brains in order. */ 1309 /* Wait a little while for the chip to get its brains in order. */
1312 usbd_delay_ms(un->un_udev, 1); 1310 usbd_delay_ms(un->un_udev, 1);
1313 1311
1314// mue_chip_init(un); /* XXX */ 1312// mue_chip_init(un); /* XXX */
1315} 1313}
1316 1314
1317static void 1315static void
1318mue_uno_stop(struct ifnet *ifp, int disable) 1316mue_uno_stop(struct ifnet *ifp, int disable)
1319{ 1317{
1320 struct usbnet * const un = ifp->if_softc; 1318 struct usbnet * const un = ifp->if_softc;
1321 1319
1322 mue_reset(un); 1320 mue_reset(un);
1323} 1321}
1324 1322
1325#ifdef _MODULE 1323#ifdef _MODULE
1326#include "ioconf.c" 1324#include "ioconf.c"
1327#endif 1325#endif
1328 1326
1329USBNET_MODULE(mue) 1327USBNET_MODULE(mue)

cvs diff -r1.75 -r1.76 src/sys/dev/usb/if_smsc.c (switch to unified diff)

--- src/sys/dev/usb/if_smsc.c 2022/03/03 05:51:17 1.75
+++ src/sys/dev/usb/if_smsc.c 2022/03/03 05:51:27 1.76
@@ -1,1101 +1,1099 @@ @@ -1,1101 +1,1099 @@
1/* $NetBSD: if_smsc.c,v 1.75 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_smsc.c,v 1.76 2022/03/03 05:51:27 riastradh Exp $ */
2 2
3/* $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */ 3/* $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */
4/* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */ 4/* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */
5/*- 5/*-
6 * Copyright (c) 2012 6 * Copyright (c) 2012
7 * Ben Gray <bgray@freebsd.org>. 7 * Ben Gray <bgray@freebsd.org>.
8 * All rights reserved. 8 * All rights reserved.
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.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31/* 31/*
32 * SMSC LAN9xxx devices (http://www.smsc.com/) 32 * SMSC LAN9xxx devices (http://www.smsc.com/)
33 * 33 *
34 * The LAN9500 & LAN9500A devices are stand-alone USB to Ethernet chips that 34 * The LAN9500 & LAN9500A devices are stand-alone USB to Ethernet chips that
35 * support USB 2.0 and 10/100 Mbps Ethernet. 35 * support USB 2.0 and 10/100 Mbps Ethernet.
36 * 36 *
37 * The LAN951x devices are an integrated USB hub and USB to Ethernet adapter. 37 * The LAN951x devices are an integrated USB hub and USB to Ethernet adapter.
38 * The driver only covers the Ethernet part, the standard USB hub driver 38 * The driver only covers the Ethernet part, the standard USB hub driver
39 * supports the hub part. 39 * supports the hub part.
40 * 40 *
41 * This driver is closely modelled on the Linux driver written and copyrighted 41 * This driver is closely modelled on the Linux driver written and copyrighted
42 * by SMSC. 42 * by SMSC.
43 * 43 *
44 * H/W TCP & UDP Checksum Offloading 44 * H/W TCP & UDP Checksum Offloading
45 * --------------------------------- 45 * ---------------------------------
46 * The chip supports both tx and rx offloading of UDP & TCP checksums, this 46 * The chip supports both tx and rx offloading of UDP & TCP checksums, this
47 * feature can be dynamically enabled/disabled. 47 * feature can be dynamically enabled/disabled.
48 * 48 *
49 * RX checksuming is performed across bytes after the IPv4 header to the end of 49 * RX checksuming is performed across bytes after the IPv4 header to the end of
50 * the Ethernet frame, this means if the frame is padded with non-zero values 50 * the Ethernet frame, this means if the frame is padded with non-zero values
51 * the H/W checksum will be incorrect, however the rx code compensates for this. 51 * the H/W checksum will be incorrect, however the rx code compensates for this.
52 * 52 *
53 * TX checksuming is more complicated, the device requires a special header to 53 * TX checksuming is more complicated, the device requires a special header to
54 * be prefixed onto the start of the frame which indicates the start and end 54 * be prefixed onto the start of the frame which indicates the start and end
55 * positions of the UDP or TCP frame. This requires the driver to manually 55 * positions of the UDP or TCP frame. This requires the driver to manually
56 * go through the packet data and decode the headers prior to sending. 56 * go through the packet data and decode the headers prior to sending.
57 * On Linux they generally provide cues to the location of the csum and the 57 * On Linux they generally provide cues to the location of the csum and the
58 * area to calculate it over, on FreeBSD we seem to have to do it all ourselves, 58 * area to calculate it over, on FreeBSD we seem to have to do it all ourselves,
59 * hence this is not as optimal and therefore h/w TX checksum is currently not 59 * hence this is not as optimal and therefore h/w TX checksum is currently not
60 * implemented. 60 * implemented.
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.75 2022/03/03 05:51:17 riastradh Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.76 2022/03/03 05:51:27 riastradh Exp $");
65 65
66#ifdef _KERNEL_OPT 66#ifdef _KERNEL_OPT
67#include "opt_usb.h" 67#include "opt_usb.h"
68#endif 68#endif
69 69
70#include <sys/param.h> 70#include <sys/param.h>
71 71
72#include <dev/usb/usbnet.h> 72#include <dev/usb/usbnet.h>
73#include <dev/usb/usbhist.h> 73#include <dev/usb/usbhist.h>
74 74
75#include <dev/usb/if_smscreg.h> 75#include <dev/usb/if_smscreg.h>
76 76
77#include "ioconf.h" 77#include "ioconf.h"
78 78
79struct smsc_softc { 79struct smsc_softc {
80 struct usbnet smsc_un; 80 struct usbnet smsc_un;
81 81
82 /* 82 /*
83 * The following stores the settings in the mac control (MAC_CSR) 83 * The following stores the settings in the mac control (MAC_CSR)
84 * register 84 * register
85 */ 85 */
86 uint32_t sc_mac_csr; 86 uint32_t sc_mac_csr;
87 uint32_t sc_rev_id; 87 uint32_t sc_rev_id;
88 88
89 uint32_t sc_coe_ctrl; 89 uint32_t sc_coe_ctrl;
90}; 90};
91 91
92#define SMSC_MIN_BUFSZ 2048 92#define SMSC_MIN_BUFSZ 2048
93#define SMSC_MAX_BUFSZ 18944 93#define SMSC_MAX_BUFSZ 18944
94 94
95/* 95/*
96 * Various supported device vendors/products. 96 * Various supported device vendors/products.
97 */ 97 */
98static const struct usb_devno smsc_devs[] = { 98static const struct usb_devno smsc_devs[] = {
99 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN89530 }, 99 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN89530 },
100 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN9530 }, 100 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN9530 },
101 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN9730 }, 101 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN9730 },
102 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500 }, 102 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500 },
103 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500A }, 103 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500A },
104 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500A_ALT }, 104 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500A_ALT },
105 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500A_HAL }, 105 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500A_HAL },
106 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500A_SAL10 }, 106 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500A_SAL10 },
107 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500_ALT }, 107 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500_ALT },
108 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500_SAL10 }, 108 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9500_SAL10 },
109 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505 }, 109 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505 },
110 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505A }, 110 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505A },
111 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505A_HAL }, 111 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505A_HAL },
112 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505A_SAL10 }, 112 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505A_SAL10 },
113 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505_SAL10 }, 113 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9505_SAL10 },
114 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9512_14 }, 114 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9512_14 },
115 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9512_14_ALT }, 115 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9512_14_ALT },
116 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9512_14_SAL10 } 116 { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_SMSC9512_14_SAL10 }
117}; 117};
118 118
119#ifdef USB_DEBUG 119#ifdef USB_DEBUG
120#ifndef USMSC_DEBUG 120#ifndef USMSC_DEBUG
121#define usmscdebug 0 121#define usmscdebug 0
122#else 122#else
123static int usmscdebug = 1; 123static int usmscdebug = 1;
124 124
125SYSCTL_SETUP(sysctl_hw_smsc_setup, "sysctl hw.usmsc setup") 125SYSCTL_SETUP(sysctl_hw_smsc_setup, "sysctl hw.usmsc setup")
126{ 126{
127 int err; 127 int err;
128 const struct sysctlnode *rnode; 128 const struct sysctlnode *rnode;
129 const struct sysctlnode *cnode; 129 const struct sysctlnode *cnode;
130 130
131 err = sysctl_createv(clog, 0, NULL, &rnode, 131 err = sysctl_createv(clog, 0, NULL, &rnode,
132 CTLFLAG_PERMANENT, CTLTYPE_NODE, "usmsc", 132 CTLFLAG_PERMANENT, CTLTYPE_NODE, "usmsc",
133 SYSCTL_DESCR("usmsc global controls"), 133 SYSCTL_DESCR("usmsc global controls"),
134 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 134 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
135 135
136 if (err) 136 if (err)
137 goto fail; 137 goto fail;
138 138
139 /* control debugging printfs */ 139 /* control debugging printfs */
140 err = sysctl_createv(clog, 0, &rnode, &cnode, 140 err = sysctl_createv(clog, 0, &rnode, &cnode,
141 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 141 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
142 "debug", SYSCTL_DESCR("Enable debugging output"), 142 "debug", SYSCTL_DESCR("Enable debugging output"),
143 NULL, 0, &usmscdebug, sizeof(usmscdebug), CTL_CREATE, CTL_EOL); 143 NULL, 0, &usmscdebug, sizeof(usmscdebug), CTL_CREATE, CTL_EOL);
144 if (err) 144 if (err)
145 goto fail; 145 goto fail;
146 146
147 return; 147 return;
148fail: 148fail:
149 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 149 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
150} 150}
151 151
152#endif /* SMSC_DEBUG */ 152#endif /* SMSC_DEBUG */
153#endif /* USB_DEBUG */ 153#endif /* USB_DEBUG */
154 154
155#define DPRINTF(FMT,A,B,C,D) USBHIST_LOG(usmscdebug,FMT,A,B,C,D) 155#define DPRINTF(FMT,A,B,C,D) USBHIST_LOG(usmscdebug,FMT,A,B,C,D)
156#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usmscdebug,N,FMT,A,B,C,D) 156#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usmscdebug,N,FMT,A,B,C,D)
157#define USMSCHIST_FUNC() USBHIST_FUNC() 157#define USMSCHIST_FUNC() USBHIST_FUNC()
158#define USMSCHIST_CALLED() USBHIST_CALLED(usmscdebug) 158#define USMSCHIST_CALLED() USBHIST_CALLED(usmscdebug)
159 159
160#define smsc_warn_printf(un, fmt, args...) \ 160#define smsc_warn_printf(un, fmt, args...) \
161 printf("%s: warning: " fmt, device_xname((un)->un_dev), ##args) 161 printf("%s: warning: " fmt, device_xname((un)->un_dev), ##args)
162 162
163#define smsc_err_printf(un, fmt, args...) \ 163#define smsc_err_printf(un, fmt, args...) \
164 printf("%s: error: " fmt, device_xname((un)->un_dev), ##args) 164 printf("%s: error: " fmt, device_xname((un)->un_dev), ##args)
165 165
166/* Function declarations */ 166/* Function declarations */
167static int smsc_match(device_t, cfdata_t, void *); 167static int smsc_match(device_t, cfdata_t, void *);
168static void smsc_attach(device_t, device_t, void *); 168static void smsc_attach(device_t, device_t, void *);
169 169
170CFATTACH_DECL_NEW(usmsc, sizeof(struct smsc_softc), 170CFATTACH_DECL_NEW(usmsc, sizeof(struct smsc_softc),
171 smsc_match, smsc_attach, usbnet_detach, usbnet_activate); 171 smsc_match, smsc_attach, usbnet_detach, usbnet_activate);
172 172
173static int smsc_chip_init(struct usbnet *); 173static int smsc_chip_init(struct usbnet *);
174static int smsc_setmacaddress(struct usbnet *, const uint8_t *); 174static int smsc_setmacaddress(struct usbnet *, const uint8_t *);
175 175
176static int smsc_uno_init(struct ifnet *); 176static int smsc_uno_init(struct ifnet *);
177static int smsc_init_locked(struct ifnet *); 177static int smsc_init_locked(struct ifnet *);
178static void smsc_uno_stop(struct ifnet *, int); 178static void smsc_uno_stop(struct ifnet *, int);
179 179
180static void smsc_reset(struct smsc_softc *); 180static void smsc_reset(struct smsc_softc *);
181 181
182static void smsc_uno_miibus_statchg(struct ifnet *); 182static void smsc_uno_miibus_statchg(struct ifnet *);
183static int smsc_readreg(struct usbnet *, uint32_t, uint32_t *); 183static int smsc_readreg(struct usbnet *, uint32_t, uint32_t *);
184static int smsc_writereg(struct usbnet *, uint32_t, uint32_t); 184static int smsc_writereg(struct usbnet *, uint32_t, uint32_t);
185static int smsc_wait_for_bits(struct usbnet *, uint32_t, uint32_t); 185static int smsc_wait_for_bits(struct usbnet *, uint32_t, uint32_t);
186static int smsc_uno_miibus_readreg(struct usbnet *, int, int, uint16_t *); 186static int smsc_uno_miibus_readreg(struct usbnet *, int, int, uint16_t *);
187static int smsc_uno_miibus_writereg(struct usbnet *, int, int, uint16_t); 187static int smsc_uno_miibus_writereg(struct usbnet *, int, int, uint16_t);
188 188
189static int smsc_uno_ioctl(struct ifnet *, u_long, void *); 189static int smsc_uno_ioctl(struct ifnet *, u_long, void *);
190static void smsc_uno_mcast(struct ifnet *); 190static void smsc_uno_mcast(struct ifnet *);
191static unsigned smsc_uno_tx_prepare(struct usbnet *, struct mbuf *, 191static unsigned smsc_uno_tx_prepare(struct usbnet *, struct mbuf *,
192 struct usbnet_chain *); 192 struct usbnet_chain *);
193static void smsc_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 193static void smsc_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
194 uint32_t); 194 uint32_t);
195 195
196static const struct usbnet_ops smsc_ops = { 196static const struct usbnet_ops smsc_ops = {
197 .uno_stop = smsc_uno_stop, 197 .uno_stop = smsc_uno_stop,
198 .uno_ioctl = smsc_uno_ioctl, 198 .uno_ioctl = smsc_uno_ioctl,
199 .uno_mcast = smsc_uno_mcast, 199 .uno_mcast = smsc_uno_mcast,
200 .uno_read_reg = smsc_uno_miibus_readreg, 200 .uno_read_reg = smsc_uno_miibus_readreg,
201 .uno_write_reg = smsc_uno_miibus_writereg, 201 .uno_write_reg = smsc_uno_miibus_writereg,
202 .uno_statchg = smsc_uno_miibus_statchg, 202 .uno_statchg = smsc_uno_miibus_statchg,
203 .uno_tx_prepare = smsc_uno_tx_prepare, 203 .uno_tx_prepare = smsc_uno_tx_prepare,
204 .uno_rx_loop = smsc_uno_rx_loop, 204 .uno_rx_loop = smsc_uno_rx_loop,
205 .uno_init = smsc_uno_init, 205 .uno_init = smsc_uno_init,
206}; 206};
207 207
208static int 208static int
209smsc_readreg(struct usbnet *un, uint32_t off, uint32_t *data) 209smsc_readreg(struct usbnet *un, uint32_t off, uint32_t *data)
210{ 210{
211 usb_device_request_t req; 211 usb_device_request_t req;
212 uint32_t buf; 212 uint32_t buf;
213 usbd_status err; 213 usbd_status err;
214 214
215 usbnet_isowned_core(un); 215 usbnet_isowned_core(un);
216 216
217 if (usbnet_isdying(un)) 217 if (usbnet_isdying(un))
218 return 0; 218 return 0;
219 219
220 req.bmRequestType = UT_READ_VENDOR_DEVICE; 220 req.bmRequestType = UT_READ_VENDOR_DEVICE;
221 req.bRequest = SMSC_UR_READ_REG; 221 req.bRequest = SMSC_UR_READ_REG;
222 USETW(req.wValue, 0); 222 USETW(req.wValue, 0);
223 USETW(req.wIndex, off); 223 USETW(req.wIndex, off);
224 USETW(req.wLength, 4); 224 USETW(req.wLength, 4);
225 225
226 err = usbd_do_request(un->un_udev, &req, &buf); 226 err = usbd_do_request(un->un_udev, &req, &buf);
227 if (err != 0) 227 if (err != 0)
228 smsc_warn_printf(un, "Failed to read register 0x%0x\n", off); 228 smsc_warn_printf(un, "Failed to read register 0x%0x\n", off);
229 229
230 *data = le32toh(buf); 230 *data = le32toh(buf);
231 231
232 return err; 232 return err;
233} 233}
234 234
235static int 235static int
236smsc_writereg(struct usbnet *un, uint32_t off, uint32_t data) 236smsc_writereg(struct usbnet *un, uint32_t off, uint32_t data)
237{ 237{
238 usb_device_request_t req; 238 usb_device_request_t req;
239 uint32_t buf; 239 uint32_t buf;
240 usbd_status err; 240 usbd_status err;
241 241
242 usbnet_isowned_core(un); 242 usbnet_isowned_core(un);
243 243
244 if (usbnet_isdying(un)) 244 if (usbnet_isdying(un))
245 return 0; 245 return 0;
246 246
247 buf = htole32(data); 247 buf = htole32(data);
248 248
249 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 249 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
250 req.bRequest = SMSC_UR_WRITE_REG; 250 req.bRequest = SMSC_UR_WRITE_REG;
251 USETW(req.wValue, 0); 251 USETW(req.wValue, 0);
252 USETW(req.wIndex, off); 252 USETW(req.wIndex, off);
253 USETW(req.wLength, 4); 253 USETW(req.wLength, 4);
254 254
255 err = usbd_do_request(un->un_udev, &req, &buf); 255 err = usbd_do_request(un->un_udev, &req, &buf);
256 if (err != 0) 256 if (err != 0)
257 smsc_warn_printf(un, "Failed to write register 0x%0x\n", off); 257 smsc_warn_printf(un, "Failed to write register 0x%0x\n", off);
258 258
259 return err; 259 return err;
260} 260}
261 261
262static int 262static int
263smsc_wait_for_bits(struct usbnet *un, uint32_t reg, uint32_t bits) 263smsc_wait_for_bits(struct usbnet *un, uint32_t reg, uint32_t bits)
264{ 264{
265 uint32_t val; 265 uint32_t val;
266 int err, i; 266 int err, i;
267 267
268 for (i = 0; i < 100; i++) { 268 for (i = 0; i < 100; i++) {
269 if (usbnet_isdying(un)) 269 if (usbnet_isdying(un))
270 return ENXIO; 270 return ENXIO;
271 if ((err = smsc_readreg(un, reg, &val)) != 0) 271 if ((err = smsc_readreg(un, reg, &val)) != 0)
272 return err; 272 return err;
273 if (!(val & bits)) 273 if (!(val & bits))
274 return 0; 274 return 0;
275 DELAY(5); 275 DELAY(5);
276 } 276 }
277 277
278 return 1; 278 return 1;
279} 279}
280 280
281static int 281static int
282smsc_uno_miibus_readreg(struct usbnet *un, int phy, int reg, uint16_t *val) 282smsc_uno_miibus_readreg(struct usbnet *un, int phy, int reg, uint16_t *val)
283{ 283{
284 uint32_t addr; 284 uint32_t addr;
285 uint32_t data = 0; 285 uint32_t data = 0;
286 286
287 if (un->un_phyno != phy) 287 if (un->un_phyno != phy)
288 return EINVAL; 288 return EINVAL;
289 289
290 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) { 290 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
291 smsc_warn_printf(un, "MII is busy\n"); 291 smsc_warn_printf(un, "MII is busy\n");
292 return ETIMEDOUT; 292 return ETIMEDOUT;
293 } 293 }
294 294
295 addr = (phy << 11) | (reg << 6) | SMSC_MII_READ; 295 addr = (phy << 11) | (reg << 6) | SMSC_MII_READ;
296 smsc_writereg(un, SMSC_MII_ADDR, addr); 296 smsc_writereg(un, SMSC_MII_ADDR, addr);
297 297
298 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) { 298 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
299 smsc_warn_printf(un, "MII read timeout\n"); 299 smsc_warn_printf(un, "MII read timeout\n");
300 return ETIMEDOUT; 300 return ETIMEDOUT;
301 } 301 }
302 302
303 smsc_readreg(un, SMSC_MII_DATA, &data); 303 smsc_readreg(un, SMSC_MII_DATA, &data);
304 304
305 *val = data & 0xffff; 305 *val = data & 0xffff;
306 return 0; 306 return 0;
307} 307}
308 308
309static int 309static int
310smsc_uno_miibus_writereg(struct usbnet *un, int phy, int reg, uint16_t val) 310smsc_uno_miibus_writereg(struct usbnet *un, int phy, int reg, uint16_t val)
311{ 311{
312 uint32_t addr; 312 uint32_t addr;
313 313
314 if (un->un_phyno != phy) 314 if (un->un_phyno != phy)
315 return EINVAL; 315 return EINVAL;
316 316
317 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) { 317 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
318 smsc_warn_printf(un, "MII is busy\n"); 318 smsc_warn_printf(un, "MII is busy\n");
319 return ETIMEDOUT; 319 return ETIMEDOUT;
320 } 320 }
321 321
322 smsc_writereg(un, SMSC_MII_DATA, val); 322 smsc_writereg(un, SMSC_MII_DATA, val);
323 323
324 addr = (phy << 11) | (reg << 6) | SMSC_MII_WRITE; 324 addr = (phy << 11) | (reg << 6) | SMSC_MII_WRITE;
325 smsc_writereg(un, SMSC_MII_ADDR, addr); 325 smsc_writereg(un, SMSC_MII_ADDR, addr);
326 326
327 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) { 327 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
328 smsc_warn_printf(un, "MII write timeout\n"); 328 smsc_warn_printf(un, "MII write timeout\n");
329 return ETIMEDOUT; 329 return ETIMEDOUT;
330 } 330 }
331 331
332 return 0; 332 return 0;
333} 333}
334 334
335static void 335static void
336smsc_uno_miibus_statchg(struct ifnet *ifp) 336smsc_uno_miibus_statchg(struct ifnet *ifp)
337{ 337{
338 USMSCHIST_FUNC(); USMSCHIST_CALLED(); 338 USMSCHIST_FUNC(); USMSCHIST_CALLED();
339 struct usbnet * const un = ifp->if_softc; 339 struct usbnet * const un = ifp->if_softc;
340 340
341 if (usbnet_isdying(un)) 341 if (usbnet_isdying(un))
342 return; 342 return;
343 343
344 struct smsc_softc * const sc = usbnet_softc(un); 344 struct smsc_softc * const sc = usbnet_softc(un);
345 struct mii_data * const mii = usbnet_mii(un); 345 struct mii_data * const mii = usbnet_mii(un);
346 uint32_t flow; 346 uint32_t flow;
347 uint32_t afc_cfg; 347 uint32_t afc_cfg;
348 348
349 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 349 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
350 (IFM_ACTIVE | IFM_AVALID)) { 350 (IFM_ACTIVE | IFM_AVALID)) {
351 switch (IFM_SUBTYPE(mii->mii_media_active)) { 351 switch (IFM_SUBTYPE(mii->mii_media_active)) {
352 case IFM_10_T: 352 case IFM_10_T:
353 case IFM_100_TX: 353 case IFM_100_TX:
354 usbnet_set_link(un, true); 354 usbnet_set_link(un, true);
355 break; 355 break;
356 case IFM_1000_T: 356 case IFM_1000_T:
357 /* Gigabit ethernet not supported by chipset */ 357 /* Gigabit ethernet not supported by chipset */
358 break; 358 break;
359 default: 359 default:
360 break; 360 break;
361 } 361 }
362 } 362 }
363 363
364 /* Lost link, do nothing. */ 364 /* Lost link, do nothing. */
365 if (!usbnet_havelink(un)) 365 if (!usbnet_havelink(un))
366 return; 366 return;
367 367
368 int err = smsc_readreg(un, SMSC_AFC_CFG, &afc_cfg); 368 int err = smsc_readreg(un, SMSC_AFC_CFG, &afc_cfg);
369 if (err) { 369 if (err) {
370 smsc_warn_printf(un, "failed to read initial AFC_CFG, " 370 smsc_warn_printf(un, "failed to read initial AFC_CFG, "
371 "error %d\n", err); 371 "error %d\n", err);
372 return; 372 return;
373 } 373 }
374 374
375 /* Enable/disable full duplex operation and TX/RX pause */ 375 /* Enable/disable full duplex operation and TX/RX pause */
376 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { 376 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
377 DPRINTF("full duplex operation", 0, 0, 0, 0); 377 DPRINTF("full duplex operation", 0, 0, 0, 0);
378 sc->sc_mac_csr &= ~SMSC_MAC_CSR_RCVOWN; 378 sc->sc_mac_csr &= ~SMSC_MAC_CSR_RCVOWN;
379 sc->sc_mac_csr |= SMSC_MAC_CSR_FDPX; 379 sc->sc_mac_csr |= SMSC_MAC_CSR_FDPX;
380 380
381 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) 381 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
382 flow = 0xffff0002; 382 flow = 0xffff0002;
383 else 383 else
384 flow = 0; 384 flow = 0;
385 385
386 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) 386 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
387 afc_cfg |= 0xf; 387 afc_cfg |= 0xf;
388 else 388 else
389 afc_cfg &= ~0xf; 389 afc_cfg &= ~0xf;
390 } else { 390 } else {
391 DPRINTF("half duplex operation", 0, 0, 0, 0); 391 DPRINTF("half duplex operation", 0, 0, 0, 0);
392 sc->sc_mac_csr &= ~SMSC_MAC_CSR_FDPX; 392 sc->sc_mac_csr &= ~SMSC_MAC_CSR_FDPX;
393 sc->sc_mac_csr |= SMSC_MAC_CSR_RCVOWN; 393 sc->sc_mac_csr |= SMSC_MAC_CSR_RCVOWN;
394 394
395 flow = 0; 395 flow = 0;
396 afc_cfg |= 0xf; 396 afc_cfg |= 0xf;
397 } 397 }
398 398
399 err = smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 399 err = smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
400 err += smsc_writereg(un, SMSC_FLOW, flow); 400 err += smsc_writereg(un, SMSC_FLOW, flow);
401 err += smsc_writereg(un, SMSC_AFC_CFG, afc_cfg); 401 err += smsc_writereg(un, SMSC_AFC_CFG, afc_cfg);
402 402
403 if (err) 403 if (err)
404 smsc_warn_printf(un, "media change failed, error %d\n", err); 404 smsc_warn_printf(un, "media change failed, error %d\n", err);
405} 405}
406 406
407static inline uint32_t 407static inline uint32_t
408smsc_hash(uint8_t addr[ETHER_ADDR_LEN]) 408smsc_hash(uint8_t addr[ETHER_ADDR_LEN])
409{ 409{
410 410
411 return (ether_crc32_be(addr, ETHER_ADDR_LEN) >> 26) & 0x3f; 411 return (ether_crc32_be(addr, ETHER_ADDR_LEN) >> 26) & 0x3f;
412} 412}
413 413
414static void 414static void
415smsc_setiff_locked(struct usbnet *un) 415smsc_setiff_locked(struct usbnet *un)
416{ 416{
417 USMSCHIST_FUNC(); USMSCHIST_CALLED(); 417 USMSCHIST_FUNC(); USMSCHIST_CALLED();
418 struct smsc_softc * const sc = usbnet_softc(un); 418 struct smsc_softc * const sc = usbnet_softc(un);
419 struct ifnet * const ifp = usbnet_ifp(un); 419 struct ifnet * const ifp = usbnet_ifp(un);
420 struct ethercom *ec = usbnet_ec(un); 420 struct ethercom *ec = usbnet_ec(un);
421 struct ether_multi *enm; 421 struct ether_multi *enm;
422 struct ether_multistep step; 422 struct ether_multistep step;
423 uint32_t hashtbl[2] = { 0, 0 }; 423 uint32_t hashtbl[2] = { 0, 0 };
424 uint32_t hash; 424 uint32_t hash;
425 425
426 usbnet_isowned_core(un); 426 usbnet_isowned_core(un);
427 427
428 if (usbnet_isdying(un)) 428 if (usbnet_isdying(un))
429 return; 429 return;
430 430
431 if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { 431 if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
432allmulti: 432allmulti:
433 DPRINTF("receive all multicast enabled", 0, 0, 0, 0); 433 DPRINTF("receive all multicast enabled", 0, 0, 0, 0);
434 sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS; 434 sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS;
435 sc->sc_mac_csr &= ~SMSC_MAC_CSR_HPFILT; 435 sc->sc_mac_csr &= ~SMSC_MAC_CSR_HPFILT;
436 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 436 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
437 return; 437 return;
438 } else { 438 } else {
439 sc->sc_mac_csr |= SMSC_MAC_CSR_HPFILT; 439 sc->sc_mac_csr |= SMSC_MAC_CSR_HPFILT;
440 sc->sc_mac_csr &= ~(SMSC_MAC_CSR_PRMS | SMSC_MAC_CSR_MCPAS); 440 sc->sc_mac_csr &= ~(SMSC_MAC_CSR_PRMS | SMSC_MAC_CSR_MCPAS);
441 } 441 }
442 442
443 ETHER_LOCK(ec); 443 ETHER_LOCK(ec);
444 ETHER_FIRST_MULTI(step, ec, enm); 444 ETHER_FIRST_MULTI(step, ec, enm);
445 while (enm != NULL) { 445 while (enm != NULL) {
446 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 446 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
447 ETHER_UNLOCK(ec); 447 ETHER_UNLOCK(ec);
448 goto allmulti; 448 goto allmulti;
449 } 449 }
450 450
451 hash = smsc_hash(enm->enm_addrlo); 451 hash = smsc_hash(enm->enm_addrlo);
452 hashtbl[hash >> 5] |= 1 << (hash & 0x1F); 452 hashtbl[hash >> 5] |= 1 << (hash & 0x1F);
453 ETHER_NEXT_MULTI(step, enm); 453 ETHER_NEXT_MULTI(step, enm);
454 } 454 }
455 ETHER_UNLOCK(ec); 455 ETHER_UNLOCK(ec);
456 456
457 /* Debug */ 457 /* Debug */
458 if (sc->sc_mac_csr & SMSC_MAC_CSR_HPFILT) { 458 if (sc->sc_mac_csr & SMSC_MAC_CSR_HPFILT) {
459 DPRINTF("receive select group of macs", 0, 0, 0, 0); 459 DPRINTF("receive select group of macs", 0, 0, 0, 0);
460 } else { 460 } else {
461 DPRINTF("receive own packets only", 0, 0, 0, 0); 461 DPRINTF("receive own packets only", 0, 0, 0, 0);
462 } 462 }
463 463
464 /* Write the hash table and mac control registers */ 464 /* Write the hash table and mac control registers */
465 465
466 //XXX should we be doing this? 466 //XXX should we be doing this?
467 ifp->if_flags &= ~IFF_ALLMULTI; 467 ifp->if_flags &= ~IFF_ALLMULTI;
468 smsc_writereg(un, SMSC_HASHH, hashtbl[1]); 468 smsc_writereg(un, SMSC_HASHH, hashtbl[1]);
469 smsc_writereg(un, SMSC_HASHL, hashtbl[0]); 469 smsc_writereg(un, SMSC_HASHL, hashtbl[0]);
470 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 470 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
471} 471}
472 472
473static int 473static int
474smsc_setoe_locked(struct usbnet *un) 474smsc_setoe_locked(struct usbnet *un)
475{ 475{
476 struct smsc_softc * const sc = usbnet_softc(un); 476 struct smsc_softc * const sc = usbnet_softc(un);
477 struct ifnet * const ifp = usbnet_ifp(un); 477 struct ifnet * const ifp = usbnet_ifp(un);
478 uint32_t val; 478 uint32_t val;
479 int err; 479 int err;
480 480
481 usbnet_isowned_core(un); 481 usbnet_isowned_core(un);
482 482
483 err = smsc_readreg(un, SMSC_COE_CTRL, &val); 483 err = smsc_readreg(un, SMSC_COE_CTRL, &val);
484 if (err != 0) { 484 if (err != 0) {
485 smsc_warn_printf(un, "failed to read SMSC_COE_CTRL (err=%d)\n", 485 smsc_warn_printf(un, "failed to read SMSC_COE_CTRL (err=%d)\n",
486 err); 486 err);
487 return err; 487 return err;
488 } 488 }
489 489
490 /* Enable/disable the Rx checksum */ 490 /* Enable/disable the Rx checksum */
491 if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) 491 if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx))
492 val |= (SMSC_COE_CTRL_RX_EN | SMSC_COE_CTRL_RX_MODE); 492 val |= (SMSC_COE_CTRL_RX_EN | SMSC_COE_CTRL_RX_MODE);
493 else 493 else
494 val &= ~(SMSC_COE_CTRL_RX_EN | SMSC_COE_CTRL_RX_MODE); 494 val &= ~(SMSC_COE_CTRL_RX_EN | SMSC_COE_CTRL_RX_MODE);
495 495
496 /* Enable/disable the Tx checksum (currently not supported) */ 496 /* Enable/disable the Tx checksum (currently not supported) */
497 if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx)) 497 if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx))
498 val |= SMSC_COE_CTRL_TX_EN; 498 val |= SMSC_COE_CTRL_TX_EN;
499 else 499 else
500 val &= ~SMSC_COE_CTRL_TX_EN; 500 val &= ~SMSC_COE_CTRL_TX_EN;
501 501
502 sc->sc_coe_ctrl = val; 502 sc->sc_coe_ctrl = val;
503 503
504 err = smsc_writereg(un, SMSC_COE_CTRL, val); 504 err = smsc_writereg(un, SMSC_COE_CTRL, val);
505 if (err != 0) { 505 if (err != 0) {
506 smsc_warn_printf(un, "failed to write SMSC_COE_CTRL (err=%d)\n", 506 smsc_warn_printf(un, "failed to write SMSC_COE_CTRL (err=%d)\n",
507 err); 507 err);
508 return err; 508 return err;
509 } 509 }
510 510
511 return 0; 511 return 0;
512} 512}
513 513
514static int 514static int
515smsc_setmacaddress(struct usbnet *un, const uint8_t *addr) 515smsc_setmacaddress(struct usbnet *un, const uint8_t *addr)
516{ 516{
517 USMSCHIST_FUNC(); USMSCHIST_CALLED(); 517 USMSCHIST_FUNC(); USMSCHIST_CALLED();
518 int err; 518 int err;
519 uint32_t val; 519 uint32_t val;
520 520
521 DPRINTF("setting mac address to %02jx:%02jx:%02jx:...", addr[0], 521 DPRINTF("setting mac address to %02jx:%02jx:%02jx:...", addr[0],
522 addr[1], addr[2], 0); 522 addr[1], addr[2], 0);
523 523
524 DPRINTF("... %02jx:%02jx:%02jx", addr[3], addr[4], addr[5], 0); 524 DPRINTF("... %02jx:%02jx:%02jx", addr[3], addr[4], addr[5], 0);
525 525
526 val = ((uint32_t)addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) 526 val = ((uint32_t)addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8)
527 | addr[0]; 527 | addr[0];
528 if ((err = smsc_writereg(un, SMSC_MAC_ADDRL, val)) != 0) 528 if ((err = smsc_writereg(un, SMSC_MAC_ADDRL, val)) != 0)
529 goto done; 529 goto done;
530 530
531 val = (addr[5] << 8) | addr[4]; 531 val = (addr[5] << 8) | addr[4];
532 err = smsc_writereg(un, SMSC_MAC_ADDRH, val); 532 err = smsc_writereg(un, SMSC_MAC_ADDRH, val);
533 533
534done: 534done:
535 return err; 535 return err;
536} 536}
537 537
538static void 538static void
539smsc_reset(struct smsc_softc *sc) 539smsc_reset(struct smsc_softc *sc)
540{ 540{
541 struct usbnet * const un = &sc->smsc_un; 541 struct usbnet * const un = &sc->smsc_un;
542 542
543 usbnet_isowned_core(un); 543 usbnet_isowned_core(un);
544 if (usbnet_isdying(un)) 544 if (usbnet_isdying(un))
545 return; 545 return;
546 546
547 /* Wait a little while for the chip to get its brains in order. */ 547 /* Wait a little while for the chip to get its brains in order. */
548 DELAY(1000); 548 DELAY(1000);
549 549
550 /* Reinitialize controller to achieve full reset. */ 550 /* Reinitialize controller to achieve full reset. */
551 smsc_chip_init(un); 551 smsc_chip_init(un);
552} 552}
553 553
554static int 554static int
555smsc_uno_init(struct ifnet *ifp) 555smsc_uno_init(struct ifnet *ifp)
556{ 556{
557 int ret = smsc_init_locked(ifp); 557 int ret = smsc_init_locked(ifp);
558 558
559 return ret; 559 return ret;
560} 560}
561 561
562static int 562static int
563smsc_init_locked(struct ifnet *ifp) 563smsc_init_locked(struct ifnet *ifp)
564{ 564{
565 struct usbnet * const un = ifp->if_softc; 565 struct usbnet * const un = ifp->if_softc;
566 struct smsc_softc * const sc = usbnet_softc(un); 566 struct smsc_softc * const sc = usbnet_softc(un);
567 567
568 usbnet_isowned_core(un); 568 usbnet_isowned_core(un);
569 569
570 if (usbnet_isdying(un)) 570 if (usbnet_isdying(un))
571 return EIO; 571 return EIO;
572 572
573 /* Cancel pending I/O */ 573 /* Cancel pending I/O */
574 usbnet_stop(un, ifp, 1); 574 usbnet_stop(un, ifp, 1);
575 575
576 /* Reset the ethernet interface. */ 576 /* Reset the ethernet interface. */
577 smsc_reset(sc); 577 smsc_reset(sc);
578 578
579 /* Load the multicast filter. */ 579 /* Load the multicast filter. */
580 smsc_setiff_locked(un); 580 smsc_setiff_locked(un);
581 581
582 /* TCP/UDP checksum offload engines. */ 582 /* TCP/UDP checksum offload engines. */
583 smsc_setoe_locked(un); 583 smsc_setoe_locked(un);
584 584
585 return usbnet_init_rx_tx(un); 585 return usbnet_init_rx_tx(un);
586} 586}
587 587
588static void 588static void
589smsc_uno_stop(struct ifnet *ifp, int disable) 589smsc_uno_stop(struct ifnet *ifp, int disable)
590{ 590{
591 struct usbnet * const un = ifp->if_softc; 591 struct usbnet * const un = ifp->if_softc;
592 struct smsc_softc * const sc = usbnet_softc(un); 592 struct smsc_softc * const sc = usbnet_softc(un);
593 593
594 // XXXNH didn't do this before 594 // XXXNH didn't do this before
595 smsc_reset(sc); 595 smsc_reset(sc);
596} 596}
597 597
598static int 598static int
599smsc_chip_init(struct usbnet *un) 599smsc_chip_init(struct usbnet *un)
600{ 600{
601 struct smsc_softc * const sc = usbnet_softc(un); 601 struct smsc_softc * const sc = usbnet_softc(un);
602 uint32_t reg_val; 602 uint32_t reg_val;
603 int burst_cap; 603 int burst_cap;
604 int err; 604 int err;
605 605
606 usbnet_isowned_core(un); 606 usbnet_isowned_core(un);
607 607
608 /* Enter H/W config mode */ 608 /* Enter H/W config mode */
609 smsc_writereg(un, SMSC_HW_CFG, SMSC_HW_CFG_LRST); 609 smsc_writereg(un, SMSC_HW_CFG, SMSC_HW_CFG_LRST);
610 610
611 if ((err = smsc_wait_for_bits(un, SMSC_HW_CFG, 611 if ((err = smsc_wait_for_bits(un, SMSC_HW_CFG,
612 SMSC_HW_CFG_LRST)) != 0) { 612 SMSC_HW_CFG_LRST)) != 0) {
613 smsc_warn_printf(un, "timed-out waiting for reset to " 613 smsc_warn_printf(un, "timed-out waiting for reset to "
614 "complete\n"); 614 "complete\n");
615 goto init_failed; 615 goto init_failed;
616 } 616 }
617 617
618 /* Reset the PHY */ 618 /* Reset the PHY */
619 smsc_writereg(un, SMSC_PM_CTRL, SMSC_PM_CTRL_PHY_RST); 619 smsc_writereg(un, SMSC_PM_CTRL, SMSC_PM_CTRL_PHY_RST);
620 620
621 if ((err = smsc_wait_for_bits(un, SMSC_PM_CTRL, 621 if ((err = smsc_wait_for_bits(un, SMSC_PM_CTRL,
622 SMSC_PM_CTRL_PHY_RST)) != 0) { 622 SMSC_PM_CTRL_PHY_RST)) != 0) {
623 smsc_warn_printf(un, "timed-out waiting for phy reset to " 623 smsc_warn_printf(un, "timed-out waiting for phy reset to "
624 "complete\n"); 624 "complete\n");
625 goto init_failed; 625 goto init_failed;
626 } 626 }
627 usbd_delay_ms(un->un_udev, 40); 627 usbd_delay_ms(un->un_udev, 40);
628 628
629 /* Set the mac address */ 629 /* Set the mac address */
630 struct ifnet * const ifp = usbnet_ifp(un); 630 struct ifnet * const ifp = usbnet_ifp(un);
631 const char *eaddr = CLLADDR(ifp->if_sadl); 631 const char *eaddr = CLLADDR(ifp->if_sadl);
632 if ((err = smsc_setmacaddress(un, eaddr)) != 0) { 632 if ((err = smsc_setmacaddress(un, eaddr)) != 0) {
633 smsc_warn_printf(un, "failed to set the MAC address\n"); 633 smsc_warn_printf(un, "failed to set the MAC address\n");
634 goto init_failed; 634 goto init_failed;
635 } 635 }
636 636
637 /* 637 /*
638 * Don't know what the HW_CFG_BIR bit is, but following the reset 638 * Don't know what the HW_CFG_BIR bit is, but following the reset
639 * sequence as used in the Linux driver. 639 * sequence as used in the Linux driver.
640 */ 640 */
641 if ((err = smsc_readreg(un, SMSC_HW_CFG, &reg_val)) != 0) { 641 if ((err = smsc_readreg(un, SMSC_HW_CFG, &reg_val)) != 0) {
642 smsc_warn_printf(un, "failed to read HW_CFG: %d\n", err); 642 smsc_warn_printf(un, "failed to read HW_CFG: %d\n", err);
643 goto init_failed; 643 goto init_failed;
644 } 644 }
645 reg_val |= SMSC_HW_CFG_BIR; 645 reg_val |= SMSC_HW_CFG_BIR;
646 smsc_writereg(un, SMSC_HW_CFG, reg_val); 646 smsc_writereg(un, SMSC_HW_CFG, reg_val);
647 647
648 /* 648 /*
649 * There is a so called 'turbo mode' that the linux driver supports, it 649 * There is a so called 'turbo mode' that the linux driver supports, it
650 * seems to allow you to jam multiple frames per Rx transaction. 650 * seems to allow you to jam multiple frames per Rx transaction.
651 * By default this driver supports that and therefore allows multiple 651 * By default this driver supports that and therefore allows multiple
652 * frames per USB transfer. 652 * frames per USB transfer.
653 * 653 *
654 * The xfer buffer size needs to reflect this as well, therefore based 654 * The xfer buffer size needs to reflect this as well, therefore based
655 * on the calculations in the Linux driver the RX bufsize is set to 655 * on the calculations in the Linux driver the RX bufsize is set to
656 * 18944, 656 * 18944,
657 * bufsz = (16 * 1024 + 5 * 512) 657 * bufsz = (16 * 1024 + 5 * 512)
658 * 658 *
659 * Burst capability is the number of URBs that can be in a burst of 659 * Burst capability is the number of URBs that can be in a burst of
660 * data/ethernet frames. 660 * data/ethernet frames.
661 */ 661 */
662 662
663 if (un->un_udev->ud_speed == USB_SPEED_HIGH) 663 if (un->un_udev->ud_speed == USB_SPEED_HIGH)
664 burst_cap = 37; 664 burst_cap = 37;
665 else 665 else
666 burst_cap = 128; 666 burst_cap = 128;
667 667
668 smsc_writereg(un, SMSC_BURST_CAP, burst_cap); 668 smsc_writereg(un, SMSC_BURST_CAP, burst_cap);
669 669
670 /* Set the default bulk in delay (magic value from Linux driver) */ 670 /* Set the default bulk in delay (magic value from Linux driver) */
671 smsc_writereg(un, SMSC_BULK_IN_DLY, 0x00002000); 671 smsc_writereg(un, SMSC_BULK_IN_DLY, 0x00002000);
672 672
673 /* 673 /*
674 * Initialise the RX interface 674 * Initialise the RX interface
675 */ 675 */
676 if ((err = smsc_readreg(un, SMSC_HW_CFG, &reg_val)) < 0) { 676 if ((err = smsc_readreg(un, SMSC_HW_CFG, &reg_val)) < 0) {
677 smsc_warn_printf(un, "failed to read HW_CFG: (err = %d)\n", 677 smsc_warn_printf(un, "failed to read HW_CFG: (err = %d)\n",
678 err); 678 err);
679 goto init_failed; 679 goto init_failed;
680 } 680 }
681 681
682 /* 682 /*
683 * The following settings are used for 'turbo mode', a.k.a multiple 683 * The following settings are used for 'turbo mode', a.k.a multiple
684 * frames per Rx transaction (again info taken form Linux driver). 684 * frames per Rx transaction (again info taken form Linux driver).
685 */ 685 */
686 reg_val |= (SMSC_HW_CFG_MEF | SMSC_HW_CFG_BCE); 686 reg_val |= (SMSC_HW_CFG_MEF | SMSC_HW_CFG_BCE);
687 687
688 /* 688 /*
689 * set Rx data offset to ETHER_ALIGN which will make the IP header 689 * set Rx data offset to ETHER_ALIGN which will make the IP header
690 * align on a word boundary. 690 * align on a word boundary.
691 */ 691 */
692 reg_val |= ETHER_ALIGN << SMSC_HW_CFG_RXDOFF_SHIFT; 692 reg_val |= ETHER_ALIGN << SMSC_HW_CFG_RXDOFF_SHIFT;
693 693
694 smsc_writereg(un, SMSC_HW_CFG, reg_val); 694 smsc_writereg(un, SMSC_HW_CFG, reg_val);
695 695
696 /* Clear the status register ? */ 696 /* Clear the status register ? */
697 smsc_writereg(un, SMSC_INTR_STATUS, 0xffffffff); 697 smsc_writereg(un, SMSC_INTR_STATUS, 0xffffffff);
698 698
699 /* Read and display the revision register */ 699 /* Read and display the revision register */
700 if ((err = smsc_readreg(un, SMSC_ID_REV, &sc->sc_rev_id)) < 0) { 700 if ((err = smsc_readreg(un, SMSC_ID_REV, &sc->sc_rev_id)) < 0) {
701 smsc_warn_printf(un, "failed to read ID_REV (err = %d)\n", err); 701 smsc_warn_printf(un, "failed to read ID_REV (err = %d)\n", err);
702 goto init_failed; 702 goto init_failed;
703 } 703 }
704 704
705 /* GPIO/LED setup */ 705 /* GPIO/LED setup */
706 reg_val = SMSC_LED_GPIO_CFG_SPD_LED | SMSC_LED_GPIO_CFG_LNK_LED | 706 reg_val = SMSC_LED_GPIO_CFG_SPD_LED | SMSC_LED_GPIO_CFG_LNK_LED |
707 SMSC_LED_GPIO_CFG_FDX_LED; 707 SMSC_LED_GPIO_CFG_FDX_LED;
708 smsc_writereg(un, SMSC_LED_GPIO_CFG, reg_val); 708 smsc_writereg(un, SMSC_LED_GPIO_CFG, reg_val);
709 709
710 /* 710 /*
711 * Initialise the TX interface 711 * Initialise the TX interface
712 */ 712 */
713 smsc_writereg(un, SMSC_FLOW, 0); 713 smsc_writereg(un, SMSC_FLOW, 0);
714 714
715 smsc_writereg(un, SMSC_AFC_CFG, AFC_CFG_DEFAULT); 715 smsc_writereg(un, SMSC_AFC_CFG, AFC_CFG_DEFAULT);
716 716
717 /* Read the current MAC configuration */ 717 /* Read the current MAC configuration */
718 if ((err = smsc_readreg(un, SMSC_MAC_CSR, &sc->sc_mac_csr)) < 0) { 718 if ((err = smsc_readreg(un, SMSC_MAC_CSR, &sc->sc_mac_csr)) < 0) {
719 smsc_warn_printf(un, "failed to read MAC_CSR (err=%d)\n", err); 719 smsc_warn_printf(un, "failed to read MAC_CSR (err=%d)\n", err);
720 goto init_failed; 720 goto init_failed;
721 } 721 }
722 722
723 /* disable pad stripping, collides with checksum offload */ 723 /* disable pad stripping, collides with checksum offload */
724 sc->sc_mac_csr &= ~SMSC_MAC_CSR_PADSTR; 724 sc->sc_mac_csr &= ~SMSC_MAC_CSR_PADSTR;
725 725
726 /* Vlan */ 726 /* Vlan */
727 smsc_writereg(un, SMSC_VLAN1, (uint32_t)ETHERTYPE_VLAN); 727 smsc_writereg(un, SMSC_VLAN1, (uint32_t)ETHERTYPE_VLAN);
728 728
729 /* 729 /*
730 * Start TX 730 * Start TX
731 */ 731 */
732 sc->sc_mac_csr |= SMSC_MAC_CSR_TXEN; 732 sc->sc_mac_csr |= SMSC_MAC_CSR_TXEN;
733 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 733 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
734 smsc_writereg(un, SMSC_TX_CFG, SMSC_TX_CFG_ON); 734 smsc_writereg(un, SMSC_TX_CFG, SMSC_TX_CFG_ON);
735 735
736 /* 736 /*
737 * Start RX 737 * Start RX
738 */ 738 */
739 sc->sc_mac_csr |= SMSC_MAC_CSR_RXEN; 739 sc->sc_mac_csr |= SMSC_MAC_CSR_RXEN;
740 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 740 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
741 741
742 return 0; 742 return 0;
743 743
744init_failed: 744init_failed:
745 smsc_err_printf(un, "smsc_chip_init failed (err=%d)\n", err); 745 smsc_err_printf(un, "smsc_chip_init failed (err=%d)\n", err);
746 return err; 746 return err;
747} 747}
748 748
749static int 749static int
750smsc_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 750smsc_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
751{ 751{
752 struct usbnet * const un = ifp->if_softc; 752 struct usbnet * const un = ifp->if_softc;
753 753
754 usbnet_lock_core(un); 754 usbnet_lock_core(un);
755 usbnet_busy(un); 755 usbnet_busy(un);
756 756
757 switch (cmd) { 757 switch (cmd) {
758 case SIOCSIFCAP: 758 case SIOCSIFCAP:
759 smsc_setoe_locked(un); 759 smsc_setoe_locked(un);
760 break; 760 break;
761 default: 761 default:
762 break; 762 break;
763 } 763 }
764 764
765 usbnet_unbusy(un); 765 usbnet_unbusy(un);
766 usbnet_unlock_core(un); 766 usbnet_unlock_core(un);
767 767
768 return 0; 768 return 0;
769} 769}
770 770
771static void 771static void
772smsc_uno_mcast(struct ifnet *ifp) 772smsc_uno_mcast(struct ifnet *ifp)
773{ 773{
774 struct usbnet * const un = ifp->if_softc; 774 struct usbnet * const un = ifp->if_softc;
775 775
776 usbnet_lock_core(un); 776 usbnet_lock_core(un);
777 usbnet_busy(un); 
778 777
779 smsc_setiff_locked(un); 778 smsc_setiff_locked(un);
780 779
781 usbnet_unbusy(un); 
782 usbnet_unlock_core(un); 780 usbnet_unlock_core(un);
783} 781}
784 782
785static int 783static int
786smsc_match(device_t parent, cfdata_t match, void *aux) 784smsc_match(device_t parent, cfdata_t match, void *aux)
787{ 785{
788 struct usb_attach_arg *uaa = aux; 786 struct usb_attach_arg *uaa = aux;
789 787
790 return (usb_lookup(smsc_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ? 788 return (usb_lookup(smsc_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ?
791 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 789 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
792} 790}
793 791
794static void 792static void
795smsc_attach(device_t parent, device_t self, void *aux) 793smsc_attach(device_t parent, device_t self, void *aux)
796{ 794{
797 USBNET_MII_DECL_DEFAULT(unm); 795 USBNET_MII_DECL_DEFAULT(unm);
798 struct smsc_softc * const sc = device_private(self); 796 struct smsc_softc * const sc = device_private(self);
799 struct usbnet * const un = &sc->smsc_un; 797 struct usbnet * const un = &sc->smsc_un;
800 struct usb_attach_arg *uaa = aux; 798 struct usb_attach_arg *uaa = aux;
801 struct usbd_device *dev = uaa->uaa_device; 799 struct usbd_device *dev = uaa->uaa_device;
802 usb_interface_descriptor_t *id; 800 usb_interface_descriptor_t *id;
803 usb_endpoint_descriptor_t *ed; 801 usb_endpoint_descriptor_t *ed;
804 char *devinfop; 802 char *devinfop;
805 unsigned bufsz; 803 unsigned bufsz;
806 int err, i; 804 int err, i;
807 uint32_t mac_h, mac_l; 805 uint32_t mac_h, mac_l;
808 806
809 KASSERT((void *)sc == un); 807 KASSERT((void *)sc == un);
810 808
811 aprint_naive("\n"); 809 aprint_naive("\n");
812 aprint_normal("\n"); 810 aprint_normal("\n");
813 811
814 un->un_dev = self; 812 un->un_dev = self;
815 un->un_udev = dev; 813 un->un_udev = dev;
816 un->un_sc = sc; 814 un->un_sc = sc;
817 un->un_ops = &smsc_ops; 815 un->un_ops = &smsc_ops;
818 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 816 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
819 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 817 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
820 un->un_rx_list_cnt = SMSC_RX_LIST_CNT; 818 un->un_rx_list_cnt = SMSC_RX_LIST_CNT;
821 un->un_tx_list_cnt = SMSC_TX_LIST_CNT; 819 un->un_tx_list_cnt = SMSC_TX_LIST_CNT;
822 820
823 devinfop = usbd_devinfo_alloc(un->un_udev, 0); 821 devinfop = usbd_devinfo_alloc(un->un_udev, 0);
824 aprint_normal_dev(self, "%s\n", devinfop); 822 aprint_normal_dev(self, "%s\n", devinfop);
825 usbd_devinfo_free(devinfop); 823 usbd_devinfo_free(devinfop);
826 824
827 err = usbd_set_config_no(dev, SMSC_CONFIG_INDEX, 1); 825 err = usbd_set_config_no(dev, SMSC_CONFIG_INDEX, 1);
828 if (err) { 826 if (err) {
829 aprint_error_dev(self, "failed to set configuration" 827 aprint_error_dev(self, "failed to set configuration"
830 ", err=%s\n", usbd_errstr(err)); 828 ", err=%s\n", usbd_errstr(err));
831 return; 829 return;
832 } 830 }
833 831
834 /* Setup the endpoints for the SMSC LAN95xx device(s) */ 832 /* Setup the endpoints for the SMSC LAN95xx device(s) */
835 err = usbd_device2interface_handle(dev, SMSC_IFACE_IDX, &un->un_iface); 833 err = usbd_device2interface_handle(dev, SMSC_IFACE_IDX, &un->un_iface);
836 if (err) { 834 if (err) {
837 aprint_error_dev(self, "getting interface handle failed\n"); 835 aprint_error_dev(self, "getting interface handle failed\n");
838 return; 836 return;
839 } 837 }
840 838
841 id = usbd_get_interface_descriptor(un->un_iface); 839 id = usbd_get_interface_descriptor(un->un_iface);
842 840
843 if (dev->ud_speed >= USB_SPEED_HIGH) { 841 if (dev->ud_speed >= USB_SPEED_HIGH) {
844 bufsz = SMSC_MAX_BUFSZ; 842 bufsz = SMSC_MAX_BUFSZ;
845 } else { 843 } else {
846 bufsz = SMSC_MIN_BUFSZ; 844 bufsz = SMSC_MIN_BUFSZ;
847 } 845 }
848 un->un_rx_bufsz = bufsz; 846 un->un_rx_bufsz = bufsz;
849 un->un_tx_bufsz = bufsz; 847 un->un_tx_bufsz = bufsz;
850 848
851 /* Find endpoints. */ 849 /* Find endpoints. */
852 for (i = 0; i < id->bNumEndpoints; i++) { 850 for (i = 0; i < id->bNumEndpoints; i++) {
853 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 851 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
854 if (!ed) { 852 if (!ed) {
855 aprint_error_dev(self, "couldn't get ep %d\n", i); 853 aprint_error_dev(self, "couldn't get ep %d\n", i);
856 return; 854 return;
857 } 855 }
858 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 856 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
859 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 857 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
860 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 858 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
861 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 859 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
862 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 860 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
863 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 861 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
864#if 0 /* not used yet */ 862#if 0 /* not used yet */
865 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 863 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
866 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 864 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
867 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 865 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
868#endif 866#endif
869 } 867 }
870 } 868 }
871 869
872 usbnet_attach(un, "smscdet"); 870 usbnet_attach(un, "smscdet");
873 871
874#ifdef notyet 872#ifdef notyet
875 /* 873 /*
876 * We can do TCPv4, and UDPv4 checksums in hardware. 874 * We can do TCPv4, and UDPv4 checksums in hardware.
877 */ 875 */
878 struct ifnet *ifp = usbnet_ifp(un); 876 struct ifnet *ifp = usbnet_ifp(un);
879 877
880 ifp->if_capabilities |= 878 ifp->if_capabilities |=
881 /*IFCAP_CSUM_TCPv4_Tx |*/ IFCAP_CSUM_TCPv4_Rx | 879 /*IFCAP_CSUM_TCPv4_Tx |*/ IFCAP_CSUM_TCPv4_Rx |
882 /*IFCAP_CSUM_UDPv4_Tx |*/ IFCAP_CSUM_UDPv4_Rx; 880 /*IFCAP_CSUM_UDPv4_Tx |*/ IFCAP_CSUM_UDPv4_Rx;
883#endif 881#endif
884 struct ethercom *ec = usbnet_ec(un); 882 struct ethercom *ec = usbnet_ec(un);
885 ec->ec_capabilities = ETHERCAP_VLAN_MTU; 883 ec->ec_capabilities = ETHERCAP_VLAN_MTU;
886 884
887 /* Setup some of the basics */ 885 /* Setup some of the basics */
888 un->un_phyno = 1; 886 un->un_phyno = 1;
889 887
890 usbnet_lock_core(un); 888 usbnet_lock_core(un);
891 usbnet_busy(un); 889 usbnet_busy(un);
892 /* 890 /*
893 * Attempt to get the mac address, if an EEPROM is not attached this 891 * Attempt to get the mac address, if an EEPROM is not attached this
894 * will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC 892 * will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC
895 * address based on urandom. 893 * address based on urandom.
896 */ 894 */
897 memset(un->un_eaddr, 0xff, ETHER_ADDR_LEN); 895 memset(un->un_eaddr, 0xff, ETHER_ADDR_LEN);
898 896
899 prop_dictionary_t dict = device_properties(self); 897 prop_dictionary_t dict = device_properties(self);
900 prop_data_t eaprop = prop_dictionary_get(dict, "mac-address"); 898 prop_data_t eaprop = prop_dictionary_get(dict, "mac-address");
901 899
902 if (eaprop != NULL) { 900 if (eaprop != NULL) {
903 KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA); 901 KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA);
904 KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN); 902 KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN);
905 memcpy(un->un_eaddr, prop_data_value(eaprop), 903 memcpy(un->un_eaddr, prop_data_value(eaprop),
906 ETHER_ADDR_LEN); 904 ETHER_ADDR_LEN);
907 } else { 905 } else {
908 /* Check if there is already a MAC address in the register */ 906 /* Check if there is already a MAC address in the register */
909 if ((smsc_readreg(un, SMSC_MAC_ADDRL, &mac_l) == 0) && 907 if ((smsc_readreg(un, SMSC_MAC_ADDRL, &mac_l) == 0) &&
910 (smsc_readreg(un, SMSC_MAC_ADDRH, &mac_h) == 0)) { 908 (smsc_readreg(un, SMSC_MAC_ADDRH, &mac_h) == 0)) {
911 un->un_eaddr[5] = (uint8_t)((mac_h >> 8) & 0xff); 909 un->un_eaddr[5] = (uint8_t)((mac_h >> 8) & 0xff);
912 un->un_eaddr[4] = (uint8_t)((mac_h) & 0xff); 910 un->un_eaddr[4] = (uint8_t)((mac_h) & 0xff);
913 un->un_eaddr[3] = (uint8_t)((mac_l >> 24) & 0xff); 911 un->un_eaddr[3] = (uint8_t)((mac_l >> 24) & 0xff);
914 un->un_eaddr[2] = (uint8_t)((mac_l >> 16) & 0xff); 912 un->un_eaddr[2] = (uint8_t)((mac_l >> 16) & 0xff);
915 un->un_eaddr[1] = (uint8_t)((mac_l >> 8) & 0xff); 913 un->un_eaddr[1] = (uint8_t)((mac_l >> 8) & 0xff);
916 un->un_eaddr[0] = (uint8_t)((mac_l) & 0xff); 914 un->un_eaddr[0] = (uint8_t)((mac_l) & 0xff);
917 } 915 }
918 } 916 }
919 usbnet_unbusy(un); 917 usbnet_unbusy(un);
920 usbnet_unlock_core(un); 918 usbnet_unlock_core(un);
921 919
922 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 920 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
923 0, &unm); 921 0, &unm);
924} 922}
925 923
926static void 924static void
927smsc_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 925smsc_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
928{ 926{
929 USMSCHIST_FUNC(); USMSCHIST_CALLED(); 927 USMSCHIST_FUNC(); USMSCHIST_CALLED();
930 struct smsc_softc * const sc = usbnet_softc(un); 928 struct smsc_softc * const sc = usbnet_softc(un);
931 struct ifnet *ifp = usbnet_ifp(un); 929 struct ifnet *ifp = usbnet_ifp(un);
932 uint8_t *buf = c->unc_buf; 930 uint8_t *buf = c->unc_buf;
933 int count; 931 int count;
934 932
935 count = 0; 933 count = 0;
936 DPRINTF("total_len %jd/%#jx", total_len, total_len, 0, 0); 934 DPRINTF("total_len %jd/%#jx", total_len, total_len, 0, 0);
937 while (total_len != 0) { 935 while (total_len != 0) {
938 uint32_t rxhdr; 936 uint32_t rxhdr;
939 if (total_len < sizeof(rxhdr)) { 937 if (total_len < sizeof(rxhdr)) {
940 DPRINTF("total_len %jd < sizeof(rxhdr) %jd", 938 DPRINTF("total_len %jd < sizeof(rxhdr) %jd",
941 total_len, sizeof(rxhdr), 0, 0); 939 total_len, sizeof(rxhdr), 0, 0);
942 if_statinc(ifp, if_ierrors); 940 if_statinc(ifp, if_ierrors);
943 return; 941 return;
944 } 942 }
945 943
946 memcpy(&rxhdr, buf, sizeof(rxhdr)); 944 memcpy(&rxhdr, buf, sizeof(rxhdr));
947 rxhdr = le32toh(rxhdr); 945 rxhdr = le32toh(rxhdr);
948 buf += sizeof(rxhdr); 946 buf += sizeof(rxhdr);
949 total_len -= sizeof(rxhdr); 947 total_len -= sizeof(rxhdr);
950 948
951 if (rxhdr & SMSC_RX_STAT_COLLISION) 949 if (rxhdr & SMSC_RX_STAT_COLLISION)
952 if_statinc(ifp, if_collisions); 950 if_statinc(ifp, if_collisions);
953 951
954 if (rxhdr & (SMSC_RX_STAT_ERROR 952 if (rxhdr & (SMSC_RX_STAT_ERROR
955 | SMSC_RX_STAT_LENGTH_ERROR 953 | SMSC_RX_STAT_LENGTH_ERROR
956 | SMSC_RX_STAT_MII_ERROR)) { 954 | SMSC_RX_STAT_MII_ERROR)) {
957 DPRINTF("rx error (hdr 0x%08jx)", rxhdr, 0, 0, 0); 955 DPRINTF("rx error (hdr 0x%08jx)", rxhdr, 0, 0, 0);
958 if_statinc(ifp, if_ierrors); 956 if_statinc(ifp, if_ierrors);
959 return; 957 return;
960 } 958 }
961 959
962 uint16_t pktlen = (uint16_t)SMSC_RX_STAT_FRM_LENGTH(rxhdr); 960 uint16_t pktlen = (uint16_t)SMSC_RX_STAT_FRM_LENGTH(rxhdr);
963 DPRINTF("total_len %jd pktlen %jd rxhdr 0x%08jx", total_len, 961 DPRINTF("total_len %jd pktlen %jd rxhdr 0x%08jx", total_len,
964 pktlen, rxhdr, 0); 962 pktlen, rxhdr, 0);
965 963
966 if (pktlen < ETHER_HDR_LEN) { 964 if (pktlen < ETHER_HDR_LEN) {
967 DPRINTF("pktlen %jd < ETHER_HDR_LEN %jd", pktlen, 965 DPRINTF("pktlen %jd < ETHER_HDR_LEN %jd", pktlen,
968 ETHER_HDR_LEN, 0, 0); 966 ETHER_HDR_LEN, 0, 0);
969 if_statinc(ifp, if_ierrors); 967 if_statinc(ifp, if_ierrors);
970 return; 968 return;
971 } 969 }
972 970
973 pktlen += ETHER_ALIGN; 971 pktlen += ETHER_ALIGN;
974 972
975 if (pktlen > MCLBYTES) { 973 if (pktlen > MCLBYTES) {
976 DPRINTF("pktlen %jd > MCLBYTES %jd", pktlen, MCLBYTES, 0, 974 DPRINTF("pktlen %jd > MCLBYTES %jd", pktlen, MCLBYTES, 0,
977 0); 975 0);
978 if_statinc(ifp, if_ierrors); 976 if_statinc(ifp, if_ierrors);
979 return; 977 return;
980 } 978 }
981 979
982 if (pktlen > total_len) { 980 if (pktlen > total_len) {
983 DPRINTF("pktlen %jd > total_len %jd", pktlen, total_len, 981 DPRINTF("pktlen %jd > total_len %jd", pktlen, total_len,
984 0, 0); 982 0, 0);
985 if_statinc(ifp, if_ierrors); 983 if_statinc(ifp, if_ierrors);
986 return; 984 return;
987 } 985 }
988 986
989 uint8_t *pktbuf = buf + ETHER_ALIGN; 987 uint8_t *pktbuf = buf + ETHER_ALIGN;
990 size_t buflen = pktlen - ETHER_ALIGN; 988 size_t buflen = pktlen - ETHER_ALIGN;
991 int mbuf_flags = M_HASFCS; 989 int mbuf_flags = M_HASFCS;
992 int csum_flags = 0; 990 int csum_flags = 0;
993 uint16_t csum_data = 0; 991 uint16_t csum_data = 0;
994 992
995 KASSERT(pktlen < MCLBYTES); 993 KASSERT(pktlen < MCLBYTES);
996 994
997 /* Check if RX TCP/UDP checksumming is being offloaded */ 995 /* Check if RX TCP/UDP checksumming is being offloaded */
998 if (sc->sc_coe_ctrl & SMSC_COE_CTRL_RX_EN) { 996 if (sc->sc_coe_ctrl & SMSC_COE_CTRL_RX_EN) {
999 DPRINTF("RX checksum offload checking", 0, 0, 0, 0); 997 DPRINTF("RX checksum offload checking", 0, 0, 0, 0);
1000 struct ether_header *eh = (struct ether_header *)pktbuf; 998 struct ether_header *eh = (struct ether_header *)pktbuf;
1001 const size_t cssz = sizeof(csum_data); 999 const size_t cssz = sizeof(csum_data);
1002 1000
1003 /* Remove the extra 2 bytes of the csum */ 1001 /* Remove the extra 2 bytes of the csum */
1004 buflen -= cssz; 1002 buflen -= cssz;
1005 1003
1006 /* 1004 /*
1007 * The checksum appears to be simplistically calculated 1005 * The checksum appears to be simplistically calculated
1008 * over the udp/tcp header and data up to the end of the 1006 * over the udp/tcp header and data up to the end of the
1009 * eth frame. Which means if the eth frame is padded 1007 * eth frame. Which means if the eth frame is padded
1010 * the csum calculation is incorrectly performed over 1008 * the csum calculation is incorrectly performed over
1011 * the padding bytes as well. Therefore to be safe we 1009 * the padding bytes as well. Therefore to be safe we
1012 * ignore the H/W csum on frames less than or equal to 1010 * ignore the H/W csum on frames less than or equal to
1013 * 64 bytes. 1011 * 64 bytes.
1014 * 1012 *
1015 * Ignore H/W csum for non-IPv4 packets. 1013 * Ignore H/W csum for non-IPv4 packets.
1016 */ 1014 */
1017 DPRINTF("Ethertype %02jx pktlen %02jx", 1015 DPRINTF("Ethertype %02jx pktlen %02jx",
1018 be16toh(eh->ether_type), pktlen, 0, 0); 1016 be16toh(eh->ether_type), pktlen, 0, 0);
1019 if (be16toh(eh->ether_type) == ETHERTYPE_IP && 1017 if (be16toh(eh->ether_type) == ETHERTYPE_IP &&
1020 pktlen > ETHER_MIN_LEN) { 1018 pktlen > ETHER_MIN_LEN) {
1021 1019
1022 csum_flags |= 1020 csum_flags |=
1023 (M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_DATA); 1021 (M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_DATA);
1024 1022
1025 /* 1023 /*
1026 * Copy the TCP/UDP checksum from the last 2 1024 * Copy the TCP/UDP checksum from the last 2
1027 * bytes of the transfer and put in the 1025 * bytes of the transfer and put in the
1028 * csum_data field. 1026 * csum_data field.
1029 */ 1027 */
1030 memcpy(&csum_data, buf + pktlen - cssz, cssz); 1028 memcpy(&csum_data, buf + pktlen - cssz, cssz);
1031 1029
1032 /* 1030 /*
1033 * The data is copied in network order, but the 1031 * The data is copied in network order, but the
1034 * csum algorithm in the kernel expects it to be 1032 * csum algorithm in the kernel expects it to be
1035 * in host network order. 1033 * in host network order.
1036 */ 1034 */
1037 csum_data = ntohs(csum_data); 1035 csum_data = ntohs(csum_data);
1038 DPRINTF("RX checksum offloaded (0x%04jx)", 1036 DPRINTF("RX checksum offloaded (0x%04jx)",
1039 csum_data, 0, 0, 0); 1037 csum_data, 0, 0, 0);
1040 } 1038 }
1041 } 1039 }
1042 1040
1043 /* round up to next longword */ 1041 /* round up to next longword */
1044 pktlen = (pktlen + 3) & ~0x3; 1042 pktlen = (pktlen + 3) & ~0x3;
1045 1043
1046 /* total_len does not include the padding */ 1044 /* total_len does not include the padding */
1047 if (pktlen > total_len) 1045 if (pktlen > total_len)
1048 pktlen = total_len; 1046 pktlen = total_len;
1049 1047
1050 buf += pktlen; 1048 buf += pktlen;
1051 total_len -= pktlen; 1049 total_len -= pktlen;
1052 1050
1053 /* push the packet up */ 1051 /* push the packet up */
1054 usbnet_enqueue(un, pktbuf, buflen, csum_flags, csum_data, 1052 usbnet_enqueue(un, pktbuf, buflen, csum_flags, csum_data,
1055 mbuf_flags); 1053 mbuf_flags);
1056 1054
1057 count++; 1055 count++;
1058 } 1056 }
1059 1057
1060 if (count != 0) 1058 if (count != 0)
1061 rnd_add_uint32(usbnet_rndsrc(un), count); 1059 rnd_add_uint32(usbnet_rndsrc(un), count);
1062} 1060}
1063 1061
1064static unsigned 1062static unsigned
1065smsc_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 1063smsc_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
1066{ 1064{
1067 uint32_t txhdr; 1065 uint32_t txhdr;
1068 uint32_t frm_len = 0; 1066 uint32_t frm_len = 0;
1069 1067
1070 const size_t hdrsz = sizeof(txhdr) * 2; 1068 const size_t hdrsz = sizeof(txhdr) * 2;
1071 1069
1072 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdrsz) 1070 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdrsz)
1073 return 0; 1071 return 0;
1074 1072
1075 /* 1073 /*
1076 * Each frame is prefixed with two 32-bit values describing the 1074 * Each frame is prefixed with two 32-bit values describing the
1077 * length of the packet and buffer. 1075 * length of the packet and buffer.
1078 */ 1076 */
1079 txhdr = SMSC_TX_CTRL_0_BUF_SIZE(m->m_pkthdr.len) | 1077 txhdr = SMSC_TX_CTRL_0_BUF_SIZE(m->m_pkthdr.len) |
1080 SMSC_TX_CTRL_0_FIRST_SEG | SMSC_TX_CTRL_0_LAST_SEG; 1078 SMSC_TX_CTRL_0_FIRST_SEG | SMSC_TX_CTRL_0_LAST_SEG;
1081 txhdr = htole32(txhdr); 1079 txhdr = htole32(txhdr);
1082 memcpy(c->unc_buf, &txhdr, sizeof(txhdr)); 1080 memcpy(c->unc_buf, &txhdr, sizeof(txhdr));
1083 1081
1084 txhdr = SMSC_TX_CTRL_1_PKT_LENGTH(m->m_pkthdr.len); 1082 txhdr = SMSC_TX_CTRL_1_PKT_LENGTH(m->m_pkthdr.len);
1085 txhdr = htole32(txhdr); 1083 txhdr = htole32(txhdr);
1086 memcpy(c->unc_buf + sizeof(txhdr), &txhdr, sizeof(txhdr)); 1084 memcpy(c->unc_buf + sizeof(txhdr), &txhdr, sizeof(txhdr));
1087 1085
1088 frm_len += hdrsz; 1086 frm_len += hdrsz;
1089 1087
1090 /* Next copy in the actual packet */ 1088 /* Next copy in the actual packet */
1091 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + frm_len); 1089 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + frm_len);
1092 frm_len += m->m_pkthdr.len; 1090 frm_len += m->m_pkthdr.len;
1093 1091
1094 return frm_len; 1092 return frm_len;
1095} 1093}
1096 1094
1097#ifdef _MODULE 1095#ifdef _MODULE
1098#include "ioconf.c" 1096#include "ioconf.c"
1099#endif 1097#endif
1100 1098
1101USBNET_MODULE(smsc) 1099USBNET_MODULE(smsc)

cvs diff -r1.82 -r1.83 src/sys/dev/usb/if_udav.c (switch to unified diff)

--- src/sys/dev/usb/if_udav.c 2022/03/03 05:51:17 1.82
+++ src/sys/dev/usb/if_udav.c 2022/03/03 05:51:27 1.83
@@ -1,853 +1,851 @@ @@ -1,853 +1,851 @@
1/* $NetBSD: if_udav.c,v 1.82 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_udav.c,v 1.83 2022/03/03 05:51:27 riastradh Exp $ */
2/* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */ 2/* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2003 5 * Copyright (c) 2003
6 * Shingo WATANABE <nabe@nabechan.org>. All rights reserved. 6 * Shingo WATANABE <nabe@nabechan.org>. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the author nor the names of any co-contributors 16 * 3. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software 17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission. 18 * without specific prior written permission.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 * 31 *
32 */ 32 */
33 33
34/* 34/*
35 * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY) 35 * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
36 * The spec can be found at the following url. 36 * The spec can be found at the following url.
37 * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-F01-062202s.pdf 37 * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-F01-062202s.pdf
38 */ 38 */
39 39
40/* 40/*
41 * TODO: 41 * TODO:
42 * Interrupt Endpoint support 42 * Interrupt Endpoint support
43 * External PHYs 43 * External PHYs
44 * powerhook() support? 44 * powerhook() support?
45 */ 45 */
46 46
47#include <sys/cdefs.h> 47#include <sys/cdefs.h>
48__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.82 2022/03/03 05:51:17 riastradh Exp $"); 48__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.83 2022/03/03 05:51:27 riastradh Exp $");
49 49
50#ifdef _KERNEL_OPT 50#ifdef _KERNEL_OPT
51#include "opt_usb.h" 51#include "opt_usb.h"
52#endif 52#endif
53 53
54#include <sys/param.h> 54#include <sys/param.h>
55 55
56#include <dev/usb/usbnet.h> 56#include <dev/usb/usbnet.h>
57#include <dev/usb/if_udavreg.h> 57#include <dev/usb/if_udavreg.h>
58 58
59/* Function declarations */ 59/* Function declarations */
60static int udav_match(device_t, cfdata_t, void *); 60static int udav_match(device_t, cfdata_t, void *);
61static void udav_attach(device_t, device_t, void *); 61static void udav_attach(device_t, device_t, void *);
62 62
63CFATTACH_DECL_NEW(udav, sizeof(struct usbnet), udav_match, udav_attach, 63CFATTACH_DECL_NEW(udav, sizeof(struct usbnet), udav_match, udav_attach,
64 usbnet_detach, usbnet_activate); 64 usbnet_detach, usbnet_activate);
65 65
66static void udav_chip_init(struct usbnet *); 66static void udav_chip_init(struct usbnet *);
67 67
68static unsigned udav_uno_tx_prepare(struct usbnet *, struct mbuf *, 68static unsigned udav_uno_tx_prepare(struct usbnet *, struct mbuf *,
69 struct usbnet_chain *); 69 struct usbnet_chain *);
70static void udav_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 70static void udav_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
71static void udav_uno_stop(struct ifnet *, int); 71static void udav_uno_stop(struct ifnet *, int);
72static void udav_uno_mcast(struct ifnet *); 72static void udav_uno_mcast(struct ifnet *);
73static int udav_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 73static int udav_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
74static int udav_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 74static int udav_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
75static void udav_uno_mii_statchg(struct ifnet *); 75static void udav_uno_mii_statchg(struct ifnet *);
76static int udav_uno_init(struct ifnet *); 76static int udav_uno_init(struct ifnet *);
77static void udav_setiff_locked(struct usbnet *); 77static void udav_setiff_locked(struct usbnet *);
78static void udav_reset(struct usbnet *); 78static void udav_reset(struct usbnet *);
79 79
80static int udav_csr_read(struct usbnet *, int, void *, int); 80static int udav_csr_read(struct usbnet *, int, void *, int);
81static int udav_csr_write(struct usbnet *, int, void *, int); 81static int udav_csr_write(struct usbnet *, int, void *, int);
82static int udav_csr_read1(struct usbnet *, int); 82static int udav_csr_read1(struct usbnet *, int);
83static int udav_csr_write1(struct usbnet *, int, unsigned char); 83static int udav_csr_write1(struct usbnet *, int, unsigned char);
84 84
85#if 0 85#if 0
86static int udav_mem_read(struct usbnet *, int, void *, int); 86static int udav_mem_read(struct usbnet *, int, void *, int);
87static int udav_mem_write(struct usbnet *, int, void *, int); 87static int udav_mem_write(struct usbnet *, int, void *, int);
88static int udav_mem_write1(struct usbnet *, int, unsigned char); 88static int udav_mem_write1(struct usbnet *, int, unsigned char);
89#endif 89#endif
90 90
91/* Macros */ 91/* Macros */
92#ifdef UDAV_DEBUG 92#ifdef UDAV_DEBUG
93#define DPRINTF(x) if (udavdebug) printf x 93#define DPRINTF(x) if (udavdebug) printf x
94#define DPRINTFN(n, x) if (udavdebug >= (n)) printf x 94#define DPRINTFN(n, x) if (udavdebug >= (n)) printf x
95int udavdebug = 0; 95int udavdebug = 0;
96#else 96#else
97#define DPRINTF(x) 97#define DPRINTF(x)
98#define DPRINTFN(n, x) 98#define DPRINTFN(n, x)
99#endif 99#endif
100 100
101#define UDAV_SETBIT(un, reg, x) \ 101#define UDAV_SETBIT(un, reg, x) \
102 udav_csr_write1(un, reg, udav_csr_read1(un, reg) | (x)) 102 udav_csr_write1(un, reg, udav_csr_read1(un, reg) | (x))
103 103
104#define UDAV_CLRBIT(un, reg, x) \ 104#define UDAV_CLRBIT(un, reg, x) \
105 udav_csr_write1(un, reg, udav_csr_read1(un, reg) & ~(x)) 105 udav_csr_write1(un, reg, udav_csr_read1(un, reg) & ~(x))
106 106
107static const struct udav_type { 107static const struct udav_type {
108 struct usb_devno udav_dev; 108 struct usb_devno udav_dev;
109 uint16_t udav_flags; 109 uint16_t udav_flags;
110#define UDAV_EXT_PHY 0x0001 110#define UDAV_EXT_PHY 0x0001
111#define UDAV_NO_PHY 0x0002 111#define UDAV_NO_PHY 0x0002
112} udav_devs [] = { 112} udav_devs [] = {
113 /* Corega USB-TXC */ 113 /* Corega USB-TXC */
114 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0}, 114 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0},
115 /* ShanTou ST268 USB NIC */ 115 /* ShanTou ST268 USB NIC */
116 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268_USB_NIC }, 0}, 116 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268_USB_NIC }, 0},
117 /* ShanTou ADM8515 */ 117 /* ShanTou ADM8515 */
118 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515 }, 0}, 118 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515 }, 0},
119 /* SUNRISING SR9600 */ 119 /* SUNRISING SR9600 */
120 {{ USB_VENDOR_SUNRISING, USB_PRODUCT_SUNRISING_SR9600 }, 0 }, 120 {{ USB_VENDOR_SUNRISING, USB_PRODUCT_SUNRISING_SR9600 }, 0 },
121 /* SUNRISING QF9700 */ 121 /* SUNRISING QF9700 */
122 {{ USB_VENDOR_SUNRISING, USB_PRODUCT_SUNRISING_QF9700 }, UDAV_NO_PHY }, 122 {{ USB_VENDOR_SUNRISING, USB_PRODUCT_SUNRISING_QF9700 }, UDAV_NO_PHY },
123 /* QUAN DM9601 */ 123 /* QUAN DM9601 */
124 {{USB_VENDOR_QUAN, USB_PRODUCT_QUAN_DM9601 }, 0}, 124 {{USB_VENDOR_QUAN, USB_PRODUCT_QUAN_DM9601 }, 0},
125#if 0 125#if 0
126 /* DAVICOM DM9601 Generic? */ 126 /* DAVICOM DM9601 Generic? */
127 /* XXX: The following ids was obtained from the data sheet. */ 127 /* XXX: The following ids was obtained from the data sheet. */
128 {{ 0x0a46, 0x9601 }, 0}, 128 {{ 0x0a46, 0x9601 }, 0},
129#endif 129#endif
130}; 130};
131#define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p)) 131#define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p))
132 132
133static const struct usbnet_ops udav_ops = { 133static const struct usbnet_ops udav_ops = {
134 .uno_stop = udav_uno_stop, 134 .uno_stop = udav_uno_stop,
135 .uno_mcast = udav_uno_mcast, 135 .uno_mcast = udav_uno_mcast,
136 .uno_read_reg = udav_uno_mii_read_reg, 136 .uno_read_reg = udav_uno_mii_read_reg,
137 .uno_write_reg = udav_uno_mii_write_reg, 137 .uno_write_reg = udav_uno_mii_write_reg,
138 .uno_statchg = udav_uno_mii_statchg, 138 .uno_statchg = udav_uno_mii_statchg,
139 .uno_tx_prepare = udav_uno_tx_prepare, 139 .uno_tx_prepare = udav_uno_tx_prepare,
140 .uno_rx_loop = udav_uno_rx_loop, 140 .uno_rx_loop = udav_uno_rx_loop,
141 .uno_init = udav_uno_init, 141 .uno_init = udav_uno_init,
142}; 142};
143 143
144/* Probe */ 144/* Probe */
145static int 145static int
146udav_match(device_t parent, cfdata_t match, void *aux) 146udav_match(device_t parent, cfdata_t match, void *aux)
147{ 147{
148 struct usb_attach_arg *uaa = aux; 148 struct usb_attach_arg *uaa = aux;
149 149
150 return udav_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 150 return udav_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
151 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 151 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
152} 152}
153 153
154/* Attach */ 154/* Attach */
155static void 155static void
156udav_attach(device_t parent, device_t self, void *aux) 156udav_attach(device_t parent, device_t self, void *aux)
157{ 157{
158 USBNET_MII_DECL_DEFAULT(unm); 158 USBNET_MII_DECL_DEFAULT(unm);
159 struct usbnet_mii *unmp; 159 struct usbnet_mii *unmp;
160 struct usbnet * const un = device_private(self); 160 struct usbnet * const un = device_private(self);
161 struct usb_attach_arg *uaa = aux; 161 struct usb_attach_arg *uaa = aux;
162 struct usbd_device *dev = uaa->uaa_device; 162 struct usbd_device *dev = uaa->uaa_device;
163 struct usbd_interface *iface; 163 struct usbd_interface *iface;
164 usbd_status err; 164 usbd_status err;
165 usb_interface_descriptor_t *id; 165 usb_interface_descriptor_t *id;
166 usb_endpoint_descriptor_t *ed; 166 usb_endpoint_descriptor_t *ed;
167 char *devinfop; 167 char *devinfop;
168 int i; 168 int i;
169 169
170 aprint_naive("\n"); 170 aprint_naive("\n");
171 aprint_normal("\n"); 171 aprint_normal("\n");
172 devinfop = usbd_devinfo_alloc(dev, 0); 172 devinfop = usbd_devinfo_alloc(dev, 0);
173 aprint_normal_dev(self, "%s\n", devinfop); 173 aprint_normal_dev(self, "%s\n", devinfop);
174 usbd_devinfo_free(devinfop); 174 usbd_devinfo_free(devinfop);
175 175
176 un->un_dev = self; 176 un->un_dev = self;
177 un->un_udev = dev; 177 un->un_udev = dev;
178 un->un_sc = un; 178 un->un_sc = un;
179 un->un_ops = &udav_ops; 179 un->un_ops = &udav_ops;
180 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 180 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
181 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 181 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
182 un->un_rx_list_cnt = UDAV_RX_LIST_CNT; 182 un->un_rx_list_cnt = UDAV_RX_LIST_CNT;
183 un->un_tx_list_cnt = UDAV_TX_LIST_CNT; 183 un->un_tx_list_cnt = UDAV_TX_LIST_CNT;
184 un->un_rx_bufsz = UDAV_BUFSZ; 184 un->un_rx_bufsz = UDAV_BUFSZ;
185 un->un_tx_bufsz = UDAV_BUFSZ; 185 un->un_tx_bufsz = UDAV_BUFSZ;
186 186
187 /* Move the device into the configured state. */ 187 /* Move the device into the configured state. */
188 err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1); /* idx 0 */ 188 err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1); /* idx 0 */
189 if (err) { 189 if (err) {
190 aprint_error_dev(self, "failed to set configuration" 190 aprint_error_dev(self, "failed to set configuration"
191 ", err=%s\n", usbd_errstr(err)); 191 ", err=%s\n", usbd_errstr(err));
192 return; 192 return;
193 } 193 }
194 194
195 /* get control interface */ 195 /* get control interface */
196 err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface); 196 err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface);
197 if (err) { 197 if (err) {
198 aprint_error_dev(self, "failed to get interface, err=%s\n", 198 aprint_error_dev(self, "failed to get interface, err=%s\n",
199 usbd_errstr(err)); 199 usbd_errstr(err));
200 return; 200 return;
201 } 201 }
202 202
203 un->un_iface = iface; 203 un->un_iface = iface;
204 un->un_flags = udav_lookup(uaa->uaa_vendor, 204 un->un_flags = udav_lookup(uaa->uaa_vendor,
205 uaa->uaa_product)->udav_flags; 205 uaa->uaa_product)->udav_flags;
206 206
207 /* get interface descriptor */ 207 /* get interface descriptor */
208 id = usbd_get_interface_descriptor(un->un_iface); 208 id = usbd_get_interface_descriptor(un->un_iface);
209 209
210 /* find endpoints */ 210 /* find endpoints */
211 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] = 211 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] =
212 un->un_ed[USBNET_ENDPT_INTR] = -1; 212 un->un_ed[USBNET_ENDPT_INTR] = -1;
213 for (i = 0; i < id->bNumEndpoints; i++) { 213 for (i = 0; i < id->bNumEndpoints; i++) {
214 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 214 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
215 if (ed == NULL) { 215 if (ed == NULL) {
216 aprint_error_dev(self, "couldn't get endpoint %d\n", i); 216 aprint_error_dev(self, "couldn't get endpoint %d\n", i);
217 return; 217 return;
218 } 218 }
219 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 219 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
220 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 220 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
221 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 221 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
222 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 222 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
223 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) 223 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
224 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 224 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
225 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT && 225 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
226 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 226 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
227 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 227 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
228 } 228 }
229 229
230 if (un->un_ed[USBNET_ENDPT_RX] == 0 || 230 if (un->un_ed[USBNET_ENDPT_RX] == 0 ||
231 un->un_ed[USBNET_ENDPT_TX] == 0 || 231 un->un_ed[USBNET_ENDPT_TX] == 0 ||
232 un->un_ed[USBNET_ENDPT_INTR] == 0) { 232 un->un_ed[USBNET_ENDPT_INTR] == 0) {
233 aprint_error_dev(self, "missing endpoint\n"); 233 aprint_error_dev(self, "missing endpoint\n");
234 return; 234 return;
235 } 235 }
236 236
237 /* Not supported yet. */ 237 /* Not supported yet. */
238 un->un_ed[USBNET_ENDPT_INTR] = 0; 238 un->un_ed[USBNET_ENDPT_INTR] = 0;
239 239
240 usbnet_attach(un, "udavdet"); 240 usbnet_attach(un, "udavdet");
241 241
242 usbnet_lock_core(un); 242 usbnet_lock_core(un);
243 usbnet_busy(un); 243 usbnet_busy(un);
244 244
245// /* reset the adapter */ 245// /* reset the adapter */
246// udav_reset(un); 246// udav_reset(un);
247 247
248 /* Get Ethernet Address */ 248 /* Get Ethernet Address */
249 err = udav_csr_read(un, UDAV_PAR, un->un_eaddr, ETHER_ADDR_LEN); 249 err = udav_csr_read(un, UDAV_PAR, un->un_eaddr, ETHER_ADDR_LEN);
250 usbnet_unbusy(un); 250 usbnet_unbusy(un);
251 usbnet_unlock_core(un); 251 usbnet_unlock_core(un);
252 if (err) { 252 if (err) {
253 aprint_error_dev(self, "read MAC address failed\n"); 253 aprint_error_dev(self, "read MAC address failed\n");
254 return; 254 return;
255 } 255 }
256 256
257 if (ISSET(un->un_flags, UDAV_NO_PHY)) 257 if (ISSET(un->un_flags, UDAV_NO_PHY))
258 unmp = NULL; 258 unmp = NULL;
259 else 259 else
260 unmp = &unm; 260 unmp = &unm;
261 261
262 /* initialize interface information */ 262 /* initialize interface information */
263 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 263 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
264 0, unmp); 264 0, unmp);
265 265
266 return; 266 return;
267} 267}
268 268
269#if 0 269#if 0
270/* read memory */ 270/* read memory */
271static int 271static int
272udav_mem_read(struct usbnet *un, int offset, void *buf, int len) 272udav_mem_read(struct usbnet *un, int offset, void *buf, int len)
273{ 273{
274 usb_device_request_t req; 274 usb_device_request_t req;
275 usbd_status err; 275 usbd_status err;
276 276
277 DPRINTFN(0x200, 277 DPRINTFN(0x200,
278 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 278 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
279 279
280 if (usbnet_isdying(un)) 280 if (usbnet_isdying(un))
281 return 0; 281 return 0;
282 282
283 offset &= 0xffff; 283 offset &= 0xffff;
284 len &= 0xff; 284 len &= 0xff;
285 285
286 req.bmRequestType = UT_READ_VENDOR_DEVICE; 286 req.bmRequestType = UT_READ_VENDOR_DEVICE;
287 req.bRequest = UDAV_REQ_MEM_READ; 287 req.bRequest = UDAV_REQ_MEM_READ;
288 USETW(req.wValue, 0x0000); 288 USETW(req.wValue, 0x0000);
289 USETW(req.wIndex, offset); 289 USETW(req.wIndex, offset);
290 USETW(req.wLength, len); 290 USETW(req.wLength, len);
291 291
292 err = usbd_do_request(un->un_udev, &req, buf); 292 err = usbd_do_request(un->un_udev, &req, buf);
293 if (err) { 293 if (err) {
294 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n", 294 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
295 device_xname(un->un_dev), __func__, offset, err)); 295 device_xname(un->un_dev), __func__, offset, err));
296 } 296 }
297 297
298 return err; 298 return err;
299} 299}
300 300
301/* write memory */ 301/* write memory */
302static int 302static int
303udav_mem_write(struct usbnet *un, int offset, void *buf, int len) 303udav_mem_write(struct usbnet *un, int offset, void *buf, int len)
304{ 304{
305 usb_device_request_t req; 305 usb_device_request_t req;
306 usbd_status err; 306 usbd_status err;
307 307
308 DPRINTFN(0x200, 308 DPRINTFN(0x200,
309 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 309 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
310 310
311 if (usbnet_isdying(un)) 311 if (usbnet_isdying(un))
312 return 0; 312 return 0;
313 313
314 offset &= 0xffff; 314 offset &= 0xffff;
315 len &= 0xff; 315 len &= 0xff;
316 316
317 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 317 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
318 req.bRequest = UDAV_REQ_MEM_WRITE; 318 req.bRequest = UDAV_REQ_MEM_WRITE;
319 USETW(req.wValue, 0x0000); 319 USETW(req.wValue, 0x0000);
320 USETW(req.wIndex, offset); 320 USETW(req.wIndex, offset);
321 USETW(req.wLength, len); 321 USETW(req.wLength, len);
322 322
323 err = usbd_do_request(un->un_udev, &req, buf); 323 err = usbd_do_request(un->un_udev, &req, buf);
324 if (err) { 324 if (err) {
325 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 325 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
326 device_xname(un->un_dev), __func__, offset, err)); 326 device_xname(un->un_dev), __func__, offset, err));
327 } 327 }
328 328
329 return err; 329 return err;
330} 330}
331 331
332/* write memory */ 332/* write memory */
333static int 333static int
334udav_mem_write1(struct usbnet *un, int offset, unsigned char ch) 334udav_mem_write1(struct usbnet *un, int offset, unsigned char ch)
335{ 335{
336 usb_device_request_t req; 336 usb_device_request_t req;
337 usbd_status err; 337 usbd_status err;
338 338
339 DPRINTFN(0x200, 339 DPRINTFN(0x200,
340 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 340 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
341 341
342 if (usbnet_isdying(un)) 342 if (usbnet_isdying(un))
343 return 0; 343 return 0;
344 344
345 offset &= 0xffff; 345 offset &= 0xffff;
346 346
347 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 347 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
348 req.bRequest = UDAV_REQ_MEM_WRITE1; 348 req.bRequest = UDAV_REQ_MEM_WRITE1;
349 USETW(req.wValue, ch); 349 USETW(req.wValue, ch);
350 USETW(req.wIndex, offset); 350 USETW(req.wIndex, offset);
351 USETW(req.wLength, 0x0000); 351 USETW(req.wLength, 0x0000);
352 352
353 err = usbd_do_request(un->un_udev, &req, NULL); 353 err = usbd_do_request(un->un_udev, &req, NULL);
354 if (err) { 354 if (err) {
355 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 355 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
356 device_xname(un->un_dev), __func__, offset, err)); 356 device_xname(un->un_dev), __func__, offset, err));
357 } 357 }
358 358
359 return err; 359 return err;
360} 360}
361#endif 361#endif
362 362
363/* read register(s) */ 363/* read register(s) */
364static int 364static int
365udav_csr_read(struct usbnet *un, int offset, void *buf, int len) 365udav_csr_read(struct usbnet *un, int offset, void *buf, int len)
366{ 366{
367 usb_device_request_t req; 367 usb_device_request_t req;
368 usbd_status err; 368 usbd_status err;
369 369
370 usbnet_isowned_core(un); 370 usbnet_isowned_core(un);
371 KASSERT(!usbnet_isdying(un)); 371 KASSERT(!usbnet_isdying(un));
372 372
373 DPRINTFN(0x200, 373 DPRINTFN(0x200,
374 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 374 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
375 375
376 offset &= 0xff; 376 offset &= 0xff;
377 len &= 0xff; 377 len &= 0xff;
378 378
379 req.bmRequestType = UT_READ_VENDOR_DEVICE; 379 req.bmRequestType = UT_READ_VENDOR_DEVICE;
380 req.bRequest = UDAV_REQ_REG_READ; 380 req.bRequest = UDAV_REQ_REG_READ;
381 USETW(req.wValue, 0x0000); 381 USETW(req.wValue, 0x0000);
382 USETW(req.wIndex, offset); 382 USETW(req.wIndex, offset);
383 USETW(req.wLength, len); 383 USETW(req.wLength, len);
384 384
385 err = usbd_do_request(un->un_udev, &req, buf); 385 err = usbd_do_request(un->un_udev, &req, buf);
386 if (err) { 386 if (err) {
387 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n", 387 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
388 device_xname(un->un_dev), __func__, offset, err)); 388 device_xname(un->un_dev), __func__, offset, err));
389 } 389 }
390 390
391 return err; 391 return err;
392} 392}
393 393
394/* write register(s) */ 394/* write register(s) */
395static int 395static int
396udav_csr_write(struct usbnet *un, int offset, void *buf, int len) 396udav_csr_write(struct usbnet *un, int offset, void *buf, int len)
397{ 397{
398 usb_device_request_t req; 398 usb_device_request_t req;
399 usbd_status err; 399 usbd_status err;
400 400
401 usbnet_isowned_core(un); 401 usbnet_isowned_core(un);
402 KASSERT(!usbnet_isdying(un)); 402 KASSERT(!usbnet_isdying(un));
403 403
404 DPRINTFN(0x200, 404 DPRINTFN(0x200,
405 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 405 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
406 406
407 offset &= 0xff; 407 offset &= 0xff;
408 len &= 0xff; 408 len &= 0xff;
409 409
410 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 410 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
411 req.bRequest = UDAV_REQ_REG_WRITE; 411 req.bRequest = UDAV_REQ_REG_WRITE;
412 USETW(req.wValue, 0x0000); 412 USETW(req.wValue, 0x0000);
413 USETW(req.wIndex, offset); 413 USETW(req.wIndex, offset);
414 USETW(req.wLength, len); 414 USETW(req.wLength, len);
415 415
416 err = usbd_do_request(un->un_udev, &req, buf); 416 err = usbd_do_request(un->un_udev, &req, buf);
417 if (err) { 417 if (err) {
418 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 418 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
419 device_xname(un->un_dev), __func__, offset, err)); 419 device_xname(un->un_dev), __func__, offset, err));
420 } 420 }
421 421
422 return err; 422 return err;
423} 423}
424 424
425static int 425static int
426udav_csr_read1(struct usbnet *un, int offset) 426udav_csr_read1(struct usbnet *un, int offset)
427{ 427{
428 uint8_t val = 0; 428 uint8_t val = 0;
429 429
430 usbnet_isowned_core(un); 430 usbnet_isowned_core(un);
431 431
432 DPRINTFN(0x200, 432 DPRINTFN(0x200,
433 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 433 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
434 434
435 if (usbnet_isdying(un)) 435 if (usbnet_isdying(un))
436 return 0; 436 return 0;
437 437
438 return udav_csr_read(un, offset, &val, 1) ? 0 : val; 438 return udav_csr_read(un, offset, &val, 1) ? 0 : val;
439} 439}
440 440
441/* write a register */ 441/* write a register */
442static int 442static int
443udav_csr_write1(struct usbnet *un, int offset, unsigned char ch) 443udav_csr_write1(struct usbnet *un, int offset, unsigned char ch)
444{ 444{
445 usb_device_request_t req; 445 usb_device_request_t req;
446 usbd_status err; 446 usbd_status err;
447 447
448 usbnet_isowned_core(un); 448 usbnet_isowned_core(un);
449 KASSERT(!usbnet_isdying(un)); 449 KASSERT(!usbnet_isdying(un));
450 450
451 DPRINTFN(0x200, 451 DPRINTFN(0x200,
452 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 452 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
453 453
454 offset &= 0xff; 454 offset &= 0xff;
455 455
456 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 456 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
457 req.bRequest = UDAV_REQ_REG_WRITE1; 457 req.bRequest = UDAV_REQ_REG_WRITE1;
458 USETW(req.wValue, ch); 458 USETW(req.wValue, ch);
459 USETW(req.wIndex, offset); 459 USETW(req.wIndex, offset);
460 USETW(req.wLength, 0x0000); 460 USETW(req.wLength, 0x0000);
461 461
462 err = usbd_do_request(un->un_udev, &req, NULL); 462 err = usbd_do_request(un->un_udev, &req, NULL);
463 if (err) { 463 if (err) {
464 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 464 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
465 device_xname(un->un_dev), __func__, offset, err)); 465 device_xname(un->un_dev), __func__, offset, err));
466 } 466 }
467 467
468 return err; 468 return err;
469} 469}
470 470
471static int 471static int
472udav_uno_init(struct ifnet *ifp) 472udav_uno_init(struct ifnet *ifp)
473{ 473{
474 struct usbnet * const un = ifp->if_softc; 474 struct usbnet * const un = ifp->if_softc;
475 struct mii_data * const mii = usbnet_mii(un); 475 struct mii_data * const mii = usbnet_mii(un);
476 uint8_t eaddr[ETHER_ADDR_LEN]; 476 uint8_t eaddr[ETHER_ADDR_LEN];
477 int rc = 0; 477 int rc = 0;
478 478
479 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 479 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
480 480
481 if (usbnet_isdying(un)) { 481 if (usbnet_isdying(un)) {
482 return EIO; 482 return EIO;
483 } 483 }
484 484
485 /* Cancel pending I/O and free all TX/RX buffers */ 485 /* Cancel pending I/O and free all TX/RX buffers */
486 if (ifp->if_flags & IFF_RUNNING) 486 if (ifp->if_flags & IFF_RUNNING)
487 usbnet_stop(un, ifp, 1); 487 usbnet_stop(un, ifp, 1);
488 488
489 memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr)); 489 memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr));
490 udav_csr_write(un, UDAV_PAR, eaddr, ETHER_ADDR_LEN); 490 udav_csr_write(un, UDAV_PAR, eaddr, ETHER_ADDR_LEN);
491 491
492 /* Initialize network control register */ 492 /* Initialize network control register */
493 /* Disable loopback */ 493 /* Disable loopback */
494 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1); 494 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
495 495
496 /* Initialize RX control register */ 496 /* Initialize RX control register */
497 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC); 497 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
498 498
499 /* If we want promiscuous mode, accept all physical frames. */ 499 /* If we want promiscuous mode, accept all physical frames. */
500 if (ifp->if_flags & IFF_PROMISC) 500 if (ifp->if_flags & IFF_PROMISC)
501 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC); 501 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
502 else 502 else
503 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC); 503 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
504 504
505 /* Load the multicast filter */ 505 /* Load the multicast filter */
506 udav_setiff_locked(un); 506 udav_setiff_locked(un);
507 507
508 /* Enable RX */ 508 /* Enable RX */
509 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_RXEN); 509 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_RXEN);
510 510
511 /* clear POWER_DOWN state of internal PHY */ 511 /* clear POWER_DOWN state of internal PHY */
512 UDAV_SETBIT(un, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0); 512 UDAV_SETBIT(un, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
513 UDAV_CLRBIT(un, UDAV_GPR, UDAV_GPR_GEPIO0); 513 UDAV_CLRBIT(un, UDAV_GPR, UDAV_GPR_GEPIO0);
514 514
515 if (mii && (rc = mii_mediachg(mii)) == ENXIO) 515 if (mii && (rc = mii_mediachg(mii)) == ENXIO)
516 rc = 0; 516 rc = 0;
517 517
518 if (rc != 0) { 518 if (rc != 0) {
519 return rc; 519 return rc;
520 } 520 }
521 521
522 if (usbnet_isdying(un)) 522 if (usbnet_isdying(un))
523 rc = EIO; 523 rc = EIO;
524 else 524 else
525 rc = usbnet_init_rx_tx(un); 525 rc = usbnet_init_rx_tx(un);
526 526
527 return rc; 527 return rc;
528} 528}
529 529
530static void 530static void
531udav_reset(struct usbnet *un) 531udav_reset(struct usbnet *un)
532{ 532{
533 usbnet_isowned_core(un); 533 usbnet_isowned_core(un);
534 534
535 if (usbnet_isdying(un)) 535 if (usbnet_isdying(un))
536 return; 536 return;
537 537
538 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 538 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
539 539
540 udav_chip_init(un); 540 udav_chip_init(un);
541} 541}
542 542
543static void 543static void
544udav_chip_init(struct usbnet *un) 544udav_chip_init(struct usbnet *un)
545{ 545{
546 usbnet_isowned_core(un); 546 usbnet_isowned_core(un);
547 547
548 /* Select PHY */ 548 /* Select PHY */
549#if 1 549#if 1
550 /* 550 /*
551 * XXX: force select internal phy. 551 * XXX: force select internal phy.
552 * external phy routines are not tested. 552 * external phy routines are not tested.
553 */ 553 */
554 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY); 554 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY);
555#else 555#else
556 if (un->un_flags & UDAV_EXT_PHY) { 556 if (un->un_flags & UDAV_EXT_PHY) {
557 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY); 557 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY);
558 } else { 558 } else {
559 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY); 559 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY);
560 } 560 }
561#endif 561#endif
562 562
563 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_RST); 563 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_RST);
564 564
565 for (int i = 0; i < UDAV_TX_TIMEOUT; i++) { 565 for (int i = 0; i < UDAV_TX_TIMEOUT; i++) {
566 if (usbnet_isdying(un)) 566 if (usbnet_isdying(un))
567 return; 567 return;
568 if (!(udav_csr_read1(un, UDAV_NCR) & UDAV_NCR_RST)) 568 if (!(udav_csr_read1(un, UDAV_NCR) & UDAV_NCR_RST))
569 break; 569 break;
570 delay(10); /* XXX */ 570 delay(10); /* XXX */
571 } 571 }
572 delay(10000); /* XXX */ 572 delay(10000); /* XXX */
573} 573}
574 574
575#define UDAV_BITS 6 575#define UDAV_BITS 6
576 576
577#define UDAV_CALCHASH(addr) \ 577#define UDAV_CALCHASH(addr) \
578 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1)) 578 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1))
579 579
580static void 580static void
581udav_setiff_locked(struct usbnet *un) 581udav_setiff_locked(struct usbnet *un)
582{ 582{
583 struct ethercom *ec = usbnet_ec(un); 583 struct ethercom *ec = usbnet_ec(un);
584 struct ifnet * const ifp = usbnet_ifp(un); 584 struct ifnet * const ifp = usbnet_ifp(un);
585 struct ether_multi *enm; 585 struct ether_multi *enm;
586 struct ether_multistep step; 586 struct ether_multistep step;
587 uint8_t hashes[8]; 587 uint8_t hashes[8];
588 int h = 0; 588 int h = 0;
589 589
590 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 590 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
591 591
592 usbnet_isowned_core(un); 592 usbnet_isowned_core(un);
593 593
594 if (usbnet_isdying(un)) 594 if (usbnet_isdying(un))
595 return; 595 return;
596 596
597 if (ISSET(un->un_flags, UDAV_NO_PHY)) { 597 if (ISSET(un->un_flags, UDAV_NO_PHY)) {
598 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL); 598 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL);
599 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_PRMSC); 599 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_PRMSC);
600 return; 600 return;
601 } 601 }
602 602
603 if (ifp->if_flags & IFF_PROMISC) { 603 if (ifp->if_flags & IFF_PROMISC) {
604 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC); 604 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
605 return; 605 return;
606 } else if (ifp->if_flags & IFF_ALLMULTI) { 606 } else if (ifp->if_flags & IFF_ALLMULTI) {
607allmulti: 607allmulti:
608 ifp->if_flags |= IFF_ALLMULTI; 608 ifp->if_flags |= IFF_ALLMULTI;
609 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL); 609 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL);
610 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_PRMSC); 610 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_PRMSC);
611 return; 611 return;
612 } 612 }
613 613
614 /* first, zot all the existing hash bits */ 614 /* first, zot all the existing hash bits */
615 memset(hashes, 0x00, sizeof(hashes)); 615 memset(hashes, 0x00, sizeof(hashes));
616 hashes[7] |= 0x80; /* broadcast address */ 616 hashes[7] |= 0x80; /* broadcast address */
617 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes)); 617 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes));
618 618
619 /* now program new ones */ 619 /* now program new ones */
620 ETHER_LOCK(ec); 620 ETHER_LOCK(ec);
621 ETHER_FIRST_MULTI(step, ec, enm); 621 ETHER_FIRST_MULTI(step, ec, enm);
622 while (enm != NULL) { 622 while (enm != NULL) {
623 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 623 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
624 ETHER_ADDR_LEN) != 0) { 624 ETHER_ADDR_LEN) != 0) {
625 ETHER_UNLOCK(ec); 625 ETHER_UNLOCK(ec);
626 goto allmulti; 626 goto allmulti;
627 } 627 }
628 628
629 h = UDAV_CALCHASH(enm->enm_addrlo); 629 h = UDAV_CALCHASH(enm->enm_addrlo);
630 hashes[h>>3] |= 1 << (h & 0x7); 630 hashes[h>>3] |= 1 << (h & 0x7);
631 ETHER_NEXT_MULTI(step, enm); 631 ETHER_NEXT_MULTI(step, enm);
632 } 632 }
633 ETHER_UNLOCK(ec); 633 ETHER_UNLOCK(ec);
634 634
635 /* disable all multicast */ 635 /* disable all multicast */
636 ifp->if_flags &= ~IFF_ALLMULTI; 636 ifp->if_flags &= ~IFF_ALLMULTI;
637 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL); 637 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL);
638 638
639 /* write hash value to the register */ 639 /* write hash value to the register */
640 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes)); 640 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes));
641} 641}
642 642
643static unsigned 643static unsigned
644udav_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 644udav_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
645{ 645{
646 int total_len; 646 int total_len;
647 uint8_t *buf = c->unc_buf; 647 uint8_t *buf = c->unc_buf;
648 648
649 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 649 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
650 650
651 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2) 651 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2)
652 return 0; 652 return 0;
653 653
654 /* Copy the mbuf data into a contiguous buffer */ 654 /* Copy the mbuf data into a contiguous buffer */
655 m_copydata(m, 0, m->m_pkthdr.len, buf + 2); 655 m_copydata(m, 0, m->m_pkthdr.len, buf + 2);
656 total_len = m->m_pkthdr.len; 656 total_len = m->m_pkthdr.len;
657 if (total_len < UDAV_MIN_FRAME_LEN) { 657 if (total_len < UDAV_MIN_FRAME_LEN) {
658 memset(buf + 2 + total_len, 0, 658 memset(buf + 2 + total_len, 0,
659 UDAV_MIN_FRAME_LEN - total_len); 659 UDAV_MIN_FRAME_LEN - total_len);
660 total_len = UDAV_MIN_FRAME_LEN; 660 total_len = UDAV_MIN_FRAME_LEN;
661 } 661 }
662 662
663 /* Frame length is specified in the first 2bytes of the buffer */ 663 /* Frame length is specified in the first 2bytes of the buffer */
664 buf[0] = (uint8_t)total_len; 664 buf[0] = (uint8_t)total_len;
665 buf[1] = (uint8_t)(total_len >> 8); 665 buf[1] = (uint8_t)(total_len >> 8);
666 total_len += 2; 666 total_len += 2;
667 667
668 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev), 668 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev),
669 __func__, total_len)); 669 __func__, total_len));
670 670
671 return total_len; 671 return total_len;
672} 672}
673 673
674static void 674static void
675udav_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 675udav_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
676{ 676{
677 struct ifnet *ifp = usbnet_ifp(un); 677 struct ifnet *ifp = usbnet_ifp(un);
678 uint8_t *buf = c->unc_buf; 678 uint8_t *buf = c->unc_buf;
679 uint16_t pkt_len; 679 uint16_t pkt_len;
680 uint8_t pktstat; 680 uint8_t pktstat;
681 681
682 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 682 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
683 683
684 /* first byte in received data */ 684 /* first byte in received data */
685 pktstat = *buf; 685 pktstat = *buf;
686 total_len -= sizeof(pktstat); 686 total_len -= sizeof(pktstat);
687 buf += sizeof(pktstat); 687 buf += sizeof(pktstat);
688 688
689 DPRINTF(("%s: RX Status: 0x%02x\n", device_xname(un->un_dev), pktstat)); 689 DPRINTF(("%s: RX Status: 0x%02x\n", device_xname(un->un_dev), pktstat));
690 690
691 pkt_len = UGETW(buf); 691 pkt_len = UGETW(buf);
692 total_len -= sizeof(pkt_len); 692 total_len -= sizeof(pkt_len);
693 buf += sizeof(pkt_len); 693 buf += sizeof(pkt_len);
694 694
695 DPRINTF(("%s: RX Length: 0x%02x\n", device_xname(un->un_dev), pkt_len)); 695 DPRINTF(("%s: RX Length: 0x%02x\n", device_xname(un->un_dev), pkt_len));
696 696
697 if (pktstat & UDAV_RSR_LCS) { 697 if (pktstat & UDAV_RSR_LCS) {
698 if_statinc(ifp, if_collisions); 698 if_statinc(ifp, if_collisions);
699 return; 699 return;
700 } 700 }
701 701
702 if (pkt_len < sizeof(struct ether_header) || 702 if (pkt_len < sizeof(struct ether_header) ||
703 pkt_len > total_len || 703 pkt_len > total_len ||
704 (pktstat & UDAV_RSR_ERR)) { 704 (pktstat & UDAV_RSR_ERR)) {
705 if_statinc(ifp, if_ierrors); 705 if_statinc(ifp, if_ierrors);
706 return; 706 return;
707 } 707 }
708 708
709 pkt_len -= ETHER_CRC_LEN; 709 pkt_len -= ETHER_CRC_LEN;
710 710
711 DPRINTF(("%s: Rx deliver: 0x%02x\n", device_xname(un->un_dev), pkt_len)); 711 DPRINTF(("%s: Rx deliver: 0x%02x\n", device_xname(un->un_dev), pkt_len));
712 712
713 usbnet_enqueue(un, buf, pkt_len, 0, 0, 0); 713 usbnet_enqueue(un, buf, pkt_len, 0, 0, 0);
714} 714}
715 715
716static void 716static void
717udav_uno_mcast(struct ifnet *ifp) 717udav_uno_mcast(struct ifnet *ifp)
718{ 718{
719 struct usbnet * const un = ifp->if_softc; 719 struct usbnet * const un = ifp->if_softc;
720 720
721 usbnet_lock_core(un); 721 usbnet_lock_core(un);
722 usbnet_busy(un); 
723 722
724 udav_setiff_locked(un); 723 udav_setiff_locked(un);
725 724
726 usbnet_unbusy(un); 
727 usbnet_unlock_core(un); 725 usbnet_unlock_core(un);
728} 726}
729 727
730/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */ 728/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
731static void 729static void
732udav_uno_stop(struct ifnet *ifp, int disable) 730udav_uno_stop(struct ifnet *ifp, int disable)
733{ 731{
734 struct usbnet * const un = ifp->if_softc; 732 struct usbnet * const un = ifp->if_softc;
735 733
736 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 734 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
737 735
738 udav_reset(un); 736 udav_reset(un);
739} 737}
740 738
741static int 739static int
742udav_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 740udav_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
743{ 741{
744 uint8_t data[2]; 742 uint8_t data[2];
745 743
746 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", 744 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
747 device_xname(un->un_dev), __func__, phy, reg)); 745 device_xname(un->un_dev), __func__, phy, reg));
748 746
749 if (usbnet_isdying(un)) { 747 if (usbnet_isdying(un)) {
750#ifdef DIAGNOSTIC 748#ifdef DIAGNOSTIC
751 printf("%s: %s: dying\n", device_xname(un->un_dev), 749 printf("%s: %s: dying\n", device_xname(un->un_dev),
752 __func__); 750 __func__);
753#endif 751#endif
754 return EINVAL; 752 return EINVAL;
755 } 753 }
756 754
757 /* XXX: one PHY only for the internal PHY */ 755 /* XXX: one PHY only for the internal PHY */
758 if (phy != 0) { 756 if (phy != 0) {
759 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 757 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
760 device_xname(un->un_dev), __func__, phy)); 758 device_xname(un->un_dev), __func__, phy));
761 return EINVAL; 759 return EINVAL;
762 } 760 }
763 761
764 /* select internal PHY and set PHY register address */ 762 /* select internal PHY and set PHY register address */
765 udav_csr_write1(un, UDAV_EPAR, 763 udav_csr_write1(un, UDAV_EPAR,
766 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); 764 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
767 765
768 /* select PHY operation and start read command */ 766 /* select PHY operation and start read command */
769 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR); 767 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
770 768
771 /* XXX: should be wait? */ 769 /* XXX: should be wait? */
772 770
773 /* end read command */ 771 /* end read command */
774 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRR); 772 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRR);
775 773
776 /* retrieve the result from data registers */ 774 /* retrieve the result from data registers */
777 udav_csr_read(un, UDAV_EPDRL, data, 2); 775 udav_csr_read(un, UDAV_EPDRL, data, 2);
778 776
779 *val = data[0] | (data[1] << 8); 777 *val = data[0] | (data[1] << 8);
780 778
781 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n", 779 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n",
782 device_xname(un->un_dev), __func__, phy, reg, *val)); 780 device_xname(un->un_dev), __func__, phy, reg, *val));
783 781
784 return 0; 782 return 0;
785} 783}
786 784
787static int 785static int
788udav_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 786udav_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
789{ 787{
790 uint8_t data[2]; 788 uint8_t data[2];
791 789
792 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n", 790 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n",
793 device_xname(un->un_dev), __func__, phy, reg, val)); 791 device_xname(un->un_dev), __func__, phy, reg, val));
794 792
795 if (usbnet_isdying(un)) { 793 if (usbnet_isdying(un)) {
796#ifdef DIAGNOSTIC 794#ifdef DIAGNOSTIC
797 printf("%s: %s: dying\n", device_xname(un->un_dev), 795 printf("%s: %s: dying\n", device_xname(un->un_dev),
798 __func__); 796 __func__);
799#endif 797#endif
800 return EIO; 798 return EIO;
801 } 799 }
802 800
803 /* XXX: one PHY only for the internal PHY */ 801 /* XXX: one PHY only for the internal PHY */
804 if (phy != 0) { 802 if (phy != 0) {
805 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 803 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
806 device_xname(un->un_dev), __func__, phy)); 804 device_xname(un->un_dev), __func__, phy));
807 return EIO; 805 return EIO;
808 } 806 }
809 807
810 /* select internal PHY and set PHY register address */ 808 /* select internal PHY and set PHY register address */
811 udav_csr_write1(un, UDAV_EPAR, 809 udav_csr_write1(un, UDAV_EPAR,
812 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); 810 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
813 811
814 /* put the value to the data registers */ 812 /* put the value to the data registers */
815 data[0] = val & 0xff; 813 data[0] = val & 0xff;
816 data[1] = (val >> 8) & 0xff; 814 data[1] = (val >> 8) & 0xff;
817 udav_csr_write(un, UDAV_EPDRL, data, 2); 815 udav_csr_write(un, UDAV_EPDRL, data, 2);
818 816
819 /* select PHY operation and start write command */ 817 /* select PHY operation and start write command */
820 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW); 818 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
821 819
822 /* XXX: should be wait? */ 820 /* XXX: should be wait? */
823 821
824 /* end write command */ 822 /* end write command */
825 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRW); 823 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRW);
826 824
827 return 0; 825 return 0;
828} 826}
829 827
830static void 828static void
831udav_uno_mii_statchg(struct ifnet *ifp) 829udav_uno_mii_statchg(struct ifnet *ifp)
832{ 830{
833 struct usbnet * const un = ifp->if_softc; 831 struct usbnet * const un = ifp->if_softc;
834 struct mii_data * const mii = usbnet_mii(un); 832 struct mii_data * const mii = usbnet_mii(un);
835 833
836 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__)); 834 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__));
837 835
838 if (usbnet_isdying(un)) 836 if (usbnet_isdying(un))
839 return; 837 return;
840 838
841 if ((mii->mii_media_status & IFM_ACTIVE) && 839 if ((mii->mii_media_status & IFM_ACTIVE) &&
842 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 840 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
843 DPRINTF(("%s: %s: got link\n", 841 DPRINTF(("%s: %s: got link\n",
844 device_xname(un->un_dev), __func__)); 842 device_xname(un->un_dev), __func__));
845 usbnet_set_link(un, true); 843 usbnet_set_link(un, true);
846 } 844 }
847} 845}
848 846
849#ifdef _MODULE 847#ifdef _MODULE
850#include "ioconf.c" 848#include "ioconf.c"
851#endif 849#endif
852 850
853USBNET_MODULE(udav) 851USBNET_MODULE(udav)

cvs diff -r1.82 -r1.83 src/sys/dev/usb/if_url.c (switch to unified diff)

--- src/sys/dev/usb/if_url.c 2022/03/03 05:51:17 1.82
+++ src/sys/dev/usb/if_url.c 2022/03/03 05:51:27 1.83
@@ -1,763 +1,761 @@ @@ -1,763 +1,761 @@
1/* $NetBSD: if_url.c,v 1.82 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_url.c,v 1.83 2022/03/03 05:51:27 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001, 2002 4 * Copyright (c) 2001, 2002
5 * Shingo WATANABE <nabe@nabechan.org>. All rights reserved. 5 * Shingo WATANABE <nabe@nabechan.org>. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the author nor the names of any co-contributors 15 * 3. Neither the name of the author nor the names of any co-contributors
16 * may be used to endorse or promote products derived from this software 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 * 30 *
31 */ 31 */
32 32
33/* 33/*
34 * The RTL8150L(Realtek USB to fast ethernet controller) spec can be found at 34 * The RTL8150L(Realtek USB to fast ethernet controller) spec can be found at
35 * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/8150v14.pdf 35 * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/8150v14.pdf
36 * ftp://152.104.125.40/lancard/data_sheet/8150/8150v14.pdf 36 * ftp://152.104.125.40/lancard/data_sheet/8150/8150v14.pdf
37 */ 37 */
38 38
39/* 39/*
40 * TODO: 40 * TODO:
41 * Interrupt Endpoint support 41 * Interrupt Endpoint support
42 * External PHYs 42 * External PHYs
43 * powerhook() support? 43 * powerhook() support?
44 */ 44 */
45 45
46#include <sys/cdefs.h> 46#include <sys/cdefs.h>
47__KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.82 2022/03/03 05:51:17 riastradh Exp $"); 47__KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.83 2022/03/03 05:51:27 riastradh Exp $");
48 48
49#ifdef _KERNEL_OPT 49#ifdef _KERNEL_OPT
50#include "opt_inet.h" 50#include "opt_inet.h"
51#include "opt_usb.h" 51#include "opt_usb.h"
52#endif 52#endif
53 53
54#include <sys/param.h> 54#include <sys/param.h>
55 55
56#include <net/if_ether.h> 56#include <net/if_ether.h>
57#ifdef INET 57#ifdef INET
58#include <netinet/in.h> 58#include <netinet/in.h>
59#include <netinet/if_inarp.h> 59#include <netinet/if_inarp.h>
60#endif 60#endif
61 61
62#include <dev/mii/urlphyreg.h> 62#include <dev/mii/urlphyreg.h>
63 63
64#include <dev/usb/usbnet.h> 64#include <dev/usb/usbnet.h>
65 65
66#include <dev/usb/if_urlreg.h> 66#include <dev/usb/if_urlreg.h>
67 67
68/* Function declarations */ 68/* Function declarations */
69static int url_match(device_t, cfdata_t, void *); 69static int url_match(device_t, cfdata_t, void *);
70static void url_attach(device_t, device_t, void *); 70static void url_attach(device_t, device_t, void *);
71 71
72CFATTACH_DECL_NEW(url, sizeof(struct usbnet), url_match, url_attach, 72CFATTACH_DECL_NEW(url, sizeof(struct usbnet), url_match, url_attach,
73 usbnet_detach, usbnet_activate); 73 usbnet_detach, usbnet_activate);
74 74
75static unsigned url_uno_tx_prepare(struct usbnet *, struct mbuf *, 75static unsigned url_uno_tx_prepare(struct usbnet *, struct mbuf *,
76 struct usbnet_chain *); 76 struct usbnet_chain *);
77static void url_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 77static void url_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
78static int url_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 78static int url_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
79static int url_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 79static int url_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
80static void url_uno_mcast(struct ifnet *); 80static void url_uno_mcast(struct ifnet *);
81static void url_uno_stop(struct ifnet *, int); 81static void url_uno_stop(struct ifnet *, int);
82static void url_uno_mii_statchg(struct ifnet *); 82static void url_uno_mii_statchg(struct ifnet *);
83static int url_uno_init(struct ifnet *); 83static int url_uno_init(struct ifnet *);
84static void url_rcvfilt_locked(struct usbnet *); 84static void url_rcvfilt_locked(struct usbnet *);
85static void url_reset(struct usbnet *); 85static void url_reset(struct usbnet *);
86 86
87static int url_csr_read_1(struct usbnet *, int); 87static int url_csr_read_1(struct usbnet *, int);
88static int url_csr_read_2(struct usbnet *, int); 88static int url_csr_read_2(struct usbnet *, int);
89static int url_csr_write_1(struct usbnet *, int, int); 89static int url_csr_write_1(struct usbnet *, int, int);
90static int url_csr_write_2(struct usbnet *, int, int); 90static int url_csr_write_2(struct usbnet *, int, int);
91static int url_csr_write_4(struct usbnet *, int, int); 91static int url_csr_write_4(struct usbnet *, int, int);
92static int url_mem(struct usbnet *, int, int, void *, int); 92static int url_mem(struct usbnet *, int, int, void *, int);
93 93
94static const struct usbnet_ops url_ops = { 94static const struct usbnet_ops url_ops = {
95 .uno_stop = url_uno_stop, 95 .uno_stop = url_uno_stop,
96 .uno_mcast = url_uno_mcast, 96 .uno_mcast = url_uno_mcast,
97 .uno_read_reg = url_uno_mii_read_reg, 97 .uno_read_reg = url_uno_mii_read_reg,
98 .uno_write_reg = url_uno_mii_write_reg, 98 .uno_write_reg = url_uno_mii_write_reg,
99 .uno_statchg = url_uno_mii_statchg, 99 .uno_statchg = url_uno_mii_statchg,
100 .uno_tx_prepare = url_uno_tx_prepare, 100 .uno_tx_prepare = url_uno_tx_prepare,
101 .uno_rx_loop = url_uno_rx_loop, 101 .uno_rx_loop = url_uno_rx_loop,
102 .uno_init = url_uno_init, 102 .uno_init = url_uno_init,
103}; 103};
104 104
105/* Macros */ 105/* Macros */
106#ifdef URL_DEBUG 106#ifdef URL_DEBUG
107#define DPRINTF(x) if (urldebug) printf x 107#define DPRINTF(x) if (urldebug) printf x
108#define DPRINTFN(n, x) if (urldebug >= (n)) printf x 108#define DPRINTFN(n, x) if (urldebug >= (n)) printf x
109int urldebug = 0; 109int urldebug = 0;
110#else 110#else
111#define DPRINTF(x) 111#define DPRINTF(x)
112#define DPRINTFN(n, x) 112#define DPRINTFN(n, x)
113#endif 113#endif
114 114
115#define URL_SETBIT(un, reg, x) \ 115#define URL_SETBIT(un, reg, x) \
116 url_csr_write_1(un, reg, url_csr_read_1(un, reg) | (x)) 116 url_csr_write_1(un, reg, url_csr_read_1(un, reg) | (x))
117 117
118#define URL_SETBIT2(un, reg, x) \ 118#define URL_SETBIT2(un, reg, x) \
119 url_csr_write_2(un, reg, url_csr_read_2(un, reg) | (x)) 119 url_csr_write_2(un, reg, url_csr_read_2(un, reg) | (x))
120 120
121#define URL_CLRBIT(un, reg, x) \ 121#define URL_CLRBIT(un, reg, x) \
122 url_csr_write_1(un, reg, url_csr_read_1(un, reg) & ~(x)) 122 url_csr_write_1(un, reg, url_csr_read_1(un, reg) & ~(x))
123 123
124#define URL_CLRBIT2(un, reg, x) \ 124#define URL_CLRBIT2(un, reg, x) \
125 url_csr_write_2(un, reg, url_csr_read_2(un, reg) & ~(x)) 125 url_csr_write_2(un, reg, url_csr_read_2(un, reg) & ~(x))
126 126
127static const struct url_type { 127static const struct url_type {
128 struct usb_devno url_dev; 128 struct usb_devno url_dev;
129 uint16_t url_flags; 129 uint16_t url_flags;
130#define URL_EXT_PHY 0x0001 130#define URL_EXT_PHY 0x0001
131} url_devs [] = { 131} url_devs [] = {
132 /* MELCO LUA-KTX */ 132 /* MELCO LUA-KTX */
133 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX }, 0}, 133 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX }, 0},
134 /* Realtek RTL8150L Generic (GREEN HOUSE USBKR100) */ 134 /* Realtek RTL8150L Generic (GREEN HOUSE USBKR100) */
135 {{ USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8150L}, 0}, 135 {{ USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8150L}, 0},
136 /* Longshine LCS-8138TX */ 136 /* Longshine LCS-8138TX */
137 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_LCS8138TX}, 0}, 137 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_LCS8138TX}, 0},
138 /* Micronet SP128AR */ 138 /* Micronet SP128AR */
139 {{ USB_VENDOR_MICRONET, USB_PRODUCT_MICRONET_SP128AR}, 0}, 139 {{ USB_VENDOR_MICRONET, USB_PRODUCT_MICRONET_SP128AR}, 0},
140 /* OQO model 01 */ 140 /* OQO model 01 */
141 {{ USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01}, 0}, 141 {{ USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01}, 0},
142}; 142};
143#define url_lookup(v, p) ((const struct url_type *)usb_lookup(url_devs, v, p)) 143#define url_lookup(v, p) ((const struct url_type *)usb_lookup(url_devs, v, p))
144 144
145 145
146/* Probe */ 146/* Probe */
147static int 147static int
148url_match(device_t parent, cfdata_t match, void *aux) 148url_match(device_t parent, cfdata_t match, void *aux)
149{ 149{
150 struct usb_attach_arg *uaa = aux; 150 struct usb_attach_arg *uaa = aux;
151 151
152 return url_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 152 return url_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
153 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 153 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
154} 154}
155/* Attach */ 155/* Attach */
156static void 156static void
157url_attach(device_t parent, device_t self, void *aux) 157url_attach(device_t parent, device_t self, void *aux)
158{ 158{
159 USBNET_MII_DECL_DEFAULT(unm); 159 USBNET_MII_DECL_DEFAULT(unm);
160 struct usbnet * const un = device_private(self); 160 struct usbnet * const un = device_private(self);
161 struct usb_attach_arg *uaa = aux; 161 struct usb_attach_arg *uaa = aux;
162 struct usbd_device *dev = uaa->uaa_device; 162 struct usbd_device *dev = uaa->uaa_device;
163 struct usbd_interface *iface; 163 struct usbd_interface *iface;
164 usbd_status err; 164 usbd_status err;
165 usb_interface_descriptor_t *id; 165 usb_interface_descriptor_t *id;
166 usb_endpoint_descriptor_t *ed; 166 usb_endpoint_descriptor_t *ed;
167 char *devinfop; 167 char *devinfop;
168 int i; 168 int i;
169 169
170 aprint_naive("\n"); 170 aprint_naive("\n");
171 aprint_normal("\n"); 171 aprint_normal("\n");
172 devinfop = usbd_devinfo_alloc(dev, 0); 172 devinfop = usbd_devinfo_alloc(dev, 0);
173 aprint_normal_dev(self, "%s\n", devinfop); 173 aprint_normal_dev(self, "%s\n", devinfop);
174 usbd_devinfo_free(devinfop); 174 usbd_devinfo_free(devinfop);
175 175
176 un->un_dev = self; 176 un->un_dev = self;
177 un->un_udev = dev; 177 un->un_udev = dev;
178 un->un_sc = un; 178 un->un_sc = un;
179 un->un_ops = &url_ops; 179 un->un_ops = &url_ops;
180 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 180 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
181 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 181 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
182 un->un_rx_list_cnt = URL_RX_LIST_CNT; 182 un->un_rx_list_cnt = URL_RX_LIST_CNT;
183 un->un_tx_list_cnt = URL_TX_LIST_CNT; 183 un->un_tx_list_cnt = URL_TX_LIST_CNT;
184 un->un_rx_bufsz = URL_BUFSZ; 184 un->un_rx_bufsz = URL_BUFSZ;
185 un->un_tx_bufsz = URL_BUFSZ; 185 un->un_tx_bufsz = URL_BUFSZ;
186 186
187 /* Move the device into the configured state. */ 187 /* Move the device into the configured state. */
188 err = usbd_set_config_no(dev, URL_CONFIG_NO, 1); 188 err = usbd_set_config_no(dev, URL_CONFIG_NO, 1);
189 if (err) { 189 if (err) {
190 aprint_error_dev(self, "failed to set configuration" 190 aprint_error_dev(self, "failed to set configuration"
191 ", err=%s\n", usbd_errstr(err)); 191 ", err=%s\n", usbd_errstr(err));
192 return; 192 return;
193 } 193 }
194 194
195 /* get control interface */ 195 /* get control interface */
196 err = usbd_device2interface_handle(dev, URL_IFACE_INDEX, &iface); 196 err = usbd_device2interface_handle(dev, URL_IFACE_INDEX, &iface);
197 if (err) { 197 if (err) {
198 aprint_error_dev(self, "failed to get interface, err=%s\n", 198 aprint_error_dev(self, "failed to get interface, err=%s\n",
199 usbd_errstr(err)); 199 usbd_errstr(err));
200 return; 200 return;
201 } 201 }
202 202
203 un->un_iface = iface; 203 un->un_iface = iface;
204 un->un_flags = url_lookup(uaa->uaa_vendor, uaa->uaa_product)->url_flags; 204 un->un_flags = url_lookup(uaa->uaa_vendor, uaa->uaa_product)->url_flags;
205#if 0 205#if 0
206 if (un->un_flags & URL_EXT_PHY) { 206 if (un->un_flags & URL_EXT_PHY) {
207 un->un_read_reg_cb = url_ext_mii_read_reg; 207 un->un_read_reg_cb = url_ext_mii_read_reg;
208 un->un_write_reg_cb = url_ext_mii_write_reg; 208 un->un_write_reg_cb = url_ext_mii_write_reg;
209 } 209 }
210#endif 210#endif
211 211
212 /* get interface descriptor */ 212 /* get interface descriptor */
213 id = usbd_get_interface_descriptor(un->un_iface); 213 id = usbd_get_interface_descriptor(un->un_iface);
214 214
215 /* find endpoints */ 215 /* find endpoints */
216 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] = 216 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] =
217 un->un_ed[USBNET_ENDPT_INTR] = 0; 217 un->un_ed[USBNET_ENDPT_INTR] = 0;
218 for (i = 0; i < id->bNumEndpoints; i++) { 218 for (i = 0; i < id->bNumEndpoints; i++) {
219 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 219 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
220 if (ed == NULL) { 220 if (ed == NULL) {
221 aprint_error_dev(self, 221 aprint_error_dev(self,
222 "couldn't get endpoint %d\n", i); 222 "couldn't get endpoint %d\n", i);
223 return; 223 return;
224 } 224 }
225 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 225 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
226 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 226 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
227 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 227 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
228 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 228 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
229 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) 229 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
230 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 230 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
231 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT && 231 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
232 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 232 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
233 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 233 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
234 } 234 }
235 235
236 if (un->un_ed[USBNET_ENDPT_RX] == 0 || 236 if (un->un_ed[USBNET_ENDPT_RX] == 0 ||
237 un->un_ed[USBNET_ENDPT_TX] == 0 || 237 un->un_ed[USBNET_ENDPT_TX] == 0 ||
238 un->un_ed[USBNET_ENDPT_INTR] == 0) { 238 un->un_ed[USBNET_ENDPT_INTR] == 0) {
239 aprint_error_dev(self, "missing endpoint\n"); 239 aprint_error_dev(self, "missing endpoint\n");
240 return; 240 return;
241 } 241 }
242 242
243 /* Set these up now for url_mem(). */ 243 /* Set these up now for url_mem(). */
244 usbnet_attach(un, "urldet"); 244 usbnet_attach(un, "urldet");
245 245
246 usbnet_lock_core(un); 246 usbnet_lock_core(un);
247 usbnet_busy(un); 247 usbnet_busy(un);
248 248
249 /* reset the adapter */ 249 /* reset the adapter */
250 url_reset(un); 250 url_reset(un);
251 251
252 /* Get Ethernet Address */ 252 /* Get Ethernet Address */
253 err = url_mem(un, URL_CMD_READMEM, URL_IDR0, (void *)un->un_eaddr, 253 err = url_mem(un, URL_CMD_READMEM, URL_IDR0, (void *)un->un_eaddr,
254 ETHER_ADDR_LEN); 254 ETHER_ADDR_LEN);
255 usbnet_unbusy(un); 255 usbnet_unbusy(un);
256 usbnet_unlock_core(un); 256 usbnet_unlock_core(un);
257 if (err) { 257 if (err) {
258 aprint_error_dev(self, "read MAC address failed\n"); 258 aprint_error_dev(self, "read MAC address failed\n");
259 return; 259 return;
260 } 260 }
261 261
262 /* initialize interface information */ 262 /* initialize interface information */
263 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 263 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
264 0, &unm); 264 0, &unm);
265} 265}
266 266
267/* read/write memory */ 267/* read/write memory */
268static int 268static int
269url_mem(struct usbnet *un, int cmd, int offset, void *buf, int len) 269url_mem(struct usbnet *un, int cmd, int offset, void *buf, int len)
270{ 270{
271 usb_device_request_t req; 271 usb_device_request_t req;
272 usbd_status err; 272 usbd_status err;
273 273
274 usbnet_isowned_core(un); 274 usbnet_isowned_core(un);
275 275
276 DPRINTFN(0x200, 276 DPRINTFN(0x200,
277 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 277 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
278 278
279 if (usbnet_isdying(un)) 279 if (usbnet_isdying(un))
280 return 0; 280 return 0;
281 281
282 if (cmd == URL_CMD_READMEM) 282 if (cmd == URL_CMD_READMEM)
283 req.bmRequestType = UT_READ_VENDOR_DEVICE; 283 req.bmRequestType = UT_READ_VENDOR_DEVICE;
284 else 284 else
285 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 285 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
286 req.bRequest = URL_REQ_MEM; 286 req.bRequest = URL_REQ_MEM;
287 USETW(req.wValue, offset); 287 USETW(req.wValue, offset);
288 USETW(req.wIndex, 0x0000); 288 USETW(req.wIndex, 0x0000);
289 USETW(req.wLength, len); 289 USETW(req.wLength, len);
290 290
291 err = usbd_do_request(un->un_udev, &req, buf); 291 err = usbd_do_request(un->un_udev, &req, buf);
292 if (err) { 292 if (err) {
293 DPRINTF(("%s: url_mem(): %s failed. off=%04x, err=%d\n", 293 DPRINTF(("%s: url_mem(): %s failed. off=%04x, err=%d\n",
294 device_xname(un->un_dev), 294 device_xname(un->un_dev),
295 cmd == URL_CMD_READMEM ? "read" : "write", 295 cmd == URL_CMD_READMEM ? "read" : "write",
296 offset, err)); 296 offset, err));
297 } 297 }
298 298
299 return err; 299 return err;
300} 300}
301 301
302/* read 1byte from register */ 302/* read 1byte from register */
303static int 303static int
304url_csr_read_1(struct usbnet *un, int reg) 304url_csr_read_1(struct usbnet *un, int reg)
305{ 305{
306 uint8_t val = 0; 306 uint8_t val = 0;
307 307
308 DPRINTFN(0x100, 308 DPRINTFN(0x100,
309 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 309 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
310 310
311 return url_mem(un, URL_CMD_READMEM, reg, &val, 1) ? 0 : val; 311 return url_mem(un, URL_CMD_READMEM, reg, &val, 1) ? 0 : val;
312} 312}
313 313
314/* read 2bytes from register */ 314/* read 2bytes from register */
315static int 315static int
316url_csr_read_2(struct usbnet *un, int reg) 316url_csr_read_2(struct usbnet *un, int reg)
317{ 317{
318 uWord val; 318 uWord val;
319 319
320 DPRINTFN(0x100, 320 DPRINTFN(0x100,
321 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 321 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
322 322
323 USETW(val, 0); 323 USETW(val, 0);
324 return url_mem(un, URL_CMD_READMEM, reg, &val, 2) ? 0 : UGETW(val); 324 return url_mem(un, URL_CMD_READMEM, reg, &val, 2) ? 0 : UGETW(val);
325} 325}
326 326
327/* write 1byte to register */ 327/* write 1byte to register */
328static int 328static int
329url_csr_write_1(struct usbnet *un, int reg, int aval) 329url_csr_write_1(struct usbnet *un, int reg, int aval)
330{ 330{
331 uint8_t val = aval; 331 uint8_t val = aval;
332 332
333 DPRINTFN(0x100, 333 DPRINTFN(0x100,
334 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 334 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
335 335
336 return url_mem(un, URL_CMD_WRITEMEM, reg, &val, 1) ? -1 : 0; 336 return url_mem(un, URL_CMD_WRITEMEM, reg, &val, 1) ? -1 : 0;
337} 337}
338 338
339/* write 2bytes to register */ 339/* write 2bytes to register */
340static int 340static int
341url_csr_write_2(struct usbnet *un, int reg, int aval) 341url_csr_write_2(struct usbnet *un, int reg, int aval)
342{ 342{
343 uWord val; 343 uWord val;
344 344
345 DPRINTFN(0x100, 345 DPRINTFN(0x100,
346 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 346 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
347 347
348 USETW(val, aval); 348 USETW(val, aval);
349 349
350 return url_mem(un, URL_CMD_WRITEMEM, reg, &val, 2) ? -1 : 0; 350 return url_mem(un, URL_CMD_WRITEMEM, reg, &val, 2) ? -1 : 0;
351} 351}
352 352
353/* write 4bytes to register */ 353/* write 4bytes to register */
354static int 354static int
355url_csr_write_4(struct usbnet *un, int reg, int aval) 355url_csr_write_4(struct usbnet *un, int reg, int aval)
356{ 356{
357 uDWord val; 357 uDWord val;
358 358
359 DPRINTFN(0x100, 359 DPRINTFN(0x100,
360 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 360 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
361 361
362 USETDW(val, aval); 362 USETDW(val, aval);
363 363
364 return url_mem(un, URL_CMD_WRITEMEM, reg, &val, 4) ? -1 : 0; 364 return url_mem(un, URL_CMD_WRITEMEM, reg, &val, 4) ? -1 : 0;
365} 365}
366 366
367static int 367static int
368url_init_locked(struct ifnet *ifp) 368url_init_locked(struct ifnet *ifp)
369{ 369{
370 struct usbnet * const un = ifp->if_softc; 370 struct usbnet * const un = ifp->if_softc;
371 const u_char *eaddr; 371 const u_char *eaddr;
372 int i; 372 int i;
373 373
374 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 374 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
375 375
376 usbnet_isowned_core(un); 376 usbnet_isowned_core(un);
377 377
378 if (usbnet_isdying(un)) 378 if (usbnet_isdying(un))
379 return EIO; 379 return EIO;
380 380
381 /* Cancel pending I/O and free all TX/RX buffers */ 381 /* Cancel pending I/O and free all TX/RX buffers */
382 usbnet_stop(un, ifp, 1); 382 usbnet_stop(un, ifp, 1);
383 383
384 eaddr = CLLADDR(ifp->if_sadl); 384 eaddr = CLLADDR(ifp->if_sadl);
385 for (i = 0; i < ETHER_ADDR_LEN; i++) 385 for (i = 0; i < ETHER_ADDR_LEN; i++)
386 url_csr_write_1(un, URL_IDR0 + i, eaddr[i]); 386 url_csr_write_1(un, URL_IDR0 + i, eaddr[i]);
387 387
388 /* Init transmission control register */ 388 /* Init transmission control register */
389 URL_CLRBIT(un, URL_TCR, 389 URL_CLRBIT(un, URL_TCR,
390 URL_TCR_TXRR1 | URL_TCR_TXRR0 | 390 URL_TCR_TXRR1 | URL_TCR_TXRR0 |
391 URL_TCR_IFG1 | URL_TCR_IFG0 | 391 URL_TCR_IFG1 | URL_TCR_IFG0 |
392 URL_TCR_NOCRC); 392 URL_TCR_NOCRC);
393 393
394 /* Init receive control register */ 394 /* Init receive control register */
395 URL_SETBIT2(un, URL_RCR, URL_RCR_TAIL | URL_RCR_AD | URL_RCR_AB); 395 URL_SETBIT2(un, URL_RCR, URL_RCR_TAIL | URL_RCR_AD | URL_RCR_AB);
396 396
397 /* Accept multicast frame or run promisc. mode */ 397 /* Accept multicast frame or run promisc. mode */
398 url_rcvfilt_locked(un); 398 url_rcvfilt_locked(un);
399 399
400 /* Enable RX and TX */ 400 /* Enable RX and TX */
401 URL_SETBIT(un, URL_CR, URL_CR_TE | URL_CR_RE); 401 URL_SETBIT(un, URL_CR, URL_CR_TE | URL_CR_RE);
402 402
403 return usbnet_init_rx_tx(un); 403 return usbnet_init_rx_tx(un);
404} 404}
405 405
406static int 406static int
407url_uno_init(struct ifnet *ifp) 407url_uno_init(struct ifnet *ifp)
408{ 408{
409 int ret = url_init_locked(ifp); 409 int ret = url_init_locked(ifp);
410 410
411 return ret; 411 return ret;
412} 412}
413 413
414static void 414static void
415url_reset(struct usbnet *un) 415url_reset(struct usbnet *un)
416{ 416{
417 int i; 417 int i;
418 418
419 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 419 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
420 420
421 if (usbnet_isdying(un)) 421 if (usbnet_isdying(un))
422 return; 422 return;
423 423
424 URL_SETBIT(un, URL_CR, URL_CR_SOFT_RST); 424 URL_SETBIT(un, URL_CR, URL_CR_SOFT_RST);
425 425
426 for (i = 0; i < URL_TX_TIMEOUT; i++) { 426 for (i = 0; i < URL_TX_TIMEOUT; i++) {
427 if (usbnet_isdying(un)) 427 if (usbnet_isdying(un))
428 return; 428 return;
429 if (!(url_csr_read_1(un, URL_CR) & URL_CR_SOFT_RST)) 429 if (!(url_csr_read_1(un, URL_CR) & URL_CR_SOFT_RST))
430 break; 430 break;
431 delay(10); /* XXX */ 431 delay(10); /* XXX */
432 } 432 }
433 433
434 delay(10000); /* XXX */ 434 delay(10000); /* XXX */
435} 435}
436 436
437static void 437static void
438url_rcvfilt_locked(struct usbnet *un) 438url_rcvfilt_locked(struct usbnet *un)
439{ 439{
440 struct ifnet * const ifp = usbnet_ifp(un); 440 struct ifnet * const ifp = usbnet_ifp(un);
441 struct ethercom *ec = usbnet_ec(un); 441 struct ethercom *ec = usbnet_ec(un);
442 struct ether_multi *enm; 442 struct ether_multi *enm;
443 struct ether_multistep step; 443 struct ether_multistep step;
444 uint32_t mchash[2] = { 0, 0 }; 444 uint32_t mchash[2] = { 0, 0 };
445 int h = 0, rcr; 445 int h = 0, rcr;
446 446
447 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 447 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
448 448
449 usbnet_isowned_core(un); 449 usbnet_isowned_core(un);
450 450
451 if (usbnet_isdying(un)) 451 if (usbnet_isdying(un))
452 return; 452 return;
453 453
454 rcr = url_csr_read_2(un, URL_RCR); 454 rcr = url_csr_read_2(un, URL_RCR);
455 rcr &= ~(URL_RCR_AAP | URL_RCR_AAM | URL_RCR_AM); 455 rcr &= ~(URL_RCR_AAP | URL_RCR_AAM | URL_RCR_AM);
456 456
457 ETHER_LOCK(ec); 457 ETHER_LOCK(ec);
458 if (ifp->if_flags & IFF_PROMISC) { 458 if (ifp->if_flags & IFF_PROMISC) {
459 ec->ec_flags |= ETHER_F_ALLMULTI; 459 ec->ec_flags |= ETHER_F_ALLMULTI;
460 ETHER_UNLOCK(ec); 460 ETHER_UNLOCK(ec);
461 /* run promisc. mode */ 461 /* run promisc. mode */
462 rcr |= URL_RCR_AAM; /* ??? */ 462 rcr |= URL_RCR_AAM; /* ??? */
463 rcr |= URL_RCR_AAP; 463 rcr |= URL_RCR_AAP;
464 goto update; 464 goto update;
465 } 465 }
466 ec->ec_flags &= ~ETHER_F_ALLMULTI; 466 ec->ec_flags &= ~ETHER_F_ALLMULTI;
467 ETHER_FIRST_MULTI(step, ec, enm); 467 ETHER_FIRST_MULTI(step, ec, enm);
468 while (enm != NULL) { 468 while (enm != NULL) {
469 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 469 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
470 ec->ec_flags |= ETHER_F_ALLMULTI; 470 ec->ec_flags |= ETHER_F_ALLMULTI;
471 ETHER_UNLOCK(ec); 471 ETHER_UNLOCK(ec);
472 /* accept all multicast frames */ 472 /* accept all multicast frames */
473 rcr |= URL_RCR_AAM; 473 rcr |= URL_RCR_AAM;
474 goto update; 474 goto update;
475 } 475 }
476 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 476 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
477 /* 1(31) and 5(30:26) bit sampling */ 477 /* 1(31) and 5(30:26) bit sampling */
478 mchash[h >> 31] |= 1 << ((h >> 26) & 0x1f); 478 mchash[h >> 31] |= 1 << ((h >> 26) & 0x1f);
479 ETHER_NEXT_MULTI(step, enm); 479 ETHER_NEXT_MULTI(step, enm);
480 } 480 }
481 ETHER_UNLOCK(ec); 481 ETHER_UNLOCK(ec);
482 if (h != 0) 482 if (h != 0)
483 rcr |= URL_RCR_AM; /* activate mcast hash filter */ 483 rcr |= URL_RCR_AM; /* activate mcast hash filter */
484 url_csr_write_4(un, URL_MAR0, mchash[0]); 484 url_csr_write_4(un, URL_MAR0, mchash[0]);
485 url_csr_write_4(un, URL_MAR4, mchash[1]); 485 url_csr_write_4(un, URL_MAR4, mchash[1]);
486 update: 486 update:
487 url_csr_write_2(un, URL_RCR, rcr); 487 url_csr_write_2(un, URL_RCR, rcr);
488} 488}
489 489
490static unsigned 490static unsigned
491url_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 491url_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
492{ 492{
493 int total_len; 493 int total_len;
494 494
495 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__)); 495 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__));
496 496
497 KASSERT(un->un_tx_bufsz >= URL_MIN_FRAME_LEN); 497 KASSERT(un->un_tx_bufsz >= URL_MIN_FRAME_LEN);
498 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz) 498 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz)
499 return 0; 499 return 0;
500 500
501 /* Copy the mbuf data into a contiguous buffer */ 501 /* Copy the mbuf data into a contiguous buffer */
502 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf); 502 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf);
503 total_len = m->m_pkthdr.len; 503 total_len = m->m_pkthdr.len;
504 504
505 if (total_len < URL_MIN_FRAME_LEN) { 505 if (total_len < URL_MIN_FRAME_LEN) {
506 memset(c->unc_buf + total_len, 0, 506 memset(c->unc_buf + total_len, 0,
507 URL_MIN_FRAME_LEN - total_len); 507 URL_MIN_FRAME_LEN - total_len);
508 total_len = URL_MIN_FRAME_LEN; 508 total_len = URL_MIN_FRAME_LEN;
509 } 509 }
510 510
511 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev), 511 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev),
512 __func__, total_len)); 512 __func__, total_len));
513 513
514 return total_len; 514 return total_len;
515} 515}
516 516
517static void 517static void
518url_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 518url_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
519{ 519{
520 struct ifnet *ifp = usbnet_ifp(un); 520 struct ifnet *ifp = usbnet_ifp(un);
521 url_rxhdr_t rxhdr; 521 url_rxhdr_t rxhdr;
522 522
523 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__)); 523 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__));
524 524
525 if (total_len <= ETHER_CRC_LEN || total_len <= sizeof(rxhdr)) { 525 if (total_len <= ETHER_CRC_LEN || total_len <= sizeof(rxhdr)) {
526 if_statinc(ifp, if_ierrors); 526 if_statinc(ifp, if_ierrors);
527 return; 527 return;
528 } 528 }
529 529
530 memcpy(&rxhdr, c->unc_buf + total_len - ETHER_CRC_LEN, sizeof(rxhdr)); 530 memcpy(&rxhdr, c->unc_buf + total_len - ETHER_CRC_LEN, sizeof(rxhdr));
531 531
532 DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n", 532 DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n",
533 device_xname(un->un_dev), 533 device_xname(un->un_dev),
534 UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK, 534 UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK,
535 UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "", 535 UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "",
536 UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "", 536 UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "",
537 UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "", 537 UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "",
538 UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : "")); 538 UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : ""));
539 539
540 if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) { 540 if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) {
541 if_statinc(ifp, if_ierrors); 541 if_statinc(ifp, if_ierrors);
542 return; 542 return;
543 } 543 }
544 544
545 total_len -= ETHER_CRC_LEN; 545 total_len -= ETHER_CRC_LEN;
546 546
547 DPRINTF(("%s: %s: deliver %d\n", device_xname(un->un_dev), 547 DPRINTF(("%s: %s: deliver %d\n", device_xname(un->un_dev),
548 __func__, total_len)); 548 __func__, total_len));
549 usbnet_enqueue(un, c->unc_buf, total_len, 0, 0, 0); 549 usbnet_enqueue(un, c->unc_buf, total_len, 0, 0, 0);
550} 550}
551 551
552#if 0 552#if 0
553static void url_intr(void) 553static void url_intr(void)
554{ 554{
555} 555}
556#endif 556#endif
557 557
558static void 558static void
559url_uno_mcast(struct ifnet *ifp) 559url_uno_mcast(struct ifnet *ifp)
560{ 560{
561 struct usbnet * const un = ifp->if_softc; 561 struct usbnet * const un = ifp->if_softc;
562 562
563 usbnet_lock_core(un); 563 usbnet_lock_core(un);
564 usbnet_busy(un); 
565 564
566 url_rcvfilt_locked(un); 565 url_rcvfilt_locked(un);
567 566
568 usbnet_unbusy(un); 
569 usbnet_unlock_core(un); 567 usbnet_unlock_core(un);
570} 568}
571 569
572/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */ 570/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
573static void 571static void
574url_uno_stop(struct ifnet *ifp, int disable) 572url_uno_stop(struct ifnet *ifp, int disable)
575{ 573{
576 struct usbnet * const un = ifp->if_softc; 574 struct usbnet * const un = ifp->if_softc;
577 575
578 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 576 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
579 577
580 url_reset(un); 578 url_reset(un);
581} 579}
582 580
583static int 581static int
584url_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 582url_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
585{ 583{
586 uint16_t data; 584 uint16_t data;
587 usbd_status err = USBD_NORMAL_COMPLETION; 585 usbd_status err = USBD_NORMAL_COMPLETION;
588 586
589 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", 587 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
590 device_xname(un->un_dev), __func__, phy, reg)); 588 device_xname(un->un_dev), __func__, phy, reg));
591 589
592 /* XXX: one PHY only for the RTL8150 internal PHY */ 590 /* XXX: one PHY only for the RTL8150 internal PHY */
593 if (phy != 0) { 591 if (phy != 0) {
594 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 592 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
595 device_xname(un->un_dev), __func__, phy)); 593 device_xname(un->un_dev), __func__, phy));
596 return EINVAL; 594 return EINVAL;
597 } 595 }
598 596
599 switch (reg) { 597 switch (reg) {
600 case MII_BMCR: /* Control Register */ 598 case MII_BMCR: /* Control Register */
601 reg = URL_BMCR; 599 reg = URL_BMCR;
602 break; 600 break;
603 case MII_BMSR: /* Status Register */ 601 case MII_BMSR: /* Status Register */
604 reg = URL_BMSR; 602 reg = URL_BMSR;
605 break; 603 break;
606 case MII_PHYIDR1: 604 case MII_PHYIDR1:
607 case MII_PHYIDR2: 605 case MII_PHYIDR2:
608 *val = 0; 606 *val = 0;
609 goto R_DONE; 607 goto R_DONE;
610 break; 608 break;
611 case MII_ANAR: /* Autonegotiation advertisement */ 609 case MII_ANAR: /* Autonegotiation advertisement */
612 reg = URL_ANAR; 610 reg = URL_ANAR;
613 break; 611 break;
614 case MII_ANLPAR: /* Autonegotiation link partner abilities */ 612 case MII_ANLPAR: /* Autonegotiation link partner abilities */
615 reg = URL_ANLP; 613 reg = URL_ANLP;
616 break; 614 break;
617 case URLPHY_MSR: /* Media Status Register */ 615 case URLPHY_MSR: /* Media Status Register */
618 reg = URL_MSR; 616 reg = URL_MSR;
619 break; 617 break;
620 default: 618 default:
621 printf("%s: %s: bad register %04x\n", 619 printf("%s: %s: bad register %04x\n",
622 device_xname(un->un_dev), __func__, reg); 620 device_xname(un->un_dev), __func__, reg);
623 return EINVAL; 621 return EINVAL;
624 } 622 }
625 623
626 if (reg == URL_MSR) 624 if (reg == URL_MSR)
627 data = url_csr_read_1(un, reg); 625 data = url_csr_read_1(un, reg);
628 else 626 else
629 data = url_csr_read_2(un, reg); 627 data = url_csr_read_2(un, reg);
630 *val = data; 628 *val = data;
631 629
632 R_DONE: 630 R_DONE:
633 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n", 631 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n",
634 device_xname(un->un_dev), __func__, phy, reg, *val)); 632 device_xname(un->un_dev), __func__, phy, reg, *val));
635 633
636 return err; 634 return err;
637} 635}
638 636
639static int 637static int
640url_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 638url_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
641{ 639{
642 640
643 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n", 641 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n",
644 device_xname(un->un_dev), __func__, phy, reg, val)); 642 device_xname(un->un_dev), __func__, phy, reg, val));
645 643
646 /* XXX: one PHY only for the RTL8150 internal PHY */ 644 /* XXX: one PHY only for the RTL8150 internal PHY */
647 if (phy != 0) { 645 if (phy != 0) {
648 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 646 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
649 device_xname(un->un_dev), __func__, phy)); 647 device_xname(un->un_dev), __func__, phy));
650 return EINVAL; 648 return EINVAL;
651 } 649 }
652 650
653 switch (reg) { 651 switch (reg) {
654 case MII_BMCR: /* Control Register */ 652 case MII_BMCR: /* Control Register */
655 reg = URL_BMCR; 653 reg = URL_BMCR;
656 break; 654 break;
657 case MII_BMSR: /* Status Register */ 655 case MII_BMSR: /* Status Register */
658 reg = URL_BMSR; 656 reg = URL_BMSR;
659 break; 657 break;
660 case MII_PHYIDR1: 658 case MII_PHYIDR1:
661 case MII_PHYIDR2: 659 case MII_PHYIDR2:
662 return 0; 660 return 0;
663 case MII_ANAR: /* Autonegotiation advertisement */ 661 case MII_ANAR: /* Autonegotiation advertisement */
664 reg = URL_ANAR; 662 reg = URL_ANAR;
665 break; 663 break;
666 case MII_ANLPAR: /* Autonegotiation link partner abilities */ 664 case MII_ANLPAR: /* Autonegotiation link partner abilities */
667 reg = URL_ANLP; 665 reg = URL_ANLP;
668 break; 666 break;
669 case URLPHY_MSR: /* Media Status Register */ 667 case URLPHY_MSR: /* Media Status Register */
670 reg = URL_MSR; 668 reg = URL_MSR;
671 break; 669 break;
672 default: 670 default:
673 printf("%s: %s: bad register %04x\n", 671 printf("%s: %s: bad register %04x\n",
674 device_xname(un->un_dev), __func__, reg); 672 device_xname(un->un_dev), __func__, reg);
675 return EINVAL; 673 return EINVAL;
676 } 674 }
677 675
678 if (reg == URL_MSR) 676 if (reg == URL_MSR)
679 url_csr_write_1(un, reg, val); 677 url_csr_write_1(un, reg, val);
680 else 678 else
681 url_csr_write_2(un, reg, val); 679 url_csr_write_2(un, reg, val);
682 680
683 return 0; 681 return 0;
684} 682}
685 683
686static void 684static void
687url_uno_mii_statchg(struct ifnet *ifp) 685url_uno_mii_statchg(struct ifnet *ifp)
688{ 686{
689 struct usbnet * const un = ifp->if_softc; 687 struct usbnet * const un = ifp->if_softc;
690 688
691 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__)); 689 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__));
692 690
693 /* XXX */ 691 /* XXX */
694 usbnet_set_link(un, true); 692 usbnet_set_link(un, true);
695} 693}
696 694
697#if 0 695#if 0
698/* 696/*
699 * external PHYs support, but not test. 697 * external PHYs support, but not test.
700 */ 698 */
701static usbd_status 699static usbd_status
702url_ext_mii_read_reg(struct usbnet *un, int phy, int reg) 700url_ext_mii_read_reg(struct usbnet *un, int phy, int reg)
703{ 701{
704 uint16_t val; 702 uint16_t val;
705 703
706 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n", 704 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n",
707 device_xname(un->un_dev), __func__, phy, reg)); 705 device_xname(un->un_dev), __func__, phy, reg));
708 706
709 url_csr_write_1(un, URL_PHYADD, phy & URL_PHYADD_MASK); 707 url_csr_write_1(un, URL_PHYADD, phy & URL_PHYADD_MASK);
710 /* 708 /*
711 * RTL8150L will initiate a MII management data transaction 709 * RTL8150L will initiate a MII management data transaction
712 * if PHYCNT_OWN bit is set 1 by software. After transaction, 710 * if PHYCNT_OWN bit is set 1 by software. After transaction,
713 * this bit is auto cleared by TRL8150L. 711 * this bit is auto cleared by TRL8150L.
714 */ 712 */
715 url_csr_write_1(un, URL_PHYCNT, 713 url_csr_write_1(un, URL_PHYCNT,
716 (reg | URL_PHYCNT_PHYOWN) & ~URL_PHYCNT_RWCR); 714 (reg | URL_PHYCNT_PHYOWN) & ~URL_PHYCNT_RWCR);
717 for (i = 0; i < URL_TIMEOUT; i++) { 715 for (i = 0; i < URL_TIMEOUT; i++) {
718 if ((url_csr_read_1(un, URL_PHYCNT) & URL_PHYCNT_PHYOWN) == 0) 716 if ((url_csr_read_1(un, URL_PHYCNT) & URL_PHYCNT_PHYOWN) == 0)
719 break; 717 break;
720 } 718 }
721 if (i == URL_TIMEOUT) { 719 if (i == URL_TIMEOUT) {
722 printf("%s: MII read timed out\n", device_xname(un->un_dev)); 720 printf("%s: MII read timed out\n", device_xname(un->un_dev));
723 } 721 }
724 722
725 val = url_csr_read_2(un, URL_PHYDAT); 723 val = url_csr_read_2(un, URL_PHYDAT);
726 724
727 DPRINTF(("%s: %s: phy=%d reg=0x%04x => 0x%04x\n", 725 DPRINTF(("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
728 device_xname(un->un_dev), __func__, phy, reg, val)); 726 device_xname(un->un_dev), __func__, phy, reg, val));
729 727
730 return USBD_NORMAL_COMPLETION; 728 return USBD_NORMAL_COMPLETION;
731} 729}
732 730
733static usbd_status 731static usbd_status
734url_ext_mii_write_reg(struct usbnet *un, int phy, int reg, int data) 732url_ext_mii_write_reg(struct usbnet *un, int phy, int reg, int data)
735{ 733{
736 734
737 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n", 735 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
738 device_xname(un->un_dev), __func__, phy, reg, data)); 736 device_xname(un->un_dev), __func__, phy, reg, data));
739 737
740 url_csr_write_2(un, URL_PHYDAT, data); 738 url_csr_write_2(un, URL_PHYDAT, data);
741 url_csr_write_1(un, URL_PHYADD, phy); 739 url_csr_write_1(un, URL_PHYADD, phy);
742 url_csr_write_1(un, URL_PHYCNT, reg | URL_PHYCNT_RWCR); /* Write */ 740 url_csr_write_1(un, URL_PHYCNT, reg | URL_PHYCNT_RWCR); /* Write */
743 741
744 for (i=0; i < URL_TIMEOUT; i++) { 742 for (i=0; i < URL_TIMEOUT; i++) {
745 if (url_csr_read_1(un, URL_PHYCNT) & URL_PHYCNT_PHYOWN) 743 if (url_csr_read_1(un, URL_PHYCNT) & URL_PHYCNT_PHYOWN)
746 break; 744 break;
747 } 745 }
748 746
749 if (i == URL_TIMEOUT) { 747 if (i == URL_TIMEOUT) {
750 printf("%s: MII write timed out\n", 748 printf("%s: MII write timed out\n",
751 device_xname(un->un_dev)); 749 device_xname(un->un_dev));
752 return USBD_TIMEOUT; 750 return USBD_TIMEOUT;
753 } 751 }
754 752
755 return USBD_NORMAL_COMPLETION; 753 return USBD_NORMAL_COMPLETION;
756} 754}
757#endif 755#endif
758 756
759#ifdef _MODULE 757#ifdef _MODULE
760#include "ioconf.c" 758#include "ioconf.c"
761#endif 759#endif
762 760
763USBNET_MODULE(url) 761USBNET_MODULE(url)

cvs diff -r1.44 -r1.45 src/sys/dev/usb/if_ure.c (switch to unified diff)

--- src/sys/dev/usb/if_ure.c 2022/03/03 05:51:17 1.44
+++ src/sys/dev/usb/if_ure.c 2022/03/03 05:51:27 1.45
@@ -1,1160 +1,1158 @@ @@ -1,1160 +1,1158 @@
1/* $NetBSD: if_ure.c,v 1.44 2022/03/03 05:51:17 riastradh Exp $ */ 1/* $NetBSD: if_ure.c,v 1.45 2022/03/03 05:51:27 riastradh Exp $ */
2/* $OpenBSD: if_ure.c,v 1.10 2018/11/02 21:32:30 jcs Exp $ */ 2/* $OpenBSD: if_ure.c,v 1.10 2018/11/02 21:32:30 jcs Exp $ */
3 3
4/*- 4/*-
5 * Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org> 5 * Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org>
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30/* RealTek RTL8152/RTL8153 10/100/Gigabit USB Ethernet device */ 30/* RealTek RTL8152/RTL8153 10/100/Gigabit USB Ethernet device */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.44 2022/03/03 05:51:17 riastradh Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.45 2022/03/03 05:51:27 riastradh Exp $");
34 34
35#ifdef _KERNEL_OPT 35#ifdef _KERNEL_OPT
36#include "opt_usb.h" 36#include "opt_usb.h"
37#include "opt_inet.h" 37#include "opt_inet.h"
38#endif 38#endif
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/cprng.h> 41#include <sys/cprng.h>
42 42
43#include <net/route.h> 43#include <net/route.h>
44 44
45#include <dev/usb/usbnet.h> 45#include <dev/usb/usbnet.h>
46 46
47#include <netinet/in_offload.h> /* XXX for in_undefer_cksum() */ 47#include <netinet/in_offload.h> /* XXX for in_undefer_cksum() */
48#ifdef INET6 48#ifdef INET6
49#include <netinet/in.h> 49#include <netinet/in.h>
50#include <netinet6/in6_offload.h> /* XXX for in6_undefer_cksum() */ 50#include <netinet6/in6_offload.h> /* XXX for in6_undefer_cksum() */
51#endif 51#endif
52 52
53#include <dev/ic/rtl81x9reg.h> /* XXX for RTK_GMEDIASTAT */ 53#include <dev/ic/rtl81x9reg.h> /* XXX for RTK_GMEDIASTAT */
54#include <dev/usb/if_urereg.h> 54#include <dev/usb/if_urereg.h>
55#include <dev/usb/if_urevar.h> 55#include <dev/usb/if_urevar.h>
56 56
57#define URE_PRINTF(un, fmt, args...) \ 57#define URE_PRINTF(un, fmt, args...) \
58 device_printf((un)->un_dev, "%s: " fmt, __func__, ##args); 58 device_printf((un)->un_dev, "%s: " fmt, __func__, ##args);
59 59
60#define URE_DEBUG 60#define URE_DEBUG
61#ifdef URE_DEBUG 61#ifdef URE_DEBUG
62#define DPRINTF(x) do { if (uredebug) printf x; } while (0) 62#define DPRINTF(x) do { if (uredebug) printf x; } while (0)
63#define DPRINTFN(n, x) do { if (uredebug >= (n)) printf x; } while (0) 63#define DPRINTFN(n, x) do { if (uredebug >= (n)) printf x; } while (0)
64int uredebug = 0; 64int uredebug = 0;
65#else 65#else
66#define DPRINTF(x) 66#define DPRINTF(x)
67#define DPRINTFN(n, x) 67#define DPRINTFN(n, x)
68#endif 68#endif
69 69
70#define ETHER_IS_ZERO(addr) \ 70#define ETHER_IS_ZERO(addr) \
71 (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) 71 (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]))
72 72
73static const struct usb_devno ure_devs[] = { 73static const struct usb_devno ure_devs[] = {
74 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8152 }, 74 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8152 },
75 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153 } 75 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153 }
76}; 76};
77 77
78#define URE_BUFSZ (16 * 1024) 78#define URE_BUFSZ (16 * 1024)
79 79
80static void ure_reset(struct usbnet *); 80static void ure_reset(struct usbnet *);
81static uint32_t ure_txcsum(struct mbuf *); 81static uint32_t ure_txcsum(struct mbuf *);
82static int ure_rxcsum(struct ifnet *, struct ure_rxpkt *); 82static int ure_rxcsum(struct ifnet *, struct ure_rxpkt *);
83static void ure_rtl8152_init(struct usbnet *); 83static void ure_rtl8152_init(struct usbnet *);
84static void ure_rtl8153_init(struct usbnet *); 84static void ure_rtl8153_init(struct usbnet *);
85static void ure_disable_teredo(struct usbnet *); 85static void ure_disable_teredo(struct usbnet *);
86static void ure_init_fifo(struct usbnet *); 86static void ure_init_fifo(struct usbnet *);
87 87
88static void ure_uno_stop(struct ifnet *, int); 88static void ure_uno_stop(struct ifnet *, int);
89static void ure_uno_mcast(struct ifnet *); 89static void ure_uno_mcast(struct ifnet *);
90static int ure_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 90static int ure_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
91static int ure_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 91static int ure_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
92static void ure_uno_miibus_statchg(struct ifnet *); 92static void ure_uno_miibus_statchg(struct ifnet *);
93static unsigned ure_uno_tx_prepare(struct usbnet *, struct mbuf *, 93static unsigned ure_uno_tx_prepare(struct usbnet *, struct mbuf *,
94 struct usbnet_chain *); 94 struct usbnet_chain *);
95static void ure_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 95static void ure_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
96 uint32_t); 96 uint32_t);
97static int ure_uno_init(struct ifnet *); 97static int ure_uno_init(struct ifnet *);
98 98
99static int ure_match(device_t, cfdata_t, void *); 99static int ure_match(device_t, cfdata_t, void *);
100static void ure_attach(device_t, device_t, void *); 100static void ure_attach(device_t, device_t, void *);
101 101
102CFATTACH_DECL_NEW(ure, sizeof(struct usbnet), ure_match, ure_attach, 102CFATTACH_DECL_NEW(ure, sizeof(struct usbnet), ure_match, ure_attach,
103 usbnet_detach, usbnet_activate); 103 usbnet_detach, usbnet_activate);
104 104
105static const struct usbnet_ops ure_ops = { 105static const struct usbnet_ops ure_ops = {
106 .uno_stop = ure_uno_stop, 106 .uno_stop = ure_uno_stop,
107 .uno_mcast = ure_uno_mcast, 107 .uno_mcast = ure_uno_mcast,
108 .uno_read_reg = ure_uno_mii_read_reg, 108 .uno_read_reg = ure_uno_mii_read_reg,
109 .uno_write_reg = ure_uno_mii_write_reg, 109 .uno_write_reg = ure_uno_mii_write_reg,
110 .uno_statchg = ure_uno_miibus_statchg, 110 .uno_statchg = ure_uno_miibus_statchg,
111 .uno_tx_prepare = ure_uno_tx_prepare, 111 .uno_tx_prepare = ure_uno_tx_prepare,
112 .uno_rx_loop = ure_uno_rx_loop, 112 .uno_rx_loop = ure_uno_rx_loop,
113 .uno_init = ure_uno_init, 113 .uno_init = ure_uno_init,
114}; 114};
115 115
116static int 116static int
117ure_ctl(struct usbnet *un, uint8_t rw, uint16_t val, uint16_t index, 117ure_ctl(struct usbnet *un, uint8_t rw, uint16_t val, uint16_t index,
118 void *buf, int len) 118 void *buf, int len)
119{ 119{
120 usb_device_request_t req; 120 usb_device_request_t req;
121 usbd_status err; 121 usbd_status err;
122 122
123 if (usbnet_isdying(un)) 123 if (usbnet_isdying(un))
124 return 0; 124 return 0;
125 125
126 if (rw == URE_CTL_WRITE) 126 if (rw == URE_CTL_WRITE)
127 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 127 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
128 else 128 else
129 req.bmRequestType = UT_READ_VENDOR_DEVICE; 129 req.bmRequestType = UT_READ_VENDOR_DEVICE;
130 req.bRequest = UR_SET_ADDRESS; 130 req.bRequest = UR_SET_ADDRESS;
131 USETW(req.wValue, val); 131 USETW(req.wValue, val);
132 USETW(req.wIndex, index); 132 USETW(req.wIndex, index);
133 USETW(req.wLength, len); 133 USETW(req.wLength, len);
134 134
135 DPRINTFN(5, ("ure_ctl: rw %d, val %04hu, index %04hu, len %d\n", 135 DPRINTFN(5, ("ure_ctl: rw %d, val %04hu, index %04hu, len %d\n",
136 rw, val, index, len)); 136 rw, val, index, len));
137 err = usbd_do_request(un->un_udev, &req, buf); 137 err = usbd_do_request(un->un_udev, &req, buf);
138 if (err) { 138 if (err) {
139 DPRINTF(("ure_ctl: error %d\n", err)); 139 DPRINTF(("ure_ctl: error %d\n", err));
140 return -1; 140 return -1;
141 } 141 }
142 142
143 return 0; 143 return 0;
144} 144}
145 145
146static int 146static int
147ure_read_mem(struct usbnet *un, uint16_t addr, uint16_t index, 147ure_read_mem(struct usbnet *un, uint16_t addr, uint16_t index,
148 void *buf, int len) 148 void *buf, int len)
149{ 149{
150 return ure_ctl(un, URE_CTL_READ, addr, index, buf, len); 150 return ure_ctl(un, URE_CTL_READ, addr, index, buf, len);
151} 151}
152 152
153static int 153static int
154ure_write_mem(struct usbnet *un, uint16_t addr, uint16_t index, 154ure_write_mem(struct usbnet *un, uint16_t addr, uint16_t index,
155 void *buf, int len) 155 void *buf, int len)
156{ 156{
157 return ure_ctl(un, URE_CTL_WRITE, addr, index, buf, len); 157 return ure_ctl(un, URE_CTL_WRITE, addr, index, buf, len);
158} 158}
159 159
160static uint8_t 160static uint8_t
161ure_read_1(struct usbnet *un, uint16_t reg, uint16_t index) 161ure_read_1(struct usbnet *un, uint16_t reg, uint16_t index)
162{ 162{
163 uint32_t val; 163 uint32_t val;
164 uint8_t temp[4]; 164 uint8_t temp[4];
165 uint8_t shift; 165 uint8_t shift;
166 166
167 shift = (reg & 3) << 3; 167 shift = (reg & 3) << 3;
168 reg &= ~3; 168 reg &= ~3;
169 169
170 ure_read_mem(un, reg, index, &temp, 4); 170 ure_read_mem(un, reg, index, &temp, 4);
171 val = UGETDW(temp); 171 val = UGETDW(temp);
172 val >>= shift; 172 val >>= shift;
173 173
174 return val & 0xff; 174 return val & 0xff;
175} 175}
176 176
177static uint16_t 177static uint16_t
178ure_read_2(struct usbnet *un, uint16_t reg, uint16_t index) 178ure_read_2(struct usbnet *un, uint16_t reg, uint16_t index)
179{ 179{
180 uint32_t val; 180 uint32_t val;
181 uint8_t temp[4]; 181 uint8_t temp[4];
182 uint8_t shift; 182 uint8_t shift;
183 183
184 shift = (reg & 2) << 3; 184 shift = (reg & 2) << 3;
185 reg &= ~3; 185 reg &= ~3;
186 186
187 ure_read_mem(un, reg, index, &temp, 4); 187 ure_read_mem(un, reg, index, &temp, 4);
188 val = UGETDW(temp); 188 val = UGETDW(temp);
189 val >>= shift; 189 val >>= shift;
190 190
191 return val & 0xffff; 191 return val & 0xffff;
192} 192}
193 193
194static uint32_t 194static uint32_t
195ure_read_4(struct usbnet *un, uint16_t reg, uint16_t index) 195ure_read_4(struct usbnet *un, uint16_t reg, uint16_t index)
196{ 196{
197 uint8_t temp[4]; 197 uint8_t temp[4];
198 198
199 ure_read_mem(un, reg, index, &temp, 4); 199 ure_read_mem(un, reg, index, &temp, 4);
200 return UGETDW(temp); 200 return UGETDW(temp);
201} 201}
202 202
203static int 203static int
204ure_write_1(struct usbnet *un, uint16_t reg, uint16_t index, uint32_t val) 204ure_write_1(struct usbnet *un, uint16_t reg, uint16_t index, uint32_t val)
205{ 205{
206 uint16_t byen; 206 uint16_t byen;
207 uint8_t temp[4]; 207 uint8_t temp[4];
208 uint8_t shift; 208 uint8_t shift;
209 209
210 byen = URE_BYTE_EN_BYTE; 210 byen = URE_BYTE_EN_BYTE;
211 shift = reg & 3; 211 shift = reg & 3;
212 val &= 0xff; 212 val &= 0xff;
213 213
214 if (reg & 3) { 214 if (reg & 3) {
215 byen <<= shift; 215 byen <<= shift;
216 val <<= (shift << 3); 216 val <<= (shift << 3);
217 reg &= ~3; 217 reg &= ~3;
218 } 218 }
219 219
220 USETDW(temp, val); 220 USETDW(temp, val);
221 return ure_write_mem(un, reg, index | byen, &temp, 4); 221 return ure_write_mem(un, reg, index | byen, &temp, 4);
222} 222}
223 223
224static int 224static int
225ure_write_2(struct usbnet *un, uint16_t reg, uint16_t index, uint32_t val) 225ure_write_2(struct usbnet *un, uint16_t reg, uint16_t index, uint32_t val)
226{ 226{
227 uint16_t byen; 227 uint16_t byen;
228 uint8_t temp[4]; 228 uint8_t temp[4];
229 uint8_t shift; 229 uint8_t shift;
230 230
231 byen = URE_BYTE_EN_WORD; 231 byen = URE_BYTE_EN_WORD;
232 shift = reg & 2; 232 shift = reg & 2;
233 val &= 0xffff; 233 val &= 0xffff;
234 234
235 if (reg & 2) { 235 if (reg & 2) {
236 byen <<= shift; 236 byen <<= shift;
237 val <<= (shift << 3); 237 val <<= (shift << 3);
238 reg &= ~3; 238 reg &= ~3;
239 } 239 }
240 240
241 USETDW(temp, val); 241 USETDW(temp, val);
242 return ure_write_mem(un, reg, index | byen, &temp, 4); 242 return ure_write_mem(un, reg, index | byen, &temp, 4);
243} 243}
244 244
245static int 245static int
246ure_write_4(struct usbnet *un, uint16_t reg, uint16_t index, uint32_t val) 246ure_write_4(struct usbnet *un, uint16_t reg, uint16_t index, uint32_t val)
247{ 247{
248 uint8_t temp[4]; 248 uint8_t temp[4];
249 249
250 USETDW(temp, val); 250 USETDW(temp, val);
251 return ure_write_mem(un, reg, index | URE_BYTE_EN_DWORD, &temp, 4); 251 return ure_write_mem(un, reg, index | URE_BYTE_EN_DWORD, &temp, 4);
252} 252}
253 253
254static uint16_t 254static uint16_t
255ure_ocp_reg_read(struct usbnet *un, uint16_t addr) 255ure_ocp_reg_read(struct usbnet *un, uint16_t addr)
256{ 256{
257 uint16_t reg; 257 uint16_t reg;
258 258
259 ure_write_2(un, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000); 259 ure_write_2(un, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000);
260 reg = (addr & 0x0fff) | 0xb000; 260 reg = (addr & 0x0fff) | 0xb000;
261 261
262 return ure_read_2(un, reg, URE_MCU_TYPE_PLA); 262 return ure_read_2(un, reg, URE_MCU_TYPE_PLA);
263} 263}
264 264
265static void 265static void
266ure_ocp_reg_write(struct usbnet *un, uint16_t addr, uint16_t data) 266ure_ocp_reg_write(struct usbnet *un, uint16_t addr, uint16_t data)
267{ 267{
268 uint16_t reg; 268 uint16_t reg;
269 269
270 ure_write_2(un, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000); 270 ure_write_2(un, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000);
271 reg = (addr & 0x0fff) | 0xb000; 271 reg = (addr & 0x0fff) | 0xb000;
272 272
273 ure_write_2(un, reg, URE_MCU_TYPE_PLA, data); 273 ure_write_2(un, reg, URE_MCU_TYPE_PLA, data);
274} 274}
275 275
276static int 276static int
277ure_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 277ure_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
278{ 278{
279 279
280 if (un->un_phyno != phy) 280 if (un->un_phyno != phy)
281 return EINVAL; 281 return EINVAL;
282 282
283 /* Let the rgephy driver read the URE_PLA_PHYSTATUS register. */ 283 /* Let the rgephy driver read the URE_PLA_PHYSTATUS register. */
284 if (reg == RTK_GMEDIASTAT) { 284 if (reg == RTK_GMEDIASTAT) {
285 *val = ure_read_1(un, URE_PLA_PHYSTATUS, URE_MCU_TYPE_PLA); 285 *val = ure_read_1(un, URE_PLA_PHYSTATUS, URE_MCU_TYPE_PLA);
286 return USBD_NORMAL_COMPLETION; 286 return USBD_NORMAL_COMPLETION;
287 } 287 }
288 288
289 *val = ure_ocp_reg_read(un, URE_OCP_BASE_MII + reg * 2); 289 *val = ure_ocp_reg_read(un, URE_OCP_BASE_MII + reg * 2);
290 290
291 return 0; 291 return 0;
292} 292}
293 293
294static int 294static int
295ure_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 295ure_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
296{ 296{
297 297
298 if (un->un_phyno != phy) 298 if (un->un_phyno != phy)
299 return EINVAL; 299 return EINVAL;
300 300
301 ure_ocp_reg_write(un, URE_OCP_BASE_MII + reg * 2, val); 301 ure_ocp_reg_write(un, URE_OCP_BASE_MII + reg * 2, val);
302 302
303 return 0; 303 return 0;
304} 304}
305 305
306static void 306static void
307ure_uno_miibus_statchg(struct ifnet *ifp) 307ure_uno_miibus_statchg(struct ifnet *ifp)
308{ 308{
309 struct usbnet * const un = ifp->if_softc; 309 struct usbnet * const un = ifp->if_softc;
310 struct mii_data * const mii = usbnet_mii(un); 310 struct mii_data * const mii = usbnet_mii(un);
311 311
312 if (usbnet_isdying(un)) 312 if (usbnet_isdying(un))
313 return; 313 return;
314 314
315 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 315 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
316 (IFM_ACTIVE | IFM_AVALID)) { 316 (IFM_ACTIVE | IFM_AVALID)) {
317 switch (IFM_SUBTYPE(mii->mii_media_active)) { 317 switch (IFM_SUBTYPE(mii->mii_media_active)) {
318 case IFM_10_T: 318 case IFM_10_T:
319 case IFM_100_TX: 319 case IFM_100_TX:
320 usbnet_set_link(un, true); 320 usbnet_set_link(un, true);
321 break; 321 break;
322 case IFM_1000_T: 322 case IFM_1000_T:
323 if ((un->un_flags & URE_FLAG_8152) != 0) 323 if ((un->un_flags & URE_FLAG_8152) != 0)
324 break; 324 break;
325 usbnet_set_link(un, true); 325 usbnet_set_link(un, true);
326 break; 326 break;
327 default: 327 default:
328 break; 328 break;
329 } 329 }
330 } 330 }
331} 331}
332 332
333static void 333static void
334ure_rcvfilt_locked(struct usbnet *un) 334ure_rcvfilt_locked(struct usbnet *un)
335{ 335{
336 struct ethercom *ec = usbnet_ec(un); 336 struct ethercom *ec = usbnet_ec(un);
337 struct ifnet *ifp = usbnet_ifp(un); 337 struct ifnet *ifp = usbnet_ifp(un);
338 struct ether_multi *enm; 338 struct ether_multi *enm;
339 struct ether_multistep step; 339 struct ether_multistep step;
340 uint32_t mchash[2] = { 0, 0 }; 340 uint32_t mchash[2] = { 0, 0 };
341 uint32_t h = 0, rxmode; 341 uint32_t h = 0, rxmode;
342 342
343 usbnet_isowned_core(un); 343 usbnet_isowned_core(un);
344 344
345 if (usbnet_isdying(un)) 345 if (usbnet_isdying(un))
346 return; 346 return;
347 347
348 rxmode = ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA); 348 rxmode = ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA);
349 rxmode &= ~(URE_RCR_AAP | URE_RCR_AM); 349 rxmode &= ~(URE_RCR_AAP | URE_RCR_AM);
350 /* continue to accept my own DA and bcast frames */ 350 /* continue to accept my own DA and bcast frames */
351 351
352 ETHER_LOCK(ec); 352 ETHER_LOCK(ec);
353 if (ifp->if_flags & IFF_PROMISC) { 353 if (ifp->if_flags & IFF_PROMISC) {
354 ec->ec_flags |= ETHER_F_ALLMULTI; 354 ec->ec_flags |= ETHER_F_ALLMULTI;
355 ETHER_UNLOCK(ec); 355 ETHER_UNLOCK(ec);
356 /* run promisc. mode */ 356 /* run promisc. mode */
357 rxmode |= URE_RCR_AM; /* ??? */ 357 rxmode |= URE_RCR_AM; /* ??? */
358 rxmode |= URE_RCR_AAP; 358 rxmode |= URE_RCR_AAP;
359 goto update; 359 goto update;
360 } 360 }
361 ec->ec_flags &= ~ETHER_F_ALLMULTI; 361 ec->ec_flags &= ~ETHER_F_ALLMULTI;
362 ETHER_FIRST_MULTI(step, ec, enm); 362 ETHER_FIRST_MULTI(step, ec, enm);
363 while (enm != NULL) { 363 while (enm != NULL) {
364 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 364 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
365 ec->ec_flags |= ETHER_F_ALLMULTI; 365 ec->ec_flags |= ETHER_F_ALLMULTI;
366 ETHER_UNLOCK(ec); 366 ETHER_UNLOCK(ec);
367 /* accept all mcast frames */ 367 /* accept all mcast frames */
368 rxmode |= URE_RCR_AM; 368 rxmode |= URE_RCR_AM;
369 mchash[0] = mchash[1] = ~0U; /* necessary ?? */ 369 mchash[0] = mchash[1] = ~0U; /* necessary ?? */
370 goto update; 370 goto update;
371 } 371 }
372 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 372 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
373 mchash[h >> 31] |= 1 << ((h >> 26) & 0x1f); 373 mchash[h >> 31] |= 1 << ((h >> 26) & 0x1f);
374 ETHER_NEXT_MULTI(step, enm); 374 ETHER_NEXT_MULTI(step, enm);
375 } 375 }
376 ETHER_UNLOCK(ec); 376 ETHER_UNLOCK(ec);
377 if (h != 0) { 377 if (h != 0) {
378 rxmode |= URE_RCR_AM; /* activate mcast hash filter */ 378 rxmode |= URE_RCR_AM; /* activate mcast hash filter */
379 h = bswap32(mchash[0]); 379 h = bswap32(mchash[0]);
380 mchash[0] = bswap32(mchash[1]); 380 mchash[0] = bswap32(mchash[1]);
381 mchash[1] = h; 381 mchash[1] = h;
382 } 382 }
383 update: 383 update:
384 ure_write_4(un, URE_PLA_MAR0, URE_MCU_TYPE_PLA, mchash[0]); 384 ure_write_4(un, URE_PLA_MAR0, URE_MCU_TYPE_PLA, mchash[0]);
385 ure_write_4(un, URE_PLA_MAR4, URE_MCU_TYPE_PLA, mchash[1]); 385 ure_write_4(un, URE_PLA_MAR4, URE_MCU_TYPE_PLA, mchash[1]);
386 ure_write_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode); 386 ure_write_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode);
387} 387}
388 388
389static void 389static void
390ure_reset(struct usbnet *un) 390ure_reset(struct usbnet *un)
391{ 391{
392 int i; 392 int i;
393 393
394 usbnet_isowned_core(un); 394 usbnet_isowned_core(un);
395 395
396 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_RST); 396 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_RST);
397 397
398 for (i = 0; i < URE_TIMEOUT; i++) { 398 for (i = 0; i < URE_TIMEOUT; i++) {
399 if (usbnet_isdying(un)) 399 if (usbnet_isdying(un))
400 return; 400 return;
401 if (!(ure_read_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA) & 401 if (!(ure_read_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA) &
402 URE_CR_RST)) 402 URE_CR_RST))
403 break; 403 break;
404 usbd_delay_ms(un->un_udev, 10); 404 usbd_delay_ms(un->un_udev, 10);
405 } 405 }
406 if (i == URE_TIMEOUT) 406 if (i == URE_TIMEOUT)
407 URE_PRINTF(un, "reset never completed\n"); 407 URE_PRINTF(un, "reset never completed\n");
408} 408}
409 409
410static int 410static int
411ure_init_locked(struct ifnet *ifp) 411ure_init_locked(struct ifnet *ifp)
412{ 412{
413 struct usbnet * const un = ifp->if_softc; 413 struct usbnet * const un = ifp->if_softc;
414 uint8_t eaddr[8]; 414 uint8_t eaddr[8];
415 415
416 usbnet_isowned_core(un); 416 usbnet_isowned_core(un);
417 417
418 if (usbnet_isdying(un)) 418 if (usbnet_isdying(un))
419 return EIO; 419 return EIO;
420 420
421 /* Cancel pending I/O. */ 421 /* Cancel pending I/O. */
422 if (ifp->if_flags & IFF_RUNNING) 422 if (ifp->if_flags & IFF_RUNNING)
423 usbnet_stop(un, ifp, 1); 423 usbnet_stop(un, ifp, 1);
424 424
425 /* Set MAC address. */ 425 /* Set MAC address. */
426 memset(eaddr, 0, sizeof(eaddr)); 426 memset(eaddr, 0, sizeof(eaddr));
427 memcpy(eaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 427 memcpy(eaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
428 ure_write_1(un, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_CONFIG); 428 ure_write_1(un, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_CONFIG);
429 ure_write_mem(un, URE_PLA_IDR, URE_MCU_TYPE_PLA | URE_BYTE_EN_SIX_BYTES, 429 ure_write_mem(un, URE_PLA_IDR, URE_MCU_TYPE_PLA | URE_BYTE_EN_SIX_BYTES,
430 eaddr, 8); 430 eaddr, 8);
431 ure_write_1(un, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML); 431 ure_write_1(un, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML);
432 432
433 /* Reset the packet filter. */ 433 /* Reset the packet filter. */
434 ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA, 434 ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA,
435 ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) & 435 ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) &
436 ~URE_FMC_FCR_MCU_EN); 436 ~URE_FMC_FCR_MCU_EN);
437 ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA, 437 ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA,
438 ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) | 438 ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) |
439 URE_FMC_FCR_MCU_EN); 439 URE_FMC_FCR_MCU_EN);
440 440
441 /* Enable transmit and receive. */ 441 /* Enable transmit and receive. */
442 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, 442 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA,
443 ure_read_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA) | URE_CR_RE | 443 ure_read_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA) | URE_CR_RE |
444 URE_CR_TE); 444 URE_CR_TE);
445 445
446 ure_write_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, 446 ure_write_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA,
447 ure_read_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) & 447 ure_read_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) &
448 ~URE_RXDY_GATED_EN); 448 ~URE_RXDY_GATED_EN);
449 449
450 /* Accept multicast frame or run promisc. mode. */ 450 /* Accept multicast frame or run promisc. mode. */
451 ure_rcvfilt_locked(un); 451 ure_rcvfilt_locked(un);
452 452
453 return usbnet_init_rx_tx(un); 453 return usbnet_init_rx_tx(un);
454} 454}
455 455
456static int 456static int
457ure_uno_init(struct ifnet *ifp) 457ure_uno_init(struct ifnet *ifp)
458{ 458{
459 int ret = ure_init_locked(ifp); 459 int ret = ure_init_locked(ifp);
460 460
461 return ret; 461 return ret;
462} 462}
463 463
464static void 464static void
465ure_uno_stop(struct ifnet *ifp, int disable __unused) 465ure_uno_stop(struct ifnet *ifp, int disable __unused)
466{ 466{
467 struct usbnet * const un = ifp->if_softc; 467 struct usbnet * const un = ifp->if_softc;
468 468
469 ure_reset(un); 469 ure_reset(un);
470} 470}
471 471
472static void 472static void
473ure_rtl8152_init(struct usbnet *un) 473ure_rtl8152_init(struct usbnet *un)
474{ 474{
475 uint32_t pwrctrl; 475 uint32_t pwrctrl;
476 476
477 /* Disable ALDPS. */ 477 /* Disable ALDPS. */
478 ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | 478 ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA |
479 URE_DIS_SDSAVE); 479 URE_DIS_SDSAVE);
480 usbd_delay_ms(un->un_udev, 20); 480 usbd_delay_ms(un->un_udev, 20);
481 481
482 if (un->un_flags & URE_FLAG_VER_4C00) { 482 if (un->un_flags & URE_FLAG_VER_4C00) {
483 ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, 483 ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA,
484 ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & 484 ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) &
485 ~URE_LED_MODE_MASK); 485 ~URE_LED_MODE_MASK);
486 } 486 }
487 487
488 ure_write_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB, 488 ure_write_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB,
489 ure_read_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB) & 489 ure_read_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB) &
490 ~URE_POWER_CUT); 490 ~URE_POWER_CUT);
491 ure_write_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB, 491 ure_write_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB,
492 ure_read_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB) & 492 ure_read_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB) &
493 ~URE_RESUME_INDICATE); 493 ~URE_RESUME_INDICATE);
494 494
495 ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, 495 ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA,
496 ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | 496 ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) |
497 URE_TX_10M_IDLE_EN | URE_PFM_PWM_SWITCH); 497 URE_TX_10M_IDLE_EN | URE_PFM_PWM_SWITCH);
498 pwrctrl = ure_read_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA); 498 pwrctrl = ure_read_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA);
499 pwrctrl &= ~URE_MCU_CLK_RATIO_MASK; 499 pwrctrl &= ~URE_MCU_CLK_RATIO_MASK;
500 pwrctrl |= URE_MCU_CLK_RATIO | URE_D3_CLK_GATED_EN; 500 pwrctrl |= URE_MCU_CLK_RATIO | URE_D3_CLK_GATED_EN;
501 ure_write_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, pwrctrl); 501 ure_write_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, pwrctrl);
502 ure_write_2(un, URE_PLA_GPHY_INTR_IMR, URE_MCU_TYPE_PLA, 502 ure_write_2(un, URE_PLA_GPHY_INTR_IMR, URE_MCU_TYPE_PLA,
503 URE_GPHY_STS_MSK | URE_SPEED_DOWN_MSK | URE_SPDWN_RXDV_MSK | 503 URE_GPHY_STS_MSK | URE_SPEED_DOWN_MSK | URE_SPDWN_RXDV_MSK |
504 URE_SPDWN_LINKCHG_MSK); 504 URE_SPDWN_LINKCHG_MSK);
505 505
506 /* Enable Rx aggregation. */ 506 /* Enable Rx aggregation. */
507 ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, 507 ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB,
508 ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & 508 ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) &
509 ~URE_RX_AGG_DISABLE); 509 ~URE_RX_AGG_DISABLE);
510 510
511 /* Disable ALDPS. */ 511 /* Disable ALDPS. */
512 ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | 512 ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA |
513 URE_DIS_SDSAVE); 513 URE_DIS_SDSAVE);
514 usbd_delay_ms(un->un_udev, 20); 514 usbd_delay_ms(un->un_udev, 20);
515 515
516 ure_init_fifo(un); 516 ure_init_fifo(un);
517 517
518 ure_write_1(un, URE_USB_TX_AGG, URE_MCU_TYPE_USB, 518 ure_write_1(un, URE_USB_TX_AGG, URE_MCU_TYPE_USB,
519 URE_TX_AGG_MAX_THRESHOLD); 519 URE_TX_AGG_MAX_THRESHOLD);
520 ure_write_4(un, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB, URE_RX_THR_HIGH); 520 ure_write_4(un, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB, URE_RX_THR_HIGH);
521 ure_write_4(un, URE_USB_TX_DMA, URE_MCU_TYPE_USB, 521 ure_write_4(un, URE_USB_TX_DMA, URE_MCU_TYPE_USB,
522 URE_TEST_MODE_DISABLE | URE_TX_SIZE_ADJUST1); 522 URE_TEST_MODE_DISABLE | URE_TX_SIZE_ADJUST1);
523} 523}
524 524
525static void 525static void
526ure_rtl8153_init(struct usbnet *un) 526ure_rtl8153_init(struct usbnet *un)
527{ 527{
528 uint16_t val; 528 uint16_t val;
529 uint8_t u1u2[8]; 529 uint8_t u1u2[8];
530 int i; 530 int i;
531 531
532 /* Disable ALDPS. */ 532 /* Disable ALDPS. */
533 ure_ocp_reg_write(un, URE_OCP_POWER_CFG, 533 ure_ocp_reg_write(un, URE_OCP_POWER_CFG,
534 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); 534 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS);
535 usbd_delay_ms(un->un_udev, 20); 535 usbd_delay_ms(un->un_udev, 20);
536 536
537 memset(u1u2, 0x00, sizeof(u1u2)); 537 memset(u1u2, 0x00, sizeof(u1u2));
538 ure_write_mem(un, URE_USB_TOLERANCE, 538 ure_write_mem(un, URE_USB_TOLERANCE,
539 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); 539 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
540 540
541 for (i = 0; i < URE_TIMEOUT; i++) { 541 for (i = 0; i < URE_TIMEOUT; i++) {
542 if (usbnet_isdying(un)) 542 if (usbnet_isdying(un))
543 return; 543 return;
544 if (ure_read_2(un, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) & 544 if (ure_read_2(un, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) &
545 URE_AUTOLOAD_DONE) 545 URE_AUTOLOAD_DONE)
546 break; 546 break;
547 usbd_delay_ms(un->un_udev, 10); 547 usbd_delay_ms(un->un_udev, 10);
548 } 548 }
549 if (i == URE_TIMEOUT) 549 if (i == URE_TIMEOUT)
550 URE_PRINTF(un, "timeout waiting for chip autoload\n"); 550 URE_PRINTF(un, "timeout waiting for chip autoload\n");
551 551
552 for (i = 0; i < URE_TIMEOUT; i++) { 552 for (i = 0; i < URE_TIMEOUT; i++) {
553 if (usbnet_isdying(un)) 553 if (usbnet_isdying(un))
554 return; 554 return;
555 val = ure_ocp_reg_read(un, URE_OCP_PHY_STATUS) & 555 val = ure_ocp_reg_read(un, URE_OCP_PHY_STATUS) &
556 URE_PHY_STAT_MASK; 556 URE_PHY_STAT_MASK;
557 if (val == URE_PHY_STAT_LAN_ON || val == URE_PHY_STAT_PWRDN) 557 if (val == URE_PHY_STAT_LAN_ON || val == URE_PHY_STAT_PWRDN)
558 break; 558 break;
559 usbd_delay_ms(un->un_udev, 10); 559 usbd_delay_ms(un->un_udev, 10);
560 } 560 }
561 if (i == URE_TIMEOUT) 561 if (i == URE_TIMEOUT)
562 URE_PRINTF(un, "timeout waiting for phy to stabilize\n"); 562 URE_PRINTF(un, "timeout waiting for phy to stabilize\n");
563 563
564 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, 564 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB,
565 ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) & 565 ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) &
566 ~URE_U2P3_ENABLE); 566 ~URE_U2P3_ENABLE);
567 567
568 if (un->un_flags & URE_FLAG_VER_5C10) { 568 if (un->un_flags & URE_FLAG_VER_5C10) {
569 val = ure_read_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB); 569 val = ure_read_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB);
570 val &= ~URE_PWD_DN_SCALE_MASK; 570 val &= ~URE_PWD_DN_SCALE_MASK;
571 val |= URE_PWD_DN_SCALE(96); 571 val |= URE_PWD_DN_SCALE(96);
572 ure_write_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val); 572 ure_write_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val);
573 573
574 ure_write_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB, 574 ure_write_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB,
575 ure_read_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB) | 575 ure_read_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB) |
576 URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND); 576 URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND);
577 } else if (un->un_flags & URE_FLAG_VER_5C20) { 577 } else if (un->un_flags & URE_FLAG_VER_5C20) {
578 ure_write_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA, 578 ure_write_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA,
579 ure_read_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) & 579 ure_read_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) &
580 ~URE_ECM_ALDPS); 580 ~URE_ECM_ALDPS);
581 } 581 }
582 if (un->un_flags & (URE_FLAG_VER_5C20 | URE_FLAG_VER_5C30)) { 582 if (un->un_flags & (URE_FLAG_VER_5C20 | URE_FLAG_VER_5C30)) {
583 val = ure_read_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB); 583 val = ure_read_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB);
584 if (ure_read_2(un, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) == 584 if (ure_read_2(un, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) ==
585 0) 585 0)
586 val &= ~URE_DYNAMIC_BURST; 586 val &= ~URE_DYNAMIC_BURST;
587 else 587 else
588 val |= URE_DYNAMIC_BURST; 588 val |= URE_DYNAMIC_BURST;
589 ure_write_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val); 589 ure_write_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val);
590 } 590 }
591 591
592 ure_write_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB, 592 ure_write_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB,
593 ure_read_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) | 593 ure_read_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) |
594 URE_EP4_FULL_FC); 594 URE_EP4_FULL_FC);
595 595
596 ure_write_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB, 596 ure_write_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB,
597 ure_read_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) & 597 ure_read_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) &
598 ~URE_TIMER11_EN); 598 ~URE_TIMER11_EN);
599 599
600 ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, 600 ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA,
601 ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & 601 ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) &
602 ~URE_LED_MODE_MASK); 602 ~URE_LED_MODE_MASK);
603 603
604 if ((un->un_flags & URE_FLAG_VER_5C10) && 604 if ((un->un_flags & URE_FLAG_VER_5C10) &&
605 un->un_udev->ud_speed != USB_SPEED_SUPER) 605 un->un_udev->ud_speed != USB_SPEED_SUPER)
606 val = URE_LPM_TIMER_500MS; 606 val = URE_LPM_TIMER_500MS;
607 else 607 else
608 val = URE_LPM_TIMER_500US; 608 val = URE_LPM_TIMER_500US;
609 ure_write_1(un, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB, 609 ure_write_1(un, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB,
610 val | URE_FIFO_EMPTY_1FB | URE_ROK_EXIT_LPM); 610 val | URE_FIFO_EMPTY_1FB | URE_ROK_EXIT_LPM);
611 611
612 val = ure_read_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB); 612 val = ure_read_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB);
613 val &= ~URE_SEN_VAL_MASK; 613 val &= ~URE_SEN_VAL_MASK;
614 val |= URE_SEN_VAL_NORMAL | URE_SEL_RXIDLE; 614 val |= URE_SEN_VAL_NORMAL | URE_SEL_RXIDLE;
615 ure_write_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val); 615 ure_write_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val);
616 616
617 ure_write_2(un, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001); 617 ure_write_2(un, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001);
618 618
619 ure_write_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB, 619 ure_write_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB,
620 ure_read_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) & 620 ure_read_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) &
621 ~(URE_PWR_EN | URE_PHASE2_EN)); 621 ~(URE_PWR_EN | URE_PHASE2_EN));
622 ure_write_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB, 622 ure_write_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB,
623 ure_read_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB) & 623 ure_read_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB) &
624 ~URE_PCUT_STATUS); 624 ~URE_PCUT_STATUS);
625 625
626 memset(u1u2, 0xff, sizeof(u1u2)); 626 memset(u1u2, 0xff, sizeof(u1u2));
627 ure_write_mem(un, URE_USB_TOLERANCE, 627 ure_write_mem(un, URE_USB_TOLERANCE,
628 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); 628 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
629 629
630 ure_write_2(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, 630 ure_write_2(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA,
631 URE_ALDPS_SPDWN_RATIO); 631 URE_ALDPS_SPDWN_RATIO);
632 ure_write_2(un, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA, 632 ure_write_2(un, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA,
633 URE_EEE_SPDWN_RATIO); 633 URE_EEE_SPDWN_RATIO);
634 ure_write_2(un, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA, 634 ure_write_2(un, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA,
635 URE_PKT_AVAIL_SPDWN_EN | URE_SUSPEND_SPDWN_EN | 635 URE_PKT_AVAIL_SPDWN_EN | URE_SUSPEND_SPDWN_EN |
636 URE_U1U2_SPDWN_EN | URE_L1_SPDWN_EN); 636 URE_U1U2_SPDWN_EN | URE_L1_SPDWN_EN);
637 ure_write_2(un, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA, 637 ure_write_2(un, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA,
638 URE_PWRSAVE_SPDWN_EN | URE_RXDV_SPDWN_EN | URE_TX10MIDLE_EN | 638 URE_PWRSAVE_SPDWN_EN | URE_RXDV_SPDWN_EN | URE_TX10MIDLE_EN |
639 URE_TP100_SPDWN_EN | URE_TP500_SPDWN_EN | URE_TP1000_SPDWN_EN | 639 URE_TP100_SPDWN_EN | URE_TP500_SPDWN_EN | URE_TP1000_SPDWN_EN |
640 URE_EEE_SPDWN_EN); 640 URE_EEE_SPDWN_EN);
641 641
642 val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); 642 val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
643 if (!(un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10))) 643 if (!(un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10)))
644 val |= URE_U2P3_ENABLE; 644 val |= URE_U2P3_ENABLE;
645 else 645 else
646 val &= ~URE_U2P3_ENABLE; 646 val &= ~URE_U2P3_ENABLE;
647 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); 647 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
648 648
649 memset(u1u2, 0x00, sizeof(u1u2)); 649 memset(u1u2, 0x00, sizeof(u1u2));
650 ure_write_mem(un, URE_USB_TOLERANCE, 650 ure_write_mem(un, URE_USB_TOLERANCE,
651 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); 651 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
652 652
653 /* Disable ALDPS. */ 653 /* Disable ALDPS. */
654 ure_ocp_reg_write(un, URE_OCP_POWER_CFG, 654 ure_ocp_reg_write(un, URE_OCP_POWER_CFG,
655 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); 655 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS);
656 usbd_delay_ms(un->un_udev, 20); 656 usbd_delay_ms(un->un_udev, 20);
657 657
658 ure_init_fifo(un); 658 ure_init_fifo(un);
659 659
660 /* Enable Rx aggregation. */ 660 /* Enable Rx aggregation. */
661 ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, 661 ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB,
662 ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & 662 ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) &
663 ~URE_RX_AGG_DISABLE); 663 ~URE_RX_AGG_DISABLE);
664 664
665 val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); 665 val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
666 if (!(un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10))) 666 if (!(un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10)))
667 val |= URE_U2P3_ENABLE; 667 val |= URE_U2P3_ENABLE;
668 else 668 else
669 val &= ~URE_U2P3_ENABLE; 669 val &= ~URE_U2P3_ENABLE;
670 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); 670 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
671 671
672 memset(u1u2, 0xff, sizeof(u1u2)); 672 memset(u1u2, 0xff, sizeof(u1u2));
673 ure_write_mem(un, URE_USB_TOLERANCE, 673 ure_write_mem(un, URE_USB_TOLERANCE,
674 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); 674 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
675} 675}
676 676
677static void 677static void
678ure_disable_teredo(struct usbnet *un) 678ure_disable_teredo(struct usbnet *un)
679{ 679{
680 ure_write_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA, 680 ure_write_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA,
681 ure_read_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA) & 681 ure_read_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA) &
682 ~(URE_TEREDO_SEL | URE_TEREDO_RS_EVENT_MASK | URE_OOB_TEREDO_EN)); 682 ~(URE_TEREDO_SEL | URE_TEREDO_RS_EVENT_MASK | URE_OOB_TEREDO_EN));
683 ure_write_2(un, URE_PLA_WDT6_CTRL, URE_MCU_TYPE_PLA, 683 ure_write_2(un, URE_PLA_WDT6_CTRL, URE_MCU_TYPE_PLA,
684 URE_WDT6_SET_MODE); 684 URE_WDT6_SET_MODE);
685 ure_write_2(un, URE_PLA_REALWOW_TIMER, URE_MCU_TYPE_PLA, 0); 685 ure_write_2(un, URE_PLA_REALWOW_TIMER, URE_MCU_TYPE_PLA, 0);
686 ure_write_4(un, URE_PLA_TEREDO_TIMER, URE_MCU_TYPE_PLA, 0); 686 ure_write_4(un, URE_PLA_TEREDO_TIMER, URE_MCU_TYPE_PLA, 0);
687} 687}
688 688
689static void 689static void
690ure_init_fifo(struct usbnet *un) 690ure_init_fifo(struct usbnet *un)
691{ 691{
692 uint32_t rxmode, rx_fifo1, rx_fifo2; 692 uint32_t rxmode, rx_fifo1, rx_fifo2;
693 int i; 693 int i;
694 694
695 ure_write_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, 695 ure_write_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA,
696 ure_read_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) | 696 ure_read_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) |
697 URE_RXDY_GATED_EN); 697 URE_RXDY_GATED_EN);
698 698
699 ure_disable_teredo(un); 699 ure_disable_teredo(un);
700 700
701 rxmode = ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA); 701 rxmode = ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA);
702 rxmode &= ~URE_RCR_ACPT_ALL; 702 rxmode &= ~URE_RCR_ACPT_ALL;
703 rxmode |= URE_RCR_APM | URE_RCR_AB; /* accept my own DA and bcast */ 703 rxmode |= URE_RCR_APM | URE_RCR_AB; /* accept my own DA and bcast */
704 ure_write_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode); 704 ure_write_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode);
705 705
706 if (!(un->un_flags & URE_FLAG_8152)) { 706 if (!(un->un_flags & URE_FLAG_8152)) {
707 if (un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10 | 707 if (un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10 |
708 URE_FLAG_VER_5C20)) 708 URE_FLAG_VER_5C20))
709 ure_ocp_reg_write(un, URE_OCP_ADC_CFG, 709 ure_ocp_reg_write(un, URE_OCP_ADC_CFG,
710 URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L); 710 URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L);
711 if (un->un_flags & URE_FLAG_VER_5C00) 711 if (un->un_flags & URE_FLAG_VER_5C00)
712 ure_ocp_reg_write(un, URE_OCP_EEE_CFG, 712 ure_ocp_reg_write(un, URE_OCP_EEE_CFG,
713 ure_ocp_reg_read(un, URE_OCP_EEE_CFG) & 713 ure_ocp_reg_read(un, URE_OCP_EEE_CFG) &
714 ~URE_CTAP_SHORT_EN); 714 ~URE_CTAP_SHORT_EN);
715 ure_ocp_reg_write(un, URE_OCP_POWER_CFG, 715 ure_ocp_reg_write(un, URE_OCP_POWER_CFG,
716 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) | 716 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) |
717 URE_EEE_CLKDIV_EN); 717 URE_EEE_CLKDIV_EN);
718 ure_ocp_reg_write(un, URE_OCP_DOWN_SPEED, 718 ure_ocp_reg_write(un, URE_OCP_DOWN_SPEED,
719 ure_ocp_reg_read(un, URE_OCP_DOWN_SPEED) | 719 ure_ocp_reg_read(un, URE_OCP_DOWN_SPEED) |
720 URE_EN_10M_BGOFF); 720 URE_EN_10M_BGOFF);
721 ure_ocp_reg_write(un, URE_OCP_POWER_CFG, 721 ure_ocp_reg_write(un, URE_OCP_POWER_CFG,
722 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) | 722 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) |
723 URE_EN_10M_PLLOFF); 723 URE_EN_10M_PLLOFF);
724 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE); 724 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE);
725 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0b13); 725 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0b13);
726 ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, 726 ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA,
727 ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | 727 ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) |
728 URE_PFM_PWM_SWITCH); 728 URE_PFM_PWM_SWITCH);
729 729
730 /* Enable LPF corner auto tune. */ 730 /* Enable LPF corner auto tune. */
731 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG); 731 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG);
732 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0xf70f); 732 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0xf70f);
733 733
734 /* Adjust 10M amplitude. */ 734 /* Adjust 10M amplitude. */
735 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1); 735 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1);
736 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x00af); 736 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x00af);
737 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2); 737 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2);
738 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0208); 738 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0208);
739 } 739 }
740 740
741 ure_reset(un); 741 ure_reset(un);
742 742
743 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, 0); 743 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, 0);
744 744
745 ure_write_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA, 745 ure_write_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA,
746 ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & 746 ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) &
747 ~URE_NOW_IS_OOB); 747 ~URE_NOW_IS_OOB);
748 748
749 ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, 749 ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA,
750 ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) & 750 ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) &
751 ~URE_MCU_BORW_EN); 751 ~URE_MCU_BORW_EN);
752 for (i = 0; i < URE_TIMEOUT; i++) { 752 for (i = 0; i < URE_TIMEOUT; i++) {
753 if (usbnet_isdying(un)) 753 if (usbnet_isdying(un))
754 return; 754 return;
755 if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & 755 if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) &
756 URE_LINK_LIST_READY) 756 URE_LINK_LIST_READY)
757 break; 757 break;
758 usbd_delay_ms(un->un_udev, 10); 758 usbd_delay_ms(un->un_udev, 10);
759 } 759 }
760 if (i == URE_TIMEOUT) 760 if (i == URE_TIMEOUT)
761 URE_PRINTF(un, "timeout waiting for OOB control\n"); 761 URE_PRINTF(un, "timeout waiting for OOB control\n");
762 ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, 762 ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA,
763 ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) | 763 ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) |
764 URE_RE_INIT_LL); 764 URE_RE_INIT_LL);
765 for (i = 0; i < URE_TIMEOUT; i++) { 765 for (i = 0; i < URE_TIMEOUT; i++) {
766 if (usbnet_isdying(un)) 766 if (usbnet_isdying(un))
767 return; 767 return;
768 if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & 768 if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) &
769 URE_LINK_LIST_READY) 769 URE_LINK_LIST_READY)
770 break; 770 break;
771 usbd_delay_ms(un->un_udev, 10); 771 usbd_delay_ms(un->un_udev, 10);
772 } 772 }
773 if (i == URE_TIMEOUT) 773 if (i == URE_TIMEOUT)
774 URE_PRINTF(un, "timeout waiting for OOB control\n"); 774 URE_PRINTF(un, "timeout waiting for OOB control\n");
775 775
776 ure_write_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA, 776 ure_write_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA,
777 ure_read_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA) & 777 ure_read_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA) &
778 ~URE_CPCR_RX_VLAN); 778 ~URE_CPCR_RX_VLAN);
779 ure_write_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA, 779 ure_write_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA,
780 ure_read_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA) | 780 ure_read_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA) |
781 URE_TCR0_AUTO_FIFO); 781 URE_TCR0_AUTO_FIFO);
782 782
783 /* Configure Rx FIFO threshold and coalescing. */ 783 /* Configure Rx FIFO threshold and coalescing. */
784 ure_write_4(un, URE_PLA_RXFIFO_CTRL0, URE_MCU_TYPE_PLA, 784 ure_write_4(un, URE_PLA_RXFIFO_CTRL0, URE_MCU_TYPE_PLA,
785 URE_RXFIFO_THR1_NORMAL); 785 URE_RXFIFO_THR1_NORMAL);
786 if (un->un_udev->ud_speed == USB_SPEED_FULL) { 786 if (un->un_udev->ud_speed == USB_SPEED_FULL) {
787 rx_fifo1 = URE_RXFIFO_THR2_FULL; 787 rx_fifo1 = URE_RXFIFO_THR2_FULL;
788 rx_fifo2 = URE_RXFIFO_THR3_FULL; 788 rx_fifo2 = URE_RXFIFO_THR3_FULL;
789 } else { 789 } else {
790 rx_fifo1 = URE_RXFIFO_THR2_HIGH; 790 rx_fifo1 = URE_RXFIFO_THR2_HIGH;
791 rx_fifo2 = URE_RXFIFO_THR3_HIGH; 791 rx_fifo2 = URE_RXFIFO_THR3_HIGH;
792 } 792 }
793 ure_write_4(un, URE_PLA_RXFIFO_CTRL1, URE_MCU_TYPE_PLA, rx_fifo1); 793 ure_write_4(un, URE_PLA_RXFIFO_CTRL1, URE_MCU_TYPE_PLA, rx_fifo1);
794 ure_write_4(un, URE_PLA_RXFIFO_CTRL2, URE_MCU_TYPE_PLA, rx_fifo2); 794 ure_write_4(un, URE_PLA_RXFIFO_CTRL2, URE_MCU_TYPE_PLA, rx_fifo2);
795 795
796 /* Configure Tx FIFO threshold. */ 796 /* Configure Tx FIFO threshold. */
797 ure_write_4(un, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA, 797 ure_write_4(un, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA,
798 URE_TXFIFO_THR_NORMAL); 798 URE_TXFIFO_THR_NORMAL);
799} 799}
800 800
801static void 801static void
802ure_uno_mcast(struct ifnet *ifp) 802ure_uno_mcast(struct ifnet *ifp)
803{ 803{
804 struct usbnet * const un = ifp->if_softc; 804 struct usbnet * const un = ifp->if_softc;
805 805
806 usbnet_lock_core(un); 806 usbnet_lock_core(un);
807 usbnet_busy(un); 
808 807
809 ure_rcvfilt_locked(un); 808 ure_rcvfilt_locked(un);
810 809
811 usbnet_unbusy(un); 
812 usbnet_unlock_core(un); 810 usbnet_unlock_core(un);
813} 811}
814 812
815static int 813static int
816ure_match(device_t parent, cfdata_t match, void *aux) 814ure_match(device_t parent, cfdata_t match, void *aux)
817{ 815{
818 struct usb_attach_arg *uaa = aux; 816 struct usb_attach_arg *uaa = aux;
819 817
820 return usb_lookup(ure_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ? 818 return usb_lookup(ure_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ?
821 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 819 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
822} 820}
823 821
824static void 822static void
825ure_attach(device_t parent, device_t self, void *aux) 823ure_attach(device_t parent, device_t self, void *aux)
826{ 824{
827 USBNET_MII_DECL_DEFAULT(unm); 825 USBNET_MII_DECL_DEFAULT(unm);
828 struct usbnet * const un = device_private(self); 826 struct usbnet * const un = device_private(self);
829 struct usb_attach_arg *uaa = aux; 827 struct usb_attach_arg *uaa = aux;
830 struct usbd_device *dev = uaa->uaa_device; 828 struct usbd_device *dev = uaa->uaa_device;
831 usb_interface_descriptor_t *id; 829 usb_interface_descriptor_t *id;
832 usb_endpoint_descriptor_t *ed; 830 usb_endpoint_descriptor_t *ed;
833 int error, i; 831 int error, i;
834 uint16_t ver; 832 uint16_t ver;
835 uint8_t eaddr[8]; /* 2byte padded */ 833 uint8_t eaddr[8]; /* 2byte padded */
836 char *devinfop; 834 char *devinfop;
837 uint32_t maclo, machi; 835 uint32_t maclo, machi;
838 836
839 aprint_naive("\n"); 837 aprint_naive("\n");
840 aprint_normal("\n"); 838 aprint_normal("\n");
841 devinfop = usbd_devinfo_alloc(dev, 0); 839 devinfop = usbd_devinfo_alloc(dev, 0);
842 aprint_normal_dev(self, "%s\n", devinfop); 840 aprint_normal_dev(self, "%s\n", devinfop);
843 usbd_devinfo_free(devinfop); 841 usbd_devinfo_free(devinfop);
844 842
845 un->un_dev = self; 843 un->un_dev = self;
846 un->un_udev = dev; 844 un->un_udev = dev;
847 un->un_sc = un; 845 un->un_sc = un;
848 un->un_ops = &ure_ops; 846 un->un_ops = &ure_ops;
849 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 847 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
850 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 848 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
851 un->un_rx_list_cnt = URE_RX_LIST_CNT; 849 un->un_rx_list_cnt = URE_RX_LIST_CNT;
852 un->un_tx_list_cnt = URE_TX_LIST_CNT; 850 un->un_tx_list_cnt = URE_TX_LIST_CNT;
853 un->un_rx_bufsz = URE_BUFSZ; 851 un->un_rx_bufsz = URE_BUFSZ;
854 un->un_tx_bufsz = URE_BUFSZ; 852 un->un_tx_bufsz = URE_BUFSZ;
855 853
856#define URE_CONFIG_NO 1 /* XXX */ 854#define URE_CONFIG_NO 1 /* XXX */
857 error = usbd_set_config_no(dev, URE_CONFIG_NO, 1); 855 error = usbd_set_config_no(dev, URE_CONFIG_NO, 1);
858 if (error) { 856 if (error) {
859 aprint_error_dev(self, "failed to set configuration: %s\n", 857 aprint_error_dev(self, "failed to set configuration: %s\n",
860 usbd_errstr(error)); 858 usbd_errstr(error));
861 return; /* XXX */ 859 return; /* XXX */
862 } 860 }
863 861
864 if (uaa->uaa_product == USB_PRODUCT_REALTEK_RTL8152) 862 if (uaa->uaa_product == USB_PRODUCT_REALTEK_RTL8152)
865 un->un_flags |= URE_FLAG_8152; 863 un->un_flags |= URE_FLAG_8152;
866 864
867#define URE_IFACE_IDX 0 /* XXX */ 865#define URE_IFACE_IDX 0 /* XXX */
868 error = usbd_device2interface_handle(dev, URE_IFACE_IDX, &un->un_iface); 866 error = usbd_device2interface_handle(dev, URE_IFACE_IDX, &un->un_iface);
869 if (error) { 867 if (error) {
870 aprint_error_dev(self, "failed to get interface handle: %s\n", 868 aprint_error_dev(self, "failed to get interface handle: %s\n",
871 usbd_errstr(error)); 869 usbd_errstr(error));
872 return; /* XXX */ 870 return; /* XXX */
873 } 871 }
874 872
875 id = usbd_get_interface_descriptor(un->un_iface); 873 id = usbd_get_interface_descriptor(un->un_iface);
876 for (i = 0; i < id->bNumEndpoints; i++) { 874 for (i = 0; i < id->bNumEndpoints; i++) {
877 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 875 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
878 if (ed == NULL) { 876 if (ed == NULL) {
879 aprint_error_dev(self, "couldn't get ep %d\n", i); 877 aprint_error_dev(self, "couldn't get ep %d\n", i);
880 return; /* XXX */ 878 return; /* XXX */
881 } 879 }
882 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 880 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
883 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 881 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
884 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 882 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
885 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 883 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
886 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 884 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
887 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 885 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
888 } 886 }
889 } 887 }
890 888
891 /* Set these up now for ure_ctl(). */ 889 /* Set these up now for ure_ctl(). */
892 usbnet_attach(un, "uredet"); 890 usbnet_attach(un, "uredet");
893 891
894 un->un_phyno = 0; 892 un->un_phyno = 0;
895 893
896 ver = ure_read_2(un, URE_PLA_TCR1, URE_MCU_TYPE_PLA) & URE_VERSION_MASK; 894 ver = ure_read_2(un, URE_PLA_TCR1, URE_MCU_TYPE_PLA) & URE_VERSION_MASK;
897 switch (ver) { 895 switch (ver) {
898 case 0x4c00: 896 case 0x4c00:
899 un->un_flags |= URE_FLAG_VER_4C00; 897 un->un_flags |= URE_FLAG_VER_4C00;
900 break; 898 break;
901 case 0x4c10: 899 case 0x4c10:
902 un->un_flags |= URE_FLAG_VER_4C10; 900 un->un_flags |= URE_FLAG_VER_4C10;
903 break; 901 break;
904 case 0x5c00: 902 case 0x5c00:
905 un->un_flags |= URE_FLAG_VER_5C00; 903 un->un_flags |= URE_FLAG_VER_5C00;
906 break; 904 break;
907 case 0x5c10: 905 case 0x5c10:
908 un->un_flags |= URE_FLAG_VER_5C10; 906 un->un_flags |= URE_FLAG_VER_5C10;
909 break; 907 break;
910 case 0x5c20: 908 case 0x5c20:
911 un->un_flags |= URE_FLAG_VER_5C20; 909 un->un_flags |= URE_FLAG_VER_5C20;
912 break; 910 break;
913 case 0x5c30: 911 case 0x5c30:
914 un->un_flags |= URE_FLAG_VER_5C30; 912 un->un_flags |= URE_FLAG_VER_5C30;
915 break; 913 break;
916 default: 914 default:
917 /* fake addr? or just fail? */ 915 /* fake addr? or just fail? */
918 break; 916 break;
919 } 917 }
920 aprint_normal_dev(self, "RTL%d %sver %04x\n", 918 aprint_normal_dev(self, "RTL%d %sver %04x\n",
921 (un->un_flags & URE_FLAG_8152) ? 8152 : 8153, 919 (un->un_flags & URE_FLAG_8152) ? 8152 : 8153,
922 (un->un_flags != 0) ? "" : "unknown ", 920 (un->un_flags != 0) ? "" : "unknown ",
923 ver); 921 ver);
924 922
925 usbnet_lock_core(un); 923 usbnet_lock_core(un);
926 if (un->un_flags & URE_FLAG_8152) 924 if (un->un_flags & URE_FLAG_8152)
927 ure_rtl8152_init(un); 925 ure_rtl8152_init(un);
928 else 926 else
929 ure_rtl8153_init(un); 927 ure_rtl8153_init(un);
930 928
931 if ((un->un_flags & URE_FLAG_VER_4C00) || 929 if ((un->un_flags & URE_FLAG_VER_4C00) ||
932 (un->un_flags & URE_FLAG_VER_4C10)) 930 (un->un_flags & URE_FLAG_VER_4C10))
933 ure_read_mem(un, URE_PLA_IDR, URE_MCU_TYPE_PLA, eaddr, 931 ure_read_mem(un, URE_PLA_IDR, URE_MCU_TYPE_PLA, eaddr,
934 sizeof(eaddr)); 932 sizeof(eaddr));
935 else 933 else
936 ure_read_mem(un, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr, 934 ure_read_mem(un, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr,
937 sizeof(eaddr)); 935 sizeof(eaddr));
938 usbnet_unlock_core(un); 936 usbnet_unlock_core(un);
939 if (ETHER_IS_ZERO(eaddr)) { 937 if (ETHER_IS_ZERO(eaddr)) {
940 maclo = 0x00f2 | (cprng_strong32() & 0xffff0000); 938 maclo = 0x00f2 | (cprng_strong32() & 0xffff0000);
941 machi = cprng_strong32() & 0xffff; 939 machi = cprng_strong32() & 0xffff;
942 eaddr[0] = maclo & 0xff; 940 eaddr[0] = maclo & 0xff;
943 eaddr[1] = (maclo >> 8) & 0xff; 941 eaddr[1] = (maclo >> 8) & 0xff;
944 eaddr[2] = (maclo >> 16) & 0xff; 942 eaddr[2] = (maclo >> 16) & 0xff;
945 eaddr[3] = (maclo >> 24) & 0xff; 943 eaddr[3] = (maclo >> 24) & 0xff;
946 eaddr[4] = machi & 0xff; 944 eaddr[4] = machi & 0xff;
947 eaddr[5] = (machi >> 8) & 0xff; 945 eaddr[5] = (machi >> 8) & 0xff;
948 } 946 }
949 memcpy(un->un_eaddr, eaddr, sizeof(un->un_eaddr)); 947 memcpy(un->un_eaddr, eaddr, sizeof(un->un_eaddr));
950 948
951 struct ifnet *ifp = usbnet_ifp(un); 949 struct ifnet *ifp = usbnet_ifp(un);
952 950
953 /* 951 /*
954 * We don't support TSOv4 and v6 for now, that are required to 952 * We don't support TSOv4 and v6 for now, that are required to
955 * be handled in software for some cases. 953 * be handled in software for some cases.
956 */ 954 */
957 ifp->if_capabilities = IFCAP_CSUM_IPv4_Tx | 955 ifp->if_capabilities = IFCAP_CSUM_IPv4_Tx |
958 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx; 956 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx;
959#ifdef INET6 957#ifdef INET6
960 ifp->if_capabilities |= IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx; 958 ifp->if_capabilities |= IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx;
961#endif 959#endif
962 if (un->un_flags & ~URE_FLAG_VER_4C00) { 960 if (un->un_flags & ~URE_FLAG_VER_4C00) {
963 ifp->if_capabilities |= IFCAP_CSUM_IPv4_Rx | 961 ifp->if_capabilities |= IFCAP_CSUM_IPv4_Rx |
964 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | 962 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |
965 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx; 963 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx;
966 } 964 }
967 struct ethercom *ec = usbnet_ec(un); 965 struct ethercom *ec = usbnet_ec(un);
968 ec->ec_capabilities = ETHERCAP_VLAN_MTU; 966 ec->ec_capabilities = ETHERCAP_VLAN_MTU;
969#ifdef notyet 967#ifdef notyet
970 ec->ec_capabilities |= ETHERCAP_JUMBO_MTU; 968 ec->ec_capabilities |= ETHERCAP_JUMBO_MTU;
971#endif 969#endif
972 970
973 unm.un_mii_phyloc = un->un_phyno; 971 unm.un_mii_phyloc = un->un_phyno;
974 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 972 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
975 0, &unm); 973 0, &unm);
976} 974}
977 975
978static void 976static void
979ure_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 977ure_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
980{ 978{
981 struct ifnet *ifp = usbnet_ifp(un); 979 struct ifnet *ifp = usbnet_ifp(un);
982 uint8_t *buf = c->unc_buf; 980 uint8_t *buf = c->unc_buf;
983 uint16_t pkt_len = 0; 981 uint16_t pkt_len = 0;
984 uint16_t pkt_count = 0; 982 uint16_t pkt_count = 0;
985 struct ure_rxpkt rxhdr; 983 struct ure_rxpkt rxhdr;
986 984
987 do { 985 do {
988 if (total_len < sizeof(rxhdr)) { 986 if (total_len < sizeof(rxhdr)) {
989 DPRINTF(("too few bytes left for a packet header\n")); 987 DPRINTF(("too few bytes left for a packet header\n"));
990 if_statinc(ifp, if_ierrors); 988 if_statinc(ifp, if_ierrors);
991 return; 989 return;
992 } 990 }
993 991
994 buf += roundup(pkt_len, 8); 992 buf += roundup(pkt_len, 8);
995 993
996 memcpy(&rxhdr, buf, sizeof(rxhdr)); 994 memcpy(&rxhdr, buf, sizeof(rxhdr));
997 total_len -= sizeof(rxhdr); 995 total_len -= sizeof(rxhdr);
998 996
999 pkt_len = le32toh(rxhdr.ure_pktlen) & URE_RXPKT_LEN_MASK; 997 pkt_len = le32toh(rxhdr.ure_pktlen) & URE_RXPKT_LEN_MASK;
1000 DPRINTFN(4, ("next packet is %d bytes\n", pkt_len)); 998 DPRINTFN(4, ("next packet is %d bytes\n", pkt_len));
1001 if (pkt_len > total_len) { 999 if (pkt_len > total_len) {
1002 DPRINTF(("not enough bytes left for next packet\n")); 1000 DPRINTF(("not enough bytes left for next packet\n"));
1003 if_statinc(ifp, if_ierrors); 1001 if_statinc(ifp, if_ierrors);
1004 return; 1002 return;
1005 } 1003 }
1006 1004
1007 total_len -= roundup(pkt_len, 8); 1005 total_len -= roundup(pkt_len, 8);
1008 buf += sizeof(rxhdr); 1006 buf += sizeof(rxhdr);
1009 1007
1010 usbnet_enqueue(un, buf, pkt_len - ETHER_CRC_LEN, 1008 usbnet_enqueue(un, buf, pkt_len - ETHER_CRC_LEN,
1011 ure_rxcsum(ifp, &rxhdr), 0, 0); 1009 ure_rxcsum(ifp, &rxhdr), 0, 0);
1012 1010
1013 pkt_count++; 1011 pkt_count++;
1014  1012
1015 } while (total_len > 0); 1013 } while (total_len > 0);
1016 1014
1017 if (pkt_count) 1015 if (pkt_count)
1018 rnd_add_uint32(usbnet_rndsrc(un), pkt_count); 1016 rnd_add_uint32(usbnet_rndsrc(un), pkt_count);
1019} 1017}
1020 1018
1021static int 1019static int
1022ure_rxcsum(struct ifnet *ifp, struct ure_rxpkt *rp) 1020ure_rxcsum(struct ifnet *ifp, struct ure_rxpkt *rp)
1023{ 1021{
1024 int enabled = ifp->if_csum_flags_rx, flags = 0; 1022 int enabled = ifp->if_csum_flags_rx, flags = 0;
1025 uint32_t csum, misc; 1023 uint32_t csum, misc;
1026 1024
1027 if (enabled == 0) 1025 if (enabled == 0)
1028 return 0; 1026 return 0;
1029 1027
1030 csum = le32toh(rp->ure_csum); 1028 csum = le32toh(rp->ure_csum);
1031 misc = le32toh(rp->ure_misc); 1029 misc = le32toh(rp->ure_misc);
1032 1030
1033 if (csum & URE_RXPKT_IPV4_CS) { 1031 if (csum & URE_RXPKT_IPV4_CS) {
1034 flags |= M_CSUM_IPv4; 1032 flags |= M_CSUM_IPv4;
1035 if (csum & URE_RXPKT_TCP_CS) 1033 if (csum & URE_RXPKT_TCP_CS)
1036 flags |= M_CSUM_TCPv4; 1034 flags |= M_CSUM_TCPv4;
1037 if (csum & URE_RXPKT_UDP_CS) 1035 if (csum & URE_RXPKT_UDP_CS)
1038 flags |= M_CSUM_UDPv4; 1036 flags |= M_CSUM_UDPv4;
1039 } else if (csum & URE_RXPKT_IPV6_CS) { 1037 } else if (csum & URE_RXPKT_IPV6_CS) {
1040 flags = 0; 1038 flags = 0;
1041 if (csum & URE_RXPKT_TCP_CS) 1039 if (csum & URE_RXPKT_TCP_CS)
1042 flags |= M_CSUM_TCPv6; 1040 flags |= M_CSUM_TCPv6;
1043 if (csum & URE_RXPKT_UDP_CS) 1041 if (csum & URE_RXPKT_UDP_CS)
1044 flags |= M_CSUM_UDPv6; 1042 flags |= M_CSUM_UDPv6;
1045 } 1043 }
1046 1044
1047 flags &= enabled; 1045 flags &= enabled;
1048 if (__predict_false((flags & M_CSUM_IPv4) && 1046 if (__predict_false((flags & M_CSUM_IPv4) &&
1049 (misc & URE_RXPKT_IP_F))) 1047 (misc & URE_RXPKT_IP_F)))
1050 flags |= M_CSUM_IPv4_BAD; 1048 flags |= M_CSUM_IPv4_BAD;
1051 if (__predict_false( 1049 if (__predict_false(
1052 ((flags & (M_CSUM_TCPv4 | M_CSUM_TCPv6)) && (misc & URE_RXPKT_TCP_F)) 1050 ((flags & (M_CSUM_TCPv4 | M_CSUM_TCPv6)) && (misc & URE_RXPKT_TCP_F))
1053 || ((flags & (M_CSUM_UDPv4 | M_CSUM_UDPv6)) && (misc & URE_RXPKT_UDP_F)) 1051 || ((flags & (M_CSUM_UDPv4 | M_CSUM_UDPv6)) && (misc & URE_RXPKT_UDP_F))
1054 )) 1052 ))
1055 flags |= M_CSUM_TCP_UDP_BAD; 1053 flags |= M_CSUM_TCP_UDP_BAD;
1056 1054
1057 return flags; 1055 return flags;
1058} 1056}
1059 1057
1060static unsigned 1058static unsigned
1061ure_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 1059ure_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
1062{ 1060{
1063 struct ure_txpkt txhdr; 1061 struct ure_txpkt txhdr;
1064 uint32_t frm_len = 0; 1062 uint32_t frm_len = 0;
1065 uint8_t *buf = c->unc_buf; 1063 uint8_t *buf = c->unc_buf;
1066 1064
1067 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(txhdr)) 1065 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(txhdr))
1068 return 0; 1066 return 0;
1069 1067
1070 /* header */ 1068 /* header */
1071 txhdr.ure_pktlen = htole32(m->m_pkthdr.len | URE_TXPKT_TX_FS | 1069 txhdr.ure_pktlen = htole32(m->m_pkthdr.len | URE_TXPKT_TX_FS |
1072 URE_TXPKT_TX_LS); 1070 URE_TXPKT_TX_LS);
1073 txhdr.ure_csum = htole32(ure_txcsum(m)); 1071 txhdr.ure_csum = htole32(ure_txcsum(m));
1074 memcpy(buf, &txhdr, sizeof(txhdr)); 1072 memcpy(buf, &txhdr, sizeof(txhdr));
1075 buf += sizeof(txhdr); 1073 buf += sizeof(txhdr);
1076 frm_len = sizeof(txhdr); 1074 frm_len = sizeof(txhdr);
1077 1075
1078 /* packet */ 1076 /* packet */
1079 m_copydata(m, 0, m->m_pkthdr.len, buf); 1077 m_copydata(m, 0, m->m_pkthdr.len, buf);
1080 frm_len += m->m_pkthdr.len; 1078 frm_len += m->m_pkthdr.len;
1081 1079
1082 DPRINTFN(2, ("tx %d bytes\n", frm_len)); 1080 DPRINTFN(2, ("tx %d bytes\n", frm_len));
1083 1081
1084 return frm_len; 1082 return frm_len;
1085} 1083}
1086 1084
1087/* 1085/*
1088 * We need to calculate L4 checksum in software, if the offset of 1086 * We need to calculate L4 checksum in software, if the offset of
1089 * L4 header is larger than 0x7ff = 2047. 1087 * L4 header is larger than 0x7ff = 2047.
1090 */ 1088 */
1091static uint32_t 1089static uint32_t
1092ure_txcsum(struct mbuf *m) 1090ure_txcsum(struct mbuf *m)
1093{ 1091{
1094 struct ether_header *eh; 1092 struct ether_header *eh;
1095 int flags = m->m_pkthdr.csum_flags; 1093 int flags = m->m_pkthdr.csum_flags;
1096 uint32_t data = m->m_pkthdr.csum_data; 1094 uint32_t data = m->m_pkthdr.csum_data;
1097 uint32_t reg = 0; 1095 uint32_t reg = 0;
1098 int l3off, l4off; 1096 int l3off, l4off;
1099 uint16_t type; 1097 uint16_t type;
1100 1098
1101 if (flags == 0) 1099 if (flags == 0)
1102 return 0; 1100 return 0;
1103 1101
1104 if (__predict_true(m->m_len >= (int)sizeof(*eh))) { 1102 if (__predict_true(m->m_len >= (int)sizeof(*eh))) {
1105 eh = mtod(m, struct ether_header *); 1103 eh = mtod(m, struct ether_header *);
1106 type = eh->ether_type; 1104 type = eh->ether_type;
1107 } else 1105 } else
1108 m_copydata(m, offsetof(struct ether_header, ether_type), 1106 m_copydata(m, offsetof(struct ether_header, ether_type),
1109 sizeof(type), &type); 1107 sizeof(type), &type);
1110 switch (type = htons(type)) { 1108 switch (type = htons(type)) {
1111 case ETHERTYPE_IP: 1109 case ETHERTYPE_IP:
1112 case ETHERTYPE_IPV6: 1110 case ETHERTYPE_IPV6:
1113 l3off = ETHER_HDR_LEN; 1111 l3off = ETHER_HDR_LEN;
1114 break; 1112 break;
1115 case ETHERTYPE_VLAN: 1113 case ETHERTYPE_VLAN:
1116 l3off = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 1114 l3off = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
1117 break; 1115 break;
1118 default: 1116 default:
1119 return 0; 1117 return 0;
1120 } 1118 }
1121 1119
1122 if (flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) { 1120 if (flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) {
1123 l4off = l3off + M_CSUM_DATA_IPv4_IPHL(data); 1121 l4off = l3off + M_CSUM_DATA_IPv4_IPHL(data);
1124 if (__predict_false(l4off > URE_L4_OFFSET_MAX)) { 1122 if (__predict_false(l4off > URE_L4_OFFSET_MAX)) {
1125 in_undefer_cksum(m, l3off, flags); 1123 in_undefer_cksum(m, l3off, flags);
1126 return 0; 1124 return 0;
1127 } 1125 }
1128 reg |= URE_TXPKT_IPV4_CS; 1126 reg |= URE_TXPKT_IPV4_CS;
1129 if (flags & M_CSUM_TCPv4) 1127 if (flags & M_CSUM_TCPv4)
1130 reg |= URE_TXPKT_TCP_CS; 1128 reg |= URE_TXPKT_TCP_CS;
1131 else 1129 else
1132 reg |= URE_TXPKT_UDP_CS; 1130 reg |= URE_TXPKT_UDP_CS;
1133 reg |= l4off << URE_L4_OFFSET_SHIFT; 1131 reg |= l4off << URE_L4_OFFSET_SHIFT;
1134 } 1132 }
1135#ifdef INET6 1133#ifdef INET6
1136 else if (flags & (M_CSUM_TCPv6 | M_CSUM_UDPv6)) { 1134 else if (flags & (M_CSUM_TCPv6 | M_CSUM_UDPv6)) {
1137 l4off = l3off + M_CSUM_DATA_IPv6_IPHL(data); 1135 l4off = l3off + M_CSUM_DATA_IPv6_IPHL(data);
1138 if (__predict_false(l4off > URE_L4_OFFSET_MAX)) { 1136 if (__predict_false(l4off > URE_L4_OFFSET_MAX)) {
1139 in6_undefer_cksum(m, l3off, flags); 1137 in6_undefer_cksum(m, l3off, flags);
1140 return 0; 1138 return 0;
1141 } 1139 }
1142 reg |= URE_TXPKT_IPV6_CS; 1140 reg |= URE_TXPKT_IPV6_CS;
1143 if (flags & M_CSUM_TCPv6) 1141 if (flags & M_CSUM_TCPv6)
1144 reg |= URE_TXPKT_TCP_CS; 1142 reg |= URE_TXPKT_TCP_CS;
1145 else 1143 else
1146 reg |= URE_TXPKT_UDP_CS; 1144 reg |= URE_TXPKT_UDP_CS;
1147 reg |= l4off << URE_L4_OFFSET_SHIFT; 1145 reg |= l4off << URE_L4_OFFSET_SHIFT;
1148 } 1146 }
1149#endif 1147#endif
1150 else if (flags & M_CSUM_IPv4) 1148 else if (flags & M_CSUM_IPv4)
1151 reg |= URE_TXPKT_IPV4_CS; 1149 reg |= URE_TXPKT_IPV4_CS;
1152 1150
1153 return reg; 1151 return reg;
1154} 1152}
1155 1153
1156#ifdef _MODULE 1154#ifdef _MODULE
1157#include "ioconf.c" 1155#include "ioconf.c"
1158#endif 1156#endif
1159 1157
1160USBNET_MODULE(ure) 1158USBNET_MODULE(ure)