Thu Mar 3 05:50:57 2022 UTC ()
usbnet drivers: Stop timeout loops early if device is detaching.


(riastradh)
diff -r1.172 -r1.173 src/sys/dev/usb/if_aue.c
diff -r1.8 -r1.9 src/sys/dev/usb/if_mos.c
diff -r1.64 -r1.65 src/sys/dev/usb/if_mue.c
diff -r1.72 -r1.73 src/sys/dev/usb/if_smsc.c
diff -r1.79 -r1.80 src/sys/dev/usb/if_udav.c
diff -r1.79 -r1.80 src/sys/dev/usb/if_url.c
diff -r1.41 -r1.42 src/sys/dev/usb/if_ure.c

cvs diff -r1.172 -r1.173 src/sys/dev/usb/if_aue.c (switch to unified diff)

--- src/sys/dev/usb/if_aue.c 2022/03/03 05:50:22 1.172
+++ src/sys/dev/usb/if_aue.c 2022/03/03 05:50:57 1.173
@@ -1,1052 +1,1058 @@ @@ -1,1052 +1,1058 @@
1/* $NetBSD: if_aue.c,v 1.172 2022/03/03 05:50:22 riastradh Exp $ */ 1/* $NetBSD: if_aue.c,v 1.173 2022/03/03 05:50:57 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_aue.c,v 1.11 2000/01/14 01:36:14 wpaul Exp $ 34 * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.11 2000/01/14 01:36:14 wpaul Exp $
35 */ 35 */
36 36
37/* 37/*
38 * ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver. 38 * ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver.
39 * Datasheet is available from http://www.admtek.com.tw. 39 * Datasheet is available from http://www.admtek.com.tw.
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 Pegasus chip uses four USB "endpoints" to provide 10/100 ethernet 47 * The Pegasus chip uses four USB "endpoints" to provide 10/100 ethernet
48 * support: the control endpoint for reading/writing registers, burst 48 * support: the control endpoint for reading/writing registers, burst
49 * read endpoint for packet reception, burst write for packet transmission 49 * read endpoint for packet reception, burst write for packet transmission
50 * and one for "interrupts." The chip uses the same RX filter scheme 50 * and one for "interrupts." The chip uses the same RX filter scheme
51 * as the other ADMtek ethernet parts: one perfect filter entry for the 51 * as the other ADMtek ethernet parts: one perfect filter entry for the
52 * the station address and a 64-bit multicast hash table. The chip supports 52 * the station address and a 64-bit multicast hash table. The chip supports
53 * both MII and HomePNA attachments. 53 * both MII and HomePNA attachments.
54 * 54 *
55 * Since the maximum data transfer speed of USB is supposed to be 12Mbps, 55 * Since the maximum data transfer speed of USB is supposed to be 12Mbps,
56 * you're never really going to get 100Mbps speeds from this device. I 56 * you're never really going to get 100Mbps speeds from this device. I
57 * think the idea is to allow the device to connect to 10 or 100Mbps 57 * think the idea is to allow the device to connect to 10 or 100Mbps
58 * networks, not necessarily to provide 100Mbps performance. Also, since 58 * networks, not necessarily to provide 100Mbps performance. Also, since
59 * the controller uses an external PHY chip, it's possible that board 59 * the controller uses an external PHY chip, it's possible that board
60 * designers might simply choose a 10Mbps PHY. 60 * designers might simply choose a 10Mbps PHY.
61 * 61 *
62 * Registers are accessed using usbd_do_request(). Packet transfers are 62 * Registers are accessed using usbd_do_request(). Packet transfers are
63 * done using usbd_transfer() and friends. 63 * done using usbd_transfer() and friends.
64 */ 64 */
65 65
66/* 66/*
67 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. 67 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson.
68 */ 68 */
69 69
70/* 70/*
71 * TODO: 71 * TODO:
72 * better error messages from rxstat 72 * better error messages from rxstat
73 * more error checks 73 * more error checks
74 * investigate short rx problem 74 * investigate short rx problem
75 * proper cleanup on errors 75 * proper cleanup on errors
76 */ 76 */
77 77
78#include <sys/cdefs.h> 78#include <sys/cdefs.h>
79__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.172 2022/03/03 05:50:22 riastradh Exp $"); 79__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.173 2022/03/03 05:50:57 riastradh Exp $");
80 80
81#ifdef _KERNEL_OPT 81#ifdef _KERNEL_OPT
82#include "opt_usb.h" 82#include "opt_usb.h"
83#include "opt_inet.h" 83#include "opt_inet.h"
84#endif 84#endif
85 85
86#include <sys/param.h> 86#include <sys/param.h>
87 87
88#include <dev/usb/usbnet.h> 88#include <dev/usb/usbnet.h>
89#include <dev/usb/usbhist.h> 89#include <dev/usb/usbhist.h>
90#include <dev/usb/if_auereg.h> 90#include <dev/usb/if_auereg.h>
91 91
92#ifdef INET 92#ifdef INET
93#include <netinet/in.h> 93#include <netinet/in.h>
94#include <netinet/if_inarp.h> 94#include <netinet/if_inarp.h>
95#endif 95#endif
96 96
97#ifdef USB_DEBUG 97#ifdef USB_DEBUG
98#ifndef AUE_DEBUG 98#ifndef AUE_DEBUG
99#define auedebug 0 99#define auedebug 0
100#else 100#else
101static int auedebug = 10; 101static int auedebug = 10;
102 102
103SYSCTL_SETUP(sysctl_hw_aue_setup, "sysctl hw.aue setup") 103SYSCTL_SETUP(sysctl_hw_aue_setup, "sysctl hw.aue setup")
104{ 104{
105 int err; 105 int err;
106 const struct sysctlnode *rnode; 106 const struct sysctlnode *rnode;
107 const struct sysctlnode *cnode; 107 const struct sysctlnode *cnode;
108 108
109 err = sysctl_createv(clog, 0, NULL, &rnode, 109 err = sysctl_createv(clog, 0, NULL, &rnode,
110 CTLFLAG_PERMANENT, CTLTYPE_NODE, "aue", 110 CTLFLAG_PERMANENT, CTLTYPE_NODE, "aue",
111 SYSCTL_DESCR("aue global controls"), 111 SYSCTL_DESCR("aue global controls"),
112 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 112 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
113 113
114 if (err) 114 if (err)
115 goto fail; 115 goto fail;
116 116
117 /* control debugging printfs */ 117 /* control debugging printfs */
118 err = sysctl_createv(clog, 0, &rnode, &cnode, 118 err = sysctl_createv(clog, 0, &rnode, &cnode,
119 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 119 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
120 "debug", SYSCTL_DESCR("Enable debugging output"), 120 "debug", SYSCTL_DESCR("Enable debugging output"),
121 NULL, 0, &auedebug, sizeof(auedebug), CTL_CREATE, CTL_EOL); 121 NULL, 0, &auedebug, sizeof(auedebug), CTL_CREATE, CTL_EOL);
122 if (err) 122 if (err)
123 goto fail; 123 goto fail;
124 124
125 return; 125 return;
126fail: 126fail:
127 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 127 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
128} 128}
129 129
130#endif /* AUE_DEBUG */ 130#endif /* AUE_DEBUG */
131#endif /* USB_DEBUG */ 131#endif /* USB_DEBUG */
132 132
133#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(auedebug,1,FMT,A,B,C,D) 133#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(auedebug,1,FMT,A,B,C,D)
134#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(auedebug,N,FMT,A,B,C,D) 134#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(auedebug,N,FMT,A,B,C,D)
135#define AUEHIST_FUNC() USBHIST_FUNC() 135#define AUEHIST_FUNC() USBHIST_FUNC()
136#define AUEHIST_CALLED(name) USBHIST_CALLED(auedebug) 136#define AUEHIST_CALLED(name) USBHIST_CALLED(auedebug)
137#define AUEHIST_CALLARGS(FMT,A,B,C,D) \ 137#define AUEHIST_CALLARGS(FMT,A,B,C,D) \
138 USBHIST_CALLARGS(auedebug,FMT,A,B,C,D) 138 USBHIST_CALLARGS(auedebug,FMT,A,B,C,D)
139#define AUEHIST_CALLARGSN(N,FMT,A,B,C,D) \ 139#define AUEHIST_CALLARGSN(N,FMT,A,B,C,D) \
140 USBHIST_CALLARGSN(auedebug,N,FMT,A,B,C,D) 140 USBHIST_CALLARGSN(auedebug,N,FMT,A,B,C,D)
141 141
142#define AUE_TX_LIST_CNT 1 142#define AUE_TX_LIST_CNT 1
143#define AUE_RX_LIST_CNT 1 143#define AUE_RX_LIST_CNT 1
144 144
145struct aue_softc { 145struct aue_softc {
146 struct usbnet aue_un; 146 struct usbnet aue_un;
147 struct usbnet_intr aue_intr; 147 struct usbnet_intr aue_intr;
148 struct aue_intrpkt aue_ibuf; 148 struct aue_intrpkt aue_ibuf;
149}; 149};
150 150
151#define AUE_TIMEOUT 1000 151#define AUE_TIMEOUT 1000
152#define AUE_BUFSZ 1536 152#define AUE_BUFSZ 1536
153#define AUE_MIN_FRAMELEN 60 153#define AUE_MIN_FRAMELEN 60
154#define AUE_TX_TIMEOUT 10000 /* ms */ 154#define AUE_TX_TIMEOUT 10000 /* ms */
155#define AUE_INTR_INTERVAL 100 /* ms */ 155#define AUE_INTR_INTERVAL 100 /* ms */
156 156
157/* 157/*
158 * Various supported device vendors/products. 158 * Various supported device vendors/products.
159 */ 159 */
160struct aue_type { 160struct aue_type {
161 struct usb_devno aue_dev; 161 struct usb_devno aue_dev;
162 uint16_t aue_flags; 162 uint16_t aue_flags;
163#define LSYS 0x0001 /* use Linksys reset */ 163#define LSYS 0x0001 /* use Linksys reset */
164#define PNA 0x0002 /* has Home PNA */ 164#define PNA 0x0002 /* has Home PNA */
165#define PII 0x0004 /* Pegasus II chip */ 165#define PII 0x0004 /* Pegasus II chip */
166}; 166};
167 167
168static const struct aue_type aue_devs[] = { 168static const struct aue_type aue_devs[] = {
169 {{ USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B}, PII }, 169 {{ USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B}, PII },
170 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1}, PNA | PII }, 170 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1}, PNA | PII },
171 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2}, PII }, 171 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2}, PII },
172 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000}, LSYS }, 172 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000}, LSYS },
173 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4}, PNA }, 173 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4}, PNA },
174 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5}, PNA }, 174 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5}, PNA },
175 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6}, PII }, 175 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6}, PII },
176 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7}, PII }, 176 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7}, PII },
177 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8}, PII }, 177 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8}, PII },
178 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9}, PNA }, 178 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9}, PNA },
179 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10}, 0 }, 179 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10}, 0 },
180 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA}, 0 }, 180 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA}, 0 },
181 {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC}, 0 }, 181 {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC}, 0 },
182 {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001}, PII }, 182 {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001}, PII },
183 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS}, PNA }, 183 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS}, PNA },
184 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII}, PII }, 184 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII}, PII },
185 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2}, PII }, 185 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2}, PII },
186 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3}, PII }, 186 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3}, PII },
187 {{ USB_VENDOR_AEI, USB_PRODUCT_AEI_USBTOLAN}, PII }, 187 {{ USB_VENDOR_AEI, USB_PRODUCT_AEI_USBTOLAN}, PII },
188 {{ USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2LAN}, PII }, 188 {{ USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2LAN}, PII },
189 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100}, 0 }, 189 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100}, 0 },
190 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100}, PNA }, 190 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100}, PNA },
191 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBEL100}, 0 }, 191 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBEL100}, 0 },
192 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBE100}, PII }, 192 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBE100}, PII },
193 {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_HNE200}, PII }, 193 {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_HNE200}, PII },
194 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX}, 0 }, 194 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX}, 0 },
195 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXS},PII }, 195 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXS},PII },
196 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4}, LSYS | PII }, 196 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4}, LSYS | PII },
197 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX1}, LSYS }, 197 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX1}, LSYS },
198 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX}, LSYS }, 198 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX}, LSYS },
199 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA}, PNA }, 199 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA}, PNA },
200 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3}, LSYS | PII }, 200 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3}, LSYS | PII },
201 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2}, LSYS | PII }, 201 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2}, LSYS | PII },
202 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650}, 0 }, 202 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650}, 0 },
203 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0}, 0 }, 203 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0}, 0 },
204 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1}, LSYS }, 204 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1}, LSYS },
205 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2}, 0 }, 205 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2}, 0 },
206 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3}, LSYS }, 206 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3}, LSYS },
207 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX}, PII }, 207 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX}, PII },
208 {{ USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET}, 0 }, 208 {{ USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET}, 0 },
209 {{ USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100}, PII }, 209 {{ USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100}, PII },
210 {{ USB_VENDOR_HP, USB_PRODUCT_HP_HN210E}, PII }, 210 {{ USB_VENDOR_HP, USB_PRODUCT_HP_HN210E}, PII },
211 {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX}, 0 }, 211 {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX}, 0 },
212 {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTXS}, PII }, 212 {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTXS}, PII },
213 {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETXUS2}, PII }, 213 {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETXUS2}, PII },
214 {{ USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_KNU101TX}, 0 }, 214 {{ USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_KNU101TX}, 0 },
215 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX1}, LSYS | PII }, 215 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX1}, LSYS | PII },
216 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T}, LSYS }, 216 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T}, LSYS },
217 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX}, LSYS }, 217 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX}, LSYS },
218 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1}, LSYS | PNA }, 218 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1}, LSYS | PNA },
219 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA}, LSYS }, 219 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA}, LSYS },
220 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2}, LSYS | PII }, 220 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2}, LSYS | PII },
221 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1}, 0 }, 221 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1}, 0 },
222 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5}, 0 }, 222 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5}, 0 },
223 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5}, PII }, 223 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5}, PII },
224 {{ USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110}, PII }, 224 {{ USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110}, PII },
225 {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101}, PII }, 225 {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101}, PII },
226 {{ USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM}, PII }, 226 {{ USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM}, PII },
227 {{ USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC},PII }, 227 {{ USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC},PII },
228 {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB}, 0 }, 228 {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB}, 0 },
229 {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB}, PII }, 229 {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB}, PII },
230 {{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100}, 0 }, 230 {{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100}, 0 },
231}; 231};
232#define aue_lookup(v, p) ((const struct aue_type *)usb_lookup(aue_devs, v, p)) 232#define aue_lookup(v, p) ((const struct aue_type *)usb_lookup(aue_devs, v, p))
233 233
234static int aue_match(device_t, cfdata_t, void *); 234static int aue_match(device_t, cfdata_t, void *);
235static void aue_attach(device_t, device_t, void *); 235static void aue_attach(device_t, device_t, void *);
236 236
237CFATTACH_DECL_NEW(aue, sizeof(struct aue_softc), aue_match, aue_attach, 237CFATTACH_DECL_NEW(aue, sizeof(struct aue_softc), aue_match, aue_attach,
238 usbnet_detach, usbnet_activate); 238 usbnet_detach, usbnet_activate);
239 239
240static void aue_reset_pegasus_II(struct aue_softc *); 240static void aue_reset_pegasus_II(struct aue_softc *);
241 241
242static void aue_uno_stop(struct ifnet *, int); 242static void aue_uno_stop(struct ifnet *, int);
243static int aue_uno_ioctl(struct ifnet *, u_long, void *); 243static int aue_uno_ioctl(struct ifnet *, u_long, void *);
244static int aue_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 244static int aue_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
245static int aue_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 245static int aue_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
246static void aue_uno_mii_statchg(struct ifnet *); 246static void aue_uno_mii_statchg(struct ifnet *);
247static unsigned aue_uno_tx_prepare(struct usbnet *, struct mbuf *, 247static unsigned aue_uno_tx_prepare(struct usbnet *, struct mbuf *,
248 struct usbnet_chain *); 248 struct usbnet_chain *);
249static void aue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 249static void aue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
250static int aue_uno_init(struct ifnet *); 250static int aue_uno_init(struct ifnet *);
251static void aue_uno_intr(struct usbnet *, usbd_status); 251static void aue_uno_intr(struct usbnet *, usbd_status);
252 252
253static const struct usbnet_ops aue_ops = { 253static const struct usbnet_ops aue_ops = {
254 .uno_stop = aue_uno_stop, 254 .uno_stop = aue_uno_stop,
255 .uno_ioctl = aue_uno_ioctl, 255 .uno_ioctl = aue_uno_ioctl,
256 .uno_read_reg = aue_uno_mii_read_reg, 256 .uno_read_reg = aue_uno_mii_read_reg,
257 .uno_write_reg = aue_uno_mii_write_reg, 257 .uno_write_reg = aue_uno_mii_write_reg,
258 .uno_statchg = aue_uno_mii_statchg, 258 .uno_statchg = aue_uno_mii_statchg,
259 .uno_tx_prepare = aue_uno_tx_prepare, 259 .uno_tx_prepare = aue_uno_tx_prepare,
260 .uno_rx_loop = aue_uno_rx_loop, 260 .uno_rx_loop = aue_uno_rx_loop,
261 .uno_init = aue_uno_init, 261 .uno_init = aue_uno_init,
262 .uno_intr = aue_uno_intr, 262 .uno_intr = aue_uno_intr,
263}; 263};
264 264
265static uint32_t aue_crc(void *); 265static uint32_t aue_crc(void *);
266static void aue_reset(struct aue_softc *); 266static void aue_reset(struct aue_softc *);
267 267
268static int aue_csr_read_1(struct aue_softc *, int); 268static int aue_csr_read_1(struct aue_softc *, int);
269static int aue_csr_write_1(struct aue_softc *, int, int); 269static int aue_csr_write_1(struct aue_softc *, int, int);
270static int aue_csr_read_2(struct aue_softc *, int); 270static int aue_csr_read_2(struct aue_softc *, int);
271static int aue_csr_write_2(struct aue_softc *, int, int); 271static int aue_csr_write_2(struct aue_softc *, int, int);
272 272
273#define AUE_SETBIT(sc, reg, x) \ 273#define AUE_SETBIT(sc, reg, x) \
274 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x)) 274 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x))
275 275
276#define AUE_CLRBIT(sc, reg, x) \ 276#define AUE_CLRBIT(sc, reg, x) \
277 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x)) 277 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x))
278 278
279static int 279static int
280aue_csr_read_1(struct aue_softc *sc, int reg) 280aue_csr_read_1(struct aue_softc *sc, int reg)
281{ 281{
282 struct usbnet * const un = &sc->aue_un; 282 struct usbnet * const un = &sc->aue_un;
283 usb_device_request_t req; 283 usb_device_request_t req;
284 usbd_status err; 284 usbd_status err;
285 uByte val = 0; 285 uByte val = 0;
286 286
287 usbnet_isowned_core(un); 287 usbnet_isowned_core(un);
288 288
289 if (usbnet_isdying(un)) 289 if (usbnet_isdying(un))
290 return 0; 290 return 0;
291 291
292 req.bmRequestType = UT_READ_VENDOR_DEVICE; 292 req.bmRequestType = UT_READ_VENDOR_DEVICE;
293 req.bRequest = AUE_UR_READREG; 293 req.bRequest = AUE_UR_READREG;
294 USETW(req.wValue, 0); 294 USETW(req.wValue, 0);
295 USETW(req.wIndex, reg); 295 USETW(req.wIndex, reg);
296 USETW(req.wLength, 1); 296 USETW(req.wLength, 1);
297 297
298 err = usbd_do_request(un->un_udev, &req, &val); 298 err = usbd_do_request(un->un_udev, &req, &val);
299 299
300 if (err) { 300 if (err) {
301 AUEHIST_FUNC(); 301 AUEHIST_FUNC();
302 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 302 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd",
303 device_unit(un->un_dev), reg, err, 0); 303 device_unit(un->un_dev), reg, err, 0);
304 return 0; 304 return 0;
305 } 305 }
306 306
307 return val; 307 return val;
308} 308}
309 309
310static int 310static int
311aue_csr_read_2(struct aue_softc *sc, int reg) 311aue_csr_read_2(struct aue_softc *sc, int reg)
312{ 312{
313 struct usbnet * const un = &sc->aue_un; 313 struct usbnet * const un = &sc->aue_un;
314 usb_device_request_t req; 314 usb_device_request_t req;
315 usbd_status err; 315 usbd_status err;
316 uWord val; 316 uWord val;
317 317
318 usbnet_isowned_core(un); 318 usbnet_isowned_core(un);
319 319
320 if (usbnet_isdying(un)) 320 if (usbnet_isdying(un))
321 return 0; 321 return 0;
322 322
323 req.bmRequestType = UT_READ_VENDOR_DEVICE; 323 req.bmRequestType = UT_READ_VENDOR_DEVICE;
324 req.bRequest = AUE_UR_READREG; 324 req.bRequest = AUE_UR_READREG;
325 USETW(req.wValue, 0); 325 USETW(req.wValue, 0);
326 USETW(req.wIndex, reg); 326 USETW(req.wIndex, reg);
327 USETW(req.wLength, 2); 327 USETW(req.wLength, 2);
328 328
329 err = usbd_do_request(un->un_udev, &req, &val); 329 err = usbd_do_request(un->un_udev, &req, &val);
330 330
331 if (err) { 331 if (err) {
332 AUEHIST_FUNC(); 332 AUEHIST_FUNC();
333 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 333 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd",
334 device_unit(un->un_dev), reg, err, 0); 334 device_unit(un->un_dev), reg, err, 0);
335 return 0; 335 return 0;
336 } 336 }
337 337
338 return UGETW(val); 338 return UGETW(val);
339} 339}
340 340
341static int 341static int
342aue_csr_write_1(struct aue_softc *sc, int reg, int aval) 342aue_csr_write_1(struct aue_softc *sc, int reg, int aval)
343{ 343{
344 struct usbnet * const un = &sc->aue_un; 344 struct usbnet * const un = &sc->aue_un;
345 usb_device_request_t req; 345 usb_device_request_t req;
346 usbd_status err; 346 usbd_status err;
347 uByte val; 347 uByte val;
348 348
349 usbnet_isowned_core(un); 349 usbnet_isowned_core(un);
350 350
351 if (usbnet_isdying(un)) 351 if (usbnet_isdying(un))
352 return 0; 352 return 0;
353 353
354 val = aval; 354 val = aval;
355 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 355 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
356 req.bRequest = AUE_UR_WRITEREG; 356 req.bRequest = AUE_UR_WRITEREG;
357 USETW(req.wValue, val); 357 USETW(req.wValue, val);
358 USETW(req.wIndex, reg); 358 USETW(req.wIndex, reg);
359 USETW(req.wLength, 1); 359 USETW(req.wLength, 1);
360 360
361 err = usbd_do_request(un->un_udev, &req, &val); 361 err = usbd_do_request(un->un_udev, &req, &val);
362 362
363 if (err) { 363 if (err) {
364 AUEHIST_FUNC(); 364 AUEHIST_FUNC();
365 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 365 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd",
366 device_unit(un->un_dev), reg, err, 0); 366 device_unit(un->un_dev), reg, err, 0);
367 return -1; 367 return -1;
368 } 368 }
369 369
370 return 0; 370 return 0;
371} 371}
372 372
373static int 373static int
374aue_csr_write_2(struct aue_softc *sc, int reg, int aval) 374aue_csr_write_2(struct aue_softc *sc, int reg, int aval)
375{ 375{
376 struct usbnet * const un = &sc->aue_un; 376 struct usbnet * const un = &sc->aue_un;
377 usb_device_request_t req; 377 usb_device_request_t req;
378 usbd_status err; 378 usbd_status err;
379 uWord val; 379 uWord val;
380 380
381 usbnet_isowned_core(un); 381 usbnet_isowned_core(un);
382 382
383 if (usbnet_isdying(un)) 383 if (usbnet_isdying(un))
384 return 0; 384 return 0;
385 385
386 USETW(val, aval); 386 USETW(val, aval);
387 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 387 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
388 req.bRequest = AUE_UR_WRITEREG; 388 req.bRequest = AUE_UR_WRITEREG;
389 USETW(req.wValue, aval); 389 USETW(req.wValue, aval);
390 USETW(req.wIndex, reg); 390 USETW(req.wIndex, reg);
391 USETW(req.wLength, 2); 391 USETW(req.wLength, 2);
392 392
393 err = usbd_do_request(un->un_udev, &req, &val); 393 err = usbd_do_request(un->un_udev, &req, &val);
394 394
395 if (err) { 395 if (err) {
396 AUEHIST_FUNC(); 396 AUEHIST_FUNC();
397 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 397 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd",
398 device_unit(un->un_dev), reg, err, 0); 398 device_unit(un->un_dev), reg, err, 0);
399 return -1; 399 return -1;
400 } 400 }
401 401
402 return 0; 402 return 0;
403} 403}
404 404
405/* 405/*
406 * Read a word of data stored in the EEPROM at address 'addr.' 406 * Read a word of data stored in the EEPROM at address 'addr.'
407 */ 407 */
408static int 408static int
409aue_eeprom_getword(struct aue_softc *sc, int addr) 409aue_eeprom_getword(struct aue_softc *sc, int addr)
410{ 410{
411 struct usbnet * const un = &sc->aue_un; 411 struct usbnet * const un = &sc->aue_un;
412 int i; 412 int i;
413 413
414 AUEHIST_FUNC(); AUEHIST_CALLED(); 414 AUEHIST_FUNC(); AUEHIST_CALLED();
415 415
416 aue_csr_write_1(sc, AUE_EE_REG, addr); 416 aue_csr_write_1(sc, AUE_EE_REG, addr);
417 aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ); 417 aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ);
418 418
419 for (i = 0; i < AUE_TIMEOUT; i++) { 419 for (i = 0; i < AUE_TIMEOUT; i++) {
420 if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE) 420 if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE)
421 break; 421 break;
422 } 422 }
423 423
424 if (i == AUE_TIMEOUT) { 424 if (i == AUE_TIMEOUT) {
425 printf("%s: EEPROM read timed out\n", 425 printf("%s: EEPROM read timed out\n",
426 device_xname(un->un_dev)); 426 device_xname(un->un_dev));
427 } 427 }
428 428
429 return aue_csr_read_2(sc, AUE_EE_DATA); 429 return aue_csr_read_2(sc, AUE_EE_DATA);
430} 430}
431 431
432/* 432/*
433 * Read the MAC from the EEPROM. It's at offset 0. 433 * Read the MAC from the EEPROM. It's at offset 0.
434 */ 434 */
435static void 435static void
436aue_read_mac(struct usbnet *un) 436aue_read_mac(struct usbnet *un)
437{ 437{
438 struct aue_softc *sc = usbnet_softc(un); 438 struct aue_softc *sc = usbnet_softc(un);
439 int i; 439 int i;
440 int off = 0; 440 int off = 0;
441 int word; 441 int word;
442 442
443 usbnet_isowned_core(un); 443 usbnet_isowned_core(un);
444 444
445 AUEHIST_FUNC(); 445 AUEHIST_FUNC();
446 AUEHIST_CALLARGS("aue%jd: enter", 446 AUEHIST_CALLARGS("aue%jd: enter",
447 device_unit(un->un_dev), 0, 0, 0); 447 device_unit(un->un_dev), 0, 0, 0);
448 448
449 for (i = 0; i < 3; i++) { 449 for (i = 0; i < 3; i++) {
450 word = aue_eeprom_getword(sc, off + i); 450 word = aue_eeprom_getword(sc, off + i);
451 un->un_eaddr[2 * i] = (u_char)word; 451 un->un_eaddr[2 * i] = (u_char)word;
452 un->un_eaddr[2 * i + 1] = (u_char)(word >> 8); 452 un->un_eaddr[2 * i + 1] = (u_char)(word >> 8);
453 } 453 }
454} 454}
455 455
456static int 456static int
457aue_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 457aue_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
458{ 458{
459 struct aue_softc *sc = usbnet_softc(un); 459 struct aue_softc *sc = usbnet_softc(un);
460 int i; 460 int i;
461 461
462 AUEHIST_FUNC(); 462 AUEHIST_FUNC();
463 463
464#if 0 464#if 0
465 /* 465 /*
466 * The Am79C901 HomePNA PHY actually contains 466 * The Am79C901 HomePNA PHY actually contains
467 * two transceivers: a 1Mbps HomePNA PHY and a 467 * two transceivers: a 1Mbps HomePNA PHY and a
468 * 10Mbps full/half duplex ethernet PHY with 468 * 10Mbps full/half duplex ethernet PHY with
469 * NWAY autoneg. However in the ADMtek adapter, 469 * NWAY autoneg. However in the ADMtek adapter,
470 * only the 1Mbps PHY is actually connected to 470 * only the 1Mbps PHY is actually connected to
471 * anything, so we ignore the 10Mbps one. It 471 * anything, so we ignore the 10Mbps one. It
472 * happens to be configured for MII address 3, 472 * happens to be configured for MII address 3,
473 * so we filter that out. 473 * so we filter that out.
474 */ 474 */
475 if (sc->aue_vendor == USB_VENDOR_ADMTEK && 475 if (sc->aue_vendor == USB_VENDOR_ADMTEK &&
476 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { 476 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) {
477 if (phy == 3) 477 if (phy == 3)
478 return EINVAL; 478 return EINVAL;
479 } 479 }
480#endif 480#endif
481 481
482 aue_csr_write_1(sc, AUE_PHY_ADDR, phy); 482 aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
483 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ); 483 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ);
484 484
485 for (i = 0; i < AUE_TIMEOUT; i++) { 485 for (i = 0; i < AUE_TIMEOUT; i++) {
 486 if (usbnet_isdying(un))
 487 return ENXIO;
486 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) 488 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
487 break; 489 break;
488 } 490 }
489 491
490 if (i == AUE_TIMEOUT) { 492 if (i == AUE_TIMEOUT) {
491 AUEHIST_CALLARGS("aue%jd: phy=%#jx reg=%#jx read timed out", 493 AUEHIST_CALLARGS("aue%jd: phy=%#jx reg=%#jx read timed out",
492 device_unit(un->un_dev), phy, reg, 0); 494 device_unit(un->un_dev), phy, reg, 0);
493 return ETIMEDOUT; 495 return ETIMEDOUT;
494 } 496 }
495 497
496 *val = aue_csr_read_2(sc, AUE_PHY_DATA); 498 *val = aue_csr_read_2(sc, AUE_PHY_DATA);
497 499
498 AUEHIST_CALLARGSN(11, "aue%jd: phy=%#jx reg=%#jx => 0x%04jx", 500 AUEHIST_CALLARGSN(11, "aue%jd: phy=%#jx reg=%#jx => 0x%04jx",
499 device_unit(un->un_dev), phy, reg, *val); 501 device_unit(un->un_dev), phy, reg, *val);
500 502
501 return 0; 503 return 0;
502} 504}
503 505
504static int 506static int
505aue_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 507aue_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
506{ 508{
507 struct aue_softc *sc = usbnet_softc(un); 509 struct aue_softc *sc = usbnet_softc(un);
508 int i; 510 int i;
509 511
510 AUEHIST_FUNC(); 512 AUEHIST_FUNC();
511 AUEHIST_CALLARGSN(11, "aue%jd: phy=%jd reg=%jd data=0x%04jx", 513 AUEHIST_CALLARGSN(11, "aue%jd: phy=%jd reg=%jd data=0x%04jx",
512 device_unit(un->un_dev), phy, reg, val); 514 device_unit(un->un_dev), phy, reg, val);
513 515
514#if 0 516#if 0
515 if (sc->aue_vendor == USB_VENDOR_ADMTEK && 517 if (sc->aue_vendor == USB_VENDOR_ADMTEK &&
516 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { 518 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) {
517 if (phy == 3) 519 if (phy == 3)
518 return EINVAL; 520 return EINVAL;
519 } 521 }
520#endif 522#endif
521 523
522 aue_csr_write_2(sc, AUE_PHY_DATA, val); 524 aue_csr_write_2(sc, AUE_PHY_DATA, val);
523 aue_csr_write_1(sc, AUE_PHY_ADDR, phy); 525 aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
524 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE); 526 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE);
525 527
526 for (i = 0; i < AUE_TIMEOUT; i++) { 528 for (i = 0; i < AUE_TIMEOUT; i++) {
 529 if (usbnet_isdying(un))
 530 return ENXIO;
527 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) 531 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
528 break; 532 break;
529 } 533 }
530 534
531 if (i == AUE_TIMEOUT) { 535 if (i == AUE_TIMEOUT) {
532 DPRINTF("aue%jd: phy=%#jx reg=%#jx val=%#jx write timed out", 536 DPRINTF("aue%jd: phy=%#jx reg=%#jx val=%#jx write timed out",
533 device_unit(un->un_dev), phy, reg, val); 537 device_unit(un->un_dev), phy, reg, val);
534 return ETIMEDOUT; 538 return ETIMEDOUT;
535 } 539 }
536 540
537 return 0; 541 return 0;
538} 542}
539 543
540static void 544static void
541aue_uno_mii_statchg(struct ifnet *ifp) 545aue_uno_mii_statchg(struct ifnet *ifp)
542{ 546{
543 struct usbnet *un = ifp->if_softc; 547 struct usbnet *un = ifp->if_softc;
544 struct aue_softc *sc = usbnet_softc(un); 548 struct aue_softc *sc = usbnet_softc(un);
545 struct mii_data *mii = usbnet_mii(un); 549 struct mii_data *mii = usbnet_mii(un);
546 const bool hadlink __diagused = usbnet_havelink(un); 550 const bool hadlink __diagused = usbnet_havelink(un);
547 551
548 AUEHIST_FUNC(); AUEHIST_CALLED(); 552 AUEHIST_FUNC(); AUEHIST_CALLED();
549 AUEHIST_CALLARGSN(5, "aue%jd: ifp=%#jx link=%jd", 553 AUEHIST_CALLARGSN(5, "aue%jd: ifp=%#jx link=%jd",
550 device_unit(un->un_dev), (uintptr_t)ifp, hadlink, 0); 554 device_unit(un->un_dev), (uintptr_t)ifp, hadlink, 0);
551 555
552 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); 556 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
553 557
554 if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) { 558 if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
555 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); 559 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
556 } else { 560 } else {
557 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); 561 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
558 } 562 }
559 563
560 if ((mii->mii_media_active & IFM_FDX) != 0) 564 if ((mii->mii_media_active & IFM_FDX) != 0)
561 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); 565 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
562 else 566 else
563 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); 567 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
564 568
565 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); 569 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
566 570
567 if (mii->mii_media_status & IFM_ACTIVE && 571 if (mii->mii_media_status & IFM_ACTIVE &&
568 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 572 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
569 usbnet_set_link(un, true); 573 usbnet_set_link(un, true);
570 } 574 }
571 575
572 /* 576 /*
573 * Set the LED modes on the LinkSys adapter. 577 * Set the LED modes on the LinkSys adapter.
574 * This turns on the 'dual link LED' bin in the auxmode 578 * This turns on the 'dual link LED' bin in the auxmode
575 * register of the Broadcom PHY. 579 * register of the Broadcom PHY.
576 */ 580 */
577 if (!usbnet_isdying(un) && (un->un_flags & LSYS)) { 581 if (!usbnet_isdying(un) && (un->un_flags & LSYS)) {
578 uint16_t auxmode; 582 uint16_t auxmode;
579 aue_uno_mii_read_reg(un, 0, 0x1b, &auxmode); 583 aue_uno_mii_read_reg(un, 0, 0x1b, &auxmode);
580 aue_uno_mii_write_reg(un, 0, 0x1b, auxmode | 0x04); 584 aue_uno_mii_write_reg(un, 0, 0x1b, auxmode | 0x04);
581 } 585 }
582 586
583 if (usbnet_havelink(un) != hadlink) { 587 if (usbnet_havelink(un) != hadlink) {
584 DPRINTFN(5, "aue%jd: exit link %jd", 588 DPRINTFN(5, "aue%jd: exit link %jd",
585 device_unit(un->un_dev), usbnet_havelink(un), 0, 0); 589 device_unit(un->un_dev), usbnet_havelink(un), 0, 0);
586 } 590 }
587} 591}
588 592
589#define AUE_POLY 0xEDB88320 593#define AUE_POLY 0xEDB88320
590#define AUE_BITS 6 594#define AUE_BITS 6
591 595
592static uint32_t 596static uint32_t
593aue_crc(void *addrv) 597aue_crc(void *addrv)
594{ 598{
595 uint32_t idx, bit, data, crc; 599 uint32_t idx, bit, data, crc;
596 char *addr = addrv; 600 char *addr = addrv;
597 601
598 /* Compute CRC for the address value. */ 602 /* Compute CRC for the address value. */
599 crc = 0xFFFFFFFF; /* initial value */ 603 crc = 0xFFFFFFFF; /* initial value */
600 604
601 for (idx = 0; idx < 6; idx++) { 605 for (idx = 0; idx < 6; idx++) {
602 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) 606 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
603 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? AUE_POLY : 0); 607 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? AUE_POLY : 0);
604 } 608 }
605 609
606 return crc & ((1 << AUE_BITS) - 1); 610 return crc & ((1 << AUE_BITS) - 1);
607} 611}
608 612
609static void 613static void
610aue_setiff_locked(struct usbnet *un) 614aue_setiff_locked(struct usbnet *un)
611{ 615{
612 struct aue_softc * const sc = usbnet_softc(un); 616 struct aue_softc * const sc = usbnet_softc(un);
613 struct ifnet * const ifp = usbnet_ifp(un); 617 struct ifnet * const ifp = usbnet_ifp(un);
614 struct ethercom * ec = usbnet_ec(un); 618 struct ethercom * ec = usbnet_ec(un);
615 struct ether_multi *enm; 619 struct ether_multi *enm;
616 struct ether_multistep step; 620 struct ether_multistep step;
617 uint32_t h = 0, i; 621 uint32_t h = 0, i;
618 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 622 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
619 623
620 AUEHIST_FUNC(); 624 AUEHIST_FUNC();
621 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); 625 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0);
622 626
623 usbnet_isowned_core(un); 627 usbnet_isowned_core(un);
624 628
625 if (ifp->if_flags & IFF_PROMISC) { 629 if (ifp->if_flags & IFF_PROMISC) {
626allmulti: 630allmulti:
627 ifp->if_flags |= IFF_ALLMULTI; 631 ifp->if_flags |= IFF_ALLMULTI;
628 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); 632 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
629 return; 633 return;
630 } 634 }
631 635
632 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); 636 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
633 637
634 /* now program new ones */ 638 /* now program new ones */
635 ETHER_LOCK(ec); 639 ETHER_LOCK(ec);
636 ETHER_FIRST_MULTI(step, ec, enm); 640 ETHER_FIRST_MULTI(step, ec, enm);
637 while (enm != NULL) { 641 while (enm != NULL) {
638 if (memcmp(enm->enm_addrlo, 642 if (memcmp(enm->enm_addrlo,
639 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) { 643 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
640 ETHER_UNLOCK(ec); 644 ETHER_UNLOCK(ec);
641 goto allmulti; 645 goto allmulti;
642 } 646 }
643 647
644 h = aue_crc(enm->enm_addrlo); 648 h = aue_crc(enm->enm_addrlo);
645 hashtbl[h >> 3] |= 1 << (h & 0x7); 649 hashtbl[h >> 3] |= 1 << (h & 0x7);
646 ETHER_NEXT_MULTI(step, enm); 650 ETHER_NEXT_MULTI(step, enm);
647 } 651 }
648 ETHER_UNLOCK(ec); 652 ETHER_UNLOCK(ec);
649 653
650 /* write the hashtable */ 654 /* write the hashtable */
651 for (i = 0; i < 8; i++) 655 for (i = 0; i < 8; i++)
652 aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]); 656 aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]);
653 657
654 ifp->if_flags &= ~IFF_ALLMULTI; 658 ifp->if_flags &= ~IFF_ALLMULTI;
655} 659}
656 660
657static void 661static void
658aue_reset_pegasus_II(struct aue_softc *sc) 662aue_reset_pegasus_II(struct aue_softc *sc)
659{ 663{
660 /* Magic constants taken from Linux driver. */ 664 /* Magic constants taken from Linux driver. */
661 aue_csr_write_1(sc, AUE_REG_1D, 0); 665 aue_csr_write_1(sc, AUE_REG_1D, 0);
662 aue_csr_write_1(sc, AUE_REG_7B, 2); 666 aue_csr_write_1(sc, AUE_REG_7B, 2);
663#if 0 667#if 0
664 if ((un->un_flags & PNA) && mii_mode) 668 if ((un->un_flags & PNA) && mii_mode)
665 aue_csr_write_1(sc, AUE_REG_81, 6); 669 aue_csr_write_1(sc, AUE_REG_81, 6);
666 else 670 else
667#endif 671#endif
668 aue_csr_write_1(sc, AUE_REG_81, 2); 672 aue_csr_write_1(sc, AUE_REG_81, 2);
669} 673}
670 674
671static void 675static void
672aue_reset(struct aue_softc *sc) 676aue_reset(struct aue_softc *sc)
673{ 677{
674 struct usbnet * const un = &sc->aue_un; 678 struct usbnet * const un = &sc->aue_un;
675 int i; 679 int i;
676 680
677 AUEHIST_FUNC(); 681 AUEHIST_FUNC();
678 AUEHIST_CALLARGSN(2, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); 682 AUEHIST_CALLARGSN(2, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0);
679 683
680 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC); 684 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC);
681 685
682 for (i = 0; i < AUE_TIMEOUT; i++) { 686 for (i = 0; i < AUE_TIMEOUT; i++) {
 687 if (usbnet_isdying(un))
 688 return;
683 if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC)) 689 if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC))
684 break; 690 break;
685 } 691 }
686 692
687 if (i == AUE_TIMEOUT) 693 if (i == AUE_TIMEOUT)
688 printf("%s: reset failed\n", device_xname(un->un_dev)); 694 printf("%s: reset failed\n", device_xname(un->un_dev));
689 695
690#if 0 696#if 0
691 /* XXX what is mii_mode supposed to be */ 697 /* XXX what is mii_mode supposed to be */
692 if (sc->sc_mii_mode && (un->un_flags & PNA)) 698 if (sc->sc_mii_mode && (un->un_flags & PNA))
693 aue_csr_write_1(sc, AUE_GPIO1, 0x34); 699 aue_csr_write_1(sc, AUE_GPIO1, 0x34);
694 else 700 else
695 aue_csr_write_1(sc, AUE_GPIO1, 0x26); 701 aue_csr_write_1(sc, AUE_GPIO1, 0x26);
696#endif 702#endif
697 703
698 /* 704 /*
699 * The PHY(s) attached to the Pegasus chip may be held 705 * The PHY(s) attached to the Pegasus chip may be held
700 * in reset until we flip on the GPIO outputs. Make sure 706 * in reset until we flip on the GPIO outputs. Make sure
701 * to set the GPIO pins high so that the PHY(s) will 707 * to set the GPIO pins high so that the PHY(s) will
702 * be enabled. 708 * be enabled.
703 * 709 *
704 * Note: We force all of the GPIO pins low first, *then* 710 * Note: We force all of the GPIO pins low first, *then*
705 * enable the ones we want. 711 * enable the ones we want.
706 */ 712 */
707 if (un->un_flags & LSYS) { 713 if (un->un_flags & LSYS) {
708 /* Grrr. LinkSys has to be different from everyone else. */ 714 /* Grrr. LinkSys has to be different from everyone else. */
709 aue_csr_write_1(sc, AUE_GPIO0, 715 aue_csr_write_1(sc, AUE_GPIO0,
710 AUE_GPIO_SEL0 | AUE_GPIO_SEL1); 716 AUE_GPIO_SEL0 | AUE_GPIO_SEL1);
711 } else { 717 } else {
712 aue_csr_write_1(sc, AUE_GPIO0, 718 aue_csr_write_1(sc, AUE_GPIO0,
713 AUE_GPIO_OUT0 | AUE_GPIO_SEL0); 719 AUE_GPIO_OUT0 | AUE_GPIO_SEL0);
714 } 720 }
715 aue_csr_write_1(sc, AUE_GPIO0, 721 aue_csr_write_1(sc, AUE_GPIO0,
716 AUE_GPIO_OUT0 | AUE_GPIO_SEL0 | AUE_GPIO_SEL1); 722 AUE_GPIO_OUT0 | AUE_GPIO_SEL0 | AUE_GPIO_SEL1);
717 723
718 if (un->un_flags & PII) 724 if (un->un_flags & PII)
719 aue_reset_pegasus_II(sc); 725 aue_reset_pegasus_II(sc);
720 726
721 /* Wait a little while for the chip to get its brains in order. */ 727 /* Wait a little while for the chip to get its brains in order. */
722 delay(10000); /* XXX */ 728 delay(10000); /* XXX */
723 //usbd_delay_ms(un->un_udev, 10); /* XXX */ 729 //usbd_delay_ms(un->un_udev, 10); /* XXX */
724 730
725 DPRINTFN(2, "aue%jd: exit", device_unit(un->un_dev), 0, 0, 0); 731 DPRINTFN(2, "aue%jd: exit", device_unit(un->un_dev), 0, 0, 0);
726} 732}
727 733
728/* 734/*
729 * Probe for a Pegasus chip. 735 * Probe for a Pegasus chip.
730 */ 736 */
731static int 737static int
732aue_match(device_t parent, cfdata_t match, void *aux) 738aue_match(device_t parent, cfdata_t match, void *aux)
733{ 739{
734 struct usb_attach_arg *uaa = aux; 740 struct usb_attach_arg *uaa = aux;
735 741
736 /* 742 /*
737 * Some manufacturers use the same vendor and product id for 743 * Some manufacturers use the same vendor and product id for
738 * different devices. We need to sanity check the DeviceClass 744 * different devices. We need to sanity check the DeviceClass
739 * in this case 745 * in this case
740 * Currently known guilty products: 746 * Currently known guilty products:
741 * 0x050d/0x0121 Belkin Bluetooth and USB2LAN 747 * 0x050d/0x0121 Belkin Bluetooth and USB2LAN
742 * 748 *
743 * If this turns out to be more common, we could use a quirk 749 * If this turns out to be more common, we could use a quirk
744 * table. 750 * table.
745 */ 751 */
746 if (uaa->uaa_vendor == USB_VENDOR_BELKIN && 752 if (uaa->uaa_vendor == USB_VENDOR_BELKIN &&
747 uaa->uaa_product == USB_PRODUCT_BELKIN_USB2LAN) { 753 uaa->uaa_product == USB_PRODUCT_BELKIN_USB2LAN) {
748 usb_device_descriptor_t *dd; 754 usb_device_descriptor_t *dd;
749 755
750 dd = usbd_get_device_descriptor(uaa->uaa_device); 756 dd = usbd_get_device_descriptor(uaa->uaa_device);
751 if (dd != NULL && 757 if (dd != NULL &&
752 dd->bDeviceClass != UDCLASS_IN_INTERFACE) 758 dd->bDeviceClass != UDCLASS_IN_INTERFACE)
753 return UMATCH_NONE; 759 return UMATCH_NONE;
754 } 760 }
755 761
756 return aue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 762 return aue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
757 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 763 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
758} 764}
759 765
760/* 766/*
761 * Attach the interface. Allocate softc structures, do ifmedia 767 * Attach the interface. Allocate softc structures, do ifmedia
762 * setup and ethernet/BPF attach. 768 * setup and ethernet/BPF attach.
763 */ 769 */
764static void 770static void
765aue_attach(device_t parent, device_t self, void *aux) 771aue_attach(device_t parent, device_t self, void *aux)
766{ 772{
767 USBNET_MII_DECL_DEFAULT(unm); 773 USBNET_MII_DECL_DEFAULT(unm);
768 struct aue_softc * const sc = device_private(self); 774 struct aue_softc * const sc = device_private(self);
769 struct usbnet * const un = &sc->aue_un; 775 struct usbnet * const un = &sc->aue_un;
770 struct usb_attach_arg *uaa = aux; 776 struct usb_attach_arg *uaa = aux;
771 char *devinfop; 777 char *devinfop;
772 struct usbd_device *dev = uaa->uaa_device; 778 struct usbd_device *dev = uaa->uaa_device;
773 usbd_status err; 779 usbd_status err;
774 usb_interface_descriptor_t *id; 780 usb_interface_descriptor_t *id;
775 usb_endpoint_descriptor_t *ed; 781 usb_endpoint_descriptor_t *ed;
776 int i; 782 int i;
777 783
778 AUEHIST_FUNC(); 784 AUEHIST_FUNC();
779 AUEHIST_CALLARGSN(2, "aue%jd: enter sc=%#jx", 785 AUEHIST_CALLARGSN(2, "aue%jd: enter sc=%#jx",
780 device_unit(self), (uintptr_t)sc, 0, 0); 786 device_unit(self), (uintptr_t)sc, 0, 0);
781 787
782 KASSERT((void *)sc == un); 788 KASSERT((void *)sc == un);
783 789
784 aprint_naive("\n"); 790 aprint_naive("\n");
785 aprint_normal("\n"); 791 aprint_normal("\n");
786 devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0); 792 devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0);
787 aprint_normal_dev(self, "%s\n", devinfop); 793 aprint_normal_dev(self, "%s\n", devinfop);
788 usbd_devinfo_free(devinfop); 794 usbd_devinfo_free(devinfop);
789 795
790 un->un_dev = self; 796 un->un_dev = self;
791 un->un_udev = dev; 797 un->un_udev = dev;
792 un->un_sc = sc; 798 un->un_sc = sc;
793 un->un_ops = &aue_ops; 799 un->un_ops = &aue_ops;
794 un->un_intr = &sc->aue_intr; 800 un->un_intr = &sc->aue_intr;
795 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 801 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
796 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 802 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
797 un->un_rx_list_cnt = AUE_RX_LIST_CNT; 803 un->un_rx_list_cnt = AUE_RX_LIST_CNT;
798 un->un_tx_list_cnt = AUE_RX_LIST_CNT; 804 un->un_tx_list_cnt = AUE_RX_LIST_CNT;
799 un->un_rx_bufsz = AUE_BUFSZ; 805 un->un_rx_bufsz = AUE_BUFSZ;
800 un->un_tx_bufsz = AUE_BUFSZ; 806 un->un_tx_bufsz = AUE_BUFSZ;
801 807
802 sc->aue_intr.uni_buf = &sc->aue_ibuf; 808 sc->aue_intr.uni_buf = &sc->aue_ibuf;
803 sc->aue_intr.uni_bufsz = sizeof(sc->aue_ibuf); 809 sc->aue_intr.uni_bufsz = sizeof(sc->aue_ibuf);
804 sc->aue_intr.uni_interval = AUE_INTR_INTERVAL; 810 sc->aue_intr.uni_interval = AUE_INTR_INTERVAL;
805 811
806 err = usbd_set_config_no(dev, AUE_CONFIG_NO, 1); 812 err = usbd_set_config_no(dev, AUE_CONFIG_NO, 1);
807 if (err) { 813 if (err) {
808 aprint_error_dev(self, "failed to set configuration" 814 aprint_error_dev(self, "failed to set configuration"
809 ", err=%s\n", usbd_errstr(err)); 815 ", err=%s\n", usbd_errstr(err));
810 return; 816 return;
811 } 817 }
812 818
813 err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &un->un_iface); 819 err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &un->un_iface);
814 if (err) { 820 if (err) {
815 aprint_error_dev(self, "getting interface handle failed\n"); 821 aprint_error_dev(self, "getting interface handle failed\n");
816 return; 822 return;
817 } 823 }
818 824
819 un->un_flags = aue_lookup(uaa->uaa_vendor, uaa->uaa_product)->aue_flags; 825 un->un_flags = aue_lookup(uaa->uaa_vendor, uaa->uaa_product)->aue_flags;
820 826
821 id = usbd_get_interface_descriptor(un->un_iface); 827 id = usbd_get_interface_descriptor(un->un_iface);
822 828
823 /* Find endpoints. */ 829 /* Find endpoints. */
824 for (i = 0; i < id->bNumEndpoints; i++) { 830 for (i = 0; i < id->bNumEndpoints; i++) {
825 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 831 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
826 if (ed == NULL) { 832 if (ed == NULL) {
827 aprint_error_dev(self, 833 aprint_error_dev(self,
828 "couldn't get endpoint descriptor %d\n", i); 834 "couldn't get endpoint descriptor %d\n", i);
829 return; 835 return;
830 } 836 }
831 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 837 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
832 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 838 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
833 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 839 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
834 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 840 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
835 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 841 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
836 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 842 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
837 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 843 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
838 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 844 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
839 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 845 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
840 } 846 }
841 } 847 }
842 848
843 if (un->un_ed[USBNET_ENDPT_RX] == 0 || 849 if (un->un_ed[USBNET_ENDPT_RX] == 0 ||
844 un->un_ed[USBNET_ENDPT_TX] == 0 || 850 un->un_ed[USBNET_ENDPT_TX] == 0 ||
845 un->un_ed[USBNET_ENDPT_INTR] == 0) { 851 un->un_ed[USBNET_ENDPT_INTR] == 0) {
846 aprint_error_dev(self, "missing endpoint\n"); 852 aprint_error_dev(self, "missing endpoint\n");
847 return; 853 return;
848 } 854 }
849 855
850 /* First level attach. */ 856 /* First level attach. */
851 usbnet_attach(un, "auedet"); 857 usbnet_attach(un, "auedet");
852 858
853 usbnet_lock_core(un); 859 usbnet_lock_core(un);
854 860
855 /* Reset the adapter and get station address from the EEPROM. */ 861 /* Reset the adapter and get station address from the EEPROM. */
856 aue_reset(sc); 862 aue_reset(sc);
857 aue_read_mac(un); 863 aue_read_mac(un);
858 864
859 usbnet_unlock_core(un); 865 usbnet_unlock_core(un);
860 866
861 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 867 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
862 0, &unm); 868 0, &unm);
863} 869}
864 870
865static void 871static void
866aue_uno_intr(struct usbnet *un, usbd_status status) 872aue_uno_intr(struct usbnet *un, usbd_status status)
867{ 873{
868 struct ifnet *ifp = usbnet_ifp(un); 874 struct ifnet *ifp = usbnet_ifp(un);
869 struct aue_softc *sc = usbnet_softc(un); 875 struct aue_softc *sc = usbnet_softc(un);
870 struct aue_intrpkt *p = &sc->aue_ibuf; 876 struct aue_intrpkt *p = &sc->aue_ibuf;
871 877
872 AUEHIST_FUNC(); 878 AUEHIST_FUNC();
873 AUEHIST_CALLARGSN(20, "aue%jd: enter txstat0 %#jx\n", 879 AUEHIST_CALLARGSN(20, "aue%jd: enter txstat0 %#jx\n",
874 device_unit(un->un_dev), p->aue_txstat0, 0, 0); 880 device_unit(un->un_dev), p->aue_txstat0, 0, 0);
875 881
876 if (p->aue_txstat0) 882 if (p->aue_txstat0)
877 if_statinc(ifp, if_oerrors); 883 if_statinc(ifp, if_oerrors);
878 884
879 if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL | AUE_TXSTAT0_EXCESSCOLL)) 885 if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL | AUE_TXSTAT0_EXCESSCOLL))
880 if_statinc(ifp, if_collisions); 886 if_statinc(ifp, if_collisions);
881} 887}
882 888
883static void 889static void
884aue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 890aue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
885{ 891{
886 struct ifnet *ifp = usbnet_ifp(un); 892 struct ifnet *ifp = usbnet_ifp(un);
887 uint8_t *buf = c->unc_buf; 893 uint8_t *buf = c->unc_buf;
888 struct aue_rxpkt r; 894 struct aue_rxpkt r;
889 uint32_t pktlen; 895 uint32_t pktlen;
890 896
891 AUEHIST_FUNC(); 897 AUEHIST_FUNC();
892 AUEHIST_CALLARGSN(10, "aue%jd: enter len %ju", 898 AUEHIST_CALLARGSN(10, "aue%jd: enter len %ju",
893 device_unit(un->un_dev), total_len, 0, 0); 899 device_unit(un->un_dev), total_len, 0, 0);
894 900
895 if (total_len <= 4 + ETHER_CRC_LEN) { 901 if (total_len <= 4 + ETHER_CRC_LEN) {
896 if_statinc(ifp, if_ierrors); 902 if_statinc(ifp, if_ierrors);
897 return; 903 return;
898 } 904 }
899 905
900 memcpy(&r, buf + total_len - 4, sizeof(r)); 906 memcpy(&r, buf + total_len - 4, sizeof(r));
901 907
902 /* Turn off all the non-error bits in the rx status word. */ 908 /* Turn off all the non-error bits in the rx status word. */
903 r.aue_rxstat &= AUE_RXSTAT_MASK; 909 r.aue_rxstat &= AUE_RXSTAT_MASK;
904 if (r.aue_rxstat) { 910 if (r.aue_rxstat) {
905 if_statinc(ifp, if_ierrors); 911 if_statinc(ifp, if_ierrors);
906 return; 912 return;
907 } 913 }
908 914
909 /* No errors; receive the packet. */ 915 /* No errors; receive the packet. */
910 pktlen = total_len - ETHER_CRC_LEN - 4; 916 pktlen = total_len - ETHER_CRC_LEN - 4;
911 917
912 usbnet_enqueue(un, buf, pktlen, 0, 0, 0); 918 usbnet_enqueue(un, buf, pktlen, 0, 0, 0);
913} 919}
914 920
915static unsigned 921static unsigned
916aue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 922aue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
917{ 923{
918 uint8_t *buf = c->unc_buf; 924 uint8_t *buf = c->unc_buf;
919 int total_len; 925 int total_len;
920 926
921 AUEHIST_FUNC(); 927 AUEHIST_FUNC();
922 AUEHIST_CALLARGSN(10, "aue%jd: enter pktlen=%jd", 928 AUEHIST_CALLARGSN(10, "aue%jd: enter pktlen=%jd",
923 device_unit(un->un_dev), m->m_pkthdr.len, 0, 0); 929 device_unit(un->un_dev), m->m_pkthdr.len, 0, 0);
924 930
925 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2) 931 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2)
926 return 0; 932 return 0;
927 933
928 /* 934 /*
929 * Copy the mbuf data into a contiguous buffer, leaving two 935 * Copy the mbuf data into a contiguous buffer, leaving two
930 * bytes at the beginning to hold the frame length. 936 * bytes at the beginning to hold the frame length.
931 */ 937 */
932 m_copydata(m, 0, m->m_pkthdr.len, buf + 2); 938 m_copydata(m, 0, m->m_pkthdr.len, buf + 2);
933 939
934 /* 940 /*
935 * The ADMtek documentation says that the packet length is 941 * The ADMtek documentation says that the packet length is
936 * supposed to be specified in the first two bytes of the 942 * supposed to be specified in the first two bytes of the
937 * transfer, however it actually seems to ignore this info 943 * transfer, however it actually seems to ignore this info
938 * and base the frame size on the bulk transfer length. 944 * and base the frame size on the bulk transfer length.
939 */ 945 */
940 buf[0] = (uint8_t)m->m_pkthdr.len; 946 buf[0] = (uint8_t)m->m_pkthdr.len;
941 buf[1] = (uint8_t)(m->m_pkthdr.len >> 8); 947 buf[1] = (uint8_t)(m->m_pkthdr.len >> 8);
942 total_len = m->m_pkthdr.len + 2; 948 total_len = m->m_pkthdr.len + 2;
943 949
944 DPRINTFN(5, "aue%jd: send %jd bytes", 950 DPRINTFN(5, "aue%jd: send %jd bytes",
945 device_unit(un->un_dev), total_len, 0, 0); 951 device_unit(un->un_dev), total_len, 0, 0);
946 952
947 return total_len; 953 return total_len;
948} 954}
949 955
950static int 956static int
951aue_init_locked(struct ifnet *ifp) 957aue_init_locked(struct ifnet *ifp)
952{ 958{
953 struct usbnet * const un = ifp->if_softc; 959 struct usbnet * const un = ifp->if_softc;
954 struct aue_softc *sc = usbnet_softc(un); 960 struct aue_softc *sc = usbnet_softc(un);
955 int i, rv; 961 int i, rv;
956 const u_char *eaddr; 962 const u_char *eaddr;
957 963
958 AUEHIST_FUNC(); 964 AUEHIST_FUNC();
959 AUEHIST_CALLARGSN(5, "aue%jd: enter link=%jd", 965 AUEHIST_CALLARGSN(5, "aue%jd: enter link=%jd",
960 device_unit(un->un_dev), usbnet_havelink(un), 0, 0); 966 device_unit(un->un_dev), usbnet_havelink(un), 0, 0);
961 967
962 if (usbnet_isdying(un)) 968 if (usbnet_isdying(un))
963 return EIO; 969 return EIO;
964 970
965 /* Cancel pending I/O */ 971 /* Cancel pending I/O */
966 if (ifp->if_flags & IFF_RUNNING) 972 if (ifp->if_flags & IFF_RUNNING)
967 return 0; 973 return 0;
968 974
969 /* Reset the interface. */ 975 /* Reset the interface. */
970 aue_reset(sc); 976 aue_reset(sc);
971 977
972 eaddr = CLLADDR(ifp->if_sadl); 978 eaddr = CLLADDR(ifp->if_sadl);
973 for (i = 0; i < ETHER_ADDR_LEN; i++) 979 for (i = 0; i < ETHER_ADDR_LEN; i++)
974 aue_csr_write_1(sc, AUE_PAR0 + i, eaddr[i]); 980 aue_csr_write_1(sc, AUE_PAR0 + i, eaddr[i]);
975 981
976 /* If we want promiscuous mode, set the allframes bit. */ 982 /* If we want promiscuous mode, set the allframes bit. */
977 if (ifp->if_flags & IFF_PROMISC) 983 if (ifp->if_flags & IFF_PROMISC)
978 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); 984 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
979 else 985 else
980 AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); 986 AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
981 987
982 rv = usbnet_init_rx_tx(un); 988 rv = usbnet_init_rx_tx(un);
983 989
984 /* Load the multicast filter. */ 990 /* Load the multicast filter. */
985 aue_setiff_locked(un); 991 aue_setiff_locked(un);
986 992
987 /* Enable RX and TX */ 993 /* Enable RX and TX */
988 aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB); 994 aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB);
989 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB); 995 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB);
990 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR); 996 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR);
991 997
992 //mii_mediachg(mii); 998 //mii_mediachg(mii);
993 999
994 return rv; 1000 return rv;
995} 1001}
996 1002
997static int 1003static int
998aue_uno_init(struct ifnet *ifp) 1004aue_uno_init(struct ifnet *ifp)
999{ 1005{
1000 struct usbnet * const un = ifp->if_softc; 1006 struct usbnet * const un = ifp->if_softc;
1001 int rv; 1007 int rv;
1002 1008
1003 usbnet_busy(un); 1009 usbnet_busy(un);
1004 rv = aue_init_locked(ifp); 1010 rv = aue_init_locked(ifp);
1005 usbnet_unbusy(un); 1011 usbnet_unbusy(un);
1006 1012
1007 return rv; 1013 return rv;
1008} 1014}
1009 1015
1010static int 1016static int
1011aue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1017aue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1012{ 1018{
1013 struct usbnet * const un = ifp->if_softc; 1019 struct usbnet * const un = ifp->if_softc;
1014 1020
1015 AUEHIST_FUNC(); 1021 AUEHIST_FUNC();
1016 AUEHIST_CALLARGSN(5, "aue%jd: enter cmd %#jx data %#jx", 1022 AUEHIST_CALLARGSN(5, "aue%jd: enter cmd %#jx data %#jx",
1017 device_unit(((struct usbnet *)(ifp->if_softc))->un_dev), 1023 device_unit(((struct usbnet *)(ifp->if_softc))->un_dev),
1018 cmd, (uintptr_t)data, 0); 1024 cmd, (uintptr_t)data, 0);
1019 1025
1020 switch (cmd) { 1026 switch (cmd) {
1021 case SIOCADDMULTI: 1027 case SIOCADDMULTI:
1022 case SIOCDELMULTI: 1028 case SIOCDELMULTI:
1023 usbnet_lock_core(un); 1029 usbnet_lock_core(un);
1024 aue_uno_init(ifp); 1030 aue_uno_init(ifp);
1025 usbnet_unlock_core(un); 1031 usbnet_unlock_core(un);
1026 break; 1032 break;
1027 default: 1033 default:
1028 break; 1034 break;
1029 } 1035 }
1030 1036
1031 return 0; 1037 return 0;
1032} 1038}
1033 1039
1034static void 1040static void
1035aue_uno_stop(struct ifnet *ifp, int disable) 1041aue_uno_stop(struct ifnet *ifp, int disable)
1036{ 1042{
1037 struct usbnet * const un = ifp->if_softc; 1043 struct usbnet * const un = ifp->if_softc;
1038 struct aue_softc * const sc = usbnet_softc(un); 1044 struct aue_softc * const sc = usbnet_softc(un);
1039 1045
1040 AUEHIST_FUNC(); 1046 AUEHIST_FUNC();
1041 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); 1047 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0);
1042 1048
1043 aue_csr_write_1(sc, AUE_CTL0, 0); 1049 aue_csr_write_1(sc, AUE_CTL0, 0);
1044 aue_csr_write_1(sc, AUE_CTL1, 0); 1050 aue_csr_write_1(sc, AUE_CTL1, 0);
1045 aue_reset(sc); 1051 aue_reset(sc);
1046} 1052}
1047 1053
1048#ifdef _MODULE 1054#ifdef _MODULE
1049#include "ioconf.c" 1055#include "ioconf.c"
1050#endif 1056#endif
1051 1057
1052USBNET_MODULE(aue) 1058USBNET_MODULE(aue)

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

--- src/sys/dev/usb/if_mos.c 2022/03/03 05:50:22 1.8
+++ src/sys/dev/usb/if_mos.c 2022/03/03 05:50:57 1.9
@@ -1,799 +1,803 @@ @@ -1,799 +1,803 @@
1/* $NetBSD: if_mos.c,v 1.8 2022/03/03 05:50:22 riastradh Exp $ */ 1/* $NetBSD: if_mos.c,v 1.9 2022/03/03 05:50:57 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.8 2022/03/03 05:50:22 riastradh Exp $"); 75__KERNEL_RCSID(0, "$NetBSD: if_mos.c,v 1.9 2022/03/03 05:50:57 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 int mos_uno_ioctl(struct ifnet *, u_long, void *); 148static int mos_uno_ioctl(struct ifnet *, u_long, void *);
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_ioctl = mos_uno_ioctl, 167 .uno_ioctl = mos_uno_ioctl,
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))
 368 return ENXIO;
367 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)
368 break; 370 break;
369 } 371 }
370 if (i == MOS_TIMEOUT) { 372 if (i == MOS_TIMEOUT) {
371 aprint_error_dev(un->un_dev, "read PHY failed\n"); 373 aprint_error_dev(un->un_dev, "read PHY failed\n");
372 return EIO; 374 return EIO;
373 } 375 }
374 376
375 res = mos_reg_read_2(un, MOS_PHY_DATA); 377 res = mos_reg_read_2(un, MOS_PHY_DATA);
376 *val = res; 378 *val = res;
377 379
378 DPRINTFN(10,("%s: %s: phy %d reg %d val %u\n", 380 DPRINTFN(10,("%s: %s: phy %d reg %d val %u\n",
379 device_xname(un->un_dev), __func__, phy, reg, res)); 381 device_xname(un->un_dev), __func__, phy, reg, res));
380 382
381 return 0; 383 return 0;
382} 384}
383 385
384static int 386static int
385mos_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)
386{ 388{
387 int i; 389 int i;
388 390
389 DPRINTFN(10,("%s: %s: phy %d reg %d val %u\n", 391 DPRINTFN(10,("%s: %s: phy %d reg %d val %u\n",
390 device_xname(un->un_dev), __func__, phy, reg, val)); 392 device_xname(un->un_dev), __func__, phy, reg, val));
391 393
392 mos_reg_write_2(un, MOS_PHY_DATA, val); 394 mos_reg_write_2(un, MOS_PHY_DATA, val);
393 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) |
394 MOS_PHYCTL_WRITE); 396 MOS_PHYCTL_WRITE);
395 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) |
396 MOS_PHYSTS_PENDING); 398 MOS_PHYSTS_PENDING);
397 399
398 for (i = 0; i < MOS_TIMEOUT; i++) { 400 for (i = 0; i < MOS_TIMEOUT; i++) {
 401 if (usbnet_isdying(un))
 402 return ENXIO;
399 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)
400 break; 404 break;
401 } 405 }
402 if (i == MOS_TIMEOUT) { 406 if (i == MOS_TIMEOUT) {
403 aprint_error_dev(un->un_dev, "write PHY failed\n"); 407 aprint_error_dev(un->un_dev, "write PHY failed\n");
404 return EIO; 408 return EIO;
405 } 409 }
406 410
407 return 0; 411 return 0;
408} 412}
409 413
410void 414void
411mos_uno_mii_statchg(struct ifnet *ifp) 415mos_uno_mii_statchg(struct ifnet *ifp)
412{ 416{
413 struct usbnet * const un = ifp->if_softc; 417 struct usbnet * const un = ifp->if_softc;
414 struct mii_data * const mii = usbnet_mii(un); 418 struct mii_data * const mii = usbnet_mii(un);
415 int val, err; 419 int val, err;
416 420
417 if (usbnet_isdying(un)) 421 if (usbnet_isdying(un))
418 return; 422 return;
419 423
420 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__));
421 425
422 /* disable RX, TX prior to changing FDX, SPEEDSEL */ 426 /* disable RX, TX prior to changing FDX, SPEEDSEL */
423 val = mos_reg_read_1(un, MOS_CTL); 427 val = mos_reg_read_1(un, MOS_CTL);
424 val &= ~(MOS_CTL_TX_ENB | MOS_CTL_RX_ENB); 428 val &= ~(MOS_CTL_TX_ENB | MOS_CTL_RX_ENB);
425 mos_reg_write_1(un, MOS_CTL, val); 429 mos_reg_write_1(un, MOS_CTL, val);
426 430
427 /* reset register which counts dropped frames */ 431 /* reset register which counts dropped frames */
428 mos_reg_write_1(un, MOS_FRAME_DROP_CNT, 0); 432 mos_reg_write_1(un, MOS_FRAME_DROP_CNT, 0);
429 433
430 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) 434 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
431 val |= MOS_CTL_FDX_ENB; 435 val |= MOS_CTL_FDX_ENB;
432 else 436 else
433 val &= ~(MOS_CTL_FDX_ENB); 437 val &= ~(MOS_CTL_FDX_ENB);
434 438
435 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 439 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
436 (IFM_ACTIVE | IFM_AVALID)) { 440 (IFM_ACTIVE | IFM_AVALID)) {
437 switch (IFM_SUBTYPE(mii->mii_media_active)) { 441 switch (IFM_SUBTYPE(mii->mii_media_active)) {
438 case IFM_100_TX: 442 case IFM_100_TX:
439 val |= MOS_CTL_SPEEDSEL; 443 val |= MOS_CTL_SPEEDSEL;
440 break; 444 break;
441 case IFM_10_T: 445 case IFM_10_T:
442 val &= ~(MOS_CTL_SPEEDSEL); 446 val &= ~(MOS_CTL_SPEEDSEL);
443 break; 447 break;
444 } 448 }
445 usbnet_set_link(un, true); 449 usbnet_set_link(un, true);
446 } 450 }
447 451
448 /* re-enable TX, RX */ 452 /* re-enable TX, RX */
449 val |= (MOS_CTL_TX_ENB | MOS_CTL_RX_ENB); 453 val |= (MOS_CTL_TX_ENB | MOS_CTL_RX_ENB);
450 err = mos_reg_write_1(un, MOS_CTL, val); 454 err = mos_reg_write_1(un, MOS_CTL, val);
451 455
452 if (err) 456 if (err)
453 aprint_error_dev(un->un_dev, "media change failed\n"); 457 aprint_error_dev(un->un_dev, "media change failed\n");
454} 458}
455 459
456static void 460static void
457mos_rcvfilt_locked(struct usbnet *un) 461mos_rcvfilt_locked(struct usbnet *un)
458{ 462{
459 struct ifnet *ifp = usbnet_ifp(un); 463 struct ifnet *ifp = usbnet_ifp(un);
460 struct ethercom *ec = usbnet_ec(un); 464 struct ethercom *ec = usbnet_ec(un);
461 struct ether_multi *enm; 465 struct ether_multi *enm;
462 struct ether_multistep step; 466 struct ether_multistep step;
463 u_int32_t h = 0; 467 u_int32_t h = 0;
464 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 };
465 469
466 if (usbnet_isdying(un)) 470 if (usbnet_isdying(un))
467 return; 471 return;
468 472
469 rxmode = mos_reg_read_1(un, MOS_CTL); 473 rxmode = mos_reg_read_1(un, MOS_CTL);
470 rxmode &= ~(MOS_CTL_ALLMULTI | MOS_CTL_RX_PROMISC); 474 rxmode &= ~(MOS_CTL_ALLMULTI | MOS_CTL_RX_PROMISC);
471 475
472 ETHER_LOCK(ec); 476 ETHER_LOCK(ec);
473 if (ifp->if_flags & IFF_PROMISC) { 477 if (ifp->if_flags & IFF_PROMISC) {
474 ec->ec_flags |= ETHER_F_ALLMULTI; 478 ec->ec_flags |= ETHER_F_ALLMULTI;
475 ETHER_UNLOCK(ec); 479 ETHER_UNLOCK(ec);
476 /* run promisc. mode */ 480 /* run promisc. mode */
477 rxmode |= MOS_CTL_ALLMULTI; /* ??? */ 481 rxmode |= MOS_CTL_ALLMULTI; /* ??? */
478 rxmode |= MOS_CTL_RX_PROMISC; 482 rxmode |= MOS_CTL_RX_PROMISC;
479 goto update; 483 goto update;
480 } 484 }
481 ec->ec_flags &= ~ETHER_F_ALLMULTI; 485 ec->ec_flags &= ~ETHER_F_ALLMULTI;
482 ETHER_FIRST_MULTI(step, ec, enm); 486 ETHER_FIRST_MULTI(step, ec, enm);
483 while (enm != NULL) { 487 while (enm != NULL) {
484 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 488 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
485 ec->ec_flags |= ETHER_F_ALLMULTI; 489 ec->ec_flags |= ETHER_F_ALLMULTI;
486 ETHER_UNLOCK(ec); 490 ETHER_UNLOCK(ec);
487 memset(mchash, 0, sizeof(mchash)); /* correct ??? */ 491 memset(mchash, 0, sizeof(mchash)); /* correct ??? */
488 /* accept all multicast frame */ 492 /* accept all multicast frame */
489 rxmode |= MOS_CTL_ALLMULTI; 493 rxmode |= MOS_CTL_ALLMULTI;
490 goto update; 494 goto update;
491 } 495 }
492 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 496 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
493 /* 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] */
494 mchash[h >> 29] |= 1 << ((h >> 26) % 8); 498 mchash[h >> 29] |= 1 << ((h >> 26) % 8);
495 ETHER_NEXT_MULTI(step, enm); 499 ETHER_NEXT_MULTI(step, enm);
496 } 500 }
497 ETHER_UNLOCK(ec); 501 ETHER_UNLOCK(ec);
498 /* MOS receive filter is always on */ 502 /* MOS receive filter is always on */
499 update: 503 update:
500 /*  504 /*
501 * The datasheet claims broadcast frames were always accepted 505 * The datasheet claims broadcast frames were always accepted
502 * regardless of filter settings. But the hardware seems to 506 * regardless of filter settings. But the hardware seems to
503 * filter broadcast frames, so pass them explicitly. 507 * filter broadcast frames, so pass them explicitly.
504 */ 508 */
505 mchash[7] |= 0x80; 509 mchash[7] |= 0x80;
506 mos_write_mcast(un, mchash); 510 mos_write_mcast(un, mchash);
507 mos_reg_write_1(un, MOS_CTL, rxmode); 511 mos_reg_write_1(un, MOS_CTL, rxmode);
508} 512}
509 513
510static void 514static void
511mos_reset(struct usbnet *un) 515mos_reset(struct usbnet *un)
512{ 516{
513 u_int8_t ctl; 517 u_int8_t ctl;
514 518
515 if (usbnet_isdying(un)) 519 if (usbnet_isdying(un))
516 return; 520 return;
517 521
518 ctl = mos_reg_read_1(un, MOS_CTL); 522 ctl = mos_reg_read_1(un, MOS_CTL);
519 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 |
520 MOS_CTL_RX_ENB); 524 MOS_CTL_RX_ENB);
521 /* Disable RX, TX, promiscuous and allmulticast mode */ 525 /* Disable RX, TX, promiscuous and allmulticast mode */
522 mos_reg_write_1(un, MOS_CTL, ctl); 526 mos_reg_write_1(un, MOS_CTL, ctl);
523 527
524 /* Reset frame drop counter register to zero */ 528 /* Reset frame drop counter register to zero */
525 mos_reg_write_1(un, MOS_FRAME_DROP_CNT, 0); 529 mos_reg_write_1(un, MOS_FRAME_DROP_CNT, 0);
526 530
527 /* 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. */
528 DELAY(1000); 532 DELAY(1000);
529} 533}
530 534
531void 535void
532mos_chip_init(struct usbnet *un) 536mos_chip_init(struct usbnet *un)
533{ 537{
534 int i; 538 int i;
535 539
536 /* 540 /*
537 * 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
538 * at startup. 542 * at startup.
539 */ 543 */
540 if (mos_reg_read_1(un, MOS_PAUSE_TRHD) != -1) { 544 if (mos_reg_read_1(un, MOS_PAUSE_TRHD) != -1) {
541 for (i = 0; i < MOS_PAUSE_REWRITES; i++) 545 for (i = 0; i < MOS_PAUSE_REWRITES; i++)
542 mos_reg_write_1(un, MOS_PAUSE_TRHD, 0); 546 mos_reg_write_1(un, MOS_PAUSE_TRHD, 0);
543 } 547 }
544} 548}
545 549
546/* 550/*
547 * Probe for a MCS7x30 chip. 551 * Probe for a MCS7x30 chip.
548 */ 552 */
549static int 553static int
550mos_match(device_t parent, cfdata_t match, void *aux) 554mos_match(device_t parent, cfdata_t match, void *aux)
551{ 555{
552 struct usb_attach_arg *uaa = aux; 556 struct usb_attach_arg *uaa = aux;
553 557
554 return (mos_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 558 return (mos_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
555 UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 559 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
556} 560}
557 561
558/* 562/*
559 * Attach the interface. 563 * Attach the interface.
560 */ 564 */
561static void 565static void
562mos_attach(device_t parent, device_t self, void *aux) 566mos_attach(device_t parent, device_t self, void *aux)
563{ 567{
564 USBNET_MII_DECL_DEFAULT(unm); 568 USBNET_MII_DECL_DEFAULT(unm);
565 struct usbnet * un = device_private(self); 569 struct usbnet * un = device_private(self);
566 struct usb_attach_arg *uaa = aux; 570 struct usb_attach_arg *uaa = aux;
567 struct usbd_device *dev = uaa->uaa_device; 571 struct usbd_device *dev = uaa->uaa_device;
568 usbd_status err; 572 usbd_status err;
569 usb_interface_descriptor_t *id; 573 usb_interface_descriptor_t *id;
570 usb_endpoint_descriptor_t *ed; 574 usb_endpoint_descriptor_t *ed;
571 char *devinfop; 575 char *devinfop;
572 int i; 576 int i;
573 577
574 aprint_naive("\n"); 578 aprint_naive("\n");
575 aprint_normal("\n"); 579 aprint_normal("\n");
576 devinfop = usbd_devinfo_alloc(dev, 0); 580 devinfop = usbd_devinfo_alloc(dev, 0);
577 aprint_normal_dev(self, "%s\n", devinfop); 581 aprint_normal_dev(self, "%s\n", devinfop);
578 usbd_devinfo_free(devinfop); 582 usbd_devinfo_free(devinfop);
579 583
580 un->un_dev = self; 584 un->un_dev = self;
581 un->un_udev = dev; 585 un->un_udev = dev;
582 un->un_sc = un; 586 un->un_sc = un;
583 un->un_ops = &mos_ops; 587 un->un_ops = &mos_ops;
584 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 588 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
585 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 589 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
586 un->un_rx_list_cnt = MOS_RX_LIST_CNT; 590 un->un_rx_list_cnt = MOS_RX_LIST_CNT;
587 un->un_tx_list_cnt = MOS_TX_LIST_CNT; 591 un->un_tx_list_cnt = MOS_TX_LIST_CNT;
588 un->un_rx_bufsz = un->un_tx_bufsz = MOS_BUFSZ; 592 un->un_rx_bufsz = un->un_tx_bufsz = MOS_BUFSZ;
589 593
590 err = usbd_set_config_no(dev, MOS_CONFIG_NO, 1); 594 err = usbd_set_config_no(dev, MOS_CONFIG_NO, 1);
591 if (err) { 595 if (err) {
592 aprint_error_dev(self, "failed to set configuration" 596 aprint_error_dev(self, "failed to set configuration"
593 ", err=%s\n", usbd_errstr(err)); 597 ", err=%s\n", usbd_errstr(err));
594 return; 598 return;
595 } 599 }
596 600
597 err = usbd_device2interface_handle(dev, MOS_IFACE_IDX, &un->un_iface); 601 err = usbd_device2interface_handle(dev, MOS_IFACE_IDX, &un->un_iface);
598 if (err) { 602 if (err) {
599 aprint_error_dev(self, "failed getting interface handle" 603 aprint_error_dev(self, "failed getting interface handle"
600 ", err=%s\n", usbd_errstr(err)); 604 ", err=%s\n", usbd_errstr(err));
601 return; 605 return;
602 } 606 }
603 607
604 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;
605 609
606 id = usbd_get_interface_descriptor(un->un_iface); 610 id = usbd_get_interface_descriptor(un->un_iface);
607 611
608 /* Find endpoints. */ 612 /* Find endpoints. */
609 for (i = 0; i < id->bNumEndpoints; i++) { 613 for (i = 0; i < id->bNumEndpoints; i++) {
610 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 614 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
611 if (!ed) { 615 if (!ed) {
612 aprint_error_dev(self, "couldn't get ep %d\n", i); 616 aprint_error_dev(self, "couldn't get ep %d\n", i);
613 return; 617 return;
614 } 618 }
615 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 619 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
616 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 620 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
617 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 621 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
618 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 622 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
619 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 623 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
620 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 624 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
621 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 625 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
622 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 626 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
623 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 627 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
624 } 628 }
625 } 629 }
626 630
627 if (un->un_flags & MCS7730) 631 if (un->un_flags & MCS7730)
628 aprint_normal_dev(self, "MCS7730\n"); 632 aprint_normal_dev(self, "MCS7730\n");
629 else if (un->un_flags & MCS7830) 633 else if (un->un_flags & MCS7830)
630 aprint_normal_dev(self, "MCS7830\n"); 634 aprint_normal_dev(self, "MCS7830\n");
631 else if (un->un_flags & MCS7832) 635 else if (un->un_flags & MCS7832)
632 aprint_normal_dev(self, "MCS7832\n"); 636 aprint_normal_dev(self, "MCS7832\n");
633 637
634 /* Set these up now for register access. */ 638 /* Set these up now for register access. */
635 usbnet_attach(un, "mosdet"); 639 usbnet_attach(un, "mosdet");
636 640
637 mos_chip_init(un); 641 mos_chip_init(un);
638 642
639 /* 643 /*
640 * Read MAC address, inform the world. 644 * Read MAC address, inform the world.
641 */ 645 */
642 err = mos_readmac(un); 646 err = mos_readmac(un);
643 if (err) { 647 if (err) {
644 aprint_error_dev(self, "couldn't read MAC address\n"); 648 aprint_error_dev(self, "couldn't read MAC address\n");
645 return; 649 return;
646 } 650 }
647 651
648 struct ifnet *ifp = usbnet_ifp(un); 652 struct ifnet *ifp = usbnet_ifp(un);
649 ifp->if_capabilities = ETHERCAP_VLAN_MTU; 653 ifp->if_capabilities = ETHERCAP_VLAN_MTU;
650 654
651 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 655 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
652 0, &unm); 656 0, &unm);
653} 657}
654 658
655/* 659/*
656 * 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
657 * the higher level protocols. 661 * the higher level protocols.
658 */ 662 */
659void 663void
660mos_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)
661{ 665{
662 struct ifnet *ifp = usbnet_ifp(un); 666 struct ifnet *ifp = usbnet_ifp(un);
663 uint8_t *buf = c->unc_buf; 667 uint8_t *buf = c->unc_buf;
664 u_int8_t rxstat; 668 u_int8_t rxstat;
665 u_int16_t pktlen = 0; 669 u_int16_t pktlen = 0;
666 670
667 DPRINTFN(5,("%s: %s: enter len %u\n", 671 DPRINTFN(5,("%s: %s: enter len %u\n",
668 device_xname(un->un_dev), __func__, total_len)); 672 device_xname(un->un_dev), __func__, total_len));
669 673
670 if (total_len <= 1) 674 if (total_len <= 1)
671 return; 675 return;
672 676
673 /* evaluate status byte at the end */ 677 /* evaluate status byte at the end */
674 pktlen = total_len - 1; 678 pktlen = total_len - 1;
675 if (pktlen > un->un_rx_bufsz) { 679 if (pktlen > un->un_rx_bufsz) {
676 if_statinc(ifp, if_ierrors); 680 if_statinc(ifp, if_ierrors);
677 return; 681 return;
678 } 682 }
679 rxstat = buf[pktlen] & MOS_RXSTS_MASK; 683 rxstat = buf[pktlen] & MOS_RXSTS_MASK;
680 684
681 if (rxstat != MOS_RXSTS_VALID) { 685 if (rxstat != MOS_RXSTS_VALID) {
682 DPRINTF(("%s: erroneous frame received: ", 686 DPRINTF(("%s: erroneous frame received: ",
683 device_xname(un->un_dev))); 687 device_xname(un->un_dev)));
684 if (rxstat & MOS_RXSTS_SHORT_FRAME) 688 if (rxstat & MOS_RXSTS_SHORT_FRAME)
685 DPRINTF(("frame size less than 64 bytes\n")); 689 DPRINTF(("frame size less than 64 bytes\n"));
686 if (rxstat & MOS_RXSTS_LARGE_FRAME) 690 if (rxstat & MOS_RXSTS_LARGE_FRAME)
687 DPRINTF(("frame size larger than 1532 bytes\n")); 691 DPRINTF(("frame size larger than 1532 bytes\n"));
688 if (rxstat & MOS_RXSTS_CRC_ERROR) 692 if (rxstat & MOS_RXSTS_CRC_ERROR)
689 DPRINTF(("CRC error\n")); 693 DPRINTF(("CRC error\n"));
690 if (rxstat & MOS_RXSTS_ALIGN_ERROR) 694 if (rxstat & MOS_RXSTS_ALIGN_ERROR)
691 DPRINTF(("alignment error\n")); 695 DPRINTF(("alignment error\n"));
692 if_statinc(ifp, if_ierrors); 696 if_statinc(ifp, if_ierrors);
693 return; 697 return;
694 } 698 }
695 699
696 if (pktlen < sizeof(struct ether_header) ) { 700 if (pktlen < sizeof(struct ether_header) ) {
697 if_statinc(ifp, if_ierrors); 701 if_statinc(ifp, if_ierrors);
698 return; 702 return;
699 } 703 }
700 704
701 usbnet_enqueue(un, c->unc_buf, pktlen, 0, 0, 0); 705 usbnet_enqueue(un, c->unc_buf, pktlen, 0, 0, 0);
702} 706}
703 707
704static unsigned 708static unsigned
705mos_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)
706{ 710{
707 int length; 711 int length;
708 712
709 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz) 713 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz)
710 return 0; 714 return 0;
711 715
712 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf); 716 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf);
713 length = m->m_pkthdr.len; 717 length = m->m_pkthdr.len;
714 718
715 DPRINTFN(5,("%s: %s: len %u\n", 719 DPRINTFN(5,("%s: %s: len %u\n",
716 device_xname(un->un_dev), __func__, length)); 720 device_xname(un->un_dev), __func__, length));
717 721
718 return length; 722 return length;
719} 723}
720 724
721static int 725static int
722mos_init_locked(struct ifnet *ifp) 726mos_init_locked(struct ifnet *ifp)
723{ 727{
724 struct usbnet * const un = ifp->if_softc; 728 struct usbnet * const un = ifp->if_softc;
725 u_int8_t rxmode; 729 u_int8_t rxmode;
726 unsigned char ipgs[2]; 730 unsigned char ipgs[2];
727 731
728 if (usbnet_isdying(un)) 732 if (usbnet_isdying(un))
729 return EIO; 733 return EIO;
730 734
731 /* Cancel pending I/O */ 735 /* Cancel pending I/O */
732 usbnet_stop(un, ifp, 1); 736 usbnet_stop(un, ifp, 1);
733 737
734 /* Reset the ethernet interface. */ 738 /* Reset the ethernet interface. */
735 mos_reset(un); 739 mos_reset(un);
736 740
737 /* Write MAC address. */ 741 /* Write MAC address. */
738 mos_writemac(un); 742 mos_writemac(un);
739 743
740 /* Read and set transmitter IPG values */ 744 /* Read and set transmitter IPG values */
741 ipgs[0] = mos_reg_read_1(un, MOS_IPG0); 745 ipgs[0] = mos_reg_read_1(un, MOS_IPG0);
742 ipgs[1] = mos_reg_read_1(un, MOS_IPG1); 746 ipgs[1] = mos_reg_read_1(un, MOS_IPG1);
743 mos_reg_write_1(un, MOS_IPG0, ipgs[0]); 747 mos_reg_write_1(un, MOS_IPG0, ipgs[0]);
744 mos_reg_write_1(un, MOS_IPG1, ipgs[1]); 748 mos_reg_write_1(un, MOS_IPG1, ipgs[1]);
745 749
746 /* Accept multicast frame or run promisc. mode */ 750 /* Accept multicast frame or run promisc. mode */
747 mos_rcvfilt_locked(un); 751 mos_rcvfilt_locked(un);
748 752
749 /* Enable receiver and transmitter, bridge controls speed/duplex mode */ 753 /* Enable receiver and transmitter, bridge controls speed/duplex mode */
750 rxmode = mos_reg_read_1(un, MOS_CTL); 754 rxmode = mos_reg_read_1(un, MOS_CTL);
751 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;
752 rxmode &= ~(MOS_CTL_SLEEP); 756 rxmode &= ~(MOS_CTL_SLEEP);
753 mos_reg_write_1(un, MOS_CTL, rxmode); 757 mos_reg_write_1(un, MOS_CTL, rxmode);
754 758
755 return usbnet_init_rx_tx(un); 759 return usbnet_init_rx_tx(un);
756} 760}
757 761
758static int 762static int
759mos_uno_init(struct ifnet *ifp) 763mos_uno_init(struct ifnet *ifp)
760{ 764{
761 struct usbnet * const un = ifp->if_softc; 765 struct usbnet * const un = ifp->if_softc;
762 766
763 usbnet_busy(un); 767 usbnet_busy(un);
764 int ret = mos_init_locked(ifp); 768 int ret = mos_init_locked(ifp);
765 usbnet_unbusy(un); 769 usbnet_unbusy(un);
766 770
767 return ret; 771 return ret;
768} 772}
769 773
770static int 774static int
771mos_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 775mos_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
772{ 776{
773 struct usbnet * const un = ifp->if_softc; 777 struct usbnet * const un = ifp->if_softc;
774 778
775 usbnet_lock_core(un); 779 usbnet_lock_core(un);
776 usbnet_busy(un); 780 usbnet_busy(un);
777 781
778 switch (cmd) { 782 switch (cmd) {
779 case SIOCADDMULTI: 783 case SIOCADDMULTI:
780 case SIOCDELMULTI: 784 case SIOCDELMULTI:
781 mos_rcvfilt_locked(un); 785 mos_rcvfilt_locked(un);
782 break; 786 break;
783 default: 787 default:
784 break; 788 break;
785 } 789 }
786 790
787 usbnet_unbusy(un); 791 usbnet_unbusy(un);
788 usbnet_unlock_core(un); 792 usbnet_unlock_core(un);
789 793
790 return 0; 794 return 0;
791} 795}
792 796
793void 797void
794mos_uno_stop(struct ifnet *ifp, int disable) 798mos_uno_stop(struct ifnet *ifp, int disable)
795{ 799{
796 struct usbnet * const un = ifp->if_softc; 800 struct usbnet * const un = ifp->if_softc;
797 801
798 mos_reset(un); 802 mos_reset(un);
799} 803}

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

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

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

--- src/sys/dev/usb/if_smsc.c 2022/03/03 05:50:22 1.72
+++ src/sys/dev/usb/if_smsc.c 2022/03/03 05:50:57 1.73
@@ -1,1091 +1,1093 @@ @@ -1,1091 +1,1093 @@
1/* $NetBSD: if_smsc.c,v 1.72 2022/03/03 05:50:22 riastradh Exp $ */ 1/* $NetBSD: if_smsc.c,v 1.73 2022/03/03 05:50:57 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.72 2022/03/03 05:50:22 riastradh Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.73 2022/03/03 05:50:57 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 unsigned smsc_uno_tx_prepare(struct usbnet *, struct mbuf *, 190static unsigned smsc_uno_tx_prepare(struct usbnet *, struct mbuf *,
191 struct usbnet_chain *); 191 struct usbnet_chain *);
192static void smsc_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 192static void smsc_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
193 uint32_t); 193 uint32_t);
194 194
195static const struct usbnet_ops smsc_ops = { 195static const struct usbnet_ops smsc_ops = {
196 .uno_stop = smsc_uno_stop, 196 .uno_stop = smsc_uno_stop,
197 .uno_ioctl = smsc_uno_ioctl, 197 .uno_ioctl = smsc_uno_ioctl,
198 .uno_read_reg = smsc_uno_miibus_readreg, 198 .uno_read_reg = smsc_uno_miibus_readreg,
199 .uno_write_reg = smsc_uno_miibus_writereg, 199 .uno_write_reg = smsc_uno_miibus_writereg,
200 .uno_statchg = smsc_uno_miibus_statchg, 200 .uno_statchg = smsc_uno_miibus_statchg,
201 .uno_tx_prepare = smsc_uno_tx_prepare, 201 .uno_tx_prepare = smsc_uno_tx_prepare,
202 .uno_rx_loop = smsc_uno_rx_loop, 202 .uno_rx_loop = smsc_uno_rx_loop,
203 .uno_init = smsc_uno_init, 203 .uno_init = smsc_uno_init,
204}; 204};
205 205
206static int 206static int
207smsc_readreg(struct usbnet *un, uint32_t off, uint32_t *data) 207smsc_readreg(struct usbnet *un, uint32_t off, uint32_t *data)
208{ 208{
209 usb_device_request_t req; 209 usb_device_request_t req;
210 uint32_t buf; 210 uint32_t buf;
211 usbd_status err; 211 usbd_status err;
212 212
213 usbnet_isowned_core(un); 213 usbnet_isowned_core(un);
214 214
215 if (usbnet_isdying(un)) 215 if (usbnet_isdying(un))
216 return 0; 216 return 0;
217 217
218 req.bmRequestType = UT_READ_VENDOR_DEVICE; 218 req.bmRequestType = UT_READ_VENDOR_DEVICE;
219 req.bRequest = SMSC_UR_READ_REG; 219 req.bRequest = SMSC_UR_READ_REG;
220 USETW(req.wValue, 0); 220 USETW(req.wValue, 0);
221 USETW(req.wIndex, off); 221 USETW(req.wIndex, off);
222 USETW(req.wLength, 4); 222 USETW(req.wLength, 4);
223 223
224 err = usbd_do_request(un->un_udev, &req, &buf); 224 err = usbd_do_request(un->un_udev, &req, &buf);
225 if (err != 0) 225 if (err != 0)
226 smsc_warn_printf(un, "Failed to read register 0x%0x\n", off); 226 smsc_warn_printf(un, "Failed to read register 0x%0x\n", off);
227 227
228 *data = le32toh(buf); 228 *data = le32toh(buf);
229 229
230 return err; 230 return err;
231} 231}
232 232
233static int 233static int
234smsc_writereg(struct usbnet *un, uint32_t off, uint32_t data) 234smsc_writereg(struct usbnet *un, uint32_t off, uint32_t data)
235{ 235{
236 usb_device_request_t req; 236 usb_device_request_t req;
237 uint32_t buf; 237 uint32_t buf;
238 usbd_status err; 238 usbd_status err;
239 239
240 usbnet_isowned_core(un); 240 usbnet_isowned_core(un);
241 241
242 if (usbnet_isdying(un)) 242 if (usbnet_isdying(un))
243 return 0; 243 return 0;
244 244
245 buf = htole32(data); 245 buf = htole32(data);
246 246
247 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 247 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
248 req.bRequest = SMSC_UR_WRITE_REG; 248 req.bRequest = SMSC_UR_WRITE_REG;
249 USETW(req.wValue, 0); 249 USETW(req.wValue, 0);
250 USETW(req.wIndex, off); 250 USETW(req.wIndex, off);
251 USETW(req.wLength, 4); 251 USETW(req.wLength, 4);
252 252
253 err = usbd_do_request(un->un_udev, &req, &buf); 253 err = usbd_do_request(un->un_udev, &req, &buf);
254 if (err != 0) 254 if (err != 0)
255 smsc_warn_printf(un, "Failed to write register 0x%0x\n", off); 255 smsc_warn_printf(un, "Failed to write register 0x%0x\n", off);
256 256
257 return err; 257 return err;
258} 258}
259 259
260static int 260static int
261smsc_wait_for_bits(struct usbnet *un, uint32_t reg, uint32_t bits) 261smsc_wait_for_bits(struct usbnet *un, uint32_t reg, uint32_t bits)
262{ 262{
263 uint32_t val; 263 uint32_t val;
264 int err, i; 264 int err, i;
265 265
266 for (i = 0; i < 100; i++) { 266 for (i = 0; i < 100; i++) {
 267 if (usbnet_isdying(un))
 268 return ENXIO;
267 if ((err = smsc_readreg(un, reg, &val)) != 0) 269 if ((err = smsc_readreg(un, reg, &val)) != 0)
268 return err; 270 return err;
269 if (!(val & bits)) 271 if (!(val & bits))
270 return 0; 272 return 0;
271 DELAY(5); 273 DELAY(5);
272 } 274 }
273 275
274 return 1; 276 return 1;
275} 277}
276 278
277static int 279static int
278smsc_uno_miibus_readreg(struct usbnet *un, int phy, int reg, uint16_t *val) 280smsc_uno_miibus_readreg(struct usbnet *un, int phy, int reg, uint16_t *val)
279{ 281{
280 uint32_t addr; 282 uint32_t addr;
281 uint32_t data = 0; 283 uint32_t data = 0;
282 284
283 if (un->un_phyno != phy) 285 if (un->un_phyno != phy)
284 return EINVAL; 286 return EINVAL;
285 287
286 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) { 288 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
287 smsc_warn_printf(un, "MII is busy\n"); 289 smsc_warn_printf(un, "MII is busy\n");
288 return ETIMEDOUT; 290 return ETIMEDOUT;
289 } 291 }
290 292
291 addr = (phy << 11) | (reg << 6) | SMSC_MII_READ; 293 addr = (phy << 11) | (reg << 6) | SMSC_MII_READ;
292 smsc_writereg(un, SMSC_MII_ADDR, addr); 294 smsc_writereg(un, SMSC_MII_ADDR, addr);
293 295
294 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) { 296 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
295 smsc_warn_printf(un, "MII read timeout\n"); 297 smsc_warn_printf(un, "MII read timeout\n");
296 return ETIMEDOUT; 298 return ETIMEDOUT;
297 } 299 }
298 300
299 smsc_readreg(un, SMSC_MII_DATA, &data); 301 smsc_readreg(un, SMSC_MII_DATA, &data);
300 302
301 *val = data & 0xffff; 303 *val = data & 0xffff;
302 return 0; 304 return 0;
303} 305}
304 306
305static int 307static int
306smsc_uno_miibus_writereg(struct usbnet *un, int phy, int reg, uint16_t val) 308smsc_uno_miibus_writereg(struct usbnet *un, int phy, int reg, uint16_t val)
307{ 309{
308 uint32_t addr; 310 uint32_t addr;
309 311
310 if (un->un_phyno != phy) 312 if (un->un_phyno != phy)
311 return EINVAL; 313 return EINVAL;
312 314
313 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) { 315 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
314 smsc_warn_printf(un, "MII is busy\n"); 316 smsc_warn_printf(un, "MII is busy\n");
315 return ETIMEDOUT; 317 return ETIMEDOUT;
316 } 318 }
317 319
318 smsc_writereg(un, SMSC_MII_DATA, val); 320 smsc_writereg(un, SMSC_MII_DATA, val);
319 321
320 addr = (phy << 11) | (reg << 6) | SMSC_MII_WRITE; 322 addr = (phy << 11) | (reg << 6) | SMSC_MII_WRITE;
321 smsc_writereg(un, SMSC_MII_ADDR, addr); 323 smsc_writereg(un, SMSC_MII_ADDR, addr);
322 324
323 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) { 325 if (smsc_wait_for_bits(un, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
324 smsc_warn_printf(un, "MII write timeout\n"); 326 smsc_warn_printf(un, "MII write timeout\n");
325 return ETIMEDOUT; 327 return ETIMEDOUT;
326 } 328 }
327 329
328 return 0; 330 return 0;
329} 331}
330 332
331static void 333static void
332smsc_uno_miibus_statchg(struct ifnet *ifp) 334smsc_uno_miibus_statchg(struct ifnet *ifp)
333{ 335{
334 USMSCHIST_FUNC(); USMSCHIST_CALLED(); 336 USMSCHIST_FUNC(); USMSCHIST_CALLED();
335 struct usbnet * const un = ifp->if_softc; 337 struct usbnet * const un = ifp->if_softc;
336 338
337 if (usbnet_isdying(un)) 339 if (usbnet_isdying(un))
338 return; 340 return;
339 341
340 struct smsc_softc * const sc = usbnet_softc(un); 342 struct smsc_softc * const sc = usbnet_softc(un);
341 struct mii_data * const mii = usbnet_mii(un); 343 struct mii_data * const mii = usbnet_mii(un);
342 uint32_t flow; 344 uint32_t flow;
343 uint32_t afc_cfg; 345 uint32_t afc_cfg;
344 346
345 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 347 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
346 (IFM_ACTIVE | IFM_AVALID)) { 348 (IFM_ACTIVE | IFM_AVALID)) {
347 switch (IFM_SUBTYPE(mii->mii_media_active)) { 349 switch (IFM_SUBTYPE(mii->mii_media_active)) {
348 case IFM_10_T: 350 case IFM_10_T:
349 case IFM_100_TX: 351 case IFM_100_TX:
350 usbnet_set_link(un, true); 352 usbnet_set_link(un, true);
351 break; 353 break;
352 case IFM_1000_T: 354 case IFM_1000_T:
353 /* Gigabit ethernet not supported by chipset */ 355 /* Gigabit ethernet not supported by chipset */
354 break; 356 break;
355 default: 357 default:
356 break; 358 break;
357 } 359 }
358 } 360 }
359 361
360 /* Lost link, do nothing. */ 362 /* Lost link, do nothing. */
361 if (!usbnet_havelink(un)) 363 if (!usbnet_havelink(un))
362 return; 364 return;
363 365
364 int err = smsc_readreg(un, SMSC_AFC_CFG, &afc_cfg); 366 int err = smsc_readreg(un, SMSC_AFC_CFG, &afc_cfg);
365 if (err) { 367 if (err) {
366 smsc_warn_printf(un, "failed to read initial AFC_CFG, " 368 smsc_warn_printf(un, "failed to read initial AFC_CFG, "
367 "error %d\n", err); 369 "error %d\n", err);
368 return; 370 return;
369 } 371 }
370 372
371 /* Enable/disable full duplex operation and TX/RX pause */ 373 /* Enable/disable full duplex operation and TX/RX pause */
372 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { 374 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
373 DPRINTF("full duplex operation", 0, 0, 0, 0); 375 DPRINTF("full duplex operation", 0, 0, 0, 0);
374 sc->sc_mac_csr &= ~SMSC_MAC_CSR_RCVOWN; 376 sc->sc_mac_csr &= ~SMSC_MAC_CSR_RCVOWN;
375 sc->sc_mac_csr |= SMSC_MAC_CSR_FDPX; 377 sc->sc_mac_csr |= SMSC_MAC_CSR_FDPX;
376 378
377 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) 379 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
378 flow = 0xffff0002; 380 flow = 0xffff0002;
379 else 381 else
380 flow = 0; 382 flow = 0;
381 383
382 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) 384 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
383 afc_cfg |= 0xf; 385 afc_cfg |= 0xf;
384 else 386 else
385 afc_cfg &= ~0xf; 387 afc_cfg &= ~0xf;
386 } else { 388 } else {
387 DPRINTF("half duplex operation", 0, 0, 0, 0); 389 DPRINTF("half duplex operation", 0, 0, 0, 0);
388 sc->sc_mac_csr &= ~SMSC_MAC_CSR_FDPX; 390 sc->sc_mac_csr &= ~SMSC_MAC_CSR_FDPX;
389 sc->sc_mac_csr |= SMSC_MAC_CSR_RCVOWN; 391 sc->sc_mac_csr |= SMSC_MAC_CSR_RCVOWN;
390 392
391 flow = 0; 393 flow = 0;
392 afc_cfg |= 0xf; 394 afc_cfg |= 0xf;
393 } 395 }
394 396
395 err = smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 397 err = smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
396 err += smsc_writereg(un, SMSC_FLOW, flow); 398 err += smsc_writereg(un, SMSC_FLOW, flow);
397 err += smsc_writereg(un, SMSC_AFC_CFG, afc_cfg); 399 err += smsc_writereg(un, SMSC_AFC_CFG, afc_cfg);
398 400
399 if (err) 401 if (err)
400 smsc_warn_printf(un, "media change failed, error %d\n", err); 402 smsc_warn_printf(un, "media change failed, error %d\n", err);
401} 403}
402 404
403static inline uint32_t 405static inline uint32_t
404smsc_hash(uint8_t addr[ETHER_ADDR_LEN]) 406smsc_hash(uint8_t addr[ETHER_ADDR_LEN])
405{ 407{
406 408
407 return (ether_crc32_be(addr, ETHER_ADDR_LEN) >> 26) & 0x3f; 409 return (ether_crc32_be(addr, ETHER_ADDR_LEN) >> 26) & 0x3f;
408} 410}
409 411
410static void 412static void
411smsc_setiff_locked(struct usbnet *un) 413smsc_setiff_locked(struct usbnet *un)
412{ 414{
413 USMSCHIST_FUNC(); USMSCHIST_CALLED(); 415 USMSCHIST_FUNC(); USMSCHIST_CALLED();
414 struct smsc_softc * const sc = usbnet_softc(un); 416 struct smsc_softc * const sc = usbnet_softc(un);
415 struct ifnet * const ifp = usbnet_ifp(un); 417 struct ifnet * const ifp = usbnet_ifp(un);
416 struct ethercom *ec = usbnet_ec(un); 418 struct ethercom *ec = usbnet_ec(un);
417 struct ether_multi *enm; 419 struct ether_multi *enm;
418 struct ether_multistep step; 420 struct ether_multistep step;
419 uint32_t hashtbl[2] = { 0, 0 }; 421 uint32_t hashtbl[2] = { 0, 0 };
420 uint32_t hash; 422 uint32_t hash;
421 423
422 usbnet_isowned_core(un); 424 usbnet_isowned_core(un);
423 425
424 if (usbnet_isdying(un)) 426 if (usbnet_isdying(un))
425 return; 427 return;
426 428
427 if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { 429 if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
428allmulti: 430allmulti:
429 DPRINTF("receive all multicast enabled", 0, 0, 0, 0); 431 DPRINTF("receive all multicast enabled", 0, 0, 0, 0);
430 sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS; 432 sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS;
431 sc->sc_mac_csr &= ~SMSC_MAC_CSR_HPFILT; 433 sc->sc_mac_csr &= ~SMSC_MAC_CSR_HPFILT;
432 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 434 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
433 return; 435 return;
434 } else { 436 } else {
435 sc->sc_mac_csr |= SMSC_MAC_CSR_HPFILT; 437 sc->sc_mac_csr |= SMSC_MAC_CSR_HPFILT;
436 sc->sc_mac_csr &= ~(SMSC_MAC_CSR_PRMS | SMSC_MAC_CSR_MCPAS); 438 sc->sc_mac_csr &= ~(SMSC_MAC_CSR_PRMS | SMSC_MAC_CSR_MCPAS);
437 } 439 }
438 440
439 ETHER_LOCK(ec); 441 ETHER_LOCK(ec);
440 ETHER_FIRST_MULTI(step, ec, enm); 442 ETHER_FIRST_MULTI(step, ec, enm);
441 while (enm != NULL) { 443 while (enm != NULL) {
442 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 444 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
443 ETHER_UNLOCK(ec); 445 ETHER_UNLOCK(ec);
444 goto allmulti; 446 goto allmulti;
445 } 447 }
446 448
447 hash = smsc_hash(enm->enm_addrlo); 449 hash = smsc_hash(enm->enm_addrlo);
448 hashtbl[hash >> 5] |= 1 << (hash & 0x1F); 450 hashtbl[hash >> 5] |= 1 << (hash & 0x1F);
449 ETHER_NEXT_MULTI(step, enm); 451 ETHER_NEXT_MULTI(step, enm);
450 } 452 }
451 ETHER_UNLOCK(ec); 453 ETHER_UNLOCK(ec);
452 454
453 /* Debug */ 455 /* Debug */
454 if (sc->sc_mac_csr & SMSC_MAC_CSR_HPFILT) { 456 if (sc->sc_mac_csr & SMSC_MAC_CSR_HPFILT) {
455 DPRINTF("receive select group of macs", 0, 0, 0, 0); 457 DPRINTF("receive select group of macs", 0, 0, 0, 0);
456 } else { 458 } else {
457 DPRINTF("receive own packets only", 0, 0, 0, 0); 459 DPRINTF("receive own packets only", 0, 0, 0, 0);
458 } 460 }
459 461
460 /* Write the hash table and mac control registers */ 462 /* Write the hash table and mac control registers */
461 463
462 //XXX should we be doing this? 464 //XXX should we be doing this?
463 ifp->if_flags &= ~IFF_ALLMULTI; 465 ifp->if_flags &= ~IFF_ALLMULTI;
464 smsc_writereg(un, SMSC_HASHH, hashtbl[1]); 466 smsc_writereg(un, SMSC_HASHH, hashtbl[1]);
465 smsc_writereg(un, SMSC_HASHL, hashtbl[0]); 467 smsc_writereg(un, SMSC_HASHL, hashtbl[0]);
466 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 468 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
467} 469}
468 470
469static int 471static int
470smsc_setoe_locked(struct usbnet *un) 472smsc_setoe_locked(struct usbnet *un)
471{ 473{
472 struct smsc_softc * const sc = usbnet_softc(un); 474 struct smsc_softc * const sc = usbnet_softc(un);
473 struct ifnet * const ifp = usbnet_ifp(un); 475 struct ifnet * const ifp = usbnet_ifp(un);
474 uint32_t val; 476 uint32_t val;
475 int err; 477 int err;
476 478
477 usbnet_isowned_core(un); 479 usbnet_isowned_core(un);
478 480
479 err = smsc_readreg(un, SMSC_COE_CTRL, &val); 481 err = smsc_readreg(un, SMSC_COE_CTRL, &val);
480 if (err != 0) { 482 if (err != 0) {
481 smsc_warn_printf(un, "failed to read SMSC_COE_CTRL (err=%d)\n", 483 smsc_warn_printf(un, "failed to read SMSC_COE_CTRL (err=%d)\n",
482 err); 484 err);
483 return err; 485 return err;
484 } 486 }
485 487
486 /* Enable/disable the Rx checksum */ 488 /* Enable/disable the Rx checksum */
487 if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) 489 if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx))
488 val |= (SMSC_COE_CTRL_RX_EN | SMSC_COE_CTRL_RX_MODE); 490 val |= (SMSC_COE_CTRL_RX_EN | SMSC_COE_CTRL_RX_MODE);
489 else 491 else
490 val &= ~(SMSC_COE_CTRL_RX_EN | SMSC_COE_CTRL_RX_MODE); 492 val &= ~(SMSC_COE_CTRL_RX_EN | SMSC_COE_CTRL_RX_MODE);
491 493
492 /* Enable/disable the Tx checksum (currently not supported) */ 494 /* Enable/disable the Tx checksum (currently not supported) */
493 if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx)) 495 if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx))
494 val |= SMSC_COE_CTRL_TX_EN; 496 val |= SMSC_COE_CTRL_TX_EN;
495 else 497 else
496 val &= ~SMSC_COE_CTRL_TX_EN; 498 val &= ~SMSC_COE_CTRL_TX_EN;
497 499
498 sc->sc_coe_ctrl = val; 500 sc->sc_coe_ctrl = val;
499 501
500 err = smsc_writereg(un, SMSC_COE_CTRL, val); 502 err = smsc_writereg(un, SMSC_COE_CTRL, val);
501 if (err != 0) { 503 if (err != 0) {
502 smsc_warn_printf(un, "failed to write SMSC_COE_CTRL (err=%d)\n", 504 smsc_warn_printf(un, "failed to write SMSC_COE_CTRL (err=%d)\n",
503 err); 505 err);
504 return err; 506 return err;
505 } 507 }
506 508
507 return 0; 509 return 0;
508} 510}
509 511
510static int 512static int
511smsc_setmacaddress(struct usbnet *un, const uint8_t *addr) 513smsc_setmacaddress(struct usbnet *un, const uint8_t *addr)
512{ 514{
513 USMSCHIST_FUNC(); USMSCHIST_CALLED(); 515 USMSCHIST_FUNC(); USMSCHIST_CALLED();
514 int err; 516 int err;
515 uint32_t val; 517 uint32_t val;
516 518
517 DPRINTF("setting mac address to %02jx:%02jx:%02jx:...", addr[0], 519 DPRINTF("setting mac address to %02jx:%02jx:%02jx:...", addr[0],
518 addr[1], addr[2], 0); 520 addr[1], addr[2], 0);
519 521
520 DPRINTF("... %02jx:%02jx:%02jx", addr[3], addr[4], addr[5], 0); 522 DPRINTF("... %02jx:%02jx:%02jx", addr[3], addr[4], addr[5], 0);
521 523
522 val = ((uint32_t)addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) 524 val = ((uint32_t)addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8)
523 | addr[0]; 525 | addr[0];
524 if ((err = smsc_writereg(un, SMSC_MAC_ADDRL, val)) != 0) 526 if ((err = smsc_writereg(un, SMSC_MAC_ADDRL, val)) != 0)
525 goto done; 527 goto done;
526 528
527 val = (addr[5] << 8) | addr[4]; 529 val = (addr[5] << 8) | addr[4];
528 err = smsc_writereg(un, SMSC_MAC_ADDRH, val); 530 err = smsc_writereg(un, SMSC_MAC_ADDRH, val);
529 531
530done: 532done:
531 return err; 533 return err;
532} 534}
533 535
534static void 536static void
535smsc_reset(struct smsc_softc *sc) 537smsc_reset(struct smsc_softc *sc)
536{ 538{
537 struct usbnet * const un = &sc->smsc_un; 539 struct usbnet * const un = &sc->smsc_un;
538 540
539 usbnet_isowned_core(un); 541 usbnet_isowned_core(un);
540 if (usbnet_isdying(un)) 542 if (usbnet_isdying(un))
541 return; 543 return;
542 544
543 /* Wait a little while for the chip to get its brains in order. */ 545 /* Wait a little while for the chip to get its brains in order. */
544 DELAY(1000); 546 DELAY(1000);
545 547
546 /* Reinitialize controller to achieve full reset. */ 548 /* Reinitialize controller to achieve full reset. */
547 smsc_chip_init(un); 549 smsc_chip_init(un);
548} 550}
549 551
550static int 552static int
551smsc_uno_init(struct ifnet *ifp) 553smsc_uno_init(struct ifnet *ifp)
552{ 554{
553 struct usbnet * const un = ifp->if_softc; 555 struct usbnet * const un = ifp->if_softc;
554 556
555 usbnet_busy(un); 557 usbnet_busy(un);
556 int ret = smsc_init_locked(ifp); 558 int ret = smsc_init_locked(ifp);
557 usbnet_unbusy(un); 559 usbnet_unbusy(un);
558 560
559 return ret; 561 return ret;
560} 562}
561 563
562static int 564static int
563smsc_init_locked(struct ifnet *ifp) 565smsc_init_locked(struct ifnet *ifp)
564{ 566{
565 struct usbnet * const un = ifp->if_softc; 567 struct usbnet * const un = ifp->if_softc;
566 struct smsc_softc * const sc = usbnet_softc(un); 568 struct smsc_softc * const sc = usbnet_softc(un);
567 569
568 usbnet_isowned_core(un); 570 usbnet_isowned_core(un);
569 571
570 if (usbnet_isdying(un)) 572 if (usbnet_isdying(un))
571 return EIO; 573 return EIO;
572 574
573 /* Cancel pending I/O */ 575 /* Cancel pending I/O */
574 usbnet_stop(un, ifp, 1); 576 usbnet_stop(un, ifp, 1);
575 577
576 /* Reset the ethernet interface. */ 578 /* Reset the ethernet interface. */
577 smsc_reset(sc); 579 smsc_reset(sc);
578 580
579 /* Load the multicast filter. */ 581 /* Load the multicast filter. */
580 smsc_setiff_locked(un); 582 smsc_setiff_locked(un);
581 583
582 /* TCP/UDP checksum offload engines. */ 584 /* TCP/UDP checksum offload engines. */
583 smsc_setoe_locked(un); 585 smsc_setoe_locked(un);
584 586
585 return usbnet_init_rx_tx(un); 587 return usbnet_init_rx_tx(un);
586} 588}
587 589
588static void 590static void
589smsc_uno_stop(struct ifnet *ifp, int disable) 591smsc_uno_stop(struct ifnet *ifp, int disable)
590{ 592{
591 struct usbnet * const un = ifp->if_softc; 593 struct usbnet * const un = ifp->if_softc;
592 struct smsc_softc * const sc = usbnet_softc(un); 594 struct smsc_softc * const sc = usbnet_softc(un);
593 595
594 // XXXNH didn't do this before 596 // XXXNH didn't do this before
595 smsc_reset(sc); 597 smsc_reset(sc);
596} 598}
597 599
598static int 600static int
599smsc_chip_init(struct usbnet *un) 601smsc_chip_init(struct usbnet *un)
600{ 602{
601 struct smsc_softc * const sc = usbnet_softc(un); 603 struct smsc_softc * const sc = usbnet_softc(un);
602 uint32_t reg_val; 604 uint32_t reg_val;
603 int burst_cap; 605 int burst_cap;
604 int err; 606 int err;
605 607
606 usbnet_isowned_core(un); 608 usbnet_isowned_core(un);
607 609
608 /* Enter H/W config mode */ 610 /* Enter H/W config mode */
609 smsc_writereg(un, SMSC_HW_CFG, SMSC_HW_CFG_LRST); 611 smsc_writereg(un, SMSC_HW_CFG, SMSC_HW_CFG_LRST);
610 612
611 if ((err = smsc_wait_for_bits(un, SMSC_HW_CFG, 613 if ((err = smsc_wait_for_bits(un, SMSC_HW_CFG,
612 SMSC_HW_CFG_LRST)) != 0) { 614 SMSC_HW_CFG_LRST)) != 0) {
613 smsc_warn_printf(un, "timed-out waiting for reset to " 615 smsc_warn_printf(un, "timed-out waiting for reset to "
614 "complete\n"); 616 "complete\n");
615 goto init_failed; 617 goto init_failed;
616 } 618 }
617 619
618 /* Reset the PHY */ 620 /* Reset the PHY */
619 smsc_writereg(un, SMSC_PM_CTRL, SMSC_PM_CTRL_PHY_RST); 621 smsc_writereg(un, SMSC_PM_CTRL, SMSC_PM_CTRL_PHY_RST);
620 622
621 if ((err = smsc_wait_for_bits(un, SMSC_PM_CTRL, 623 if ((err = smsc_wait_for_bits(un, SMSC_PM_CTRL,
622 SMSC_PM_CTRL_PHY_RST)) != 0) { 624 SMSC_PM_CTRL_PHY_RST)) != 0) {
623 smsc_warn_printf(un, "timed-out waiting for phy reset to " 625 smsc_warn_printf(un, "timed-out waiting for phy reset to "
624 "complete\n"); 626 "complete\n");
625 goto init_failed; 627 goto init_failed;
626 } 628 }
627 usbd_delay_ms(un->un_udev, 40); 629 usbd_delay_ms(un->un_udev, 40);
628 630
629 /* Set the mac address */ 631 /* Set the mac address */
630 struct ifnet * const ifp = usbnet_ifp(un); 632 struct ifnet * const ifp = usbnet_ifp(un);
631 const char *eaddr = CLLADDR(ifp->if_sadl); 633 const char *eaddr = CLLADDR(ifp->if_sadl);
632 if ((err = smsc_setmacaddress(un, eaddr)) != 0) { 634 if ((err = smsc_setmacaddress(un, eaddr)) != 0) {
633 smsc_warn_printf(un, "failed to set the MAC address\n"); 635 smsc_warn_printf(un, "failed to set the MAC address\n");
634 goto init_failed; 636 goto init_failed;
635 } 637 }
636 638
637 /* 639 /*
638 * Don't know what the HW_CFG_BIR bit is, but following the reset 640 * Don't know what the HW_CFG_BIR bit is, but following the reset
639 * sequence as used in the Linux driver. 641 * sequence as used in the Linux driver.
640 */ 642 */
641 if ((err = smsc_readreg(un, SMSC_HW_CFG, &reg_val)) != 0) { 643 if ((err = smsc_readreg(un, SMSC_HW_CFG, &reg_val)) != 0) {
642 smsc_warn_printf(un, "failed to read HW_CFG: %d\n", err); 644 smsc_warn_printf(un, "failed to read HW_CFG: %d\n", err);
643 goto init_failed; 645 goto init_failed;
644 } 646 }
645 reg_val |= SMSC_HW_CFG_BIR; 647 reg_val |= SMSC_HW_CFG_BIR;
646 smsc_writereg(un, SMSC_HW_CFG, reg_val); 648 smsc_writereg(un, SMSC_HW_CFG, reg_val);
647 649
648 /* 650 /*
649 * There is a so called 'turbo mode' that the linux driver supports, it 651 * 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. 652 * seems to allow you to jam multiple frames per Rx transaction.
651 * By default this driver supports that and therefore allows multiple 653 * By default this driver supports that and therefore allows multiple
652 * frames per USB transfer. 654 * frames per USB transfer.
653 * 655 *
654 * The xfer buffer size needs to reflect this as well, therefore based 656 * 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 657 * on the calculations in the Linux driver the RX bufsize is set to
656 * 18944, 658 * 18944,
657 * bufsz = (16 * 1024 + 5 * 512) 659 * bufsz = (16 * 1024 + 5 * 512)
658 * 660 *
659 * Burst capability is the number of URBs that can be in a burst of 661 * Burst capability is the number of URBs that can be in a burst of
660 * data/ethernet frames. 662 * data/ethernet frames.
661 */ 663 */
662 664
663 if (un->un_udev->ud_speed == USB_SPEED_HIGH) 665 if (un->un_udev->ud_speed == USB_SPEED_HIGH)
664 burst_cap = 37; 666 burst_cap = 37;
665 else 667 else
666 burst_cap = 128; 668 burst_cap = 128;
667 669
668 smsc_writereg(un, SMSC_BURST_CAP, burst_cap); 670 smsc_writereg(un, SMSC_BURST_CAP, burst_cap);
669 671
670 /* Set the default bulk in delay (magic value from Linux driver) */ 672 /* Set the default bulk in delay (magic value from Linux driver) */
671 smsc_writereg(un, SMSC_BULK_IN_DLY, 0x00002000); 673 smsc_writereg(un, SMSC_BULK_IN_DLY, 0x00002000);
672 674
673 /* 675 /*
674 * Initialise the RX interface 676 * Initialise the RX interface
675 */ 677 */
676 if ((err = smsc_readreg(un, SMSC_HW_CFG, &reg_val)) < 0) { 678 if ((err = smsc_readreg(un, SMSC_HW_CFG, &reg_val)) < 0) {
677 smsc_warn_printf(un, "failed to read HW_CFG: (err = %d)\n", 679 smsc_warn_printf(un, "failed to read HW_CFG: (err = %d)\n",
678 err); 680 err);
679 goto init_failed; 681 goto init_failed;
680 } 682 }
681 683
682 /* 684 /*
683 * The following settings are used for 'turbo mode', a.k.a multiple 685 * The following settings are used for 'turbo mode', a.k.a multiple
684 * frames per Rx transaction (again info taken form Linux driver). 686 * frames per Rx transaction (again info taken form Linux driver).
685 */ 687 */
686 reg_val |= (SMSC_HW_CFG_MEF | SMSC_HW_CFG_BCE); 688 reg_val |= (SMSC_HW_CFG_MEF | SMSC_HW_CFG_BCE);
687 689
688 /* 690 /*
689 * set Rx data offset to ETHER_ALIGN which will make the IP header 691 * set Rx data offset to ETHER_ALIGN which will make the IP header
690 * align on a word boundary. 692 * align on a word boundary.
691 */ 693 */
692 reg_val |= ETHER_ALIGN << SMSC_HW_CFG_RXDOFF_SHIFT; 694 reg_val |= ETHER_ALIGN << SMSC_HW_CFG_RXDOFF_SHIFT;
693 695
694 smsc_writereg(un, SMSC_HW_CFG, reg_val); 696 smsc_writereg(un, SMSC_HW_CFG, reg_val);
695 697
696 /* Clear the status register ? */ 698 /* Clear the status register ? */
697 smsc_writereg(un, SMSC_INTR_STATUS, 0xffffffff); 699 smsc_writereg(un, SMSC_INTR_STATUS, 0xffffffff);
698 700
699 /* Read and display the revision register */ 701 /* Read and display the revision register */
700 if ((err = smsc_readreg(un, SMSC_ID_REV, &sc->sc_rev_id)) < 0) { 702 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); 703 smsc_warn_printf(un, "failed to read ID_REV (err = %d)\n", err);
702 goto init_failed; 704 goto init_failed;
703 } 705 }
704 706
705 /* GPIO/LED setup */ 707 /* GPIO/LED setup */
706 reg_val = SMSC_LED_GPIO_CFG_SPD_LED | SMSC_LED_GPIO_CFG_LNK_LED | 708 reg_val = SMSC_LED_GPIO_CFG_SPD_LED | SMSC_LED_GPIO_CFG_LNK_LED |
707 SMSC_LED_GPIO_CFG_FDX_LED; 709 SMSC_LED_GPIO_CFG_FDX_LED;
708 smsc_writereg(un, SMSC_LED_GPIO_CFG, reg_val); 710 smsc_writereg(un, SMSC_LED_GPIO_CFG, reg_val);
709 711
710 /* 712 /*
711 * Initialise the TX interface 713 * Initialise the TX interface
712 */ 714 */
713 smsc_writereg(un, SMSC_FLOW, 0); 715 smsc_writereg(un, SMSC_FLOW, 0);
714 716
715 smsc_writereg(un, SMSC_AFC_CFG, AFC_CFG_DEFAULT); 717 smsc_writereg(un, SMSC_AFC_CFG, AFC_CFG_DEFAULT);
716 718
717 /* Read the current MAC configuration */ 719 /* Read the current MAC configuration */
718 if ((err = smsc_readreg(un, SMSC_MAC_CSR, &sc->sc_mac_csr)) < 0) { 720 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); 721 smsc_warn_printf(un, "failed to read MAC_CSR (err=%d)\n", err);
720 goto init_failed; 722 goto init_failed;
721 } 723 }
722 724
723 /* disable pad stripping, collides with checksum offload */ 725 /* disable pad stripping, collides with checksum offload */
724 sc->sc_mac_csr &= ~SMSC_MAC_CSR_PADSTR; 726 sc->sc_mac_csr &= ~SMSC_MAC_CSR_PADSTR;
725 727
726 /* Vlan */ 728 /* Vlan */
727 smsc_writereg(un, SMSC_VLAN1, (uint32_t)ETHERTYPE_VLAN); 729 smsc_writereg(un, SMSC_VLAN1, (uint32_t)ETHERTYPE_VLAN);
728 730
729 /* 731 /*
730 * Start TX 732 * Start TX
731 */ 733 */
732 sc->sc_mac_csr |= SMSC_MAC_CSR_TXEN; 734 sc->sc_mac_csr |= SMSC_MAC_CSR_TXEN;
733 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 735 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
734 smsc_writereg(un, SMSC_TX_CFG, SMSC_TX_CFG_ON); 736 smsc_writereg(un, SMSC_TX_CFG, SMSC_TX_CFG_ON);
735 737
736 /* 738 /*
737 * Start RX 739 * Start RX
738 */ 740 */
739 sc->sc_mac_csr |= SMSC_MAC_CSR_RXEN; 741 sc->sc_mac_csr |= SMSC_MAC_CSR_RXEN;
740 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); 742 smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
741 743
742 return 0; 744 return 0;
743 745
744init_failed: 746init_failed:
745 smsc_err_printf(un, "smsc_chip_init failed (err=%d)\n", err); 747 smsc_err_printf(un, "smsc_chip_init failed (err=%d)\n", err);
746 return err; 748 return err;
747} 749}
748 750
749static int 751static int
750smsc_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 752smsc_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
751{ 753{
752 struct usbnet * const un = ifp->if_softc; 754 struct usbnet * const un = ifp->if_softc;
753 755
754 usbnet_lock_core(un); 756 usbnet_lock_core(un);
755 usbnet_busy(un); 757 usbnet_busy(un);
756 758
757 switch (cmd) { 759 switch (cmd) {
758 case SIOCADDMULTI: 760 case SIOCADDMULTI:
759 case SIOCDELMULTI: 761 case SIOCDELMULTI:
760 smsc_setiff_locked(un); 762 smsc_setiff_locked(un);
761 break; 763 break;
762 case SIOCSIFCAP: 764 case SIOCSIFCAP:
763 smsc_setoe_locked(un); 765 smsc_setoe_locked(un);
764 break; 766 break;
765 default: 767 default:
766 break; 768 break;
767 } 769 }
768 770
769 usbnet_unbusy(un); 771 usbnet_unbusy(un);
770 usbnet_unlock_core(un); 772 usbnet_unlock_core(un);
771 773
772 return 0; 774 return 0;
773} 775}
774 776
775static int 777static int
776smsc_match(device_t parent, cfdata_t match, void *aux) 778smsc_match(device_t parent, cfdata_t match, void *aux)
777{ 779{
778 struct usb_attach_arg *uaa = aux; 780 struct usb_attach_arg *uaa = aux;
779 781
780 return (usb_lookup(smsc_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ? 782 return (usb_lookup(smsc_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ?
781 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 783 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
782} 784}
783 785
784static void 786static void
785smsc_attach(device_t parent, device_t self, void *aux) 787smsc_attach(device_t parent, device_t self, void *aux)
786{ 788{
787 USBNET_MII_DECL_DEFAULT(unm); 789 USBNET_MII_DECL_DEFAULT(unm);
788 struct smsc_softc * const sc = device_private(self); 790 struct smsc_softc * const sc = device_private(self);
789 struct usbnet * const un = &sc->smsc_un; 791 struct usbnet * const un = &sc->smsc_un;
790 struct usb_attach_arg *uaa = aux; 792 struct usb_attach_arg *uaa = aux;
791 struct usbd_device *dev = uaa->uaa_device; 793 struct usbd_device *dev = uaa->uaa_device;
792 usb_interface_descriptor_t *id; 794 usb_interface_descriptor_t *id;
793 usb_endpoint_descriptor_t *ed; 795 usb_endpoint_descriptor_t *ed;
794 char *devinfop; 796 char *devinfop;
795 unsigned bufsz; 797 unsigned bufsz;
796 int err, i; 798 int err, i;
797 uint32_t mac_h, mac_l; 799 uint32_t mac_h, mac_l;
798 800
799 KASSERT((void *)sc == un); 801 KASSERT((void *)sc == un);
800 802
801 aprint_naive("\n"); 803 aprint_naive("\n");
802 aprint_normal("\n"); 804 aprint_normal("\n");
803 805
804 un->un_dev = self; 806 un->un_dev = self;
805 un->un_udev = dev; 807 un->un_udev = dev;
806 un->un_sc = sc; 808 un->un_sc = sc;
807 un->un_ops = &smsc_ops; 809 un->un_ops = &smsc_ops;
808 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 810 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
809 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 811 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
810 un->un_rx_list_cnt = SMSC_RX_LIST_CNT; 812 un->un_rx_list_cnt = SMSC_RX_LIST_CNT;
811 un->un_tx_list_cnt = SMSC_TX_LIST_CNT; 813 un->un_tx_list_cnt = SMSC_TX_LIST_CNT;
812 814
813 devinfop = usbd_devinfo_alloc(un->un_udev, 0); 815 devinfop = usbd_devinfo_alloc(un->un_udev, 0);
814 aprint_normal_dev(self, "%s\n", devinfop); 816 aprint_normal_dev(self, "%s\n", devinfop);
815 usbd_devinfo_free(devinfop); 817 usbd_devinfo_free(devinfop);
816 818
817 err = usbd_set_config_no(dev, SMSC_CONFIG_INDEX, 1); 819 err = usbd_set_config_no(dev, SMSC_CONFIG_INDEX, 1);
818 if (err) { 820 if (err) {
819 aprint_error_dev(self, "failed to set configuration" 821 aprint_error_dev(self, "failed to set configuration"
820 ", err=%s\n", usbd_errstr(err)); 822 ", err=%s\n", usbd_errstr(err));
821 return; 823 return;
822 } 824 }
823 825
824 /* Setup the endpoints for the SMSC LAN95xx device(s) */ 826 /* Setup the endpoints for the SMSC LAN95xx device(s) */
825 err = usbd_device2interface_handle(dev, SMSC_IFACE_IDX, &un->un_iface); 827 err = usbd_device2interface_handle(dev, SMSC_IFACE_IDX, &un->un_iface);
826 if (err) { 828 if (err) {
827 aprint_error_dev(self, "getting interface handle failed\n"); 829 aprint_error_dev(self, "getting interface handle failed\n");
828 return; 830 return;
829 } 831 }
830 832
831 id = usbd_get_interface_descriptor(un->un_iface); 833 id = usbd_get_interface_descriptor(un->un_iface);
832 834
833 if (dev->ud_speed >= USB_SPEED_HIGH) { 835 if (dev->ud_speed >= USB_SPEED_HIGH) {
834 bufsz = SMSC_MAX_BUFSZ; 836 bufsz = SMSC_MAX_BUFSZ;
835 } else { 837 } else {
836 bufsz = SMSC_MIN_BUFSZ; 838 bufsz = SMSC_MIN_BUFSZ;
837 } 839 }
838 un->un_rx_bufsz = bufsz; 840 un->un_rx_bufsz = bufsz;
839 un->un_tx_bufsz = bufsz; 841 un->un_tx_bufsz = bufsz;
840 842
841 /* Find endpoints. */ 843 /* Find endpoints. */
842 for (i = 0; i < id->bNumEndpoints; i++) { 844 for (i = 0; i < id->bNumEndpoints; i++) {
843 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 845 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
844 if (!ed) { 846 if (!ed) {
845 aprint_error_dev(self, "couldn't get ep %d\n", i); 847 aprint_error_dev(self, "couldn't get ep %d\n", i);
846 return; 848 return;
847 } 849 }
848 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 850 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
849 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 851 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
850 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 852 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
851 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 853 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
852 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 854 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
853 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 855 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
854#if 0 /* not used yet */ 856#if 0 /* not used yet */
855 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 857 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
856 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 858 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
857 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 859 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
858#endif 860#endif
859 } 861 }
860 } 862 }
861 863
862 usbnet_attach(un, "smscdet"); 864 usbnet_attach(un, "smscdet");
863 865
864#ifdef notyet 866#ifdef notyet
865 /* 867 /*
866 * We can do TCPv4, and UDPv4 checksums in hardware. 868 * We can do TCPv4, and UDPv4 checksums in hardware.
867 */ 869 */
868 struct ifnet *ifp = usbnet_ifp(un); 870 struct ifnet *ifp = usbnet_ifp(un);
869 871
870 ifp->if_capabilities |= 872 ifp->if_capabilities |=
871 /*IFCAP_CSUM_TCPv4_Tx |*/ IFCAP_CSUM_TCPv4_Rx | 873 /*IFCAP_CSUM_TCPv4_Tx |*/ IFCAP_CSUM_TCPv4_Rx |
872 /*IFCAP_CSUM_UDPv4_Tx |*/ IFCAP_CSUM_UDPv4_Rx; 874 /*IFCAP_CSUM_UDPv4_Tx |*/ IFCAP_CSUM_UDPv4_Rx;
873#endif 875#endif
874 struct ethercom *ec = usbnet_ec(un); 876 struct ethercom *ec = usbnet_ec(un);
875 ec->ec_capabilities = ETHERCAP_VLAN_MTU; 877 ec->ec_capabilities = ETHERCAP_VLAN_MTU;
876 878
877 /* Setup some of the basics */ 879 /* Setup some of the basics */
878 un->un_phyno = 1; 880 un->un_phyno = 1;
879 881
880 usbnet_lock_core(un); 882 usbnet_lock_core(un);
881 usbnet_busy(un); 883 usbnet_busy(un);
882 /* 884 /*
883 * Attempt to get the mac address, if an EEPROM is not attached this 885 * Attempt to get the mac address, if an EEPROM is not attached this
884 * will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC 886 * will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC
885 * address based on urandom. 887 * address based on urandom.
886 */ 888 */
887 memset(un->un_eaddr, 0xff, ETHER_ADDR_LEN); 889 memset(un->un_eaddr, 0xff, ETHER_ADDR_LEN);
888 890
889 prop_dictionary_t dict = device_properties(self); 891 prop_dictionary_t dict = device_properties(self);
890 prop_data_t eaprop = prop_dictionary_get(dict, "mac-address"); 892 prop_data_t eaprop = prop_dictionary_get(dict, "mac-address");
891 893
892 if (eaprop != NULL) { 894 if (eaprop != NULL) {
893 KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA); 895 KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA);
894 KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN); 896 KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN);
895 memcpy(un->un_eaddr, prop_data_value(eaprop), 897 memcpy(un->un_eaddr, prop_data_value(eaprop),
896 ETHER_ADDR_LEN); 898 ETHER_ADDR_LEN);
897 } else { 899 } else {
898 /* Check if there is already a MAC address in the register */ 900 /* Check if there is already a MAC address in the register */
899 if ((smsc_readreg(un, SMSC_MAC_ADDRL, &mac_l) == 0) && 901 if ((smsc_readreg(un, SMSC_MAC_ADDRL, &mac_l) == 0) &&
900 (smsc_readreg(un, SMSC_MAC_ADDRH, &mac_h) == 0)) { 902 (smsc_readreg(un, SMSC_MAC_ADDRH, &mac_h) == 0)) {
901 un->un_eaddr[5] = (uint8_t)((mac_h >> 8) & 0xff); 903 un->un_eaddr[5] = (uint8_t)((mac_h >> 8) & 0xff);
902 un->un_eaddr[4] = (uint8_t)((mac_h) & 0xff); 904 un->un_eaddr[4] = (uint8_t)((mac_h) & 0xff);
903 un->un_eaddr[3] = (uint8_t)((mac_l >> 24) & 0xff); 905 un->un_eaddr[3] = (uint8_t)((mac_l >> 24) & 0xff);
904 un->un_eaddr[2] = (uint8_t)((mac_l >> 16) & 0xff); 906 un->un_eaddr[2] = (uint8_t)((mac_l >> 16) & 0xff);
905 un->un_eaddr[1] = (uint8_t)((mac_l >> 8) & 0xff); 907 un->un_eaddr[1] = (uint8_t)((mac_l >> 8) & 0xff);
906 un->un_eaddr[0] = (uint8_t)((mac_l) & 0xff); 908 un->un_eaddr[0] = (uint8_t)((mac_l) & 0xff);
907 } 909 }
908 } 910 }
909 usbnet_unbusy(un); 911 usbnet_unbusy(un);
910 usbnet_unlock_core(un); 912 usbnet_unlock_core(un);
911 913
912 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 914 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
913 0, &unm); 915 0, &unm);
914} 916}
915 917
916static void 918static void
917smsc_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 919smsc_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
918{ 920{
919 USMSCHIST_FUNC(); USMSCHIST_CALLED(); 921 USMSCHIST_FUNC(); USMSCHIST_CALLED();
920 struct smsc_softc * const sc = usbnet_softc(un); 922 struct smsc_softc * const sc = usbnet_softc(un);
921 struct ifnet *ifp = usbnet_ifp(un); 923 struct ifnet *ifp = usbnet_ifp(un);
922 uint8_t *buf = c->unc_buf; 924 uint8_t *buf = c->unc_buf;
923 int count; 925 int count;
924 926
925 count = 0; 927 count = 0;
926 DPRINTF("total_len %jd/%#jx", total_len, total_len, 0, 0); 928 DPRINTF("total_len %jd/%#jx", total_len, total_len, 0, 0);
927 while (total_len != 0) { 929 while (total_len != 0) {
928 uint32_t rxhdr; 930 uint32_t rxhdr;
929 if (total_len < sizeof(rxhdr)) { 931 if (total_len < sizeof(rxhdr)) {
930 DPRINTF("total_len %jd < sizeof(rxhdr) %jd", 932 DPRINTF("total_len %jd < sizeof(rxhdr) %jd",
931 total_len, sizeof(rxhdr), 0, 0); 933 total_len, sizeof(rxhdr), 0, 0);
932 if_statinc(ifp, if_ierrors); 934 if_statinc(ifp, if_ierrors);
933 return; 935 return;
934 } 936 }
935 937
936 memcpy(&rxhdr, buf, sizeof(rxhdr)); 938 memcpy(&rxhdr, buf, sizeof(rxhdr));
937 rxhdr = le32toh(rxhdr); 939 rxhdr = le32toh(rxhdr);
938 buf += sizeof(rxhdr); 940 buf += sizeof(rxhdr);
939 total_len -= sizeof(rxhdr); 941 total_len -= sizeof(rxhdr);
940 942
941 if (rxhdr & SMSC_RX_STAT_COLLISION) 943 if (rxhdr & SMSC_RX_STAT_COLLISION)
942 if_statinc(ifp, if_collisions); 944 if_statinc(ifp, if_collisions);
943 945
944 if (rxhdr & (SMSC_RX_STAT_ERROR 946 if (rxhdr & (SMSC_RX_STAT_ERROR
945 | SMSC_RX_STAT_LENGTH_ERROR 947 | SMSC_RX_STAT_LENGTH_ERROR
946 | SMSC_RX_STAT_MII_ERROR)) { 948 | SMSC_RX_STAT_MII_ERROR)) {
947 DPRINTF("rx error (hdr 0x%08jx)", rxhdr, 0, 0, 0); 949 DPRINTF("rx error (hdr 0x%08jx)", rxhdr, 0, 0, 0);
948 if_statinc(ifp, if_ierrors); 950 if_statinc(ifp, if_ierrors);
949 return; 951 return;
950 } 952 }
951 953
952 uint16_t pktlen = (uint16_t)SMSC_RX_STAT_FRM_LENGTH(rxhdr); 954 uint16_t pktlen = (uint16_t)SMSC_RX_STAT_FRM_LENGTH(rxhdr);
953 DPRINTF("total_len %jd pktlen %jd rxhdr 0x%08jx", total_len, 955 DPRINTF("total_len %jd pktlen %jd rxhdr 0x%08jx", total_len,
954 pktlen, rxhdr, 0); 956 pktlen, rxhdr, 0);
955 957
956 if (pktlen < ETHER_HDR_LEN) { 958 if (pktlen < ETHER_HDR_LEN) {
957 DPRINTF("pktlen %jd < ETHER_HDR_LEN %jd", pktlen, 959 DPRINTF("pktlen %jd < ETHER_HDR_LEN %jd", pktlen,
958 ETHER_HDR_LEN, 0, 0); 960 ETHER_HDR_LEN, 0, 0);
959 if_statinc(ifp, if_ierrors); 961 if_statinc(ifp, if_ierrors);
960 return; 962 return;
961 } 963 }
962 964
963 pktlen += ETHER_ALIGN; 965 pktlen += ETHER_ALIGN;
964 966
965 if (pktlen > MCLBYTES) { 967 if (pktlen > MCLBYTES) {
966 DPRINTF("pktlen %jd > MCLBYTES %jd", pktlen, MCLBYTES, 0, 968 DPRINTF("pktlen %jd > MCLBYTES %jd", pktlen, MCLBYTES, 0,
967 0); 969 0);
968 if_statinc(ifp, if_ierrors); 970 if_statinc(ifp, if_ierrors);
969 return; 971 return;
970 } 972 }
971 973
972 if (pktlen > total_len) { 974 if (pktlen > total_len) {
973 DPRINTF("pktlen %jd > total_len %jd", pktlen, total_len, 975 DPRINTF("pktlen %jd > total_len %jd", pktlen, total_len,
974 0, 0); 976 0, 0);
975 if_statinc(ifp, if_ierrors); 977 if_statinc(ifp, if_ierrors);
976 return; 978 return;
977 } 979 }
978 980
979 uint8_t *pktbuf = buf + ETHER_ALIGN; 981 uint8_t *pktbuf = buf + ETHER_ALIGN;
980 size_t buflen = pktlen - ETHER_ALIGN; 982 size_t buflen = pktlen - ETHER_ALIGN;
981 int mbuf_flags = M_HASFCS; 983 int mbuf_flags = M_HASFCS;
982 int csum_flags = 0; 984 int csum_flags = 0;
983 uint16_t csum_data = 0; 985 uint16_t csum_data = 0;
984 986
985 KASSERT(pktlen < MCLBYTES); 987 KASSERT(pktlen < MCLBYTES);
986 988
987 /* Check if RX TCP/UDP checksumming is being offloaded */ 989 /* Check if RX TCP/UDP checksumming is being offloaded */
988 if (sc->sc_coe_ctrl & SMSC_COE_CTRL_RX_EN) { 990 if (sc->sc_coe_ctrl & SMSC_COE_CTRL_RX_EN) {
989 DPRINTF("RX checksum offload checking", 0, 0, 0, 0); 991 DPRINTF("RX checksum offload checking", 0, 0, 0, 0);
990 struct ether_header *eh = (struct ether_header *)pktbuf; 992 struct ether_header *eh = (struct ether_header *)pktbuf;
991 const size_t cssz = sizeof(csum_data); 993 const size_t cssz = sizeof(csum_data);
992 994
993 /* Remove the extra 2 bytes of the csum */ 995 /* Remove the extra 2 bytes of the csum */
994 buflen -= cssz; 996 buflen -= cssz;
995 997
996 /* 998 /*
997 * The checksum appears to be simplistically calculated 999 * The checksum appears to be simplistically calculated
998 * over the udp/tcp header and data up to the end of the 1000 * over the udp/tcp header and data up to the end of the
999 * eth frame. Which means if the eth frame is padded 1001 * eth frame. Which means if the eth frame is padded
1000 * the csum calculation is incorrectly performed over 1002 * the csum calculation is incorrectly performed over
1001 * the padding bytes as well. Therefore to be safe we 1003 * the padding bytes as well. Therefore to be safe we
1002 * ignore the H/W csum on frames less than or equal to 1004 * ignore the H/W csum on frames less than or equal to
1003 * 64 bytes. 1005 * 64 bytes.
1004 * 1006 *
1005 * Ignore H/W csum for non-IPv4 packets. 1007 * Ignore H/W csum for non-IPv4 packets.
1006 */ 1008 */
1007 DPRINTF("Ethertype %02jx pktlen %02jx", 1009 DPRINTF("Ethertype %02jx pktlen %02jx",
1008 be16toh(eh->ether_type), pktlen, 0, 0); 1010 be16toh(eh->ether_type), pktlen, 0, 0);
1009 if (be16toh(eh->ether_type) == ETHERTYPE_IP && 1011 if (be16toh(eh->ether_type) == ETHERTYPE_IP &&
1010 pktlen > ETHER_MIN_LEN) { 1012 pktlen > ETHER_MIN_LEN) {
1011 1013
1012 csum_flags |= 1014 csum_flags |=
1013 (M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_DATA); 1015 (M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_DATA);
1014 1016
1015 /* 1017 /*
1016 * Copy the TCP/UDP checksum from the last 2 1018 * Copy the TCP/UDP checksum from the last 2
1017 * bytes of the transfer and put in the 1019 * bytes of the transfer and put in the
1018 * csum_data field. 1020 * csum_data field.
1019 */ 1021 */
1020 memcpy(&csum_data, buf + pktlen - cssz, cssz); 1022 memcpy(&csum_data, buf + pktlen - cssz, cssz);
1021 1023
1022 /* 1024 /*
1023 * The data is copied in network order, but the 1025 * The data is copied in network order, but the
1024 * csum algorithm in the kernel expects it to be 1026 * csum algorithm in the kernel expects it to be
1025 * in host network order. 1027 * in host network order.
1026 */ 1028 */
1027 csum_data = ntohs(csum_data); 1029 csum_data = ntohs(csum_data);
1028 DPRINTF("RX checksum offloaded (0x%04jx)", 1030 DPRINTF("RX checksum offloaded (0x%04jx)",
1029 csum_data, 0, 0, 0); 1031 csum_data, 0, 0, 0);
1030 } 1032 }
1031 } 1033 }
1032 1034
1033 /* round up to next longword */ 1035 /* round up to next longword */
1034 pktlen = (pktlen + 3) & ~0x3; 1036 pktlen = (pktlen + 3) & ~0x3;
1035 1037
1036 /* total_len does not include the padding */ 1038 /* total_len does not include the padding */
1037 if (pktlen > total_len) 1039 if (pktlen > total_len)
1038 pktlen = total_len; 1040 pktlen = total_len;
1039 1041
1040 buf += pktlen; 1042 buf += pktlen;
1041 total_len -= pktlen; 1043 total_len -= pktlen;
1042 1044
1043 /* push the packet up */ 1045 /* push the packet up */
1044 usbnet_enqueue(un, pktbuf, buflen, csum_flags, csum_data, 1046 usbnet_enqueue(un, pktbuf, buflen, csum_flags, csum_data,
1045 mbuf_flags); 1047 mbuf_flags);
1046 1048
1047 count++; 1049 count++;
1048 } 1050 }
1049 1051
1050 if (count != 0) 1052 if (count != 0)
1051 rnd_add_uint32(usbnet_rndsrc(un), count); 1053 rnd_add_uint32(usbnet_rndsrc(un), count);
1052} 1054}
1053 1055
1054static unsigned 1056static unsigned
1055smsc_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 1057smsc_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
1056{ 1058{
1057 uint32_t txhdr; 1059 uint32_t txhdr;
1058 uint32_t frm_len = 0; 1060 uint32_t frm_len = 0;
1059 1061
1060 const size_t hdrsz = sizeof(txhdr) * 2; 1062 const size_t hdrsz = sizeof(txhdr) * 2;
1061 1063
1062 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdrsz) 1064 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdrsz)
1063 return 0; 1065 return 0;
1064 1066
1065 /* 1067 /*
1066 * Each frame is prefixed with two 32-bit values describing the 1068 * Each frame is prefixed with two 32-bit values describing the
1067 * length of the packet and buffer. 1069 * length of the packet and buffer.
1068 */ 1070 */
1069 txhdr = SMSC_TX_CTRL_0_BUF_SIZE(m->m_pkthdr.len) | 1071 txhdr = SMSC_TX_CTRL_0_BUF_SIZE(m->m_pkthdr.len) |
1070 SMSC_TX_CTRL_0_FIRST_SEG | SMSC_TX_CTRL_0_LAST_SEG; 1072 SMSC_TX_CTRL_0_FIRST_SEG | SMSC_TX_CTRL_0_LAST_SEG;
1071 txhdr = htole32(txhdr); 1073 txhdr = htole32(txhdr);
1072 memcpy(c->unc_buf, &txhdr, sizeof(txhdr)); 1074 memcpy(c->unc_buf, &txhdr, sizeof(txhdr));
1073 1075
1074 txhdr = SMSC_TX_CTRL_1_PKT_LENGTH(m->m_pkthdr.len); 1076 txhdr = SMSC_TX_CTRL_1_PKT_LENGTH(m->m_pkthdr.len);
1075 txhdr = htole32(txhdr); 1077 txhdr = htole32(txhdr);
1076 memcpy(c->unc_buf + sizeof(txhdr), &txhdr, sizeof(txhdr)); 1078 memcpy(c->unc_buf + sizeof(txhdr), &txhdr, sizeof(txhdr));
1077 1079
1078 frm_len += hdrsz; 1080 frm_len += hdrsz;
1079 1081
1080 /* Next copy in the actual packet */ 1082 /* Next copy in the actual packet */
1081 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + frm_len); 1083 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + frm_len);
1082 frm_len += m->m_pkthdr.len; 1084 frm_len += m->m_pkthdr.len;
1083 1085
1084 return frm_len; 1086 return frm_len;
1085} 1087}
1086 1088
1087#ifdef _MODULE 1089#ifdef _MODULE
1088#include "ioconf.c" 1090#include "ioconf.c"
1089#endif 1091#endif
1090 1092
1091USBNET_MODULE(smsc) 1093USBNET_MODULE(smsc)

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

--- src/sys/dev/usb/if_udav.c 2022/03/03 05:50:22 1.79
+++ src/sys/dev/usb/if_udav.c 2022/03/03 05:50:57 1.80
@@ -1,865 +1,867 @@ @@ -1,865 +1,867 @@
1/* $NetBSD: if_udav.c,v 1.79 2022/03/03 05:50:22 riastradh Exp $ */ 1/* $NetBSD: if_udav.c,v 1.80 2022/03/03 05:50:57 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.79 2022/03/03 05:50:22 riastradh Exp $"); 48__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.80 2022/03/03 05:50:57 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 int udav_uno_ioctl(struct ifnet *, u_long, void *); 72static int udav_uno_ioctl(struct ifnet *, u_long, void *);
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_ioctl = udav_uno_ioctl, 135 .uno_ioctl = udav_uno_ioctl,
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 usbnet_busy(un); 489 usbnet_busy(un);
490 490
491 memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr)); 491 memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr));
492 udav_csr_write(un, UDAV_PAR, eaddr, ETHER_ADDR_LEN); 492 udav_csr_write(un, UDAV_PAR, eaddr, ETHER_ADDR_LEN);
493 493
494 /* Initialize network control register */ 494 /* Initialize network control register */
495 /* Disable loopback */ 495 /* Disable loopback */
496 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1); 496 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
497 497
498 /* Initialize RX control register */ 498 /* Initialize RX control register */
499 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC); 499 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
500 500
501 /* If we want promiscuous mode, accept all physical frames. */ 501 /* If we want promiscuous mode, accept all physical frames. */
502 if (ifp->if_flags & IFF_PROMISC) 502 if (ifp->if_flags & IFF_PROMISC)
503 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC); 503 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
504 else 504 else
505 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC); 505 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
506 506
507 /* Load the multicast filter */ 507 /* Load the multicast filter */
508 udav_setiff_locked(un); 508 udav_setiff_locked(un);
509 509
510 /* Enable RX */ 510 /* Enable RX */
511 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_RXEN); 511 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_RXEN);
512 512
513 /* clear POWER_DOWN state of internal PHY */ 513 /* clear POWER_DOWN state of internal PHY */
514 UDAV_SETBIT(un, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0); 514 UDAV_SETBIT(un, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
515 UDAV_CLRBIT(un, UDAV_GPR, UDAV_GPR_GEPIO0); 515 UDAV_CLRBIT(un, UDAV_GPR, UDAV_GPR_GEPIO0);
516 516
517 if (mii && (rc = mii_mediachg(mii)) == ENXIO) 517 if (mii && (rc = mii_mediachg(mii)) == ENXIO)
518 rc = 0; 518 rc = 0;
519 519
520 if (rc != 0) { 520 if (rc != 0) {
521 usbnet_unbusy(un); 521 usbnet_unbusy(un);
522 return rc; 522 return rc;
523 } 523 }
524 524
525 if (usbnet_isdying(un)) 525 if (usbnet_isdying(un))
526 rc = EIO; 526 rc = EIO;
527 else 527 else
528 rc = usbnet_init_rx_tx(un); 528 rc = usbnet_init_rx_tx(un);
529 529
530 usbnet_unbusy(un); 530 usbnet_unbusy(un);
531 531
532 return rc; 532 return rc;
533} 533}
534 534
535static void 535static void
536udav_reset(struct usbnet *un) 536udav_reset(struct usbnet *un)
537{ 537{
538 usbnet_isowned_core(un); 538 usbnet_isowned_core(un);
539 539
540 if (usbnet_isdying(un)) 540 if (usbnet_isdying(un))
541 return; 541 return;
542 542
543 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 543 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
544 544
545 udav_chip_init(un); 545 udav_chip_init(un);
546} 546}
547 547
548static void 548static void
549udav_chip_init(struct usbnet *un) 549udav_chip_init(struct usbnet *un)
550{ 550{
551 usbnet_isowned_core(un); 551 usbnet_isowned_core(un);
552 552
553 /* Select PHY */ 553 /* Select PHY */
554#if 1 554#if 1
555 /* 555 /*
556 * XXX: force select internal phy. 556 * XXX: force select internal phy.
557 * external phy routines are not tested. 557 * external phy routines are not tested.
558 */ 558 */
559 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY); 559 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY);
560#else 560#else
561 if (un->un_flags & UDAV_EXT_PHY) { 561 if (un->un_flags & UDAV_EXT_PHY) {
562 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY); 562 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY);
563 } else { 563 } else {
564 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY); 564 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY);
565 } 565 }
566#endif 566#endif
567 567
568 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_RST); 568 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_RST);
569 569
570 for (int i = 0; i < UDAV_TX_TIMEOUT; i++) { 570 for (int i = 0; i < UDAV_TX_TIMEOUT; i++) {
 571 if (usbnet_isdying(un))
 572 return;
571 if (!(udav_csr_read1(un, UDAV_NCR) & UDAV_NCR_RST)) 573 if (!(udav_csr_read1(un, UDAV_NCR) & UDAV_NCR_RST))
572 break; 574 break;
573 delay(10); /* XXX */ 575 delay(10); /* XXX */
574 } 576 }
575 delay(10000); /* XXX */ 577 delay(10000); /* XXX */
576} 578}
577 579
578#define UDAV_BITS 6 580#define UDAV_BITS 6
579 581
580#define UDAV_CALCHASH(addr) \ 582#define UDAV_CALCHASH(addr) \
581 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1)) 583 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1))
582 584
583static void 585static void
584udav_setiff_locked(struct usbnet *un) 586udav_setiff_locked(struct usbnet *un)
585{ 587{
586 struct ethercom *ec = usbnet_ec(un); 588 struct ethercom *ec = usbnet_ec(un);
587 struct ifnet * const ifp = usbnet_ifp(un); 589 struct ifnet * const ifp = usbnet_ifp(un);
588 struct ether_multi *enm; 590 struct ether_multi *enm;
589 struct ether_multistep step; 591 struct ether_multistep step;
590 uint8_t hashes[8]; 592 uint8_t hashes[8];
591 int h = 0; 593 int h = 0;
592 594
593 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 595 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
594 596
595 usbnet_isowned_core(un); 597 usbnet_isowned_core(un);
596 598
597 if (usbnet_isdying(un)) 599 if (usbnet_isdying(un))
598 return; 600 return;
599 601
600 if (ISSET(un->un_flags, UDAV_NO_PHY)) { 602 if (ISSET(un->un_flags, UDAV_NO_PHY)) {
601 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL); 603 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL);
602 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_PRMSC); 604 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_PRMSC);
603 return; 605 return;
604 } 606 }
605 607
606 if (ifp->if_flags & IFF_PROMISC) { 608 if (ifp->if_flags & IFF_PROMISC) {
607 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC); 609 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
608 return; 610 return;
609 } else if (ifp->if_flags & IFF_ALLMULTI) { 611 } else if (ifp->if_flags & IFF_ALLMULTI) {
610allmulti: 612allmulti:
611 ifp->if_flags |= IFF_ALLMULTI; 613 ifp->if_flags |= IFF_ALLMULTI;
612 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL); 614 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL);
613 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_PRMSC); 615 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_PRMSC);
614 return; 616 return;
615 } 617 }
616 618
617 /* first, zot all the existing hash bits */ 619 /* first, zot all the existing hash bits */
618 memset(hashes, 0x00, sizeof(hashes)); 620 memset(hashes, 0x00, sizeof(hashes));
619 hashes[7] |= 0x80; /* broadcast address */ 621 hashes[7] |= 0x80; /* broadcast address */
620 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes)); 622 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes));
621 623
622 /* now program new ones */ 624 /* now program new ones */
623 ETHER_LOCK(ec); 625 ETHER_LOCK(ec);
624 ETHER_FIRST_MULTI(step, ec, enm); 626 ETHER_FIRST_MULTI(step, ec, enm);
625 while (enm != NULL) { 627 while (enm != NULL) {
626 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 628 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
627 ETHER_ADDR_LEN) != 0) { 629 ETHER_ADDR_LEN) != 0) {
628 ETHER_UNLOCK(ec); 630 ETHER_UNLOCK(ec);
629 goto allmulti; 631 goto allmulti;
630 } 632 }
631 633
632 h = UDAV_CALCHASH(enm->enm_addrlo); 634 h = UDAV_CALCHASH(enm->enm_addrlo);
633 hashes[h>>3] |= 1 << (h & 0x7); 635 hashes[h>>3] |= 1 << (h & 0x7);
634 ETHER_NEXT_MULTI(step, enm); 636 ETHER_NEXT_MULTI(step, enm);
635 } 637 }
636 ETHER_UNLOCK(ec); 638 ETHER_UNLOCK(ec);
637 639
638 /* disable all multicast */ 640 /* disable all multicast */
639 ifp->if_flags &= ~IFF_ALLMULTI; 641 ifp->if_flags &= ~IFF_ALLMULTI;
640 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL); 642 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL);
641 643
642 /* write hash value to the register */ 644 /* write hash value to the register */
643 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes)); 645 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes));
644} 646}
645 647
646static unsigned 648static unsigned
647udav_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 649udav_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
648{ 650{
649 int total_len; 651 int total_len;
650 uint8_t *buf = c->unc_buf; 652 uint8_t *buf = c->unc_buf;
651 653
652 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 654 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
653 655
654 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2) 656 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2)
655 return 0; 657 return 0;
656 658
657 /* Copy the mbuf data into a contiguous buffer */ 659 /* Copy the mbuf data into a contiguous buffer */
658 m_copydata(m, 0, m->m_pkthdr.len, buf + 2); 660 m_copydata(m, 0, m->m_pkthdr.len, buf + 2);
659 total_len = m->m_pkthdr.len; 661 total_len = m->m_pkthdr.len;
660 if (total_len < UDAV_MIN_FRAME_LEN) { 662 if (total_len < UDAV_MIN_FRAME_LEN) {
661 memset(buf + 2 + total_len, 0, 663 memset(buf + 2 + total_len, 0,
662 UDAV_MIN_FRAME_LEN - total_len); 664 UDAV_MIN_FRAME_LEN - total_len);
663 total_len = UDAV_MIN_FRAME_LEN; 665 total_len = UDAV_MIN_FRAME_LEN;
664 } 666 }
665 667
666 /* Frame length is specified in the first 2bytes of the buffer */ 668 /* Frame length is specified in the first 2bytes of the buffer */
667 buf[0] = (uint8_t)total_len; 669 buf[0] = (uint8_t)total_len;
668 buf[1] = (uint8_t)(total_len >> 8); 670 buf[1] = (uint8_t)(total_len >> 8);
669 total_len += 2; 671 total_len += 2;
670 672
671 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev), 673 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev),
672 __func__, total_len)); 674 __func__, total_len));
673 675
674 return total_len; 676 return total_len;
675} 677}
676 678
677static void 679static void
678udav_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 680udav_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
679{ 681{
680 struct ifnet *ifp = usbnet_ifp(un); 682 struct ifnet *ifp = usbnet_ifp(un);
681 uint8_t *buf = c->unc_buf; 683 uint8_t *buf = c->unc_buf;
682 uint16_t pkt_len; 684 uint16_t pkt_len;
683 uint8_t pktstat; 685 uint8_t pktstat;
684 686
685 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 687 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
686 688
687 /* first byte in received data */ 689 /* first byte in received data */
688 pktstat = *buf; 690 pktstat = *buf;
689 total_len -= sizeof(pktstat); 691 total_len -= sizeof(pktstat);
690 buf += sizeof(pktstat); 692 buf += sizeof(pktstat);
691 693
692 DPRINTF(("%s: RX Status: 0x%02x\n", device_xname(un->un_dev), pktstat)); 694 DPRINTF(("%s: RX Status: 0x%02x\n", device_xname(un->un_dev), pktstat));
693 695
694 pkt_len = UGETW(buf); 696 pkt_len = UGETW(buf);
695 total_len -= sizeof(pkt_len); 697 total_len -= sizeof(pkt_len);
696 buf += sizeof(pkt_len); 698 buf += sizeof(pkt_len);
697 699
698 DPRINTF(("%s: RX Length: 0x%02x\n", device_xname(un->un_dev), pkt_len)); 700 DPRINTF(("%s: RX Length: 0x%02x\n", device_xname(un->un_dev), pkt_len));
699 701
700 if (pktstat & UDAV_RSR_LCS) { 702 if (pktstat & UDAV_RSR_LCS) {
701 if_statinc(ifp, if_collisions); 703 if_statinc(ifp, if_collisions);
702 return; 704 return;
703 } 705 }
704 706
705 if (pkt_len < sizeof(struct ether_header) || 707 if (pkt_len < sizeof(struct ether_header) ||
706 pkt_len > total_len || 708 pkt_len > total_len ||
707 (pktstat & UDAV_RSR_ERR)) { 709 (pktstat & UDAV_RSR_ERR)) {
708 if_statinc(ifp, if_ierrors); 710 if_statinc(ifp, if_ierrors);
709 return; 711 return;
710 } 712 }
711 713
712 pkt_len -= ETHER_CRC_LEN; 714 pkt_len -= ETHER_CRC_LEN;
713 715
714 DPRINTF(("%s: Rx deliver: 0x%02x\n", device_xname(un->un_dev), pkt_len)); 716 DPRINTF(("%s: Rx deliver: 0x%02x\n", device_xname(un->un_dev), pkt_len));
715 717
716 usbnet_enqueue(un, buf, pkt_len, 0, 0, 0); 718 usbnet_enqueue(un, buf, pkt_len, 0, 0, 0);
717} 719}
718 720
719static int 721static int
720udav_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 722udav_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
721{ 723{
722 struct usbnet * const un = ifp->if_softc; 724 struct usbnet * const un = ifp->if_softc;
723 725
724 usbnet_lock_core(un); 726 usbnet_lock_core(un);
725 usbnet_busy(un); 727 usbnet_busy(un);
726 728
727 switch (cmd) { 729 switch (cmd) {
728 case SIOCADDMULTI: 730 case SIOCADDMULTI:
729 case SIOCDELMULTI: 731 case SIOCDELMULTI:
730 udav_setiff_locked(un); 732 udav_setiff_locked(un);
731 break; 733 break;
732 default: 734 default:
733 break; 735 break;
734 } 736 }
735 737
736 usbnet_unbusy(un); 738 usbnet_unbusy(un);
737 usbnet_unlock_core(un); 739 usbnet_unlock_core(un);
738 740
739 return 0; 741 return 0;
740} 742}
741 743
742/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */ 744/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
743static void 745static void
744udav_uno_stop(struct ifnet *ifp, int disable) 746udav_uno_stop(struct ifnet *ifp, int disable)
745{ 747{
746 struct usbnet * const un = ifp->if_softc; 748 struct usbnet * const un = ifp->if_softc;
747 749
748 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 750 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
749 751
750 udav_reset(un); 752 udav_reset(un);
751} 753}
752 754
753static int 755static int
754udav_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 756udav_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
755{ 757{
756 uint8_t data[2]; 758 uint8_t data[2];
757 759
758 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", 760 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
759 device_xname(un->un_dev), __func__, phy, reg)); 761 device_xname(un->un_dev), __func__, phy, reg));
760 762
761 if (usbnet_isdying(un)) { 763 if (usbnet_isdying(un)) {
762#ifdef DIAGNOSTIC 764#ifdef DIAGNOSTIC
763 printf("%s: %s: dying\n", device_xname(un->un_dev), 765 printf("%s: %s: dying\n", device_xname(un->un_dev),
764 __func__); 766 __func__);
765#endif 767#endif
766 return EINVAL; 768 return EINVAL;
767 } 769 }
768 770
769 /* XXX: one PHY only for the internal PHY */ 771 /* XXX: one PHY only for the internal PHY */
770 if (phy != 0) { 772 if (phy != 0) {
771 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 773 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
772 device_xname(un->un_dev), __func__, phy)); 774 device_xname(un->un_dev), __func__, phy));
773 return EINVAL; 775 return EINVAL;
774 } 776 }
775 777
776 /* select internal PHY and set PHY register address */ 778 /* select internal PHY and set PHY register address */
777 udav_csr_write1(un, UDAV_EPAR, 779 udav_csr_write1(un, UDAV_EPAR,
778 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); 780 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
779 781
780 /* select PHY operation and start read command */ 782 /* select PHY operation and start read command */
781 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR); 783 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
782 784
783 /* XXX: should be wait? */ 785 /* XXX: should be wait? */
784 786
785 /* end read command */ 787 /* end read command */
786 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRR); 788 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRR);
787 789
788 /* retrieve the result from data registers */ 790 /* retrieve the result from data registers */
789 udav_csr_read(un, UDAV_EPDRL, data, 2); 791 udav_csr_read(un, UDAV_EPDRL, data, 2);
790 792
791 *val = data[0] | (data[1] << 8); 793 *val = data[0] | (data[1] << 8);
792 794
793 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n", 795 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n",
794 device_xname(un->un_dev), __func__, phy, reg, *val)); 796 device_xname(un->un_dev), __func__, phy, reg, *val));
795 797
796 return 0; 798 return 0;
797} 799}
798 800
799static int 801static int
800udav_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 802udav_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
801{ 803{
802 uint8_t data[2]; 804 uint8_t data[2];
803 805
804 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n", 806 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n",
805 device_xname(un->un_dev), __func__, phy, reg, val)); 807 device_xname(un->un_dev), __func__, phy, reg, val));
806 808
807 if (usbnet_isdying(un)) { 809 if (usbnet_isdying(un)) {
808#ifdef DIAGNOSTIC 810#ifdef DIAGNOSTIC
809 printf("%s: %s: dying\n", device_xname(un->un_dev), 811 printf("%s: %s: dying\n", device_xname(un->un_dev),
810 __func__); 812 __func__);
811#endif 813#endif
812 return EIO; 814 return EIO;
813 } 815 }
814 816
815 /* XXX: one PHY only for the internal PHY */ 817 /* XXX: one PHY only for the internal PHY */
816 if (phy != 0) { 818 if (phy != 0) {
817 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 819 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
818 device_xname(un->un_dev), __func__, phy)); 820 device_xname(un->un_dev), __func__, phy));
819 return EIO; 821 return EIO;
820 } 822 }
821 823
822 /* select internal PHY and set PHY register address */ 824 /* select internal PHY and set PHY register address */
823 udav_csr_write1(un, UDAV_EPAR, 825 udav_csr_write1(un, UDAV_EPAR,
824 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); 826 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
825 827
826 /* put the value to the data registers */ 828 /* put the value to the data registers */
827 data[0] = val & 0xff; 829 data[0] = val & 0xff;
828 data[1] = (val >> 8) & 0xff; 830 data[1] = (val >> 8) & 0xff;
829 udav_csr_write(un, UDAV_EPDRL, data, 2); 831 udav_csr_write(un, UDAV_EPDRL, data, 2);
830 832
831 /* select PHY operation and start write command */ 833 /* select PHY operation and start write command */
832 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW); 834 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
833 835
834 /* XXX: should be wait? */ 836 /* XXX: should be wait? */
835 837
836 /* end write command */ 838 /* end write command */
837 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRW); 839 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRW);
838 840
839 return 0; 841 return 0;
840} 842}
841 843
842static void 844static void
843udav_uno_mii_statchg(struct ifnet *ifp) 845udav_uno_mii_statchg(struct ifnet *ifp)
844{ 846{
845 struct usbnet * const un = ifp->if_softc; 847 struct usbnet * const un = ifp->if_softc;
846 struct mii_data * const mii = usbnet_mii(un); 848 struct mii_data * const mii = usbnet_mii(un);
847 849
848 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__)); 850 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__));
849 851
850 if (usbnet_isdying(un)) 852 if (usbnet_isdying(un))
851 return; 853 return;
852 854
853 if ((mii->mii_media_status & IFM_ACTIVE) && 855 if ((mii->mii_media_status & IFM_ACTIVE) &&
854 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 856 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
855 DPRINTF(("%s: %s: got link\n", 857 DPRINTF(("%s: %s: got link\n",
856 device_xname(un->un_dev), __func__)); 858 device_xname(un->un_dev), __func__));
857 usbnet_set_link(un, true); 859 usbnet_set_link(un, true);
858 } 860 }
859} 861}
860 862
861#ifdef _MODULE 863#ifdef _MODULE
862#include "ioconf.c" 864#include "ioconf.c"
863#endif 865#endif
864 866
865USBNET_MODULE(udav) 867USBNET_MODULE(udav)

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

--- src/sys/dev/usb/if_url.c 2022/03/03 05:50:22 1.79
+++ src/sys/dev/usb/if_url.c 2022/03/03 05:50:57 1.80
@@ -1,774 +1,776 @@ @@ -1,774 +1,776 @@
1/* $NetBSD: if_url.c,v 1.79 2022/03/03 05:50:22 riastradh Exp $ */ 1/* $NetBSD: if_url.c,v 1.80 2022/03/03 05:50:57 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.79 2022/03/03 05:50:22 riastradh Exp $"); 47__KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.80 2022/03/03 05:50:57 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 int url_uno_ioctl(struct ifnet *, u_long, void *); 80static int url_uno_ioctl(struct ifnet *, u_long, void *);
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_ioctl = url_uno_ioctl, 96 .uno_ioctl = url_uno_ioctl,
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 struct usbnet * const un = ifp->if_softc; 409 struct usbnet * const un = ifp->if_softc;
410 410
411 usbnet_busy(un); 411 usbnet_busy(un);
412 int ret = url_init_locked(ifp); 412 int ret = url_init_locked(ifp);
413 usbnet_unbusy(un); 413 usbnet_unbusy(un);
414 414
415 return ret; 415 return ret;
416} 416}
417 417
418static void 418static void
419url_reset(struct usbnet *un) 419url_reset(struct usbnet *un)
420{ 420{
421 int i; 421 int i;
422 422
423 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 423 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
424 424
425 if (usbnet_isdying(un)) 425 if (usbnet_isdying(un))
426 return; 426 return;
427 427
428 URL_SETBIT(un, URL_CR, URL_CR_SOFT_RST); 428 URL_SETBIT(un, URL_CR, URL_CR_SOFT_RST);
429 429
430 for (i = 0; i < URL_TX_TIMEOUT; i++) { 430 for (i = 0; i < URL_TX_TIMEOUT; i++) {
 431 if (usbnet_isdying(un))
 432 return;
431 if (!(url_csr_read_1(un, URL_CR) & URL_CR_SOFT_RST)) 433 if (!(url_csr_read_1(un, URL_CR) & URL_CR_SOFT_RST))
432 break; 434 break;
433 delay(10); /* XXX */ 435 delay(10); /* XXX */
434 } 436 }
435 437
436 delay(10000); /* XXX */ 438 delay(10000); /* XXX */
437} 439}
438 440
439static void 441static void
440url_rcvfilt_locked(struct usbnet *un) 442url_rcvfilt_locked(struct usbnet *un)
441{ 443{
442 struct ifnet * const ifp = usbnet_ifp(un); 444 struct ifnet * const ifp = usbnet_ifp(un);
443 struct ethercom *ec = usbnet_ec(un); 445 struct ethercom *ec = usbnet_ec(un);
444 struct ether_multi *enm; 446 struct ether_multi *enm;
445 struct ether_multistep step; 447 struct ether_multistep step;
446 uint32_t mchash[2] = { 0, 0 }; 448 uint32_t mchash[2] = { 0, 0 };
447 int h = 0, rcr; 449 int h = 0, rcr;
448 450
449 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 451 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
450 452
451 usbnet_isowned_core(un); 453 usbnet_isowned_core(un);
452 454
453 if (usbnet_isdying(un)) 455 if (usbnet_isdying(un))
454 return; 456 return;
455 457
456 rcr = url_csr_read_2(un, URL_RCR); 458 rcr = url_csr_read_2(un, URL_RCR);
457 rcr &= ~(URL_RCR_AAP | URL_RCR_AAM | URL_RCR_AM); 459 rcr &= ~(URL_RCR_AAP | URL_RCR_AAM | URL_RCR_AM);
458 460
459 ETHER_LOCK(ec); 461 ETHER_LOCK(ec);
460 if (ifp->if_flags & IFF_PROMISC) { 462 if (ifp->if_flags & IFF_PROMISC) {
461 ec->ec_flags |= ETHER_F_ALLMULTI; 463 ec->ec_flags |= ETHER_F_ALLMULTI;
462 ETHER_UNLOCK(ec); 464 ETHER_UNLOCK(ec);
463 /* run promisc. mode */ 465 /* run promisc. mode */
464 rcr |= URL_RCR_AAM; /* ??? */ 466 rcr |= URL_RCR_AAM; /* ??? */
465 rcr |= URL_RCR_AAP; 467 rcr |= URL_RCR_AAP;
466 goto update; 468 goto update;
467 } 469 }
468 ec->ec_flags &= ~ETHER_F_ALLMULTI; 470 ec->ec_flags &= ~ETHER_F_ALLMULTI;
469 ETHER_FIRST_MULTI(step, ec, enm); 471 ETHER_FIRST_MULTI(step, ec, enm);
470 while (enm != NULL) { 472 while (enm != NULL) {
471 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 473 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
472 ec->ec_flags |= ETHER_F_ALLMULTI; 474 ec->ec_flags |= ETHER_F_ALLMULTI;
473 ETHER_UNLOCK(ec); 475 ETHER_UNLOCK(ec);
474 /* accept all multicast frames */ 476 /* accept all multicast frames */
475 rcr |= URL_RCR_AAM; 477 rcr |= URL_RCR_AAM;
476 goto update; 478 goto update;
477 } 479 }
478 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 480 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
479 /* 1(31) and 5(30:26) bit sampling */ 481 /* 1(31) and 5(30:26) bit sampling */
480 mchash[h >> 31] |= 1 << ((h >> 26) & 0x1f); 482 mchash[h >> 31] |= 1 << ((h >> 26) & 0x1f);
481 ETHER_NEXT_MULTI(step, enm); 483 ETHER_NEXT_MULTI(step, enm);
482 } 484 }
483 ETHER_UNLOCK(ec); 485 ETHER_UNLOCK(ec);
484 if (h != 0) 486 if (h != 0)
485 rcr |= URL_RCR_AM; /* activate mcast hash filter */ 487 rcr |= URL_RCR_AM; /* activate mcast hash filter */
486 url_csr_write_4(un, URL_MAR0, mchash[0]); 488 url_csr_write_4(un, URL_MAR0, mchash[0]);
487 url_csr_write_4(un, URL_MAR4, mchash[1]); 489 url_csr_write_4(un, URL_MAR4, mchash[1]);
488 update: 490 update:
489 url_csr_write_2(un, URL_RCR, rcr); 491 url_csr_write_2(un, URL_RCR, rcr);
490} 492}
491 493
492static unsigned 494static unsigned
493url_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 495url_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
494{ 496{
495 int total_len; 497 int total_len;
496 498
497 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__)); 499 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__));
498 500
499 KASSERT(un->un_tx_bufsz >= URL_MIN_FRAME_LEN); 501 KASSERT(un->un_tx_bufsz >= URL_MIN_FRAME_LEN);
500 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz) 502 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz)
501 return 0; 503 return 0;
502 504
503 /* Copy the mbuf data into a contiguous buffer */ 505 /* Copy the mbuf data into a contiguous buffer */
504 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf); 506 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf);
505 total_len = m->m_pkthdr.len; 507 total_len = m->m_pkthdr.len;
506 508
507 if (total_len < URL_MIN_FRAME_LEN) { 509 if (total_len < URL_MIN_FRAME_LEN) {
508 memset(c->unc_buf + total_len, 0, 510 memset(c->unc_buf + total_len, 0,
509 URL_MIN_FRAME_LEN - total_len); 511 URL_MIN_FRAME_LEN - total_len);
510 total_len = URL_MIN_FRAME_LEN; 512 total_len = URL_MIN_FRAME_LEN;
511 } 513 }
512 514
513 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev), 515 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev),
514 __func__, total_len)); 516 __func__, total_len));
515 517
516 return total_len; 518 return total_len;
517} 519}
518 520
519static void 521static void
520url_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 522url_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
521{ 523{
522 struct ifnet *ifp = usbnet_ifp(un); 524 struct ifnet *ifp = usbnet_ifp(un);
523 url_rxhdr_t rxhdr; 525 url_rxhdr_t rxhdr;
524 526
525 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__)); 527 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__));
526 528
527 if (total_len <= ETHER_CRC_LEN || total_len <= sizeof(rxhdr)) { 529 if (total_len <= ETHER_CRC_LEN || total_len <= sizeof(rxhdr)) {
528 if_statinc(ifp, if_ierrors); 530 if_statinc(ifp, if_ierrors);
529 return; 531 return;
530 } 532 }
531 533
532 memcpy(&rxhdr, c->unc_buf + total_len - ETHER_CRC_LEN, sizeof(rxhdr)); 534 memcpy(&rxhdr, c->unc_buf + total_len - ETHER_CRC_LEN, sizeof(rxhdr));
533 535
534 DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n", 536 DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n",
535 device_xname(un->un_dev), 537 device_xname(un->un_dev),
536 UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK, 538 UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK,
537 UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "", 539 UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "",
538 UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "", 540 UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "",
539 UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "", 541 UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "",
540 UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : "")); 542 UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : ""));
541 543
542 if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) { 544 if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) {
543 if_statinc(ifp, if_ierrors); 545 if_statinc(ifp, if_ierrors);
544 return; 546 return;
545 } 547 }
546 548
547 total_len -= ETHER_CRC_LEN; 549 total_len -= ETHER_CRC_LEN;
548 550
549 DPRINTF(("%s: %s: deliver %d\n", device_xname(un->un_dev), 551 DPRINTF(("%s: %s: deliver %d\n", device_xname(un->un_dev),
550 __func__, total_len)); 552 __func__, total_len));
551 usbnet_enqueue(un, c->unc_buf, total_len, 0, 0, 0); 553 usbnet_enqueue(un, c->unc_buf, total_len, 0, 0, 0);
552} 554}
553 555
554#if 0 556#if 0
555static void url_intr(void) 557static void url_intr(void)
556{ 558{
557} 559}
558#endif 560#endif
559 561
560static int 562static int
561url_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 563url_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
562{ 564{
563 struct usbnet * const un = ifp->if_softc; 565 struct usbnet * const un = ifp->if_softc;
564 566
565 usbnet_lock_core(un); 567 usbnet_lock_core(un);
566 usbnet_busy(un); 568 usbnet_busy(un);
567 569
568 switch (cmd) { 570 switch (cmd) {
569 case SIOCADDMULTI: 571 case SIOCADDMULTI:
570 case SIOCDELMULTI: 572 case SIOCDELMULTI:
571 url_rcvfilt_locked(un); 573 url_rcvfilt_locked(un);
572 break; 574 break;
573 default: 575 default:
574 break; 576 break;
575 } 577 }
576 578
577 usbnet_unbusy(un); 579 usbnet_unbusy(un);
578 usbnet_unlock_core(un); 580 usbnet_unlock_core(un);
579 581
580 return 0; 582 return 0;
581} 583}
582 584
583/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */ 585/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
584static void 586static void
585url_uno_stop(struct ifnet *ifp, int disable) 587url_uno_stop(struct ifnet *ifp, int disable)
586{ 588{
587 struct usbnet * const un = ifp->if_softc; 589 struct usbnet * const un = ifp->if_softc;
588 590
589 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 591 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
590 592
591 url_reset(un); 593 url_reset(un);
592} 594}
593 595
594static int 596static int
595url_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 597url_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
596{ 598{
597 uint16_t data; 599 uint16_t data;
598 usbd_status err = USBD_NORMAL_COMPLETION; 600 usbd_status err = USBD_NORMAL_COMPLETION;
599 601
600 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", 602 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
601 device_xname(un->un_dev), __func__, phy, reg)); 603 device_xname(un->un_dev), __func__, phy, reg));
602 604
603 /* XXX: one PHY only for the RTL8150 internal PHY */ 605 /* XXX: one PHY only for the RTL8150 internal PHY */
604 if (phy != 0) { 606 if (phy != 0) {
605 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 607 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
606 device_xname(un->un_dev), __func__, phy)); 608 device_xname(un->un_dev), __func__, phy));
607 return EINVAL; 609 return EINVAL;
608 } 610 }
609 611
610 switch (reg) { 612 switch (reg) {
611 case MII_BMCR: /* Control Register */ 613 case MII_BMCR: /* Control Register */
612 reg = URL_BMCR; 614 reg = URL_BMCR;
613 break; 615 break;
614 case MII_BMSR: /* Status Register */ 616 case MII_BMSR: /* Status Register */
615 reg = URL_BMSR; 617 reg = URL_BMSR;
616 break; 618 break;
617 case MII_PHYIDR1: 619 case MII_PHYIDR1:
618 case MII_PHYIDR2: 620 case MII_PHYIDR2:
619 *val = 0; 621 *val = 0;
620 goto R_DONE; 622 goto R_DONE;
621 break; 623 break;
622 case MII_ANAR: /* Autonegotiation advertisement */ 624 case MII_ANAR: /* Autonegotiation advertisement */
623 reg = URL_ANAR; 625 reg = URL_ANAR;
624 break; 626 break;
625 case MII_ANLPAR: /* Autonegotiation link partner abilities */ 627 case MII_ANLPAR: /* Autonegotiation link partner abilities */
626 reg = URL_ANLP; 628 reg = URL_ANLP;
627 break; 629 break;
628 case URLPHY_MSR: /* Media Status Register */ 630 case URLPHY_MSR: /* Media Status Register */
629 reg = URL_MSR; 631 reg = URL_MSR;
630 break; 632 break;
631 default: 633 default:
632 printf("%s: %s: bad register %04x\n", 634 printf("%s: %s: bad register %04x\n",
633 device_xname(un->un_dev), __func__, reg); 635 device_xname(un->un_dev), __func__, reg);
634 return EINVAL; 636 return EINVAL;
635 } 637 }
636 638
637 if (reg == URL_MSR) 639 if (reg == URL_MSR)
638 data = url_csr_read_1(un, reg); 640 data = url_csr_read_1(un, reg);
639 else 641 else
640 data = url_csr_read_2(un, reg); 642 data = url_csr_read_2(un, reg);
641 *val = data; 643 *val = data;
642 644
643 R_DONE: 645 R_DONE:
644 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n", 646 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n",
645 device_xname(un->un_dev), __func__, phy, reg, *val)); 647 device_xname(un->un_dev), __func__, phy, reg, *val));
646 648
647 return err; 649 return err;
648} 650}
649 651
650static int 652static int
651url_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 653url_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
652{ 654{
653 655
654 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n", 656 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n",
655 device_xname(un->un_dev), __func__, phy, reg, val)); 657 device_xname(un->un_dev), __func__, phy, reg, val));
656 658
657 /* XXX: one PHY only for the RTL8150 internal PHY */ 659 /* XXX: one PHY only for the RTL8150 internal PHY */
658 if (phy != 0) { 660 if (phy != 0) {
659 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 661 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
660 device_xname(un->un_dev), __func__, phy)); 662 device_xname(un->un_dev), __func__, phy));
661 return EINVAL; 663 return EINVAL;
662 } 664 }
663 665
664 switch (reg) { 666 switch (reg) {
665 case MII_BMCR: /* Control Register */ 667 case MII_BMCR: /* Control Register */
666 reg = URL_BMCR; 668 reg = URL_BMCR;
667 break; 669 break;
668 case MII_BMSR: /* Status Register */ 670 case MII_BMSR: /* Status Register */
669 reg = URL_BMSR; 671 reg = URL_BMSR;
670 break; 672 break;
671 case MII_PHYIDR1: 673 case MII_PHYIDR1:
672 case MII_PHYIDR2: 674 case MII_PHYIDR2:
673 return 0; 675 return 0;
674 case MII_ANAR: /* Autonegotiation advertisement */ 676 case MII_ANAR: /* Autonegotiation advertisement */
675 reg = URL_ANAR; 677 reg = URL_ANAR;
676 break; 678 break;
677 case MII_ANLPAR: /* Autonegotiation link partner abilities */ 679 case MII_ANLPAR: /* Autonegotiation link partner abilities */
678 reg = URL_ANLP; 680 reg = URL_ANLP;
679 break; 681 break;
680 case URLPHY_MSR: /* Media Status Register */ 682 case URLPHY_MSR: /* Media Status Register */
681 reg = URL_MSR; 683 reg = URL_MSR;
682 break; 684 break;
683 default: 685 default:
684 printf("%s: %s: bad register %04x\n", 686 printf("%s: %s: bad register %04x\n",
685 device_xname(un->un_dev), __func__, reg); 687 device_xname(un->un_dev), __func__, reg);
686 return EINVAL; 688 return EINVAL;
687 } 689 }
688 690
689 if (reg == URL_MSR) 691 if (reg == URL_MSR)
690 url_csr_write_1(un, reg, val); 692 url_csr_write_1(un, reg, val);
691 else 693 else
692 url_csr_write_2(un, reg, val); 694 url_csr_write_2(un, reg, val);
693 695
694 return 0; 696 return 0;
695} 697}
696 698
697static void 699static void
698url_uno_mii_statchg(struct ifnet *ifp) 700url_uno_mii_statchg(struct ifnet *ifp)
699{ 701{
700 struct usbnet * const un = ifp->if_softc; 702 struct usbnet * const un = ifp->if_softc;
701 703
702 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__)); 704 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__));
703 705
704 /* XXX */ 706 /* XXX */
705 usbnet_set_link(un, true); 707 usbnet_set_link(un, true);
706} 708}
707 709
708#if 0 710#if 0
709/* 711/*
710 * external PHYs support, but not test. 712 * external PHYs support, but not test.
711 */ 713 */
712static usbd_status 714static usbd_status
713url_ext_mii_read_reg(struct usbnet *un, int phy, int reg) 715url_ext_mii_read_reg(struct usbnet *un, int phy, int reg)
714{ 716{
715 uint16_t val; 717 uint16_t val;
716 718
717 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n", 719 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n",
718 device_xname(un->un_dev), __func__, phy, reg)); 720 device_xname(un->un_dev), __func__, phy, reg));
719 721
720 url_csr_write_1(un, URL_PHYADD, phy & URL_PHYADD_MASK); 722 url_csr_write_1(un, URL_PHYADD, phy & URL_PHYADD_MASK);
721 /* 723 /*
722 * RTL8150L will initiate a MII management data transaction 724 * RTL8150L will initiate a MII management data transaction
723 * if PHYCNT_OWN bit is set 1 by software. After transaction, 725 * if PHYCNT_OWN bit is set 1 by software. After transaction,
724 * this bit is auto cleared by TRL8150L. 726 * this bit is auto cleared by TRL8150L.
725 */ 727 */
726 url_csr_write_1(un, URL_PHYCNT, 728 url_csr_write_1(un, URL_PHYCNT,
727 (reg | URL_PHYCNT_PHYOWN) & ~URL_PHYCNT_RWCR); 729 (reg | URL_PHYCNT_PHYOWN) & ~URL_PHYCNT_RWCR);
728 for (i = 0; i < URL_TIMEOUT; i++) { 730 for (i = 0; i < URL_TIMEOUT; i++) {
729 if ((url_csr_read_1(un, URL_PHYCNT) & URL_PHYCNT_PHYOWN) == 0) 731 if ((url_csr_read_1(un, URL_PHYCNT) & URL_PHYCNT_PHYOWN) == 0)
730 break; 732 break;
731 } 733 }
732 if (i == URL_TIMEOUT) { 734 if (i == URL_TIMEOUT) {
733 printf("%s: MII read timed out\n", device_xname(un->un_dev)); 735 printf("%s: MII read timed out\n", device_xname(un->un_dev));
734 } 736 }
735 737
736 val = url_csr_read_2(un, URL_PHYDAT); 738 val = url_csr_read_2(un, URL_PHYDAT);
737 739
738 DPRINTF(("%s: %s: phy=%d reg=0x%04x => 0x%04x\n", 740 DPRINTF(("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
739 device_xname(un->un_dev), __func__, phy, reg, val)); 741 device_xname(un->un_dev), __func__, phy, reg, val));
740 742
741 return USBD_NORMAL_COMPLETION; 743 return USBD_NORMAL_COMPLETION;
742} 744}
743 745
744static usbd_status 746static usbd_status
745url_ext_mii_write_reg(struct usbnet *un, int phy, int reg, int data) 747url_ext_mii_write_reg(struct usbnet *un, int phy, int reg, int data)
746{ 748{
747 749
748 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n", 750 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
749 device_xname(un->un_dev), __func__, phy, reg, data)); 751 device_xname(un->un_dev), __func__, phy, reg, data));
750 752
751 url_csr_write_2(un, URL_PHYDAT, data); 753 url_csr_write_2(un, URL_PHYDAT, data);
752 url_csr_write_1(un, URL_PHYADD, phy); 754 url_csr_write_1(un, URL_PHYADD, phy);
753 url_csr_write_1(un, URL_PHYCNT, reg | URL_PHYCNT_RWCR); /* Write */ 755 url_csr_write_1(un, URL_PHYCNT, reg | URL_PHYCNT_RWCR); /* Write */
754 756
755 for (i=0; i < URL_TIMEOUT; i++) { 757 for (i=0; i < URL_TIMEOUT; i++) {
756 if (url_csr_read_1(un, URL_PHYCNT) & URL_PHYCNT_PHYOWN) 758 if (url_csr_read_1(un, URL_PHYCNT) & URL_PHYCNT_PHYOWN)
757 break; 759 break;
758 } 760 }
759 761
760 if (i == URL_TIMEOUT) { 762 if (i == URL_TIMEOUT) {
761 printf("%s: MII write timed out\n", 763 printf("%s: MII write timed out\n",
762 device_xname(un->un_dev)); 764 device_xname(un->un_dev));
763 return USBD_TIMEOUT; 765 return USBD_TIMEOUT;
764 } 766 }
765 767
766 return USBD_NORMAL_COMPLETION; 768 return USBD_NORMAL_COMPLETION;
767} 769}
768#endif 770#endif
769 771
770#ifdef _MODULE 772#ifdef _MODULE
771#include "ioconf.c" 773#include "ioconf.c"
772#endif 774#endif
773 775
774USBNET_MODULE(url) 776USBNET_MODULE(url)

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

--- src/sys/dev/usb/if_ure.c 2022/03/03 05:50:22 1.41
+++ src/sys/dev/usb/if_ure.c 2022/03/03 05:50:57 1.42
@@ -1,1163 +1,1173 @@ @@ -1,1163 +1,1173 @@
1/* $NetBSD: if_ure.c,v 1.41 2022/03/03 05:50:22 riastradh Exp $ */ 1/* $NetBSD: if_ure.c,v 1.42 2022/03/03 05:50:57 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.41 2022/03/03 05:50:22 riastradh Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.42 2022/03/03 05:50:57 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 int ure_uno_ioctl(struct ifnet *, u_long, void *); 89static int ure_uno_ioctl(struct ifnet *, u_long, void *);
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_ioctl = ure_uno_ioctl, 107 .uno_ioctl = ure_uno_ioctl,
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))
 400 return;
399 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) &
400 URE_CR_RST)) 402 URE_CR_RST))
401 break; 403 break;
402 usbd_delay_ms(un->un_udev, 10); 404 usbd_delay_ms(un->un_udev, 10);
403 } 405 }
404 if (i == URE_TIMEOUT) 406 if (i == URE_TIMEOUT)
405 URE_PRINTF(un, "reset never completed\n"); 407 URE_PRINTF(un, "reset never completed\n");
406} 408}
407 409
408static int 410static int
409ure_init_locked(struct ifnet *ifp) 411ure_init_locked(struct ifnet *ifp)
410{ 412{
411 struct usbnet * const un = ifp->if_softc; 413 struct usbnet * const un = ifp->if_softc;
412 uint8_t eaddr[8]; 414 uint8_t eaddr[8];
413 415
414 usbnet_isowned_core(un); 416 usbnet_isowned_core(un);
415 417
416 if (usbnet_isdying(un)) 418 if (usbnet_isdying(un))
417 return EIO; 419 return EIO;
418 420
419 /* Cancel pending I/O. */ 421 /* Cancel pending I/O. */
420 if (ifp->if_flags & IFF_RUNNING) 422 if (ifp->if_flags & IFF_RUNNING)
421 usbnet_stop(un, ifp, 1); 423 usbnet_stop(un, ifp, 1);
422 424
423 /* Set MAC address. */ 425 /* Set MAC address. */
424 memset(eaddr, 0, sizeof(eaddr)); 426 memset(eaddr, 0, sizeof(eaddr));
425 memcpy(eaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 427 memcpy(eaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
426 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);
427 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,
428 eaddr, 8); 430 eaddr, 8);
429 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);
430 432
431 /* Reset the packet filter. */ 433 /* Reset the packet filter. */
432 ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA, 434 ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA,
433 ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) & 435 ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) &
434 ~URE_FMC_FCR_MCU_EN); 436 ~URE_FMC_FCR_MCU_EN);
435 ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA, 437 ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA,
436 ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) | 438 ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) |
437 URE_FMC_FCR_MCU_EN); 439 URE_FMC_FCR_MCU_EN);
438 440
439 /* Enable transmit and receive. */ 441 /* Enable transmit and receive. */
440 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, 442 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA,
441 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 |
442 URE_CR_TE); 444 URE_CR_TE);
443 445
444 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,
445 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) &
446 ~URE_RXDY_GATED_EN); 448 ~URE_RXDY_GATED_EN);
447 449
448 /* Accept multicast frame or run promisc. mode. */ 450 /* Accept multicast frame or run promisc. mode. */
449 ure_rcvfilt_locked(un); 451 ure_rcvfilt_locked(un);
450 452
451 return usbnet_init_rx_tx(un); 453 return usbnet_init_rx_tx(un);
452} 454}
453 455
454static int 456static int
455ure_uno_init(struct ifnet *ifp) 457ure_uno_init(struct ifnet *ifp)
456{ 458{
457 struct usbnet * const un = ifp->if_softc; 459 struct usbnet * const un = ifp->if_softc;
458 460
459 usbnet_busy(un); 461 usbnet_busy(un);
460 int ret = ure_init_locked(ifp); 462 int ret = ure_init_locked(ifp);
461 usbnet_unbusy(un); 463 usbnet_unbusy(un);
462 464
463 return ret; 465 return ret;
464} 466}
465 467
466static void 468static void
467ure_uno_stop(struct ifnet *ifp, int disable __unused) 469ure_uno_stop(struct ifnet *ifp, int disable __unused)
468{ 470{
469 struct usbnet * const un = ifp->if_softc; 471 struct usbnet * const un = ifp->if_softc;
470 472
471 ure_reset(un); 473 ure_reset(un);
472} 474}
473 475
474static void 476static void
475ure_rtl8152_init(struct usbnet *un) 477ure_rtl8152_init(struct usbnet *un)
476{ 478{
477 uint32_t pwrctrl; 479 uint32_t pwrctrl;
478 480
479 /* Disable ALDPS. */ 481 /* Disable ALDPS. */
480 ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | 482 ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA |
481 URE_DIS_SDSAVE); 483 URE_DIS_SDSAVE);
482 usbd_delay_ms(un->un_udev, 20); 484 usbd_delay_ms(un->un_udev, 20);
483 485
484 if (un->un_flags & URE_FLAG_VER_4C00) { 486 if (un->un_flags & URE_FLAG_VER_4C00) {
485 ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, 487 ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA,
486 ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & 488 ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) &
487 ~URE_LED_MODE_MASK); 489 ~URE_LED_MODE_MASK);
488 } 490 }
489 491
490 ure_write_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB, 492 ure_write_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB,
491 ure_read_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB) & 493 ure_read_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB) &
492 ~URE_POWER_CUT); 494 ~URE_POWER_CUT);
493 ure_write_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB, 495 ure_write_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB,
494 ure_read_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB) & 496 ure_read_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB) &
495 ~URE_RESUME_INDICATE); 497 ~URE_RESUME_INDICATE);
496 498
497 ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, 499 ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA,
498 ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | 500 ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) |
499 URE_TX_10M_IDLE_EN | URE_PFM_PWM_SWITCH); 501 URE_TX_10M_IDLE_EN | URE_PFM_PWM_SWITCH);
500 pwrctrl = ure_read_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA); 502 pwrctrl = ure_read_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA);
501 pwrctrl &= ~URE_MCU_CLK_RATIO_MASK; 503 pwrctrl &= ~URE_MCU_CLK_RATIO_MASK;
502 pwrctrl |= URE_MCU_CLK_RATIO | URE_D3_CLK_GATED_EN; 504 pwrctrl |= URE_MCU_CLK_RATIO | URE_D3_CLK_GATED_EN;
503 ure_write_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, pwrctrl); 505 ure_write_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, pwrctrl);
504 ure_write_2(un, URE_PLA_GPHY_INTR_IMR, URE_MCU_TYPE_PLA, 506 ure_write_2(un, URE_PLA_GPHY_INTR_IMR, URE_MCU_TYPE_PLA,
505 URE_GPHY_STS_MSK | URE_SPEED_DOWN_MSK | URE_SPDWN_RXDV_MSK | 507 URE_GPHY_STS_MSK | URE_SPEED_DOWN_MSK | URE_SPDWN_RXDV_MSK |
506 URE_SPDWN_LINKCHG_MSK); 508 URE_SPDWN_LINKCHG_MSK);
507 509
508 /* Enable Rx aggregation. */ 510 /* Enable Rx aggregation. */
509 ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, 511 ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB,
510 ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & 512 ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) &
511 ~URE_RX_AGG_DISABLE); 513 ~URE_RX_AGG_DISABLE);
512 514
513 /* Disable ALDPS. */ 515 /* Disable ALDPS. */
514 ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | 516 ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA |
515 URE_DIS_SDSAVE); 517 URE_DIS_SDSAVE);
516 usbd_delay_ms(un->un_udev, 20); 518 usbd_delay_ms(un->un_udev, 20);
517 519
518 ure_init_fifo(un); 520 ure_init_fifo(un);
519 521
520 ure_write_1(un, URE_USB_TX_AGG, URE_MCU_TYPE_USB, 522 ure_write_1(un, URE_USB_TX_AGG, URE_MCU_TYPE_USB,
521 URE_TX_AGG_MAX_THRESHOLD); 523 URE_TX_AGG_MAX_THRESHOLD);
522 ure_write_4(un, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB, URE_RX_THR_HIGH); 524 ure_write_4(un, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB, URE_RX_THR_HIGH);
523 ure_write_4(un, URE_USB_TX_DMA, URE_MCU_TYPE_USB, 525 ure_write_4(un, URE_USB_TX_DMA, URE_MCU_TYPE_USB,
524 URE_TEST_MODE_DISABLE | URE_TX_SIZE_ADJUST1); 526 URE_TEST_MODE_DISABLE | URE_TX_SIZE_ADJUST1);
525} 527}
526 528
527static void 529static void
528ure_rtl8153_init(struct usbnet *un) 530ure_rtl8153_init(struct usbnet *un)
529{ 531{
530 uint16_t val; 532 uint16_t val;
531 uint8_t u1u2[8]; 533 uint8_t u1u2[8];
532 int i; 534 int i;
533 535
534 /* Disable ALDPS. */ 536 /* Disable ALDPS. */
535 ure_ocp_reg_write(un, URE_OCP_POWER_CFG, 537 ure_ocp_reg_write(un, URE_OCP_POWER_CFG,
536 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); 538 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS);
537 usbd_delay_ms(un->un_udev, 20); 539 usbd_delay_ms(un->un_udev, 20);
538 540
539 memset(u1u2, 0x00, sizeof(u1u2)); 541 memset(u1u2, 0x00, sizeof(u1u2));
540 ure_write_mem(un, URE_USB_TOLERANCE, 542 ure_write_mem(un, URE_USB_TOLERANCE,
541 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); 543 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
542 544
543 for (i = 0; i < URE_TIMEOUT; i++) { 545 for (i = 0; i < URE_TIMEOUT; i++) {
 546 if (usbnet_isdying(un))
 547 return;
544 if (ure_read_2(un, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) & 548 if (ure_read_2(un, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) &
545 URE_AUTOLOAD_DONE) 549 URE_AUTOLOAD_DONE)
546 break; 550 break;
547 usbd_delay_ms(un->un_udev, 10); 551 usbd_delay_ms(un->un_udev, 10);
548 } 552 }
549 if (i == URE_TIMEOUT) 553 if (i == URE_TIMEOUT)
550 URE_PRINTF(un, "timeout waiting for chip autoload\n"); 554 URE_PRINTF(un, "timeout waiting for chip autoload\n");
551 555
552 for (i = 0; i < URE_TIMEOUT; i++) { 556 for (i = 0; i < URE_TIMEOUT; i++) {
 557 if (usbnet_isdying(un))
 558 return;
553 val = ure_ocp_reg_read(un, URE_OCP_PHY_STATUS) & 559 val = ure_ocp_reg_read(un, URE_OCP_PHY_STATUS) &
554 URE_PHY_STAT_MASK; 560 URE_PHY_STAT_MASK;
555 if (val == URE_PHY_STAT_LAN_ON || val == URE_PHY_STAT_PWRDN) 561 if (val == URE_PHY_STAT_LAN_ON || val == URE_PHY_STAT_PWRDN)
556 break; 562 break;
557 usbd_delay_ms(un->un_udev, 10); 563 usbd_delay_ms(un->un_udev, 10);
558 } 564 }
559 if (i == URE_TIMEOUT) 565 if (i == URE_TIMEOUT)
560 URE_PRINTF(un, "timeout waiting for phy to stabilize\n"); 566 URE_PRINTF(un, "timeout waiting for phy to stabilize\n");
561 567
562 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, 568 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB,
563 ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) & 569 ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) &
564 ~URE_U2P3_ENABLE); 570 ~URE_U2P3_ENABLE);
565 571
566 if (un->un_flags & URE_FLAG_VER_5C10) { 572 if (un->un_flags & URE_FLAG_VER_5C10) {
567 val = ure_read_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB); 573 val = ure_read_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB);
568 val &= ~URE_PWD_DN_SCALE_MASK; 574 val &= ~URE_PWD_DN_SCALE_MASK;
569 val |= URE_PWD_DN_SCALE(96); 575 val |= URE_PWD_DN_SCALE(96);
570 ure_write_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val); 576 ure_write_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val);
571 577
572 ure_write_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB, 578 ure_write_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB,
573 ure_read_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB) | 579 ure_read_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB) |
574 URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND); 580 URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND);
575 } else if (un->un_flags & URE_FLAG_VER_5C20) { 581 } else if (un->un_flags & URE_FLAG_VER_5C20) {
576 ure_write_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA, 582 ure_write_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA,
577 ure_read_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) & 583 ure_read_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) &
578 ~URE_ECM_ALDPS); 584 ~URE_ECM_ALDPS);
579 } 585 }
580 if (un->un_flags & (URE_FLAG_VER_5C20 | URE_FLAG_VER_5C30)) { 586 if (un->un_flags & (URE_FLAG_VER_5C20 | URE_FLAG_VER_5C30)) {
581 val = ure_read_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB); 587 val = ure_read_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB);
582 if (ure_read_2(un, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) == 588 if (ure_read_2(un, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) ==
583 0) 589 0)
584 val &= ~URE_DYNAMIC_BURST; 590 val &= ~URE_DYNAMIC_BURST;
585 else 591 else
586 val |= URE_DYNAMIC_BURST; 592 val |= URE_DYNAMIC_BURST;
587 ure_write_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val); 593 ure_write_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val);
588 } 594 }
589 595
590 ure_write_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB, 596 ure_write_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB,
591 ure_read_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) | 597 ure_read_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) |
592 URE_EP4_FULL_FC); 598 URE_EP4_FULL_FC);
593 599
594 ure_write_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB, 600 ure_write_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB,
595 ure_read_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) & 601 ure_read_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) &
596 ~URE_TIMER11_EN); 602 ~URE_TIMER11_EN);
597 603
598 ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, 604 ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA,
599 ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & 605 ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) &
600 ~URE_LED_MODE_MASK); 606 ~URE_LED_MODE_MASK);
601 607
602 if ((un->un_flags & URE_FLAG_VER_5C10) && 608 if ((un->un_flags & URE_FLAG_VER_5C10) &&
603 un->un_udev->ud_speed != USB_SPEED_SUPER) 609 un->un_udev->ud_speed != USB_SPEED_SUPER)
604 val = URE_LPM_TIMER_500MS; 610 val = URE_LPM_TIMER_500MS;
605 else 611 else
606 val = URE_LPM_TIMER_500US; 612 val = URE_LPM_TIMER_500US;
607 ure_write_1(un, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB, 613 ure_write_1(un, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB,
608 val | URE_FIFO_EMPTY_1FB | URE_ROK_EXIT_LPM); 614 val | URE_FIFO_EMPTY_1FB | URE_ROK_EXIT_LPM);
609 615
610 val = ure_read_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB); 616 val = ure_read_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB);
611 val &= ~URE_SEN_VAL_MASK; 617 val &= ~URE_SEN_VAL_MASK;
612 val |= URE_SEN_VAL_NORMAL | URE_SEL_RXIDLE; 618 val |= URE_SEN_VAL_NORMAL | URE_SEL_RXIDLE;
613 ure_write_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val); 619 ure_write_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val);
614 620
615 ure_write_2(un, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001); 621 ure_write_2(un, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001);
616 622
617 ure_write_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB, 623 ure_write_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB,
618 ure_read_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) & 624 ure_read_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) &
619 ~(URE_PWR_EN | URE_PHASE2_EN)); 625 ~(URE_PWR_EN | URE_PHASE2_EN));
620 ure_write_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB, 626 ure_write_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB,
621 ure_read_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB) & 627 ure_read_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB) &
622 ~URE_PCUT_STATUS); 628 ~URE_PCUT_STATUS);
623 629
624 memset(u1u2, 0xff, sizeof(u1u2)); 630 memset(u1u2, 0xff, sizeof(u1u2));
625 ure_write_mem(un, URE_USB_TOLERANCE, 631 ure_write_mem(un, URE_USB_TOLERANCE,
626 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); 632 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
627 633
628 ure_write_2(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, 634 ure_write_2(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA,
629 URE_ALDPS_SPDWN_RATIO); 635 URE_ALDPS_SPDWN_RATIO);
630 ure_write_2(un, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA, 636 ure_write_2(un, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA,
631 URE_EEE_SPDWN_RATIO); 637 URE_EEE_SPDWN_RATIO);
632 ure_write_2(un, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA, 638 ure_write_2(un, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA,
633 URE_PKT_AVAIL_SPDWN_EN | URE_SUSPEND_SPDWN_EN | 639 URE_PKT_AVAIL_SPDWN_EN | URE_SUSPEND_SPDWN_EN |
634 URE_U1U2_SPDWN_EN | URE_L1_SPDWN_EN); 640 URE_U1U2_SPDWN_EN | URE_L1_SPDWN_EN);
635 ure_write_2(un, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA, 641 ure_write_2(un, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA,
636 URE_PWRSAVE_SPDWN_EN | URE_RXDV_SPDWN_EN | URE_TX10MIDLE_EN | 642 URE_PWRSAVE_SPDWN_EN | URE_RXDV_SPDWN_EN | URE_TX10MIDLE_EN |
637 URE_TP100_SPDWN_EN | URE_TP500_SPDWN_EN | URE_TP1000_SPDWN_EN | 643 URE_TP100_SPDWN_EN | URE_TP500_SPDWN_EN | URE_TP1000_SPDWN_EN |
638 URE_EEE_SPDWN_EN); 644 URE_EEE_SPDWN_EN);
639 645
640 val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); 646 val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
641 if (!(un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10))) 647 if (!(un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10)))
642 val |= URE_U2P3_ENABLE; 648 val |= URE_U2P3_ENABLE;
643 else 649 else
644 val &= ~URE_U2P3_ENABLE; 650 val &= ~URE_U2P3_ENABLE;
645 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); 651 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
646 652
647 memset(u1u2, 0x00, sizeof(u1u2)); 653 memset(u1u2, 0x00, sizeof(u1u2));
648 ure_write_mem(un, URE_USB_TOLERANCE, 654 ure_write_mem(un, URE_USB_TOLERANCE,
649 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); 655 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
650 656
651 /* Disable ALDPS. */ 657 /* Disable ALDPS. */
652 ure_ocp_reg_write(un, URE_OCP_POWER_CFG, 658 ure_ocp_reg_write(un, URE_OCP_POWER_CFG,
653 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); 659 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS);
654 usbd_delay_ms(un->un_udev, 20); 660 usbd_delay_ms(un->un_udev, 20);
655 661
656 ure_init_fifo(un); 662 ure_init_fifo(un);
657 663
658 /* Enable Rx aggregation. */ 664 /* Enable Rx aggregation. */
659 ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, 665 ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB,
660 ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & 666 ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) &
661 ~URE_RX_AGG_DISABLE); 667 ~URE_RX_AGG_DISABLE);
662 668
663 val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); 669 val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
664 if (!(un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10))) 670 if (!(un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10)))
665 val |= URE_U2P3_ENABLE; 671 val |= URE_U2P3_ENABLE;
666 else 672 else
667 val &= ~URE_U2P3_ENABLE; 673 val &= ~URE_U2P3_ENABLE;
668 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); 674 ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
669 675
670 memset(u1u2, 0xff, sizeof(u1u2)); 676 memset(u1u2, 0xff, sizeof(u1u2));
671 ure_write_mem(un, URE_USB_TOLERANCE, 677 ure_write_mem(un, URE_USB_TOLERANCE,
672 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); 678 URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
673} 679}
674 680
675static void 681static void
676ure_disable_teredo(struct usbnet *un) 682ure_disable_teredo(struct usbnet *un)
677{ 683{
678 ure_write_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA, 684 ure_write_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA,
679 ure_read_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA) & 685 ure_read_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA) &
680 ~(URE_TEREDO_SEL | URE_TEREDO_RS_EVENT_MASK | URE_OOB_TEREDO_EN)); 686 ~(URE_TEREDO_SEL | URE_TEREDO_RS_EVENT_MASK | URE_OOB_TEREDO_EN));
681 ure_write_2(un, URE_PLA_WDT6_CTRL, URE_MCU_TYPE_PLA, 687 ure_write_2(un, URE_PLA_WDT6_CTRL, URE_MCU_TYPE_PLA,
682 URE_WDT6_SET_MODE); 688 URE_WDT6_SET_MODE);
683 ure_write_2(un, URE_PLA_REALWOW_TIMER, URE_MCU_TYPE_PLA, 0); 689 ure_write_2(un, URE_PLA_REALWOW_TIMER, URE_MCU_TYPE_PLA, 0);
684 ure_write_4(un, URE_PLA_TEREDO_TIMER, URE_MCU_TYPE_PLA, 0); 690 ure_write_4(un, URE_PLA_TEREDO_TIMER, URE_MCU_TYPE_PLA, 0);
685} 691}
686 692
687static void 693static void
688ure_init_fifo(struct usbnet *un) 694ure_init_fifo(struct usbnet *un)
689{ 695{
690 uint32_t rxmode, rx_fifo1, rx_fifo2; 696 uint32_t rxmode, rx_fifo1, rx_fifo2;
691 int i; 697 int i;
692 698
693 ure_write_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, 699 ure_write_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA,
694 ure_read_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) | 700 ure_read_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) |
695 URE_RXDY_GATED_EN); 701 URE_RXDY_GATED_EN);
696 702
697 ure_disable_teredo(un); 703 ure_disable_teredo(un);
698 704
699 rxmode = ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA); 705 rxmode = ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA);
700 rxmode &= ~URE_RCR_ACPT_ALL; 706 rxmode &= ~URE_RCR_ACPT_ALL;
701 rxmode |= URE_RCR_APM | URE_RCR_AB; /* accept my own DA and bcast */ 707 rxmode |= URE_RCR_APM | URE_RCR_AB; /* accept my own DA and bcast */
702 ure_write_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode); 708 ure_write_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode);
703 709
704 if (!(un->un_flags & URE_FLAG_8152)) { 710 if (!(un->un_flags & URE_FLAG_8152)) {
705 if (un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10 | 711 if (un->un_flags & (URE_FLAG_VER_5C00 | URE_FLAG_VER_5C10 |
706 URE_FLAG_VER_5C20)) 712 URE_FLAG_VER_5C20))
707 ure_ocp_reg_write(un, URE_OCP_ADC_CFG, 713 ure_ocp_reg_write(un, URE_OCP_ADC_CFG,
708 URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L); 714 URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L);
709 if (un->un_flags & URE_FLAG_VER_5C00) 715 if (un->un_flags & URE_FLAG_VER_5C00)
710 ure_ocp_reg_write(un, URE_OCP_EEE_CFG, 716 ure_ocp_reg_write(un, URE_OCP_EEE_CFG,
711 ure_ocp_reg_read(un, URE_OCP_EEE_CFG) & 717 ure_ocp_reg_read(un, URE_OCP_EEE_CFG) &
712 ~URE_CTAP_SHORT_EN); 718 ~URE_CTAP_SHORT_EN);
713 ure_ocp_reg_write(un, URE_OCP_POWER_CFG, 719 ure_ocp_reg_write(un, URE_OCP_POWER_CFG,
714 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) | 720 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) |
715 URE_EEE_CLKDIV_EN); 721 URE_EEE_CLKDIV_EN);
716 ure_ocp_reg_write(un, URE_OCP_DOWN_SPEED, 722 ure_ocp_reg_write(un, URE_OCP_DOWN_SPEED,
717 ure_ocp_reg_read(un, URE_OCP_DOWN_SPEED) | 723 ure_ocp_reg_read(un, URE_OCP_DOWN_SPEED) |
718 URE_EN_10M_BGOFF); 724 URE_EN_10M_BGOFF);
719 ure_ocp_reg_write(un, URE_OCP_POWER_CFG, 725 ure_ocp_reg_write(un, URE_OCP_POWER_CFG,
720 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) | 726 ure_ocp_reg_read(un, URE_OCP_POWER_CFG) |
721 URE_EN_10M_PLLOFF); 727 URE_EN_10M_PLLOFF);
722 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE); 728 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE);
723 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0b13); 729 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0b13);
724 ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, 730 ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA,
725 ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | 731 ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) |
726 URE_PFM_PWM_SWITCH); 732 URE_PFM_PWM_SWITCH);
727 733
728 /* Enable LPF corner auto tune. */ 734 /* Enable LPF corner auto tune. */
729 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG); 735 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG);
730 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0xf70f); 736 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0xf70f);
731 737
732 /* Adjust 10M amplitude. */ 738 /* Adjust 10M amplitude. */
733 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1); 739 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1);
734 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x00af); 740 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x00af);
735 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2); 741 ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2);
736 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0208); 742 ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0208);
737 } 743 }
738 744
739 ure_reset(un); 745 ure_reset(un);
740 746
741 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, 0); 747 ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, 0);
742 748
743 ure_write_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA, 749 ure_write_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA,
744 ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & 750 ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) &
745 ~URE_NOW_IS_OOB); 751 ~URE_NOW_IS_OOB);
746 752
747 ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, 753 ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA,
748 ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) & 754 ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) &
749 ~URE_MCU_BORW_EN); 755 ~URE_MCU_BORW_EN);
750 for (i = 0; i < URE_TIMEOUT; i++) { 756 for (i = 0; i < URE_TIMEOUT; i++) {
 757 if (usbnet_isdying(un))
 758 return;
751 if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & 759 if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) &
752 URE_LINK_LIST_READY) 760 URE_LINK_LIST_READY)
753 break; 761 break;
754 usbd_delay_ms(un->un_udev, 10); 762 usbd_delay_ms(un->un_udev, 10);
755 } 763 }
756 if (i == URE_TIMEOUT) 764 if (i == URE_TIMEOUT)
757 URE_PRINTF(un, "timeout waiting for OOB control\n"); 765 URE_PRINTF(un, "timeout waiting for OOB control\n");
758 ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, 766 ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA,
759 ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) | 767 ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) |
760 URE_RE_INIT_LL); 768 URE_RE_INIT_LL);
761 for (i = 0; i < URE_TIMEOUT; i++) { 769 for (i = 0; i < URE_TIMEOUT; i++) {
 770 if (usbnet_isdying(un))
 771 return;
762 if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & 772 if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) &
763 URE_LINK_LIST_READY) 773 URE_LINK_LIST_READY)
764 break; 774 break;
765 usbd_delay_ms(un->un_udev, 10); 775 usbd_delay_ms(un->un_udev, 10);
766 } 776 }
767 if (i == URE_TIMEOUT) 777 if (i == URE_TIMEOUT)
768 URE_PRINTF(un, "timeout waiting for OOB control\n"); 778 URE_PRINTF(un, "timeout waiting for OOB control\n");
769 779
770 ure_write_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA, 780 ure_write_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA,
771 ure_read_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA) & 781 ure_read_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA) &
772 ~URE_CPCR_RX_VLAN); 782 ~URE_CPCR_RX_VLAN);
773 ure_write_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA, 783 ure_write_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA,
774 ure_read_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA) | 784 ure_read_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA) |
775 URE_TCR0_AUTO_FIFO); 785 URE_TCR0_AUTO_FIFO);
776 786
777 /* Configure Rx FIFO threshold and coalescing. */ 787 /* Configure Rx FIFO threshold and coalescing. */
778 ure_write_4(un, URE_PLA_RXFIFO_CTRL0, URE_MCU_TYPE_PLA, 788 ure_write_4(un, URE_PLA_RXFIFO_CTRL0, URE_MCU_TYPE_PLA,
779 URE_RXFIFO_THR1_NORMAL); 789 URE_RXFIFO_THR1_NORMAL);
780 if (un->un_udev->ud_speed == USB_SPEED_FULL) { 790 if (un->un_udev->ud_speed == USB_SPEED_FULL) {
781 rx_fifo1 = URE_RXFIFO_THR2_FULL; 791 rx_fifo1 = URE_RXFIFO_THR2_FULL;
782 rx_fifo2 = URE_RXFIFO_THR3_FULL; 792 rx_fifo2 = URE_RXFIFO_THR3_FULL;
783 } else { 793 } else {
784 rx_fifo1 = URE_RXFIFO_THR2_HIGH; 794 rx_fifo1 = URE_RXFIFO_THR2_HIGH;
785 rx_fifo2 = URE_RXFIFO_THR3_HIGH; 795 rx_fifo2 = URE_RXFIFO_THR3_HIGH;
786 } 796 }
787 ure_write_4(un, URE_PLA_RXFIFO_CTRL1, URE_MCU_TYPE_PLA, rx_fifo1); 797 ure_write_4(un, URE_PLA_RXFIFO_CTRL1, URE_MCU_TYPE_PLA, rx_fifo1);
788 ure_write_4(un, URE_PLA_RXFIFO_CTRL2, URE_MCU_TYPE_PLA, rx_fifo2); 798 ure_write_4(un, URE_PLA_RXFIFO_CTRL2, URE_MCU_TYPE_PLA, rx_fifo2);
789 799
790 /* Configure Tx FIFO threshold. */ 800 /* Configure Tx FIFO threshold. */
791 ure_write_4(un, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA, 801 ure_write_4(un, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA,
792 URE_TXFIFO_THR_NORMAL); 802 URE_TXFIFO_THR_NORMAL);
793} 803}
794 804
795static int 805static int
796ure_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 806ure_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
797{ 807{
798 struct usbnet * const un = ifp->if_softc; 808 struct usbnet * const un = ifp->if_softc;
799 809
800 usbnet_lock_core(un); 810 usbnet_lock_core(un);
801 usbnet_busy(un); 811 usbnet_busy(un);
802 812
803 switch (cmd) { 813 switch (cmd) {
804 case SIOCADDMULTI: 814 case SIOCADDMULTI:
805 case SIOCDELMULTI: 815 case SIOCDELMULTI:
806 ure_rcvfilt_locked(un); 816 ure_rcvfilt_locked(un);
807 break; 817 break;
808 default: 818 default:
809 break; 819 break;
810 } 820 }
811 821
812 usbnet_unbusy(un); 822 usbnet_unbusy(un);
813 usbnet_unlock_core(un); 823 usbnet_unlock_core(un);
814 824
815 return 0; 825 return 0;
816} 826}
817 827
818static int 828static int
819ure_match(device_t parent, cfdata_t match, void *aux) 829ure_match(device_t parent, cfdata_t match, void *aux)
820{ 830{
821 struct usb_attach_arg *uaa = aux; 831 struct usb_attach_arg *uaa = aux;
822 832
823 return usb_lookup(ure_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ? 833 return usb_lookup(ure_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ?
824 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 834 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
825} 835}
826 836
827static void 837static void
828ure_attach(device_t parent, device_t self, void *aux) 838ure_attach(device_t parent, device_t self, void *aux)
829{ 839{
830 USBNET_MII_DECL_DEFAULT(unm); 840 USBNET_MII_DECL_DEFAULT(unm);
831 struct usbnet * const un = device_private(self); 841 struct usbnet * const un = device_private(self);
832 struct usb_attach_arg *uaa = aux; 842 struct usb_attach_arg *uaa = aux;
833 struct usbd_device *dev = uaa->uaa_device; 843 struct usbd_device *dev = uaa->uaa_device;
834 usb_interface_descriptor_t *id; 844 usb_interface_descriptor_t *id;
835 usb_endpoint_descriptor_t *ed; 845 usb_endpoint_descriptor_t *ed;
836 int error, i; 846 int error, i;
837 uint16_t ver; 847 uint16_t ver;
838 uint8_t eaddr[8]; /* 2byte padded */ 848 uint8_t eaddr[8]; /* 2byte padded */
839 char *devinfop; 849 char *devinfop;
840 uint32_t maclo, machi; 850 uint32_t maclo, machi;
841 851
842 aprint_naive("\n"); 852 aprint_naive("\n");
843 aprint_normal("\n"); 853 aprint_normal("\n");
844 devinfop = usbd_devinfo_alloc(dev, 0); 854 devinfop = usbd_devinfo_alloc(dev, 0);
845 aprint_normal_dev(self, "%s\n", devinfop); 855 aprint_normal_dev(self, "%s\n", devinfop);
846 usbd_devinfo_free(devinfop); 856 usbd_devinfo_free(devinfop);
847 857
848 un->un_dev = self; 858 un->un_dev = self;
849 un->un_udev = dev; 859 un->un_udev = dev;
850 un->un_sc = un; 860 un->un_sc = un;
851 un->un_ops = &ure_ops; 861 un->un_ops = &ure_ops;
852 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 862 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
853 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 863 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
854 un->un_rx_list_cnt = URE_RX_LIST_CNT; 864 un->un_rx_list_cnt = URE_RX_LIST_CNT;
855 un->un_tx_list_cnt = URE_TX_LIST_CNT; 865 un->un_tx_list_cnt = URE_TX_LIST_CNT;
856 un->un_rx_bufsz = URE_BUFSZ; 866 un->un_rx_bufsz = URE_BUFSZ;
857 un->un_tx_bufsz = URE_BUFSZ; 867 un->un_tx_bufsz = URE_BUFSZ;
858 868
859#define URE_CONFIG_NO 1 /* XXX */ 869#define URE_CONFIG_NO 1 /* XXX */
860 error = usbd_set_config_no(dev, URE_CONFIG_NO, 1); 870 error = usbd_set_config_no(dev, URE_CONFIG_NO, 1);
861 if (error) { 871 if (error) {
862 aprint_error_dev(self, "failed to set configuration: %s\n", 872 aprint_error_dev(self, "failed to set configuration: %s\n",
863 usbd_errstr(error)); 873 usbd_errstr(error));
864 return; /* XXX */ 874 return; /* XXX */
865 } 875 }
866 876
867 if (uaa->uaa_product == USB_PRODUCT_REALTEK_RTL8152) 877 if (uaa->uaa_product == USB_PRODUCT_REALTEK_RTL8152)
868 un->un_flags |= URE_FLAG_8152; 878 un->un_flags |= URE_FLAG_8152;
869 879
870#define URE_IFACE_IDX 0 /* XXX */ 880#define URE_IFACE_IDX 0 /* XXX */
871 error = usbd_device2interface_handle(dev, URE_IFACE_IDX, &un->un_iface); 881 error = usbd_device2interface_handle(dev, URE_IFACE_IDX, &un->un_iface);
872 if (error) { 882 if (error) {
873 aprint_error_dev(self, "failed to get interface handle: %s\n", 883 aprint_error_dev(self, "failed to get interface handle: %s\n",
874 usbd_errstr(error)); 884 usbd_errstr(error));
875 return; /* XXX */ 885 return; /* XXX */
876 } 886 }
877 887
878 id = usbd_get_interface_descriptor(un->un_iface); 888 id = usbd_get_interface_descriptor(un->un_iface);
879 for (i = 0; i < id->bNumEndpoints; i++) { 889 for (i = 0; i < id->bNumEndpoints; i++) {
880 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 890 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
881 if (ed == NULL) { 891 if (ed == NULL) {
882 aprint_error_dev(self, "couldn't get ep %d\n", i); 892 aprint_error_dev(self, "couldn't get ep %d\n", i);
883 return; /* XXX */ 893 return; /* XXX */
884 } 894 }
885 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 895 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
886 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 896 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
887 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 897 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
888 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 898 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
889 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 899 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
890 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 900 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
891 } 901 }
892 } 902 }
893 903
894 /* Set these up now for ure_ctl(). */ 904 /* Set these up now for ure_ctl(). */
895 usbnet_attach(un, "uredet"); 905 usbnet_attach(un, "uredet");
896 906
897 un->un_phyno = 0; 907 un->un_phyno = 0;
898 908
899 ver = ure_read_2(un, URE_PLA_TCR1, URE_MCU_TYPE_PLA) & URE_VERSION_MASK; 909 ver = ure_read_2(un, URE_PLA_TCR1, URE_MCU_TYPE_PLA) & URE_VERSION_MASK;
900 switch (ver) { 910 switch (ver) {
901 case 0x4c00: 911 case 0x4c00:
902 un->un_flags |= URE_FLAG_VER_4C00; 912 un->un_flags |= URE_FLAG_VER_4C00;
903 break; 913 break;
904 case 0x4c10: 914 case 0x4c10:
905 un->un_flags |= URE_FLAG_VER_4C10; 915 un->un_flags |= URE_FLAG_VER_4C10;
906 break; 916 break;
907 case 0x5c00: 917 case 0x5c00:
908 un->un_flags |= URE_FLAG_VER_5C00; 918 un->un_flags |= URE_FLAG_VER_5C00;
909 break; 919 break;
910 case 0x5c10: 920 case 0x5c10:
911 un->un_flags |= URE_FLAG_VER_5C10; 921 un->un_flags |= URE_FLAG_VER_5C10;
912 break; 922 break;
913 case 0x5c20: 923 case 0x5c20:
914 un->un_flags |= URE_FLAG_VER_5C20; 924 un->un_flags |= URE_FLAG_VER_5C20;
915 break; 925 break;
916 case 0x5c30: 926 case 0x5c30:
917 un->un_flags |= URE_FLAG_VER_5C30; 927 un->un_flags |= URE_FLAG_VER_5C30;
918 break; 928 break;
919 default: 929 default:
920 /* fake addr? or just fail? */ 930 /* fake addr? or just fail? */
921 break; 931 break;
922 } 932 }
923 aprint_normal_dev(self, "RTL%d %sver %04x\n", 933 aprint_normal_dev(self, "RTL%d %sver %04x\n",
924 (un->un_flags & URE_FLAG_8152) ? 8152 : 8153, 934 (un->un_flags & URE_FLAG_8152) ? 8152 : 8153,
925 (un->un_flags != 0) ? "" : "unknown ", 935 (un->un_flags != 0) ? "" : "unknown ",
926 ver); 936 ver);
927 937
928 usbnet_lock_core(un); 938 usbnet_lock_core(un);
929 if (un->un_flags & URE_FLAG_8152) 939 if (un->un_flags & URE_FLAG_8152)
930 ure_rtl8152_init(un); 940 ure_rtl8152_init(un);
931 else 941 else
932 ure_rtl8153_init(un); 942 ure_rtl8153_init(un);
933 943
934 if ((un->un_flags & URE_FLAG_VER_4C00) || 944 if ((un->un_flags & URE_FLAG_VER_4C00) ||
935 (un->un_flags & URE_FLAG_VER_4C10)) 945 (un->un_flags & URE_FLAG_VER_4C10))
936 ure_read_mem(un, URE_PLA_IDR, URE_MCU_TYPE_PLA, eaddr, 946 ure_read_mem(un, URE_PLA_IDR, URE_MCU_TYPE_PLA, eaddr,
937 sizeof(eaddr)); 947 sizeof(eaddr));
938 else 948 else
939 ure_read_mem(un, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr, 949 ure_read_mem(un, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr,
940 sizeof(eaddr)); 950 sizeof(eaddr));
941 usbnet_unlock_core(un); 951 usbnet_unlock_core(un);
942 if (ETHER_IS_ZERO(eaddr)) { 952 if (ETHER_IS_ZERO(eaddr)) {
943 maclo = 0x00f2 | (cprng_strong32() & 0xffff0000); 953 maclo = 0x00f2 | (cprng_strong32() & 0xffff0000);
944 machi = cprng_strong32() & 0xffff; 954 machi = cprng_strong32() & 0xffff;
945 eaddr[0] = maclo & 0xff; 955 eaddr[0] = maclo & 0xff;
946 eaddr[1] = (maclo >> 8) & 0xff; 956 eaddr[1] = (maclo >> 8) & 0xff;
947 eaddr[2] = (maclo >> 16) & 0xff; 957 eaddr[2] = (maclo >> 16) & 0xff;
948 eaddr[3] = (maclo >> 24) & 0xff; 958 eaddr[3] = (maclo >> 24) & 0xff;
949 eaddr[4] = machi & 0xff; 959 eaddr[4] = machi & 0xff;
950 eaddr[5] = (machi >> 8) & 0xff; 960 eaddr[5] = (machi >> 8) & 0xff;
951 } 961 }
952 memcpy(un->un_eaddr, eaddr, sizeof(un->un_eaddr)); 962 memcpy(un->un_eaddr, eaddr, sizeof(un->un_eaddr));
953 963
954 struct ifnet *ifp = usbnet_ifp(un); 964 struct ifnet *ifp = usbnet_ifp(un);
955 965
956 /* 966 /*
957 * We don't support TSOv4 and v6 for now, that are required to 967 * We don't support TSOv4 and v6 for now, that are required to
958 * be handled in software for some cases. 968 * be handled in software for some cases.
959 */ 969 */
960 ifp->if_capabilities = IFCAP_CSUM_IPv4_Tx | 970 ifp->if_capabilities = IFCAP_CSUM_IPv4_Tx |
961 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx; 971 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx;
962#ifdef INET6 972#ifdef INET6
963 ifp->if_capabilities |= IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx; 973 ifp->if_capabilities |= IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx;
964#endif 974#endif
965 if (un->un_flags & ~URE_FLAG_VER_4C00) { 975 if (un->un_flags & ~URE_FLAG_VER_4C00) {
966 ifp->if_capabilities |= IFCAP_CSUM_IPv4_Rx | 976 ifp->if_capabilities |= IFCAP_CSUM_IPv4_Rx |
967 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | 977 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |
968 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx; 978 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx;
969 } 979 }
970 struct ethercom *ec = usbnet_ec(un); 980 struct ethercom *ec = usbnet_ec(un);
971 ec->ec_capabilities = ETHERCAP_VLAN_MTU; 981 ec->ec_capabilities = ETHERCAP_VLAN_MTU;
972#ifdef notyet 982#ifdef notyet
973 ec->ec_capabilities |= ETHERCAP_JUMBO_MTU; 983 ec->ec_capabilities |= ETHERCAP_JUMBO_MTU;
974#endif 984#endif
975 985
976 unm.un_mii_phyloc = un->un_phyno; 986 unm.un_mii_phyloc = un->un_phyno;
977 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 987 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
978 0, &unm); 988 0, &unm);
979} 989}
980 990
981static void 991static void
982ure_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 992ure_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
983{ 993{
984 struct ifnet *ifp = usbnet_ifp(un); 994 struct ifnet *ifp = usbnet_ifp(un);
985 uint8_t *buf = c->unc_buf; 995 uint8_t *buf = c->unc_buf;
986 uint16_t pkt_len = 0; 996 uint16_t pkt_len = 0;
987 uint16_t pkt_count = 0; 997 uint16_t pkt_count = 0;
988 struct ure_rxpkt rxhdr; 998 struct ure_rxpkt rxhdr;
989 999
990 do { 1000 do {
991 if (total_len < sizeof(rxhdr)) { 1001 if (total_len < sizeof(rxhdr)) {
992 DPRINTF(("too few bytes left for a packet header\n")); 1002 DPRINTF(("too few bytes left for a packet header\n"));
993 if_statinc(ifp, if_ierrors); 1003 if_statinc(ifp, if_ierrors);
994 return; 1004 return;
995 } 1005 }
996 1006
997 buf += roundup(pkt_len, 8); 1007 buf += roundup(pkt_len, 8);
998 1008
999 memcpy(&rxhdr, buf, sizeof(rxhdr)); 1009 memcpy(&rxhdr, buf, sizeof(rxhdr));
1000 total_len -= sizeof(rxhdr); 1010 total_len -= sizeof(rxhdr);
1001 1011
1002 pkt_len = le32toh(rxhdr.ure_pktlen) & URE_RXPKT_LEN_MASK; 1012 pkt_len = le32toh(rxhdr.ure_pktlen) & URE_RXPKT_LEN_MASK;
1003 DPRINTFN(4, ("next packet is %d bytes\n", pkt_len)); 1013 DPRINTFN(4, ("next packet is %d bytes\n", pkt_len));
1004 if (pkt_len > total_len) { 1014 if (pkt_len > total_len) {
1005 DPRINTF(("not enough bytes left for next packet\n")); 1015 DPRINTF(("not enough bytes left for next packet\n"));
1006 if_statinc(ifp, if_ierrors); 1016 if_statinc(ifp, if_ierrors);
1007 return; 1017 return;
1008 } 1018 }
1009 1019
1010 total_len -= roundup(pkt_len, 8); 1020 total_len -= roundup(pkt_len, 8);
1011 buf += sizeof(rxhdr); 1021 buf += sizeof(rxhdr);
1012 1022
1013 usbnet_enqueue(un, buf, pkt_len - ETHER_CRC_LEN, 1023 usbnet_enqueue(un, buf, pkt_len - ETHER_CRC_LEN,
1014 ure_rxcsum(ifp, &rxhdr), 0, 0); 1024 ure_rxcsum(ifp, &rxhdr), 0, 0);
1015 1025
1016 pkt_count++; 1026 pkt_count++;
1017  1027
1018 } while (total_len > 0); 1028 } while (total_len > 0);
1019 1029
1020 if (pkt_count) 1030 if (pkt_count)
1021 rnd_add_uint32(usbnet_rndsrc(un), pkt_count); 1031 rnd_add_uint32(usbnet_rndsrc(un), pkt_count);
1022} 1032}
1023 1033
1024static int 1034static int
1025ure_rxcsum(struct ifnet *ifp, struct ure_rxpkt *rp) 1035ure_rxcsum(struct ifnet *ifp, struct ure_rxpkt *rp)
1026{ 1036{
1027 int enabled = ifp->if_csum_flags_rx, flags = 0; 1037 int enabled = ifp->if_csum_flags_rx, flags = 0;
1028 uint32_t csum, misc; 1038 uint32_t csum, misc;
1029 1039
1030 if (enabled == 0) 1040 if (enabled == 0)
1031 return 0; 1041 return 0;
1032 1042
1033 csum = le32toh(rp->ure_csum); 1043 csum = le32toh(rp->ure_csum);
1034 misc = le32toh(rp->ure_misc); 1044 misc = le32toh(rp->ure_misc);
1035 1045
1036 if (csum & URE_RXPKT_IPV4_CS) { 1046 if (csum & URE_RXPKT_IPV4_CS) {
1037 flags |= M_CSUM_IPv4; 1047 flags |= M_CSUM_IPv4;
1038 if (csum & URE_RXPKT_TCP_CS) 1048 if (csum & URE_RXPKT_TCP_CS)
1039 flags |= M_CSUM_TCPv4; 1049 flags |= M_CSUM_TCPv4;
1040 if (csum & URE_RXPKT_UDP_CS) 1050 if (csum & URE_RXPKT_UDP_CS)
1041 flags |= M_CSUM_UDPv4; 1051 flags |= M_CSUM_UDPv4;
1042 } else if (csum & URE_RXPKT_IPV6_CS) { 1052 } else if (csum & URE_RXPKT_IPV6_CS) {
1043 flags = 0; 1053 flags = 0;
1044 if (csum & URE_RXPKT_TCP_CS) 1054 if (csum & URE_RXPKT_TCP_CS)
1045 flags |= M_CSUM_TCPv6; 1055 flags |= M_CSUM_TCPv6;
1046 if (csum & URE_RXPKT_UDP_CS) 1056 if (csum & URE_RXPKT_UDP_CS)
1047 flags |= M_CSUM_UDPv6; 1057 flags |= M_CSUM_UDPv6;
1048 } 1058 }
1049 1059
1050 flags &= enabled; 1060 flags &= enabled;
1051 if (__predict_false((flags & M_CSUM_IPv4) && 1061 if (__predict_false((flags & M_CSUM_IPv4) &&
1052 (misc & URE_RXPKT_IP_F))) 1062 (misc & URE_RXPKT_IP_F)))
1053 flags |= M_CSUM_IPv4_BAD; 1063 flags |= M_CSUM_IPv4_BAD;
1054 if (__predict_false( 1064 if (__predict_false(
1055 ((flags & (M_CSUM_TCPv4 | M_CSUM_TCPv6)) && (misc & URE_RXPKT_TCP_F)) 1065 ((flags & (M_CSUM_TCPv4 | M_CSUM_TCPv6)) && (misc & URE_RXPKT_TCP_F))
1056 || ((flags & (M_CSUM_UDPv4 | M_CSUM_UDPv6)) && (misc & URE_RXPKT_UDP_F)) 1066 || ((flags & (M_CSUM_UDPv4 | M_CSUM_UDPv6)) && (misc & URE_RXPKT_UDP_F))
1057 )) 1067 ))
1058 flags |= M_CSUM_TCP_UDP_BAD; 1068 flags |= M_CSUM_TCP_UDP_BAD;
1059 1069
1060 return flags; 1070 return flags;
1061} 1071}
1062 1072
1063static unsigned 1073static unsigned
1064ure_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 1074ure_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
1065{ 1075{
1066 struct ure_txpkt txhdr; 1076 struct ure_txpkt txhdr;
1067 uint32_t frm_len = 0; 1077 uint32_t frm_len = 0;
1068 uint8_t *buf = c->unc_buf; 1078 uint8_t *buf = c->unc_buf;
1069 1079
1070 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(txhdr)) 1080 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(txhdr))
1071 return 0; 1081 return 0;
1072 1082
1073 /* header */ 1083 /* header */
1074 txhdr.ure_pktlen = htole32(m->m_pkthdr.len | URE_TXPKT_TX_FS | 1084 txhdr.ure_pktlen = htole32(m->m_pkthdr.len | URE_TXPKT_TX_FS |
1075 URE_TXPKT_TX_LS); 1085 URE_TXPKT_TX_LS);
1076 txhdr.ure_csum = htole32(ure_txcsum(m)); 1086 txhdr.ure_csum = htole32(ure_txcsum(m));
1077 memcpy(buf, &txhdr, sizeof(txhdr)); 1087 memcpy(buf, &txhdr, sizeof(txhdr));
1078 buf += sizeof(txhdr); 1088 buf += sizeof(txhdr);
1079 frm_len = sizeof(txhdr); 1089 frm_len = sizeof(txhdr);
1080 1090
1081 /* packet */ 1091 /* packet */
1082 m_copydata(m, 0, m->m_pkthdr.len, buf); 1092 m_copydata(m, 0, m->m_pkthdr.len, buf);
1083 frm_len += m->m_pkthdr.len; 1093 frm_len += m->m_pkthdr.len;
1084 1094
1085 DPRINTFN(2, ("tx %d bytes\n", frm_len)); 1095 DPRINTFN(2, ("tx %d bytes\n", frm_len));
1086 1096
1087 return frm_len; 1097 return frm_len;
1088} 1098}
1089 1099
1090/* 1100/*
1091 * We need to calculate L4 checksum in software, if the offset of 1101 * We need to calculate L4 checksum in software, if the offset of
1092 * L4 header is larger than 0x7ff = 2047. 1102 * L4 header is larger than 0x7ff = 2047.
1093 */ 1103 */
1094static uint32_t 1104static uint32_t
1095ure_txcsum(struct mbuf *m) 1105ure_txcsum(struct mbuf *m)
1096{ 1106{
1097 struct ether_header *eh; 1107 struct ether_header *eh;
1098 int flags = m->m_pkthdr.csum_flags; 1108 int flags = m->m_pkthdr.csum_flags;
1099 uint32_t data = m->m_pkthdr.csum_data; 1109 uint32_t data = m->m_pkthdr.csum_data;
1100 uint32_t reg = 0; 1110 uint32_t reg = 0;
1101 int l3off, l4off; 1111 int l3off, l4off;
1102 uint16_t type; 1112 uint16_t type;
1103 1113
1104 if (flags == 0) 1114 if (flags == 0)
1105 return 0; 1115 return 0;
1106 1116
1107 if (__predict_true(m->m_len >= (int)sizeof(*eh))) { 1117 if (__predict_true(m->m_len >= (int)sizeof(*eh))) {
1108 eh = mtod(m, struct ether_header *); 1118 eh = mtod(m, struct ether_header *);
1109 type = eh->ether_type; 1119 type = eh->ether_type;
1110 } else 1120 } else
1111 m_copydata(m, offsetof(struct ether_header, ether_type), 1121 m_copydata(m, offsetof(struct ether_header, ether_type),
1112 sizeof(type), &type); 1122 sizeof(type), &type);
1113 switch (type = htons(type)) { 1123 switch (type = htons(type)) {
1114 case ETHERTYPE_IP: 1124 case ETHERTYPE_IP:
1115 case ETHERTYPE_IPV6: 1125 case ETHERTYPE_IPV6:
1116 l3off = ETHER_HDR_LEN; 1126 l3off = ETHER_HDR_LEN;
1117 break; 1127 break;
1118 case ETHERTYPE_VLAN: 1128 case ETHERTYPE_VLAN:
1119 l3off = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 1129 l3off = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
1120 break; 1130 break;
1121 default: 1131 default:
1122 return 0; 1132 return 0;
1123 } 1133 }
1124 1134
1125 if (flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) { 1135 if (flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) {
1126 l4off = l3off + M_CSUM_DATA_IPv4_IPHL(data); 1136 l4off = l3off + M_CSUM_DATA_IPv4_IPHL(data);
1127 if (__predict_false(l4off > URE_L4_OFFSET_MAX)) { 1137 if (__predict_false(l4off > URE_L4_OFFSET_MAX)) {
1128 in_undefer_cksum(m, l3off, flags); 1138 in_undefer_cksum(m, l3off, flags);
1129 return 0; 1139 return 0;
1130 } 1140 }
1131 reg |= URE_TXPKT_IPV4_CS; 1141 reg |= URE_TXPKT_IPV4_CS;
1132 if (flags & M_CSUM_TCPv4) 1142 if (flags & M_CSUM_TCPv4)
1133 reg |= URE_TXPKT_TCP_CS; 1143 reg |= URE_TXPKT_TCP_CS;
1134 else 1144 else
1135 reg |= URE_TXPKT_UDP_CS; 1145 reg |= URE_TXPKT_UDP_CS;
1136 reg |= l4off << URE_L4_OFFSET_SHIFT; 1146 reg |= l4off << URE_L4_OFFSET_SHIFT;
1137 } 1147 }
1138#ifdef INET6 1148#ifdef INET6
1139 else if (flags & (M_CSUM_TCPv6 | M_CSUM_UDPv6)) { 1149 else if (flags & (M_CSUM_TCPv6 | M_CSUM_UDPv6)) {
1140 l4off = l3off + M_CSUM_DATA_IPv6_IPHL(data); 1150 l4off = l3off + M_CSUM_DATA_IPv6_IPHL(data);
1141 if (__predict_false(l4off > URE_L4_OFFSET_MAX)) { 1151 if (__predict_false(l4off > URE_L4_OFFSET_MAX)) {
1142 in6_undefer_cksum(m, l3off, flags); 1152 in6_undefer_cksum(m, l3off, flags);
1143 return 0; 1153 return 0;
1144 } 1154 }
1145 reg |= URE_TXPKT_IPV6_CS; 1155 reg |= URE_TXPKT_IPV6_CS;
1146 if (flags & M_CSUM_TCPv6) 1156 if (flags & M_CSUM_TCPv6)
1147 reg |= URE_TXPKT_TCP_CS; 1157 reg |= URE_TXPKT_TCP_CS;
1148 else 1158 else
1149 reg |= URE_TXPKT_UDP_CS; 1159 reg |= URE_TXPKT_UDP_CS;
1150 reg |= l4off << URE_L4_OFFSET_SHIFT; 1160 reg |= l4off << URE_L4_OFFSET_SHIFT;
1151 } 1161 }
1152#endif 1162#endif
1153 else if (flags & M_CSUM_IPv4) 1163 else if (flags & M_CSUM_IPv4)
1154 reg |= URE_TXPKT_IPV4_CS; 1164 reg |= URE_TXPKT_IPV4_CS;
1155 1165
1156 return reg; 1166 return reg;
1157} 1167}
1158 1168
1159#ifdef _MODULE 1169#ifdef _MODULE
1160#include "ioconf.c" 1170#include "ioconf.c"
1161#endif 1171#endif
1162 1172
1163USBNET_MODULE(ure) 1173USBNET_MODULE(ure)