Thu Mar 3 05:55:19 2022 UTC ()
usbnet drivers: Prune dead IFF_RUNNING branches in *_uno_init.

usbnet(9) guarantees !IFF_RUNNING now before calling it.


(riastradh)
diff -r1.187 -r1.188 src/sys/dev/usb/if_aue.c
diff -r1.78 -r1.79 src/sys/dev/usb/if_mue.c
diff -r1.93 -r1.94 src/sys/dev/usb/if_udav.c
diff -r1.53 -r1.54 src/sys/dev/usb/if_ure.c
diff -r1.41 -r1.42 src/sys/dev/usb/if_urndis.c

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

--- src/sys/dev/usb/if_aue.c 2022/03/03 05:55:01 1.187
+++ src/sys/dev/usb/if_aue.c 2022/03/03 05:55:19 1.188
@@ -1,1000 +1,996 @@ @@ -1,1000 +1,996 @@
1/* $NetBSD: if_aue.c,v 1.187 2022/03/03 05:55:01 riastradh Exp $ */ 1/* $NetBSD: if_aue.c,v 1.188 2022/03/03 05:55:19 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.187 2022/03/03 05:55:01 riastradh Exp $"); 79__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.188 2022/03/03 05:55:19 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 void aue_uno_mcast(struct ifnet *); 243static void aue_uno_mcast(struct ifnet *);
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_mcast = aue_uno_mcast, 255 .uno_mcast = aue_uno_mcast,
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 if (usbnet_isdying(un)) 287 if (usbnet_isdying(un))
288 return 0; 288 return 0;
289 289
290 req.bmRequestType = UT_READ_VENDOR_DEVICE; 290 req.bmRequestType = UT_READ_VENDOR_DEVICE;
291 req.bRequest = AUE_UR_READREG; 291 req.bRequest = AUE_UR_READREG;
292 USETW(req.wValue, 0); 292 USETW(req.wValue, 0);
293 USETW(req.wIndex, reg); 293 USETW(req.wIndex, reg);
294 USETW(req.wLength, 1); 294 USETW(req.wLength, 1);
295 295
296 err = usbd_do_request(un->un_udev, &req, &val); 296 err = usbd_do_request(un->un_udev, &req, &val);
297 297
298 if (err) { 298 if (err) {
299 AUEHIST_FUNC(); 299 AUEHIST_FUNC();
300 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 300 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd",
301 device_unit(un->un_dev), reg, err, 0); 301 device_unit(un->un_dev), reg, err, 0);
302 return 0; 302 return 0;
303 } 303 }
304 304
305 return val; 305 return val;
306} 306}
307 307
308static int 308static int
309aue_csr_read_2(struct aue_softc *sc, int reg) 309aue_csr_read_2(struct aue_softc *sc, int reg)
310{ 310{
311 struct usbnet * const un = &sc->aue_un; 311 struct usbnet * const un = &sc->aue_un;
312 usb_device_request_t req; 312 usb_device_request_t req;
313 usbd_status err; 313 usbd_status err;
314 uWord val; 314 uWord val;
315 315
316 if (usbnet_isdying(un)) 316 if (usbnet_isdying(un))
317 return 0; 317 return 0;
318 318
319 req.bmRequestType = UT_READ_VENDOR_DEVICE; 319 req.bmRequestType = UT_READ_VENDOR_DEVICE;
320 req.bRequest = AUE_UR_READREG; 320 req.bRequest = AUE_UR_READREG;
321 USETW(req.wValue, 0); 321 USETW(req.wValue, 0);
322 USETW(req.wIndex, reg); 322 USETW(req.wIndex, reg);
323 USETW(req.wLength, 2); 323 USETW(req.wLength, 2);
324 324
325 err = usbd_do_request(un->un_udev, &req, &val); 325 err = usbd_do_request(un->un_udev, &req, &val);
326 326
327 if (err) { 327 if (err) {
328 AUEHIST_FUNC(); 328 AUEHIST_FUNC();
329 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 329 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd",
330 device_unit(un->un_dev), reg, err, 0); 330 device_unit(un->un_dev), reg, err, 0);
331 return 0; 331 return 0;
332 } 332 }
333 333
334 return UGETW(val); 334 return UGETW(val);
335} 335}
336 336
337static int 337static int
338aue_csr_write_1(struct aue_softc *sc, int reg, int aval) 338aue_csr_write_1(struct aue_softc *sc, int reg, int aval)
339{ 339{
340 struct usbnet * const un = &sc->aue_un; 340 struct usbnet * const un = &sc->aue_un;
341 usb_device_request_t req; 341 usb_device_request_t req;
342 usbd_status err; 342 usbd_status err;
343 uByte val; 343 uByte val;
344 344
345 if (usbnet_isdying(un)) 345 if (usbnet_isdying(un))
346 return 0; 346 return 0;
347 347
348 val = aval; 348 val = aval;
349 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 349 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
350 req.bRequest = AUE_UR_WRITEREG; 350 req.bRequest = AUE_UR_WRITEREG;
351 USETW(req.wValue, val); 351 USETW(req.wValue, val);
352 USETW(req.wIndex, reg); 352 USETW(req.wIndex, reg);
353 USETW(req.wLength, 1); 353 USETW(req.wLength, 1);
354 354
355 err = usbd_do_request(un->un_udev, &req, &val); 355 err = usbd_do_request(un->un_udev, &req, &val);
356 356
357 if (err) { 357 if (err) {
358 AUEHIST_FUNC(); 358 AUEHIST_FUNC();
359 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 359 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd",
360 device_unit(un->un_dev), reg, err, 0); 360 device_unit(un->un_dev), reg, err, 0);
361 return -1; 361 return -1;
362 } 362 }
363 363
364 return 0; 364 return 0;
365} 365}
366 366
367static int 367static int
368aue_csr_write_2(struct aue_softc *sc, int reg, int aval) 368aue_csr_write_2(struct aue_softc *sc, int reg, int aval)
369{ 369{
370 struct usbnet * const un = &sc->aue_un; 370 struct usbnet * const un = &sc->aue_un;
371 usb_device_request_t req; 371 usb_device_request_t req;
372 usbd_status err; 372 usbd_status err;
373 uWord val; 373 uWord val;
374 374
375 if (usbnet_isdying(un)) 375 if (usbnet_isdying(un))
376 return 0; 376 return 0;
377 377
378 USETW(val, aval); 378 USETW(val, aval);
379 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 379 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
380 req.bRequest = AUE_UR_WRITEREG; 380 req.bRequest = AUE_UR_WRITEREG;
381 USETW(req.wValue, aval); 381 USETW(req.wValue, aval);
382 USETW(req.wIndex, reg); 382 USETW(req.wIndex, reg);
383 USETW(req.wLength, 2); 383 USETW(req.wLength, 2);
384 384
385 err = usbd_do_request(un->un_udev, &req, &val); 385 err = usbd_do_request(un->un_udev, &req, &val);
386 386
387 if (err) { 387 if (err) {
388 AUEHIST_FUNC(); 388 AUEHIST_FUNC();
389 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 389 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd",
390 device_unit(un->un_dev), reg, err, 0); 390 device_unit(un->un_dev), reg, err, 0);
391 return -1; 391 return -1;
392 } 392 }
393 393
394 return 0; 394 return 0;
395} 395}
396 396
397/* 397/*
398 * Read a word of data stored in the EEPROM at address 'addr.' 398 * Read a word of data stored in the EEPROM at address 'addr.'
399 */ 399 */
400static int 400static int
401aue_eeprom_getword(struct aue_softc *sc, int addr) 401aue_eeprom_getword(struct aue_softc *sc, int addr)
402{ 402{
403 struct usbnet * const un = &sc->aue_un; 403 struct usbnet * const un = &sc->aue_un;
404 int i; 404 int i;
405 405
406 AUEHIST_FUNC(); AUEHIST_CALLED(); 406 AUEHIST_FUNC(); AUEHIST_CALLED();
407 407
408 aue_csr_write_1(sc, AUE_EE_REG, addr); 408 aue_csr_write_1(sc, AUE_EE_REG, addr);
409 aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ); 409 aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ);
410 410
411 for (i = 0; i < AUE_TIMEOUT; i++) { 411 for (i = 0; i < AUE_TIMEOUT; i++) {
412 if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE) 412 if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE)
413 break; 413 break;
414 } 414 }
415 415
416 if (i == AUE_TIMEOUT) { 416 if (i == AUE_TIMEOUT) {
417 printf("%s: EEPROM read timed out\n", 417 printf("%s: EEPROM read timed out\n",
418 device_xname(un->un_dev)); 418 device_xname(un->un_dev));
419 } 419 }
420 420
421 return aue_csr_read_2(sc, AUE_EE_DATA); 421 return aue_csr_read_2(sc, AUE_EE_DATA);
422} 422}
423 423
424/* 424/*
425 * Read the MAC from the EEPROM. It's at offset 0. 425 * Read the MAC from the EEPROM. It's at offset 0.
426 */ 426 */
427static void 427static void
428aue_read_mac(struct usbnet *un) 428aue_read_mac(struct usbnet *un)
429{ 429{
430 struct aue_softc *sc = usbnet_softc(un); 430 struct aue_softc *sc = usbnet_softc(un);
431 int i; 431 int i;
432 int off = 0; 432 int off = 0;
433 int word; 433 int word;
434 434
435 AUEHIST_FUNC(); 435 AUEHIST_FUNC();
436 AUEHIST_CALLARGS("aue%jd: enter", 436 AUEHIST_CALLARGS("aue%jd: enter",
437 device_unit(un->un_dev), 0, 0, 0); 437 device_unit(un->un_dev), 0, 0, 0);
438 438
439 for (i = 0; i < 3; i++) { 439 for (i = 0; i < 3; i++) {
440 word = aue_eeprom_getword(sc, off + i); 440 word = aue_eeprom_getword(sc, off + i);
441 un->un_eaddr[2 * i] = (u_char)word; 441 un->un_eaddr[2 * i] = (u_char)word;
442 un->un_eaddr[2 * i + 1] = (u_char)(word >> 8); 442 un->un_eaddr[2 * i + 1] = (u_char)(word >> 8);
443 } 443 }
444} 444}
445 445
446static int 446static int
447aue_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 447aue_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
448{ 448{
449 struct aue_softc *sc = usbnet_softc(un); 449 struct aue_softc *sc = usbnet_softc(un);
450 int i; 450 int i;
451 451
452 AUEHIST_FUNC(); 452 AUEHIST_FUNC();
453 453
454#if 0 454#if 0
455 /* 455 /*
456 * The Am79C901 HomePNA PHY actually contains 456 * The Am79C901 HomePNA PHY actually contains
457 * two transceivers: a 1Mbps HomePNA PHY and a 457 * two transceivers: a 1Mbps HomePNA PHY and a
458 * 10Mbps full/half duplex ethernet PHY with 458 * 10Mbps full/half duplex ethernet PHY with
459 * NWAY autoneg. However in the ADMtek adapter, 459 * NWAY autoneg. However in the ADMtek adapter,
460 * only the 1Mbps PHY is actually connected to 460 * only the 1Mbps PHY is actually connected to
461 * anything, so we ignore the 10Mbps one. It 461 * anything, so we ignore the 10Mbps one. It
462 * happens to be configured for MII address 3, 462 * happens to be configured for MII address 3,
463 * so we filter that out. 463 * so we filter that out.
464 */ 464 */
465 if (sc->aue_vendor == USB_VENDOR_ADMTEK && 465 if (sc->aue_vendor == USB_VENDOR_ADMTEK &&
466 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { 466 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) {
467 if (phy == 3) { 467 if (phy == 3) {
468 *val = 0; 468 *val = 0;
469 return EINVAL; 469 return EINVAL;
470 } 470 }
471 } 471 }
472#endif 472#endif
473 473
474 aue_csr_write_1(sc, AUE_PHY_ADDR, phy); 474 aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
475 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ); 475 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ);
476 476
477 for (i = 0; i < AUE_TIMEOUT; i++) { 477 for (i = 0; i < AUE_TIMEOUT; i++) {
478 if (usbnet_isdying(un)) { 478 if (usbnet_isdying(un)) {
479 *val = 0; 479 *val = 0;
480 return ENXIO; 480 return ENXIO;
481 } 481 }
482 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) 482 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
483 break; 483 break;
484 } 484 }
485 485
486 if (i == AUE_TIMEOUT) { 486 if (i == AUE_TIMEOUT) {
487 AUEHIST_CALLARGS("aue%jd: phy=%#jx reg=%#jx read timed out", 487 AUEHIST_CALLARGS("aue%jd: phy=%#jx reg=%#jx read timed out",
488 device_unit(un->un_dev), phy, reg, 0); 488 device_unit(un->un_dev), phy, reg, 0);
489 *val = 0; 489 *val = 0;
490 return ETIMEDOUT; 490 return ETIMEDOUT;
491 } 491 }
492 492
493 *val = aue_csr_read_2(sc, AUE_PHY_DATA); 493 *val = aue_csr_read_2(sc, AUE_PHY_DATA);
494 494
495 AUEHIST_CALLARGSN(11, "aue%jd: phy=%#jx reg=%#jx => 0x%04jx", 495 AUEHIST_CALLARGSN(11, "aue%jd: phy=%#jx reg=%#jx => 0x%04jx",
496 device_unit(un->un_dev), phy, reg, *val); 496 device_unit(un->un_dev), phy, reg, *val);
497 497
498 return 0; 498 return 0;
499} 499}
500 500
501static int 501static int
502aue_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 502aue_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
503{ 503{
504 struct aue_softc *sc = usbnet_softc(un); 504 struct aue_softc *sc = usbnet_softc(un);
505 int i; 505 int i;
506 506
507 AUEHIST_FUNC(); 507 AUEHIST_FUNC();
508 AUEHIST_CALLARGSN(11, "aue%jd: phy=%jd reg=%jd data=0x%04jx", 508 AUEHIST_CALLARGSN(11, "aue%jd: phy=%jd reg=%jd data=0x%04jx",
509 device_unit(un->un_dev), phy, reg, val); 509 device_unit(un->un_dev), phy, reg, val);
510 510
511#if 0 511#if 0
512 if (sc->aue_vendor == USB_VENDOR_ADMTEK && 512 if (sc->aue_vendor == USB_VENDOR_ADMTEK &&
513 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { 513 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) {
514 if (phy == 3) 514 if (phy == 3)
515 return EINVAL; 515 return EINVAL;
516 } 516 }
517#endif 517#endif
518 518
519 aue_csr_write_2(sc, AUE_PHY_DATA, val); 519 aue_csr_write_2(sc, AUE_PHY_DATA, val);
520 aue_csr_write_1(sc, AUE_PHY_ADDR, phy); 520 aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
521 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE); 521 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE);
522 522
523 for (i = 0; i < AUE_TIMEOUT; i++) { 523 for (i = 0; i < AUE_TIMEOUT; i++) {
524 if (usbnet_isdying(un)) 524 if (usbnet_isdying(un))
525 return ENXIO; 525 return ENXIO;
526 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) 526 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
527 break; 527 break;
528 } 528 }
529 529
530 if (i == AUE_TIMEOUT) { 530 if (i == AUE_TIMEOUT) {
531 DPRINTF("aue%jd: phy=%#jx reg=%#jx val=%#jx write timed out", 531 DPRINTF("aue%jd: phy=%#jx reg=%#jx val=%#jx write timed out",
532 device_unit(un->un_dev), phy, reg, val); 532 device_unit(un->un_dev), phy, reg, val);
533 return ETIMEDOUT; 533 return ETIMEDOUT;
534 } 534 }
535 535
536 return 0; 536 return 0;
537} 537}
538 538
539static void 539static void
540aue_uno_mii_statchg(struct ifnet *ifp) 540aue_uno_mii_statchg(struct ifnet *ifp)
541{ 541{
542 struct usbnet *un = ifp->if_softc; 542 struct usbnet *un = ifp->if_softc;
543 struct aue_softc *sc = usbnet_softc(un); 543 struct aue_softc *sc = usbnet_softc(un);
544 struct mii_data *mii = usbnet_mii(un); 544 struct mii_data *mii = usbnet_mii(un);
545 const bool hadlink __diagused = usbnet_havelink(un); 545 const bool hadlink __diagused = usbnet_havelink(un);
546 546
547 AUEHIST_FUNC(); AUEHIST_CALLED(); 547 AUEHIST_FUNC(); AUEHIST_CALLED();
548 AUEHIST_CALLARGSN(5, "aue%jd: ifp=%#jx link=%jd", 548 AUEHIST_CALLARGSN(5, "aue%jd: ifp=%#jx link=%jd",
549 device_unit(un->un_dev), (uintptr_t)ifp, hadlink, 0); 549 device_unit(un->un_dev), (uintptr_t)ifp, hadlink, 0);
550 550
551 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); 551 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
552 552
553 if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) { 553 if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
554 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); 554 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
555 } else { 555 } else {
556 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); 556 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
557 } 557 }
558 558
559 if ((mii->mii_media_active & IFM_FDX) != 0) 559 if ((mii->mii_media_active & IFM_FDX) != 0)
560 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); 560 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
561 else 561 else
562 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); 562 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
563 563
564 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); 564 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
565 565
566 if (mii->mii_media_status & IFM_ACTIVE && 566 if (mii->mii_media_status & IFM_ACTIVE &&
567 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 567 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
568 usbnet_set_link(un, true); 568 usbnet_set_link(un, true);
569 } 569 }
570 570
571 /* 571 /*
572 * Set the LED modes on the LinkSys adapter. 572 * Set the LED modes on the LinkSys adapter.
573 * This turns on the 'dual link LED' bin in the auxmode 573 * This turns on the 'dual link LED' bin in the auxmode
574 * register of the Broadcom PHY. 574 * register of the Broadcom PHY.
575 */ 575 */
576 if (!usbnet_isdying(un) && (un->un_flags & LSYS)) { 576 if (!usbnet_isdying(un) && (un->un_flags & LSYS)) {
577 uint16_t auxmode; 577 uint16_t auxmode;
578 aue_uno_mii_read_reg(un, 0, 0x1b, &auxmode); 578 aue_uno_mii_read_reg(un, 0, 0x1b, &auxmode);
579 aue_uno_mii_write_reg(un, 0, 0x1b, auxmode | 0x04); 579 aue_uno_mii_write_reg(un, 0, 0x1b, auxmode | 0x04);
580 } 580 }
581 581
582 if (usbnet_havelink(un) != hadlink) { 582 if (usbnet_havelink(un) != hadlink) {
583 DPRINTFN(5, "aue%jd: exit link %jd", 583 DPRINTFN(5, "aue%jd: exit link %jd",
584 device_unit(un->un_dev), usbnet_havelink(un), 0, 0); 584 device_unit(un->un_dev), usbnet_havelink(un), 0, 0);
585 } 585 }
586} 586}
587 587
588#define AUE_POLY 0xEDB88320 588#define AUE_POLY 0xEDB88320
589#define AUE_BITS 6 589#define AUE_BITS 6
590 590
591static uint32_t 591static uint32_t
592aue_crc(void *addrv) 592aue_crc(void *addrv)
593{ 593{
594 uint32_t idx, bit, data, crc; 594 uint32_t idx, bit, data, crc;
595 char *addr = addrv; 595 char *addr = addrv;
596 596
597 /* Compute CRC for the address value. */ 597 /* Compute CRC for the address value. */
598 crc = 0xFFFFFFFF; /* initial value */ 598 crc = 0xFFFFFFFF; /* initial value */
599 599
600 for (idx = 0; idx < 6; idx++) { 600 for (idx = 0; idx < 6; idx++) {
601 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) 601 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
602 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? AUE_POLY : 0); 602 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? AUE_POLY : 0);
603 } 603 }
604 604
605 return crc & ((1 << AUE_BITS) - 1); 605 return crc & ((1 << AUE_BITS) - 1);
606} 606}
607 607
608static void 608static void
609aue_uno_mcast(struct ifnet *ifp) 609aue_uno_mcast(struct ifnet *ifp)
610{ 610{
611 struct usbnet * const un = ifp->if_softc; 611 struct usbnet * const un = ifp->if_softc;
612 struct aue_softc * const sc = usbnet_softc(un); 612 struct aue_softc * const sc = usbnet_softc(un);
613 struct ethercom * ec = usbnet_ec(un); 613 struct ethercom * ec = usbnet_ec(un);
614 struct ether_multi *enm; 614 struct ether_multi *enm;
615 struct ether_multistep step; 615 struct ether_multistep step;
616 uint32_t h = 0, i; 616 uint32_t h = 0, i;
617 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 617 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
618 618
619 AUEHIST_FUNC(); 619 AUEHIST_FUNC();
620 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); 620 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0);
621 621
622 if (ifp->if_flags & IFF_PROMISC) { 622 if (ifp->if_flags & IFF_PROMISC) {
623 ETHER_LOCK(ec); 623 ETHER_LOCK(ec);
624allmulti: 624allmulti:
625 ec->ec_flags |= ETHER_F_ALLMULTI; 625 ec->ec_flags |= ETHER_F_ALLMULTI;
626 ETHER_UNLOCK(ec); 626 ETHER_UNLOCK(ec);
627 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); 627 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
628 return; 628 return;
629 } 629 }
630 630
631 /* now program new ones */ 631 /* now program new ones */
632 ETHER_LOCK(ec); 632 ETHER_LOCK(ec);
633 ETHER_FIRST_MULTI(step, ec, enm); 633 ETHER_FIRST_MULTI(step, ec, enm);
634 while (enm != NULL) { 634 while (enm != NULL) {
635 if (memcmp(enm->enm_addrlo, 635 if (memcmp(enm->enm_addrlo,
636 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) { 636 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
637 goto allmulti; 637 goto allmulti;
638 } 638 }
639 639
640 h = aue_crc(enm->enm_addrlo); 640 h = aue_crc(enm->enm_addrlo);
641 hashtbl[h >> 3] |= 1 << (h & 0x7); 641 hashtbl[h >> 3] |= 1 << (h & 0x7);
642 ETHER_NEXT_MULTI(step, enm); 642 ETHER_NEXT_MULTI(step, enm);
643 } 643 }
644 ec->ec_flags &= ~ETHER_F_ALLMULTI; 644 ec->ec_flags &= ~ETHER_F_ALLMULTI;
645 ETHER_UNLOCK(ec); 645 ETHER_UNLOCK(ec);
646 646
647 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); 647 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
648 648
649 /* write the hashtable */ 649 /* write the hashtable */
650 for (i = 0; i < 8; i++) 650 for (i = 0; i < 8; i++)
651 aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]); 651 aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]);
652} 652}
653 653
654static void 654static void
655aue_reset_pegasus_II(struct aue_softc *sc) 655aue_reset_pegasus_II(struct aue_softc *sc)
656{ 656{
657 /* Magic constants taken from Linux driver. */ 657 /* Magic constants taken from Linux driver. */
658 aue_csr_write_1(sc, AUE_REG_1D, 0); 658 aue_csr_write_1(sc, AUE_REG_1D, 0);
659 aue_csr_write_1(sc, AUE_REG_7B, 2); 659 aue_csr_write_1(sc, AUE_REG_7B, 2);
660#if 0 660#if 0
661 if ((un->un_flags & PNA) && mii_mode) 661 if ((un->un_flags & PNA) && mii_mode)
662 aue_csr_write_1(sc, AUE_REG_81, 6); 662 aue_csr_write_1(sc, AUE_REG_81, 6);
663 else 663 else
664#endif 664#endif
665 aue_csr_write_1(sc, AUE_REG_81, 2); 665 aue_csr_write_1(sc, AUE_REG_81, 2);
666} 666}
667 667
668static void 668static void
669aue_reset(struct aue_softc *sc) 669aue_reset(struct aue_softc *sc)
670{ 670{
671 struct usbnet * const un = &sc->aue_un; 671 struct usbnet * const un = &sc->aue_un;
672 int i; 672 int i;
673 673
674 AUEHIST_FUNC(); 674 AUEHIST_FUNC();
675 AUEHIST_CALLARGSN(2, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); 675 AUEHIST_CALLARGSN(2, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0);
676 676
677 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC); 677 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC);
678 678
679 for (i = 0; i < AUE_TIMEOUT; i++) { 679 for (i = 0; i < AUE_TIMEOUT; i++) {
680 if (usbnet_isdying(un)) 680 if (usbnet_isdying(un))
681 return; 681 return;
682 if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC)) 682 if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC))
683 break; 683 break;
684 } 684 }
685 685
686 if (i == AUE_TIMEOUT) 686 if (i == AUE_TIMEOUT)
687 printf("%s: reset failed\n", device_xname(un->un_dev)); 687 printf("%s: reset failed\n", device_xname(un->un_dev));
688 688
689#if 0 689#if 0
690 /* XXX what is mii_mode supposed to be */ 690 /* XXX what is mii_mode supposed to be */
691 if (sc->sc_mii_mode && (un->un_flags & PNA)) 691 if (sc->sc_mii_mode && (un->un_flags & PNA))
692 aue_csr_write_1(sc, AUE_GPIO1, 0x34); 692 aue_csr_write_1(sc, AUE_GPIO1, 0x34);
693 else 693 else
694 aue_csr_write_1(sc, AUE_GPIO1, 0x26); 694 aue_csr_write_1(sc, AUE_GPIO1, 0x26);
695#endif 695#endif
696 696
697 /* 697 /*
698 * The PHY(s) attached to the Pegasus chip may be held 698 * The PHY(s) attached to the Pegasus chip may be held
699 * in reset until we flip on the GPIO outputs. Make sure 699 * in reset until we flip on the GPIO outputs. Make sure
700 * to set the GPIO pins high so that the PHY(s) will 700 * to set the GPIO pins high so that the PHY(s) will
701 * be enabled. 701 * be enabled.
702 * 702 *
703 * Note: We force all of the GPIO pins low first, *then* 703 * Note: We force all of the GPIO pins low first, *then*
704 * enable the ones we want. 704 * enable the ones we want.
705 */ 705 */
706 if (un->un_flags & LSYS) { 706 if (un->un_flags & LSYS) {
707 /* Grrr. LinkSys has to be different from everyone else. */ 707 /* Grrr. LinkSys has to be different from everyone else. */
708 aue_csr_write_1(sc, AUE_GPIO0, 708 aue_csr_write_1(sc, AUE_GPIO0,
709 AUE_GPIO_SEL0 | AUE_GPIO_SEL1); 709 AUE_GPIO_SEL0 | AUE_GPIO_SEL1);
710 } else { 710 } else {
711 aue_csr_write_1(sc, AUE_GPIO0, 711 aue_csr_write_1(sc, AUE_GPIO0,
712 AUE_GPIO_OUT0 | AUE_GPIO_SEL0); 712 AUE_GPIO_OUT0 | AUE_GPIO_SEL0);
713 } 713 }
714 aue_csr_write_1(sc, AUE_GPIO0, 714 aue_csr_write_1(sc, AUE_GPIO0,
715 AUE_GPIO_OUT0 | AUE_GPIO_SEL0 | AUE_GPIO_SEL1); 715 AUE_GPIO_OUT0 | AUE_GPIO_SEL0 | AUE_GPIO_SEL1);
716 716
717 if (un->un_flags & PII) 717 if (un->un_flags & PII)
718 aue_reset_pegasus_II(sc); 718 aue_reset_pegasus_II(sc);
719 719
720 /* Wait a little while for the chip to get its brains in order. */ 720 /* Wait a little while for the chip to get its brains in order. */
721 delay(10000); /* XXX */ 721 delay(10000); /* XXX */
722 //usbd_delay_ms(un->un_udev, 10); /* XXX */ 722 //usbd_delay_ms(un->un_udev, 10); /* XXX */
723 723
724 DPRINTFN(2, "aue%jd: exit", device_unit(un->un_dev), 0, 0, 0); 724 DPRINTFN(2, "aue%jd: exit", device_unit(un->un_dev), 0, 0, 0);
725} 725}
726 726
727/* 727/*
728 * Probe for a Pegasus chip. 728 * Probe for a Pegasus chip.
729 */ 729 */
730static int 730static int
731aue_match(device_t parent, cfdata_t match, void *aux) 731aue_match(device_t parent, cfdata_t match, void *aux)
732{ 732{
733 struct usb_attach_arg *uaa = aux; 733 struct usb_attach_arg *uaa = aux;
734 734
735 /* 735 /*
736 * Some manufacturers use the same vendor and product id for 736 * Some manufacturers use the same vendor and product id for
737 * different devices. We need to sanity check the DeviceClass 737 * different devices. We need to sanity check the DeviceClass
738 * in this case 738 * in this case
739 * Currently known guilty products: 739 * Currently known guilty products:
740 * 0x050d/0x0121 Belkin Bluetooth and USB2LAN 740 * 0x050d/0x0121 Belkin Bluetooth and USB2LAN
741 * 741 *
742 * If this turns out to be more common, we could use a quirk 742 * If this turns out to be more common, we could use a quirk
743 * table. 743 * table.
744 */ 744 */
745 if (uaa->uaa_vendor == USB_VENDOR_BELKIN && 745 if (uaa->uaa_vendor == USB_VENDOR_BELKIN &&
746 uaa->uaa_product == USB_PRODUCT_BELKIN_USB2LAN) { 746 uaa->uaa_product == USB_PRODUCT_BELKIN_USB2LAN) {
747 usb_device_descriptor_t *dd; 747 usb_device_descriptor_t *dd;
748 748
749 dd = usbd_get_device_descriptor(uaa->uaa_device); 749 dd = usbd_get_device_descriptor(uaa->uaa_device);
750 if (dd != NULL && 750 if (dd != NULL &&
751 dd->bDeviceClass != UDCLASS_IN_INTERFACE) 751 dd->bDeviceClass != UDCLASS_IN_INTERFACE)
752 return UMATCH_NONE; 752 return UMATCH_NONE;
753 } 753 }
754 754
755 return aue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 755 return aue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
756 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 756 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
757} 757}
758 758
759/* 759/*
760 * Attach the interface. Allocate softc structures, do ifmedia 760 * Attach the interface. Allocate softc structures, do ifmedia
761 * setup and ethernet/BPF attach. 761 * setup and ethernet/BPF attach.
762 */ 762 */
763static void 763static void
764aue_attach(device_t parent, device_t self, void *aux) 764aue_attach(device_t parent, device_t self, void *aux)
765{ 765{
766 USBNET_MII_DECL_DEFAULT(unm); 766 USBNET_MII_DECL_DEFAULT(unm);
767 struct aue_softc * const sc = device_private(self); 767 struct aue_softc * const sc = device_private(self);
768 struct usbnet * const un = &sc->aue_un; 768 struct usbnet * const un = &sc->aue_un;
769 struct usb_attach_arg *uaa = aux; 769 struct usb_attach_arg *uaa = aux;
770 char *devinfop; 770 char *devinfop;
771 struct usbd_device *dev = uaa->uaa_device; 771 struct usbd_device *dev = uaa->uaa_device;
772 usbd_status err; 772 usbd_status err;
773 usb_interface_descriptor_t *id; 773 usb_interface_descriptor_t *id;
774 usb_endpoint_descriptor_t *ed; 774 usb_endpoint_descriptor_t *ed;
775 int i; 775 int i;
776 776
777 AUEHIST_FUNC(); 777 AUEHIST_FUNC();
778 AUEHIST_CALLARGSN(2, "aue%jd: enter sc=%#jx", 778 AUEHIST_CALLARGSN(2, "aue%jd: enter sc=%#jx",
779 device_unit(self), (uintptr_t)sc, 0, 0); 779 device_unit(self), (uintptr_t)sc, 0, 0);
780 780
781 KASSERT((void *)sc == un); 781 KASSERT((void *)sc == un);
782 782
783 aprint_naive("\n"); 783 aprint_naive("\n");
784 aprint_normal("\n"); 784 aprint_normal("\n");
785 devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0); 785 devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0);
786 aprint_normal_dev(self, "%s\n", devinfop); 786 aprint_normal_dev(self, "%s\n", devinfop);
787 usbd_devinfo_free(devinfop); 787 usbd_devinfo_free(devinfop);
788 788
789 un->un_dev = self; 789 un->un_dev = self;
790 un->un_udev = dev; 790 un->un_udev = dev;
791 un->un_sc = sc; 791 un->un_sc = sc;
792 un->un_ops = &aue_ops; 792 un->un_ops = &aue_ops;
793 un->un_intr = &sc->aue_intr; 793 un->un_intr = &sc->aue_intr;
794 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 794 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
795 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 795 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
796 un->un_rx_list_cnt = AUE_RX_LIST_CNT; 796 un->un_rx_list_cnt = AUE_RX_LIST_CNT;
797 un->un_tx_list_cnt = AUE_RX_LIST_CNT; 797 un->un_tx_list_cnt = AUE_RX_LIST_CNT;
798 un->un_rx_bufsz = AUE_BUFSZ; 798 un->un_rx_bufsz = AUE_BUFSZ;
799 un->un_tx_bufsz = AUE_BUFSZ; 799 un->un_tx_bufsz = AUE_BUFSZ;
800 800
801 sc->aue_intr.uni_buf = &sc->aue_ibuf; 801 sc->aue_intr.uni_buf = &sc->aue_ibuf;
802 sc->aue_intr.uni_bufsz = sizeof(sc->aue_ibuf); 802 sc->aue_intr.uni_bufsz = sizeof(sc->aue_ibuf);
803 sc->aue_intr.uni_interval = AUE_INTR_INTERVAL; 803 sc->aue_intr.uni_interval = AUE_INTR_INTERVAL;
804 804
805 err = usbd_set_config_no(dev, AUE_CONFIG_NO, 1); 805 err = usbd_set_config_no(dev, AUE_CONFIG_NO, 1);
806 if (err) { 806 if (err) {
807 aprint_error_dev(self, "failed to set configuration" 807 aprint_error_dev(self, "failed to set configuration"
808 ", err=%s\n", usbd_errstr(err)); 808 ", err=%s\n", usbd_errstr(err));
809 return; 809 return;
810 } 810 }
811 811
812 err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &un->un_iface); 812 err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &un->un_iface);
813 if (err) { 813 if (err) {
814 aprint_error_dev(self, "getting interface handle failed\n"); 814 aprint_error_dev(self, "getting interface handle failed\n");
815 return; 815 return;
816 } 816 }
817 817
818 un->un_flags = aue_lookup(uaa->uaa_vendor, uaa->uaa_product)->aue_flags; 818 un->un_flags = aue_lookup(uaa->uaa_vendor, uaa->uaa_product)->aue_flags;
819 819
820 id = usbd_get_interface_descriptor(un->un_iface); 820 id = usbd_get_interface_descriptor(un->un_iface);
821 821
822 /* Find endpoints. */ 822 /* Find endpoints. */
823 for (i = 0; i < id->bNumEndpoints; i++) { 823 for (i = 0; i < id->bNumEndpoints; i++) {
824 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 824 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
825 if (ed == NULL) { 825 if (ed == NULL) {
826 aprint_error_dev(self, 826 aprint_error_dev(self,
827 "couldn't get endpoint descriptor %d\n", i); 827 "couldn't get endpoint descriptor %d\n", i);
828 return; 828 return;
829 } 829 }
830 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 830 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
831 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 831 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
832 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 832 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
833 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 833 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
834 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 834 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
835 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 835 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
836 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 836 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
837 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 837 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
838 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 838 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
839 } 839 }
840 } 840 }
841 841
842 if (un->un_ed[USBNET_ENDPT_RX] == 0 || 842 if (un->un_ed[USBNET_ENDPT_RX] == 0 ||
843 un->un_ed[USBNET_ENDPT_TX] == 0 || 843 un->un_ed[USBNET_ENDPT_TX] == 0 ||
844 un->un_ed[USBNET_ENDPT_INTR] == 0) { 844 un->un_ed[USBNET_ENDPT_INTR] == 0) {
845 aprint_error_dev(self, "missing endpoint\n"); 845 aprint_error_dev(self, "missing endpoint\n");
846 return; 846 return;
847 } 847 }
848 848
849 /* First level attach. */ 849 /* First level attach. */
850 usbnet_attach(un, "auedet"); 850 usbnet_attach(un, "auedet");
851 851
852 /* Reset the adapter and get station address from the EEPROM. */ 852 /* Reset the adapter and get station address from the EEPROM. */
853 aue_reset(sc); 853 aue_reset(sc);
854 aue_read_mac(un); 854 aue_read_mac(un);
855 855
856 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 856 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
857 0, &unm); 857 0, &unm);
858} 858}
859 859
860static void 860static void
861aue_uno_intr(struct usbnet *un, usbd_status status) 861aue_uno_intr(struct usbnet *un, usbd_status status)
862{ 862{
863 struct ifnet *ifp = usbnet_ifp(un); 863 struct ifnet *ifp = usbnet_ifp(un);
864 struct aue_softc *sc = usbnet_softc(un); 864 struct aue_softc *sc = usbnet_softc(un);
865 struct aue_intrpkt *p = &sc->aue_ibuf; 865 struct aue_intrpkt *p = &sc->aue_ibuf;
866 866
867 AUEHIST_FUNC(); 867 AUEHIST_FUNC();
868 AUEHIST_CALLARGSN(20, "aue%jd: enter txstat0 %#jx\n", 868 AUEHIST_CALLARGSN(20, "aue%jd: enter txstat0 %#jx\n",
869 device_unit(un->un_dev), p->aue_txstat0, 0, 0); 869 device_unit(un->un_dev), p->aue_txstat0, 0, 0);
870 870
871 if (p->aue_txstat0) 871 if (p->aue_txstat0)
872 if_statinc(ifp, if_oerrors); 872 if_statinc(ifp, if_oerrors);
873 873
874 if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL | AUE_TXSTAT0_EXCESSCOLL)) 874 if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL | AUE_TXSTAT0_EXCESSCOLL))
875 if_statinc(ifp, if_collisions); 875 if_statinc(ifp, if_collisions);
876} 876}
877 877
878static void 878static void
879aue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 879aue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
880{ 880{
881 struct ifnet *ifp = usbnet_ifp(un); 881 struct ifnet *ifp = usbnet_ifp(un);
882 uint8_t *buf = c->unc_buf; 882 uint8_t *buf = c->unc_buf;
883 struct aue_rxpkt r; 883 struct aue_rxpkt r;
884 uint32_t pktlen; 884 uint32_t pktlen;
885 885
886 AUEHIST_FUNC(); 886 AUEHIST_FUNC();
887 AUEHIST_CALLARGSN(10, "aue%jd: enter len %ju", 887 AUEHIST_CALLARGSN(10, "aue%jd: enter len %ju",
888 device_unit(un->un_dev), total_len, 0, 0); 888 device_unit(un->un_dev), total_len, 0, 0);
889 889
890 if (total_len <= 4 + ETHER_CRC_LEN) { 890 if (total_len <= 4 + ETHER_CRC_LEN) {
891 if_statinc(ifp, if_ierrors); 891 if_statinc(ifp, if_ierrors);
892 return; 892 return;
893 } 893 }
894 894
895 memcpy(&r, buf + total_len - 4, sizeof(r)); 895 memcpy(&r, buf + total_len - 4, sizeof(r));
896 896
897 /* Turn off all the non-error bits in the rx status word. */ 897 /* Turn off all the non-error bits in the rx status word. */
898 r.aue_rxstat &= AUE_RXSTAT_MASK; 898 r.aue_rxstat &= AUE_RXSTAT_MASK;
899 if (r.aue_rxstat) { 899 if (r.aue_rxstat) {
900 if_statinc(ifp, if_ierrors); 900 if_statinc(ifp, if_ierrors);
901 return; 901 return;
902 } 902 }
903 903
904 /* No errors; receive the packet. */ 904 /* No errors; receive the packet. */
905 pktlen = total_len - ETHER_CRC_LEN - 4; 905 pktlen = total_len - ETHER_CRC_LEN - 4;
906 906
907 usbnet_enqueue(un, buf, pktlen, 0, 0, 0); 907 usbnet_enqueue(un, buf, pktlen, 0, 0, 0);
908} 908}
909 909
910static unsigned 910static unsigned
911aue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 911aue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
912{ 912{
913 uint8_t *buf = c->unc_buf; 913 uint8_t *buf = c->unc_buf;
914 int total_len; 914 int total_len;
915 915
916 AUEHIST_FUNC(); 916 AUEHIST_FUNC();
917 AUEHIST_CALLARGSN(10, "aue%jd: enter pktlen=%jd", 917 AUEHIST_CALLARGSN(10, "aue%jd: enter pktlen=%jd",
918 device_unit(un->un_dev), m->m_pkthdr.len, 0, 0); 918 device_unit(un->un_dev), m->m_pkthdr.len, 0, 0);
919 919
920 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2) 920 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2)
921 return 0; 921 return 0;
922 922
923 /* 923 /*
924 * Copy the mbuf data into a contiguous buffer, leaving two 924 * Copy the mbuf data into a contiguous buffer, leaving two
925 * bytes at the beginning to hold the frame length. 925 * bytes at the beginning to hold the frame length.
926 */ 926 */
927 m_copydata(m, 0, m->m_pkthdr.len, buf + 2); 927 m_copydata(m, 0, m->m_pkthdr.len, buf + 2);
928 928
929 /* 929 /*
930 * The ADMtek documentation says that the packet length is 930 * The ADMtek documentation says that the packet length is
931 * supposed to be specified in the first two bytes of the 931 * supposed to be specified in the first two bytes of the
932 * transfer, however it actually seems to ignore this info 932 * transfer, however it actually seems to ignore this info
933 * and base the frame size on the bulk transfer length. 933 * and base the frame size on the bulk transfer length.
934 */ 934 */
935 buf[0] = (uint8_t)m->m_pkthdr.len; 935 buf[0] = (uint8_t)m->m_pkthdr.len;
936 buf[1] = (uint8_t)(m->m_pkthdr.len >> 8); 936 buf[1] = (uint8_t)(m->m_pkthdr.len >> 8);
937 total_len = m->m_pkthdr.len + 2; 937 total_len = m->m_pkthdr.len + 2;
938 938
939 DPRINTFN(5, "aue%jd: send %jd bytes", 939 DPRINTFN(5, "aue%jd: send %jd bytes",
940 device_unit(un->un_dev), total_len, 0, 0); 940 device_unit(un->un_dev), total_len, 0, 0);
941 941
942 return total_len; 942 return total_len;
943} 943}
944 944
945static int 945static int
946aue_uno_init(struct ifnet *ifp) 946aue_uno_init(struct ifnet *ifp)
947{ 947{
948 struct usbnet * const un = ifp->if_softc; 948 struct usbnet * const un = ifp->if_softc;
949 struct aue_softc *sc = usbnet_softc(un); 949 struct aue_softc *sc = usbnet_softc(un);
950 int i; 950 int i;
951 const u_char *eaddr; 951 const u_char *eaddr;
952 952
953 AUEHIST_FUNC(); 953 AUEHIST_FUNC();
954 AUEHIST_CALLARGSN(5, "aue%jd: enter link=%jd", 954 AUEHIST_CALLARGSN(5, "aue%jd: enter link=%jd",
955 device_unit(un->un_dev), usbnet_havelink(un), 0, 0); 955 device_unit(un->un_dev), usbnet_havelink(un), 0, 0);
956 956
957 /* Cancel pending I/O */ 
958 if (ifp->if_flags & IFF_RUNNING) 
959 return 0; 
960 
961 /* Reset the interface. */ 957 /* Reset the interface. */
962 aue_reset(sc); 958 aue_reset(sc);
963 959
964 eaddr = CLLADDR(ifp->if_sadl); 960 eaddr = CLLADDR(ifp->if_sadl);
965 for (i = 0; i < ETHER_ADDR_LEN; i++) 961 for (i = 0; i < ETHER_ADDR_LEN; i++)
966 aue_csr_write_1(sc, AUE_PAR0 + i, eaddr[i]); 962 aue_csr_write_1(sc, AUE_PAR0 + i, eaddr[i]);
967 963
968 /* If we want promiscuous mode, set the allframes bit. */ 964 /* If we want promiscuous mode, set the allframes bit. */
969 if (ifp->if_flags & IFF_PROMISC) 965 if (ifp->if_flags & IFF_PROMISC)
970 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); 966 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
971 else 967 else
972 AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); 968 AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
973 969
974 /* Enable RX and TX */ 970 /* Enable RX and TX */
975 aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB); 971 aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB);
976 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB); 972 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB);
977 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR); 973 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR);
978 974
979 return usbnet_init_rx_tx(un); 975 return usbnet_init_rx_tx(un);
980} 976}
981 977
982static void 978static void
983aue_uno_stop(struct ifnet *ifp, int disable) 979aue_uno_stop(struct ifnet *ifp, int disable)
984{ 980{
985 struct usbnet * const un = ifp->if_softc; 981 struct usbnet * const un = ifp->if_softc;
986 struct aue_softc * const sc = usbnet_softc(un); 982 struct aue_softc * const sc = usbnet_softc(un);
987 983
988 AUEHIST_FUNC(); 984 AUEHIST_FUNC();
989 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); 985 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0);
990 986
991 aue_csr_write_1(sc, AUE_CTL0, 0); 987 aue_csr_write_1(sc, AUE_CTL0, 0);
992 aue_csr_write_1(sc, AUE_CTL1, 0); 988 aue_csr_write_1(sc, AUE_CTL1, 0);
993 aue_reset(sc); 989 aue_reset(sc);
994} 990}
995 991
996#ifdef _MODULE 992#ifdef _MODULE
997#include "ioconf.c" 993#include "ioconf.c"
998#endif 994#endif
999 995
1000USBNET_MODULE(aue) 996USBNET_MODULE(aue)

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

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

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

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

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

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

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

--- src/sys/dev/usb/if_urndis.c 2022/03/03 05:54:45 1.41
+++ src/sys/dev/usb/if_urndis.c 2022/03/03 05:55:19 1.42
@@ -1,1090 +1,1087 @@ @@ -1,1090 +1,1087 @@
1/* $NetBSD: if_urndis.c,v 1.41 2022/03/03 05:54:45 riastradh Exp $ */ 1/* $NetBSD: if_urndis.c,v 1.42 2022/03/03 05:55:19 riastradh Exp $ */
2/* $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */ 2/* $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2010 Jonathan Armani <armani@openbsd.org> 5 * Copyright (c) 2010 Jonathan Armani <armani@openbsd.org>
6 * Copyright (c) 2010 Fabien Romano <fabien@openbsd.org> 6 * Copyright (c) 2010 Fabien Romano <fabien@openbsd.org>
7 * Copyright (c) 2010 Michael Knudsen <mk@openbsd.org> 7 * Copyright (c) 2010 Michael Knudsen <mk@openbsd.org>
8 * All rights reserved. 8 * All rights reserved.
9 * 9 *
10 * Permission to use, copy, modify, and distribute this software for any 10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above 11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies. 12 * copyright notice and this permission notice appear in all copies.
13 * 13 *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */ 21 */
22 22
23#include <sys/cdefs.h> 23#include <sys/cdefs.h>
24__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.41 2022/03/03 05:54:45 riastradh Exp $"); 24__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.42 2022/03/03 05:55:19 riastradh Exp $");
25 25
26#ifdef _KERNEL_OPT 26#ifdef _KERNEL_OPT
27#include "opt_usb.h" 27#include "opt_usb.h"
28#endif 28#endif
29 29
30#include <sys/param.h> 30#include <sys/param.h>
31#include <sys/kmem.h> 31#include <sys/kmem.h>
32 32
33#include <dev/usb/usbnet.h> 33#include <dev/usb/usbnet.h>
34#include <dev/usb/usbdevs.h> 34#include <dev/usb/usbdevs.h>
35#include <dev/usb/usbcdc.h> 35#include <dev/usb/usbcdc.h>
36 36
37#include <dev/ic/rndisreg.h> 37#include <dev/ic/rndisreg.h>
38 38
39#define RNDIS_RX_LIST_CNT 1 39#define RNDIS_RX_LIST_CNT 1
40#define RNDIS_TX_LIST_CNT 1 40#define RNDIS_TX_LIST_CNT 1
41#define RNDIS_BUFSZ 1562 41#define RNDIS_BUFSZ 1562
42 42
43struct urndis_softc { 43struct urndis_softc {
44 struct usbnet sc_un; 44 struct usbnet sc_un;
45 45
46 int sc_ifaceno_ctl; 46 int sc_ifaceno_ctl;
47 47
48 /* RNDIS device info */ 48 /* RNDIS device info */
49 uint32_t sc_filter; 49 uint32_t sc_filter;
50 uint32_t sc_maxppt; 50 uint32_t sc_maxppt;
51 uint32_t sc_maxtsz; 51 uint32_t sc_maxtsz;
52 uint32_t sc_palign; 52 uint32_t sc_palign;
53}; 53};
54 54
55#ifdef URNDIS_DEBUG 55#ifdef URNDIS_DEBUG
56#define DPRINTF(x) do { printf x; } while (0) 56#define DPRINTF(x) do { printf x; } while (0)
57#else 57#else
58#define DPRINTF(x) 58#define DPRINTF(x)
59#endif 59#endif
60 60
61#define DEVNAME(un) (device_xname(un->un_dev)) 61#define DEVNAME(un) (device_xname(un->un_dev))
62 62
63#define URNDIS_RESPONSE_LEN 0x400 63#define URNDIS_RESPONSE_LEN 0x400
64 64
65#if 0 65#if 0
66static void urndis_watchdog(struct ifnet *); 66static void urndis_watchdog(struct ifnet *);
67#endif 67#endif
68 68
69static int urndis_uno_init(struct ifnet *); 69static int urndis_uno_init(struct ifnet *);
70static void urndis_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 70static void urndis_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
71 uint32_t); 71 uint32_t);
72static unsigned urndis_uno_tx_prepare(struct usbnet *, struct mbuf *, 72static unsigned urndis_uno_tx_prepare(struct usbnet *, struct mbuf *,
73 struct usbnet_chain *); 73 struct usbnet_chain *);
74 74
75static int urndis_init_un(struct ifnet *, struct usbnet *); 75static int urndis_init_un(struct ifnet *, struct usbnet *);
76 76
77static uint32_t urndis_ctrl_handle_init(struct usbnet *, 77static uint32_t urndis_ctrl_handle_init(struct usbnet *,
78 const struct rndis_comp_hdr *); 78 const struct rndis_comp_hdr *);
79static uint32_t urndis_ctrl_handle_query(struct usbnet *, 79static uint32_t urndis_ctrl_handle_query(struct usbnet *,
80 const struct rndis_comp_hdr *, void **, size_t *); 80 const struct rndis_comp_hdr *, void **, size_t *);
81static uint32_t urndis_ctrl_handle_reset(struct usbnet *, 81static uint32_t urndis_ctrl_handle_reset(struct usbnet *,
82 const struct rndis_comp_hdr *); 82 const struct rndis_comp_hdr *);
83static uint32_t urndis_ctrl_handle_status(struct usbnet *, 83static uint32_t urndis_ctrl_handle_status(struct usbnet *,
84 const struct rndis_comp_hdr *); 84 const struct rndis_comp_hdr *);
85 85
86static uint32_t urndis_ctrl_set(struct usbnet *, uint32_t, void *, 86static uint32_t urndis_ctrl_set(struct usbnet *, uint32_t, void *,
87 size_t); 87 size_t);
88 88
89static int urndis_match(device_t, cfdata_t, void *); 89static int urndis_match(device_t, cfdata_t, void *);
90static void urndis_attach(device_t, device_t, void *); 90static void urndis_attach(device_t, device_t, void *);
91 91
92static const struct usbnet_ops urndis_ops = { 92static const struct usbnet_ops urndis_ops = {
93 .uno_init = urndis_uno_init, 93 .uno_init = urndis_uno_init,
94 .uno_tx_prepare = urndis_uno_tx_prepare, 94 .uno_tx_prepare = urndis_uno_tx_prepare,
95 .uno_rx_loop = urndis_uno_rx_loop, 95 .uno_rx_loop = urndis_uno_rx_loop,
96}; 96};
97 97
98CFATTACH_DECL_NEW(urndis, sizeof(struct urndis_softc), 98CFATTACH_DECL_NEW(urndis, sizeof(struct urndis_softc),
99 urndis_match, urndis_attach, usbnet_detach, usbnet_activate); 99 urndis_match, urndis_attach, usbnet_detach, usbnet_activate);
100 100
101/* 101/*
102 * Supported devices that we can't match by class IDs. 102 * Supported devices that we can't match by class IDs.
103 */ 103 */
104static const struct usb_devno urndis_devs[] = { 104static const struct usb_devno urndis_devs[] = {
105 { USB_VENDOR_HTC, USB_PRODUCT_HTC_ANDROID }, 105 { USB_VENDOR_HTC, USB_PRODUCT_HTC_ANDROID },
106 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_ANDROID2 }, 106 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_ANDROID2 },
107 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_ANDROID }, 107 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_ANDROID },
108}; 108};
109 109
110static usbd_status 110static usbd_status
111urndis_ctrl_msg(struct usbnet *un, uint8_t rt, uint8_t r, 111urndis_ctrl_msg(struct usbnet *un, uint8_t rt, uint8_t r,
112 uint16_t index, uint16_t value, void *buf, size_t buflen) 112 uint16_t index, uint16_t value, void *buf, size_t buflen)
113{ 113{
114 usb_device_request_t req; 114 usb_device_request_t req;
115 115
116 req.bmRequestType = rt; 116 req.bmRequestType = rt;
117 req.bRequest = r; 117 req.bRequest = r;
118 USETW(req.wValue, value); 118 USETW(req.wValue, value);
119 USETW(req.wIndex, index); 119 USETW(req.wIndex, index);
120 USETW(req.wLength, buflen); 120 USETW(req.wLength, buflen);
121 121
122 return usbd_do_request(un->un_udev, &req, buf); 122 return usbd_do_request(un->un_udev, &req, buf);
123} 123}
124 124
125static usbd_status 125static usbd_status
126urndis_ctrl_send(struct usbnet *un, void *buf, size_t len) 126urndis_ctrl_send(struct usbnet *un, void *buf, size_t len)
127{ 127{
128 struct urndis_softc *sc = usbnet_softc(un); 128 struct urndis_softc *sc = usbnet_softc(un);
129 usbd_status err; 129 usbd_status err;
130 130
131 if (usbnet_isdying(un)) 131 if (usbnet_isdying(un))
132 return(0); 132 return(0);
133 133
134 err = urndis_ctrl_msg(un, UT_WRITE_CLASS_INTERFACE, UR_GET_STATUS, 134 err = urndis_ctrl_msg(un, UT_WRITE_CLASS_INTERFACE, UR_GET_STATUS,
135 sc->sc_ifaceno_ctl, 0, buf, len); 135 sc->sc_ifaceno_ctl, 0, buf, len);
136 136
137 if (err != USBD_NORMAL_COMPLETION) 137 if (err != USBD_NORMAL_COMPLETION)
138 printf("%s: %s\n", DEVNAME(un), usbd_errstr(err)); 138 printf("%s: %s\n", DEVNAME(un), usbd_errstr(err));
139 139
140 return err; 140 return err;
141} 141}
142 142
143static struct rndis_comp_hdr * 143static struct rndis_comp_hdr *
144urndis_ctrl_recv(struct usbnet *un) 144urndis_ctrl_recv(struct usbnet *un)
145{ 145{
146 struct urndis_softc *sc = usbnet_softc(un); 146 struct urndis_softc *sc = usbnet_softc(un);
147 struct rndis_comp_hdr *hdr; 147 struct rndis_comp_hdr *hdr;
148 char *buf; 148 char *buf;
149 usbd_status err; 149 usbd_status err;
150 150
151 if (usbnet_isdying(un)) 151 if (usbnet_isdying(un))
152 return(0); 152 return(0);
153 153
154 buf = kmem_alloc(URNDIS_RESPONSE_LEN, KM_SLEEP); 154 buf = kmem_alloc(URNDIS_RESPONSE_LEN, KM_SLEEP);
155 err = urndis_ctrl_msg(un, UT_READ_CLASS_INTERFACE, UR_CLEAR_FEATURE, 155 err = urndis_ctrl_msg(un, UT_READ_CLASS_INTERFACE, UR_CLEAR_FEATURE,
156 sc->sc_ifaceno_ctl, 0, buf, URNDIS_RESPONSE_LEN); 156 sc->sc_ifaceno_ctl, 0, buf, URNDIS_RESPONSE_LEN);
157 157
158 if (err != USBD_NORMAL_COMPLETION && err != USBD_SHORT_XFER) { 158 if (err != USBD_NORMAL_COMPLETION && err != USBD_SHORT_XFER) {
159 printf("%s: %s\n", DEVNAME(un), usbd_errstr(err)); 159 printf("%s: %s\n", DEVNAME(un), usbd_errstr(err));
160 kmem_free(buf, URNDIS_RESPONSE_LEN); 160 kmem_free(buf, URNDIS_RESPONSE_LEN);
161 return NULL; 161 return NULL;
162 } 162 }
163 163
164 hdr = (struct rndis_comp_hdr *)buf; 164 hdr = (struct rndis_comp_hdr *)buf;
165 DPRINTF(("%s: urndis_ctrl_recv: type %#x len %u\n", 165 DPRINTF(("%s: urndis_ctrl_recv: type %#x len %u\n",
166 DEVNAME(un), 166 DEVNAME(un),
167 le32toh(hdr->rm_type), 167 le32toh(hdr->rm_type),
168 le32toh(hdr->rm_len))); 168 le32toh(hdr->rm_len)));
169 169
170 if (le32toh(hdr->rm_len) > URNDIS_RESPONSE_LEN) { 170 if (le32toh(hdr->rm_len) > URNDIS_RESPONSE_LEN) {
171 printf("%s: ctrl message error: wrong size %u > %u\n", 171 printf("%s: ctrl message error: wrong size %u > %u\n",
172 DEVNAME(un), 172 DEVNAME(un),
173 le32toh(hdr->rm_len), 173 le32toh(hdr->rm_len),
174 URNDIS_RESPONSE_LEN); 174 URNDIS_RESPONSE_LEN);
175 kmem_free(buf, URNDIS_RESPONSE_LEN); 175 kmem_free(buf, URNDIS_RESPONSE_LEN);
176 return NULL; 176 return NULL;
177 } 177 }
178 178
179 return hdr; 179 return hdr;
180} 180}
181 181
182static uint32_t 182static uint32_t
183urndis_ctrl_handle(struct usbnet *un, struct rndis_comp_hdr *hdr, 183urndis_ctrl_handle(struct usbnet *un, struct rndis_comp_hdr *hdr,
184 void **buf, size_t *bufsz) 184 void **buf, size_t *bufsz)
185{ 185{
186 uint32_t rval; 186 uint32_t rval;
187 187
188 DPRINTF(("%s: urndis_ctrl_handle\n", DEVNAME(un))); 188 DPRINTF(("%s: urndis_ctrl_handle\n", DEVNAME(un)));
189 189
190 if (buf && bufsz) { 190 if (buf && bufsz) {
191 *buf = NULL; 191 *buf = NULL;
192 *bufsz = 0; 192 *bufsz = 0;
193 } 193 }
194 194
195 switch (le32toh(hdr->rm_type)) { 195 switch (le32toh(hdr->rm_type)) {
196 case REMOTE_NDIS_INITIALIZE_CMPLT: 196 case REMOTE_NDIS_INITIALIZE_CMPLT:
197 rval = urndis_ctrl_handle_init(un, hdr); 197 rval = urndis_ctrl_handle_init(un, hdr);
198 break; 198 break;
199 199
200 case REMOTE_NDIS_QUERY_CMPLT: 200 case REMOTE_NDIS_QUERY_CMPLT:
201 rval = urndis_ctrl_handle_query(un, hdr, buf, bufsz); 201 rval = urndis_ctrl_handle_query(un, hdr, buf, bufsz);
202 break; 202 break;
203 203
204 case REMOTE_NDIS_RESET_CMPLT: 204 case REMOTE_NDIS_RESET_CMPLT:
205 rval = urndis_ctrl_handle_reset(un, hdr); 205 rval = urndis_ctrl_handle_reset(un, hdr);
206 break; 206 break;
207 207
208 case REMOTE_NDIS_KEEPALIVE_CMPLT: 208 case REMOTE_NDIS_KEEPALIVE_CMPLT:
209 case REMOTE_NDIS_SET_CMPLT: 209 case REMOTE_NDIS_SET_CMPLT:
210 rval = le32toh(hdr->rm_status); 210 rval = le32toh(hdr->rm_status);
211 break; 211 break;
212 212
213 case REMOTE_NDIS_INDICATE_STATUS_MSG: 213 case REMOTE_NDIS_INDICATE_STATUS_MSG:
214 rval = urndis_ctrl_handle_status(un, hdr); 214 rval = urndis_ctrl_handle_status(un, hdr);
215 break; 215 break;
216 216
217 default: 217 default:
218 printf("%s: ctrl message error: unknown event %#x\n", 218 printf("%s: ctrl message error: unknown event %#x\n",
219 DEVNAME(un), le32toh(hdr->rm_type)); 219 DEVNAME(un), le32toh(hdr->rm_type));
220 rval = RNDIS_STATUS_FAILURE; 220 rval = RNDIS_STATUS_FAILURE;
221 } 221 }
222 222
223 kmem_free(hdr, URNDIS_RESPONSE_LEN); 223 kmem_free(hdr, URNDIS_RESPONSE_LEN);
224 224
225 return rval; 225 return rval;
226} 226}
227 227
228static uint32_t 228static uint32_t
229urndis_ctrl_handle_init(struct usbnet *un, const struct rndis_comp_hdr *hdr) 229urndis_ctrl_handle_init(struct usbnet *un, const struct rndis_comp_hdr *hdr)
230{ 230{
231 struct urndis_softc *sc = usbnet_softc(un); 231 struct urndis_softc *sc = usbnet_softc(un);
232 const struct rndis_init_comp *msg; 232 const struct rndis_init_comp *msg;
233 233
234 msg = (const struct rndis_init_comp *) hdr; 234 msg = (const struct rndis_init_comp *) hdr;
235 235
236 DPRINTF(("%s: urndis_ctrl_handle_init: len %u rid %u status %#x " 236 DPRINTF(("%s: urndis_ctrl_handle_init: len %u rid %u status %#x "
237 "ver_major %u ver_minor %u devflags %#x medium %#x pktmaxcnt %u " 237 "ver_major %u ver_minor %u devflags %#x medium %#x pktmaxcnt %u "
238 "pktmaxsz %u align %u aflistoffset %u aflistsz %u\n", 238 "pktmaxsz %u align %u aflistoffset %u aflistsz %u\n",
239 DEVNAME(un), 239 DEVNAME(un),
240 le32toh(msg->rm_len), 240 le32toh(msg->rm_len),
241 le32toh(msg->rm_rid), 241 le32toh(msg->rm_rid),
242 le32toh(msg->rm_status), 242 le32toh(msg->rm_status),
243 le32toh(msg->rm_ver_major), 243 le32toh(msg->rm_ver_major),
244 le32toh(msg->rm_ver_minor), 244 le32toh(msg->rm_ver_minor),
245 le32toh(msg->rm_devflags), 245 le32toh(msg->rm_devflags),
246 le32toh(msg->rm_medium), 246 le32toh(msg->rm_medium),
247 le32toh(msg->rm_pktmaxcnt), 247 le32toh(msg->rm_pktmaxcnt),
248 le32toh(msg->rm_pktmaxsz), 248 le32toh(msg->rm_pktmaxsz),
249 le32toh(msg->rm_align), 249 le32toh(msg->rm_align),
250 le32toh(msg->rm_aflistoffset), 250 le32toh(msg->rm_aflistoffset),
251 le32toh(msg->rm_aflistsz))); 251 le32toh(msg->rm_aflistsz)));
252 252
253 if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) { 253 if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) {
254 printf("%s: init failed %#x\n", 254 printf("%s: init failed %#x\n",
255 DEVNAME(un), 255 DEVNAME(un),
256 le32toh(msg->rm_status)); 256 le32toh(msg->rm_status));
257 257
258 return le32toh(msg->rm_status); 258 return le32toh(msg->rm_status);
259 } 259 }
260 260
261 if (le32toh(msg->rm_devflags) != RNDIS_DF_CONNECTIONLESS) { 261 if (le32toh(msg->rm_devflags) != RNDIS_DF_CONNECTIONLESS) {
262 printf("%s: wrong device type (current type: %#x)\n", 262 printf("%s: wrong device type (current type: %#x)\n",
263 DEVNAME(un), 263 DEVNAME(un),
264 le32toh(msg->rm_devflags)); 264 le32toh(msg->rm_devflags));
265 265
266 return RNDIS_STATUS_FAILURE; 266 return RNDIS_STATUS_FAILURE;
267 } 267 }
268 268
269 if (le32toh(msg->rm_medium) != RNDIS_MEDIUM_802_3) { 269 if (le32toh(msg->rm_medium) != RNDIS_MEDIUM_802_3) {
270 printf("%s: medium not 802.3 (current medium: %#x)\n", 270 printf("%s: medium not 802.3 (current medium: %#x)\n",
271 DEVNAME(un), le32toh(msg->rm_medium)); 271 DEVNAME(un), le32toh(msg->rm_medium));
272 272
273 return RNDIS_STATUS_FAILURE; 273 return RNDIS_STATUS_FAILURE;
274 } 274 }
275 275
276 if (le32toh(msg->rm_ver_major) != RNDIS_MAJOR_VERSION || 276 if (le32toh(msg->rm_ver_major) != RNDIS_MAJOR_VERSION ||
277 le32toh(msg->rm_ver_minor) != RNDIS_MINOR_VERSION) { 277 le32toh(msg->rm_ver_minor) != RNDIS_MINOR_VERSION) {
278 printf("%s: version not %u.%u (current version: %u.%u)\n", 278 printf("%s: version not %u.%u (current version: %u.%u)\n",
279 DEVNAME(un), RNDIS_MAJOR_VERSION, RNDIS_MINOR_VERSION, 279 DEVNAME(un), RNDIS_MAJOR_VERSION, RNDIS_MINOR_VERSION,
280 le32toh(msg->rm_ver_major), le32toh(msg->rm_ver_minor)); 280 le32toh(msg->rm_ver_major), le32toh(msg->rm_ver_minor));
281 281
282 return RNDIS_STATUS_FAILURE; 282 return RNDIS_STATUS_FAILURE;
283 } 283 }
284 284
285 sc->sc_maxppt = le32toh(msg->rm_pktmaxcnt); 285 sc->sc_maxppt = le32toh(msg->rm_pktmaxcnt);
286 sc->sc_maxtsz = le32toh(msg->rm_pktmaxsz); 286 sc->sc_maxtsz = le32toh(msg->rm_pktmaxsz);
287 sc->sc_palign = 1U << le32toh(msg->rm_align); 287 sc->sc_palign = 1U << le32toh(msg->rm_align);
288 288
289 return le32toh(msg->rm_status); 289 return le32toh(msg->rm_status);
290} 290}
291 291
292static uint32_t 292static uint32_t
293urndis_ctrl_handle_query(struct usbnet *un, 293urndis_ctrl_handle_query(struct usbnet *un,
294 const struct rndis_comp_hdr *hdr, void **buf, size_t *bufsz) 294 const struct rndis_comp_hdr *hdr, void **buf, size_t *bufsz)
295{ 295{
296 const struct rndis_query_comp *msg; 296 const struct rndis_query_comp *msg;
297 297
298 msg = (const struct rndis_query_comp *) hdr; 298 msg = (const struct rndis_query_comp *) hdr;
299 299
300 DPRINTF(("%s: urndis_ctrl_handle_query: len %u rid %u status %#x " 300 DPRINTF(("%s: urndis_ctrl_handle_query: len %u rid %u status %#x "
301 "buflen %u bufoff %u\n", 301 "buflen %u bufoff %u\n",
302 DEVNAME(un), 302 DEVNAME(un),
303 le32toh(msg->rm_len), 303 le32toh(msg->rm_len),
304 le32toh(msg->rm_rid), 304 le32toh(msg->rm_rid),
305 le32toh(msg->rm_status), 305 le32toh(msg->rm_status),
306 le32toh(msg->rm_infobuflen), 306 le32toh(msg->rm_infobuflen),
307 le32toh(msg->rm_infobufoffset))); 307 le32toh(msg->rm_infobufoffset)));
308 308
309 if (buf && bufsz) { 309 if (buf && bufsz) {
310 *buf = NULL; 310 *buf = NULL;
311 *bufsz = 0; 311 *bufsz = 0;
312 } 312 }
313 313
314 if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) { 314 if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) {
315 printf("%s: query failed %#x\n", 315 printf("%s: query failed %#x\n",
316 DEVNAME(un), 316 DEVNAME(un),
317 le32toh(msg->rm_status)); 317 le32toh(msg->rm_status));
318 318
319 return le32toh(msg->rm_status); 319 return le32toh(msg->rm_status);
320 } 320 }
321 321
322 if (le32toh(msg->rm_infobuflen) + le32toh(msg->rm_infobufoffset) + 322 if (le32toh(msg->rm_infobuflen) + le32toh(msg->rm_infobufoffset) +
323 RNDIS_HEADER_OFFSET > le32toh(msg->rm_len)) { 323 RNDIS_HEADER_OFFSET > le32toh(msg->rm_len)) {
324 printf("%s: ctrl message error: invalid query info " 324 printf("%s: ctrl message error: invalid query info "
325 "len/offset/end_position(%u/%u/%u) -> " 325 "len/offset/end_position(%u/%u/%u) -> "
326 "go out of buffer limit %u\n", 326 "go out of buffer limit %u\n",
327 DEVNAME(un), 327 DEVNAME(un),
328 le32toh(msg->rm_infobuflen), 328 le32toh(msg->rm_infobuflen),
329 le32toh(msg->rm_infobufoffset), 329 le32toh(msg->rm_infobufoffset),
330 le32toh(msg->rm_infobuflen) + 330 le32toh(msg->rm_infobuflen) +
331 le32toh(msg->rm_infobufoffset) + (uint32_t)RNDIS_HEADER_OFFSET, 331 le32toh(msg->rm_infobufoffset) + (uint32_t)RNDIS_HEADER_OFFSET,
332 le32toh(msg->rm_len)); 332 le32toh(msg->rm_len));
333 return RNDIS_STATUS_FAILURE; 333 return RNDIS_STATUS_FAILURE;
334 } 334 }
335 335
336 if (buf && bufsz) { 336 if (buf && bufsz) {
337 const char *p; 337 const char *p;
338 338
339 *buf = kmem_alloc(le32toh(msg->rm_infobuflen), KM_SLEEP); 339 *buf = kmem_alloc(le32toh(msg->rm_infobuflen), KM_SLEEP);
340 *bufsz = le32toh(msg->rm_infobuflen); 340 *bufsz = le32toh(msg->rm_infobuflen);
341 341
342 p = (const char *)&msg->rm_rid; 342 p = (const char *)&msg->rm_rid;
343 p += le32toh(msg->rm_infobufoffset); 343 p += le32toh(msg->rm_infobufoffset);
344 memcpy(*buf, p, le32toh(msg->rm_infobuflen)); 344 memcpy(*buf, p, le32toh(msg->rm_infobuflen));
345 } 345 }
346 346
347 return le32toh(msg->rm_status); 347 return le32toh(msg->rm_status);
348} 348}
349 349
350static uint32_t 350static uint32_t
351urndis_ctrl_handle_reset(struct usbnet *un, const struct rndis_comp_hdr *hdr) 351urndis_ctrl_handle_reset(struct usbnet *un, const struct rndis_comp_hdr *hdr)
352{ 352{
353 struct urndis_softc *sc = usbnet_softc(un); 353 struct urndis_softc *sc = usbnet_softc(un);
354 const struct rndis_reset_comp *msg; 354 const struct rndis_reset_comp *msg;
355 uint32_t rval; 355 uint32_t rval;
356 356
357 msg = (const struct rndis_reset_comp *) hdr; 357 msg = (const struct rndis_reset_comp *) hdr;
358 358
359 rval = le32toh(msg->rm_status); 359 rval = le32toh(msg->rm_status);
360 360
361 DPRINTF(("%s: urndis_ctrl_handle_reset: len %u status %#x " 361 DPRINTF(("%s: urndis_ctrl_handle_reset: len %u status %#x "
362 "adrreset %u\n", 362 "adrreset %u\n",
363 DEVNAME(un), 363 DEVNAME(un),
364 le32toh(msg->rm_len), 364 le32toh(msg->rm_len),
365 rval, 365 rval,
366 le32toh(msg->rm_adrreset))); 366 le32toh(msg->rm_adrreset)));
367 367
368 if (rval != RNDIS_STATUS_SUCCESS) { 368 if (rval != RNDIS_STATUS_SUCCESS) {
369 printf("%s: reset failed %#x\n", DEVNAME(un), rval); 369 printf("%s: reset failed %#x\n", DEVNAME(un), rval);
370 return rval; 370 return rval;
371 } 371 }
372 372
373 if (le32toh(msg->rm_adrreset) != 0) { 373 if (le32toh(msg->rm_adrreset) != 0) {
374 uint32_t filter; 374 uint32_t filter;
375 375
376 filter = htole32(sc->sc_filter); 376 filter = htole32(sc->sc_filter);
377 rval = urndis_ctrl_set(un, OID_GEN_CURRENT_PACKET_FILTER, 377 rval = urndis_ctrl_set(un, OID_GEN_CURRENT_PACKET_FILTER,
378 &filter, sizeof(filter)); 378 &filter, sizeof(filter));
379 if (rval != RNDIS_STATUS_SUCCESS) { 379 if (rval != RNDIS_STATUS_SUCCESS) {
380 printf("%s: unable to reset data filters\n", 380 printf("%s: unable to reset data filters\n",
381 DEVNAME(un)); 381 DEVNAME(un));
382 return rval; 382 return rval;
383 } 383 }
384 } 384 }
385 385
386 return rval; 386 return rval;
387} 387}
388 388
389static uint32_t 389static uint32_t
390urndis_ctrl_handle_status(struct usbnet *un, 390urndis_ctrl_handle_status(struct usbnet *un,
391 const struct rndis_comp_hdr *hdr) 391 const struct rndis_comp_hdr *hdr)
392{ 392{
393 const struct rndis_status_msg *msg; 393 const struct rndis_status_msg *msg;
394 uint32_t rval; 394 uint32_t rval;
395 395
396 msg = (const struct rndis_status_msg *)hdr; 396 msg = (const struct rndis_status_msg *)hdr;
397 397
398 rval = le32toh(msg->rm_status); 398 rval = le32toh(msg->rm_status);
399 399
400 DPRINTF(("%s: urndis_ctrl_handle_status: len %u status %#x " 400 DPRINTF(("%s: urndis_ctrl_handle_status: len %u status %#x "
401 "stbuflen %u\n", 401 "stbuflen %u\n",
402 DEVNAME(un), 402 DEVNAME(un),
403 le32toh(msg->rm_len), 403 le32toh(msg->rm_len),
404 rval, 404 rval,
405 le32toh(msg->rm_stbuflen))); 405 le32toh(msg->rm_stbuflen)));
406 406
407 switch (rval) { 407 switch (rval) {
408 case RNDIS_STATUS_MEDIA_CONNECT: 408 case RNDIS_STATUS_MEDIA_CONNECT:
409 case RNDIS_STATUS_MEDIA_DISCONNECT: 409 case RNDIS_STATUS_MEDIA_DISCONNECT:
410 case RNDIS_STATUS_OFFLOAD_CURRENT_CONFIG: 410 case RNDIS_STATUS_OFFLOAD_CURRENT_CONFIG:
411 rval = RNDIS_STATUS_SUCCESS; 411 rval = RNDIS_STATUS_SUCCESS;
412 break; 412 break;
413 413
414 default: 414 default:
415 printf("%s: status %#x\n", DEVNAME(un), rval); 415 printf("%s: status %#x\n", DEVNAME(un), rval);
416 } 416 }
417 417
418 return rval; 418 return rval;
419} 419}
420 420
421static uint32_t 421static uint32_t
422urndis_ctrl_init(struct usbnet *un) 422urndis_ctrl_init(struct usbnet *un)
423{ 423{
424 struct rndis_init_req *msg; 424 struct rndis_init_req *msg;
425 uint32_t rval; 425 uint32_t rval;
426 struct rndis_comp_hdr *hdr; 426 struct rndis_comp_hdr *hdr;
427 427
428 msg = kmem_alloc(sizeof(*msg), KM_SLEEP); 428 msg = kmem_alloc(sizeof(*msg), KM_SLEEP);
429 msg->rm_type = htole32(REMOTE_NDIS_INITIALIZE_MSG); 429 msg->rm_type = htole32(REMOTE_NDIS_INITIALIZE_MSG);
430 msg->rm_len = htole32(sizeof(*msg)); 430 msg->rm_len = htole32(sizeof(*msg));
431 msg->rm_rid = htole32(0); 431 msg->rm_rid = htole32(0);
432 msg->rm_ver_major = htole32(RNDIS_MAJOR_VERSION); 432 msg->rm_ver_major = htole32(RNDIS_MAJOR_VERSION);
433 msg->rm_ver_minor = htole32(RNDIS_MINOR_VERSION); 433 msg->rm_ver_minor = htole32(RNDIS_MINOR_VERSION);
434 msg->rm_max_xfersz = htole32(RNDIS_BUFSZ); 434 msg->rm_max_xfersz = htole32(RNDIS_BUFSZ);
435 435
436 DPRINTF(("%s: urndis_ctrl_init send: type %u len %u rid %u ver_major %u " 436 DPRINTF(("%s: urndis_ctrl_init send: type %u len %u rid %u ver_major %u "
437 "ver_minor %u max_xfersz %u\n", 437 "ver_minor %u max_xfersz %u\n",
438 DEVNAME(un), 438 DEVNAME(un),
439 le32toh(msg->rm_type), 439 le32toh(msg->rm_type),
440 le32toh(msg->rm_len), 440 le32toh(msg->rm_len),
441 le32toh(msg->rm_rid), 441 le32toh(msg->rm_rid),
442 le32toh(msg->rm_ver_major), 442 le32toh(msg->rm_ver_major),
443 le32toh(msg->rm_ver_minor), 443 le32toh(msg->rm_ver_minor),
444 le32toh(msg->rm_max_xfersz))); 444 le32toh(msg->rm_max_xfersz)));
445 445
446 rval = urndis_ctrl_send(un, msg, sizeof(*msg)); 446 rval = urndis_ctrl_send(un, msg, sizeof(*msg));
447 kmem_free(msg, sizeof(*msg)); 447 kmem_free(msg, sizeof(*msg));
448 448
449 if (rval != RNDIS_STATUS_SUCCESS) { 449 if (rval != RNDIS_STATUS_SUCCESS) {
450 printf("%s: init failed\n", DEVNAME(un)); 450 printf("%s: init failed\n", DEVNAME(un));
451 return rval; 451 return rval;
452 } 452 }
453 453
454 if ((hdr = urndis_ctrl_recv(un)) == NULL) { 454 if ((hdr = urndis_ctrl_recv(un)) == NULL) {
455 printf("%s: unable to get init response\n", DEVNAME(un)); 455 printf("%s: unable to get init response\n", DEVNAME(un));
456 return RNDIS_STATUS_FAILURE; 456 return RNDIS_STATUS_FAILURE;
457 } 457 }
458 rval = urndis_ctrl_handle(un, hdr, NULL, NULL); 458 rval = urndis_ctrl_handle(un, hdr, NULL, NULL);
459 459
460 return rval; 460 return rval;
461} 461}
462 462
463#if 0 463#if 0
464static uint32_t 464static uint32_t
465urndis_ctrl_halt(struct usbnet *un) 465urndis_ctrl_halt(struct usbnet *un)
466{ 466{
467 struct rndis_halt_req *msg; 467 struct rndis_halt_req *msg;
468 uint32_t rval; 468 uint32_t rval;
469 469
470 msg = kmem_alloc(sizeof(*msg), KM_SLEEP); 470 msg = kmem_alloc(sizeof(*msg), KM_SLEEP);
471 msg->rm_type = htole32(REMOTE_NDIS_HALT_MSG); 471 msg->rm_type = htole32(REMOTE_NDIS_HALT_MSG);
472 msg->rm_len = htole32(sizeof(*msg)); 472 msg->rm_len = htole32(sizeof(*msg));
473 msg->rm_rid = 0; 473 msg->rm_rid = 0;
474 474
475 DPRINTF(("%s: urndis_ctrl_halt send: type %u len %u rid %u\n", 475 DPRINTF(("%s: urndis_ctrl_halt send: type %u len %u rid %u\n",
476 DEVNAME(un), 476 DEVNAME(un),
477 le32toh(msg->rm_type), 477 le32toh(msg->rm_type),
478 le32toh(msg->rm_len), 478 le32toh(msg->rm_len),
479 le32toh(msg->rm_rid))); 479 le32toh(msg->rm_rid)));
480 480
481 rval = urndis_ctrl_send(un, msg, sizeof(*msg)); 481 rval = urndis_ctrl_send(un, msg, sizeof(*msg));
482 kmem_free(msg, sizeof(*msg)); 482 kmem_free(msg, sizeof(*msg));
483 483
484 if (rval != RNDIS_STATUS_SUCCESS) 484 if (rval != RNDIS_STATUS_SUCCESS)
485 printf("%s: halt failed\n", DEVNAME(un)); 485 printf("%s: halt failed\n", DEVNAME(un));
486 486
487 return rval; 487 return rval;
488} 488}
489#endif 489#endif
490 490
491static uint32_t 491static uint32_t
492urndis_ctrl_query(struct usbnet *un, uint32_t oid, 492urndis_ctrl_query(struct usbnet *un, uint32_t oid,
493 void *qbuf, size_t qlen, 493 void *qbuf, size_t qlen,
494 void **rbuf, size_t *rbufsz) 494 void **rbuf, size_t *rbufsz)
495{ 495{
496 struct rndis_query_req *msg; 496 struct rndis_query_req *msg;
497 uint32_t rval; 497 uint32_t rval;
498 struct rndis_comp_hdr *hdr; 498 struct rndis_comp_hdr *hdr;
499 499
500 msg = kmem_alloc(sizeof(*msg) + qlen, KM_SLEEP); 500 msg = kmem_alloc(sizeof(*msg) + qlen, KM_SLEEP);
501 msg->rm_type = htole32(REMOTE_NDIS_QUERY_MSG); 501 msg->rm_type = htole32(REMOTE_NDIS_QUERY_MSG);
502 msg->rm_len = htole32(sizeof(*msg) + qlen); 502 msg->rm_len = htole32(sizeof(*msg) + qlen);
503 msg->rm_rid = 0; /* XXX */ 503 msg->rm_rid = 0; /* XXX */
504 msg->rm_oid = htole32(oid); 504 msg->rm_oid = htole32(oid);
505 msg->rm_infobuflen = htole32(qlen); 505 msg->rm_infobuflen = htole32(qlen);
506 if (qlen != 0) { 506 if (qlen != 0) {
507 msg->rm_infobufoffset = htole32(20); 507 msg->rm_infobufoffset = htole32(20);
508 memcpy((char*)msg + 20, qbuf, qlen); 508 memcpy((char*)msg + 20, qbuf, qlen);
509 } else 509 } else
510 msg->rm_infobufoffset = 0; 510 msg->rm_infobufoffset = 0;
511 msg->rm_devicevchdl = 0; 511 msg->rm_devicevchdl = 0;
512 512
513 DPRINTF(("%s: urndis_ctrl_query send: type %u len %u rid %u oid %#x " 513 DPRINTF(("%s: urndis_ctrl_query send: type %u len %u rid %u oid %#x "
514 "infobuflen %u infobufoffset %u devicevchdl %u\n", 514 "infobuflen %u infobufoffset %u devicevchdl %u\n",
515 DEVNAME(un), 515 DEVNAME(un),
516 le32toh(msg->rm_type), 516 le32toh(msg->rm_type),
517 le32toh(msg->rm_len), 517 le32toh(msg->rm_len),
518 le32toh(msg->rm_rid), 518 le32toh(msg->rm_rid),
519 le32toh(msg->rm_oid), 519 le32toh(msg->rm_oid),
520 le32toh(msg->rm_infobuflen), 520 le32toh(msg->rm_infobuflen),
521 le32toh(msg->rm_infobufoffset), 521 le32toh(msg->rm_infobufoffset),
522 le32toh(msg->rm_devicevchdl))); 522 le32toh(msg->rm_devicevchdl)));
523 523
524 rval = urndis_ctrl_send(un, msg, sizeof(*msg)); 524 rval = urndis_ctrl_send(un, msg, sizeof(*msg));
525 kmem_free(msg, sizeof(*msg) + qlen); 525 kmem_free(msg, sizeof(*msg) + qlen);
526 526
527 if (rval != RNDIS_STATUS_SUCCESS) { 527 if (rval != RNDIS_STATUS_SUCCESS) {
528 printf("%s: query failed\n", DEVNAME(un)); 528 printf("%s: query failed\n", DEVNAME(un));
529 return rval; 529 return rval;
530 } 530 }
531 531
532 if ((hdr = urndis_ctrl_recv(un)) == NULL) { 532 if ((hdr = urndis_ctrl_recv(un)) == NULL) {
533 printf("%s: unable to get query response\n", DEVNAME(un)); 533 printf("%s: unable to get query response\n", DEVNAME(un));
534 return RNDIS_STATUS_FAILURE; 534 return RNDIS_STATUS_FAILURE;
535 } 535 }
536 rval = urndis_ctrl_handle(un, hdr, rbuf, rbufsz); 536 rval = urndis_ctrl_handle(un, hdr, rbuf, rbufsz);
537 537
538 return rval; 538 return rval;
539} 539}
540 540
541static uint32_t 541static uint32_t
542urndis_ctrl_set(struct usbnet *un, uint32_t oid, void *buf, size_t len) 542urndis_ctrl_set(struct usbnet *un, uint32_t oid, void *buf, size_t len)
543{ 543{
544 struct rndis_set_req *msg; 544 struct rndis_set_req *msg;
545 uint32_t rval; 545 uint32_t rval;
546 struct rndis_comp_hdr *hdr; 546 struct rndis_comp_hdr *hdr;
547 547
548 msg = kmem_alloc(sizeof(*msg) + len, KM_SLEEP); 548 msg = kmem_alloc(sizeof(*msg) + len, KM_SLEEP);
549 msg->rm_type = htole32(REMOTE_NDIS_SET_MSG); 549 msg->rm_type = htole32(REMOTE_NDIS_SET_MSG);
550 msg->rm_len = htole32(sizeof(*msg) + len); 550 msg->rm_len = htole32(sizeof(*msg) + len);
551 msg->rm_rid = 0; /* XXX */ 551 msg->rm_rid = 0; /* XXX */
552 msg->rm_oid = htole32(oid); 552 msg->rm_oid = htole32(oid);
553 msg->rm_infobuflen = htole32(len); 553 msg->rm_infobuflen = htole32(len);
554 if (len != 0) { 554 if (len != 0) {
555 msg->rm_infobufoffset = htole32(20); 555 msg->rm_infobufoffset = htole32(20);
556 memcpy((char*)msg + 20, buf, len); 556 memcpy((char*)msg + 20, buf, len);
557 } else 557 } else
558 msg->rm_infobufoffset = 0; 558 msg->rm_infobufoffset = 0;
559 msg->rm_devicevchdl = 0; 559 msg->rm_devicevchdl = 0;
560 560
561 DPRINTF(("%s: urndis_ctrl_set send: type %u len %u rid %u oid %#x " 561 DPRINTF(("%s: urndis_ctrl_set send: type %u len %u rid %u oid %#x "
562 "infobuflen %u infobufoffset %u devicevchdl %u\n", 562 "infobuflen %u infobufoffset %u devicevchdl %u\n",
563 DEVNAME(un), 563 DEVNAME(un),
564 le32toh(msg->rm_type), 564 le32toh(msg->rm_type),
565 le32toh(msg->rm_len), 565 le32toh(msg->rm_len),
566 le32toh(msg->rm_rid), 566 le32toh(msg->rm_rid),
567 le32toh(msg->rm_oid), 567 le32toh(msg->rm_oid),
568 le32toh(msg->rm_infobuflen), 568 le32toh(msg->rm_infobuflen),
569 le32toh(msg->rm_infobufoffset), 569 le32toh(msg->rm_infobufoffset),
570 le32toh(msg->rm_devicevchdl))); 570 le32toh(msg->rm_devicevchdl)));
571 571
572 rval = urndis_ctrl_send(un, msg, sizeof(*msg)); 572 rval = urndis_ctrl_send(un, msg, sizeof(*msg));
573 kmem_free(msg, sizeof(*msg) + len); 573 kmem_free(msg, sizeof(*msg) + len);
574 574
575 if (rval != RNDIS_STATUS_SUCCESS) { 575 if (rval != RNDIS_STATUS_SUCCESS) {
576 printf("%s: set failed\n", DEVNAME(un)); 576 printf("%s: set failed\n", DEVNAME(un));
577 return rval; 577 return rval;
578 } 578 }
579 579
580 if ((hdr = urndis_ctrl_recv(un)) == NULL) { 580 if ((hdr = urndis_ctrl_recv(un)) == NULL) {
581 printf("%s: unable to get set response\n", DEVNAME(un)); 581 printf("%s: unable to get set response\n", DEVNAME(un));
582 return RNDIS_STATUS_FAILURE; 582 return RNDIS_STATUS_FAILURE;
583 } 583 }
584 rval = urndis_ctrl_handle(un, hdr, NULL, NULL); 584 rval = urndis_ctrl_handle(un, hdr, NULL, NULL);
585 if (rval != RNDIS_STATUS_SUCCESS) 585 if (rval != RNDIS_STATUS_SUCCESS)
586 printf("%s: set failed %#x\n", DEVNAME(un), rval); 586 printf("%s: set failed %#x\n", DEVNAME(un), rval);
587 587
588 return rval; 588 return rval;
589} 589}
590 590
591#if 0 591#if 0
592static uint32_t 592static uint32_t
593urndis_ctrl_set_param(struct urndis_softc *un, 593urndis_ctrl_set_param(struct urndis_softc *un,
594 const char *name, 594 const char *name,
595 uint32_t type, 595 uint32_t type,
596 void *buf, 596 void *buf,
597 size_t len) 597 size_t len)
598{ 598{
599 struct rndis_set_parameter *param; 599 struct rndis_set_parameter *param;
600 uint32_t rval; 600 uint32_t rval;
601 size_t namelen, tlen; 601 size_t namelen, tlen;
602 602
603 if (name) 603 if (name)
604 namelen = strlen(name); 604 namelen = strlen(name);
605 else 605 else
606 namelen = 0; 606 namelen = 0;
607 tlen = sizeof(*param) + len + namelen; 607 tlen = sizeof(*param) + len + namelen;
608 param = kmem_alloc(tlen, KM_SLEEP); 608 param = kmem_alloc(tlen, KM_SLEEP);
609 param->rm_namelen = htole32(namelen); 609 param->rm_namelen = htole32(namelen);
610 param->rm_valuelen = htole32(len); 610 param->rm_valuelen = htole32(len);
611 param->rm_type = htole32(type); 611 param->rm_type = htole32(type);
612 if (namelen != 0) { 612 if (namelen != 0) {
613 param->rm_nameoffset = htole32(20); 613 param->rm_nameoffset = htole32(20);
614 memcpy(param + 20, name, namelen); 614 memcpy(param + 20, name, namelen);
615 } else 615 } else
616 param->rm_nameoffset = 0; 616 param->rm_nameoffset = 0;
617 if (len != 0) { 617 if (len != 0) {
618 param->rm_valueoffset = htole32(20 + namelen); 618 param->rm_valueoffset = htole32(20 + namelen);
619 memcpy(param + 20 + namelen, buf, len); 619 memcpy(param + 20 + namelen, buf, len);
620 } else 620 } else
621 param->rm_valueoffset = 0; 621 param->rm_valueoffset = 0;
622 622
623 DPRINTF(("%s: urndis_ctrl_set_param send: nameoffset %u namelen %u " 623 DPRINTF(("%s: urndis_ctrl_set_param send: nameoffset %u namelen %u "
624 "type %#x valueoffset %u valuelen %u\n", 624 "type %#x valueoffset %u valuelen %u\n",
625 DEVNAME(un), 625 DEVNAME(un),
626 le32toh(param->rm_nameoffset), 626 le32toh(param->rm_nameoffset),
627 le32toh(param->rm_namelen), 627 le32toh(param->rm_namelen),
628 le32toh(param->rm_type), 628 le32toh(param->rm_type),
629 le32toh(param->rm_valueoffset), 629 le32toh(param->rm_valueoffset),
630 le32toh(param->rm_valuelen))); 630 le32toh(param->rm_valuelen)));
631 631
632 rval = urndis_ctrl_set(un, OID_GEN_RNDIS_CONFIG_PARAMETER, param, tlen); 632 rval = urndis_ctrl_set(un, OID_GEN_RNDIS_CONFIG_PARAMETER, param, tlen);
633 kmem_free(param, tlen); 633 kmem_free(param, tlen);
634 if (rval != RNDIS_STATUS_SUCCESS) 634 if (rval != RNDIS_STATUS_SUCCESS)
635 printf("%s: set param failed %#x\n", DEVNAME(un), rval); 635 printf("%s: set param failed %#x\n", DEVNAME(un), rval);
636 636
637 return rval; 637 return rval;
638} 638}
639 639
640/* XXX : adrreset, get it from response */ 640/* XXX : adrreset, get it from response */
641static uint32_t 641static uint32_t
642urndis_ctrl_reset(struct usbnet *un) 642urndis_ctrl_reset(struct usbnet *un)
643{ 643{
644 struct rndis_reset_req *reset; 644 struct rndis_reset_req *reset;
645 uint32_t rval; 645 uint32_t rval;
646 struct rndis_comp_hdr *hdr; 646 struct rndis_comp_hdr *hdr;
647 647
648 reset = kmem_alloc(sizeof(*reset), KM_SLEEP); 648 reset = kmem_alloc(sizeof(*reset), KM_SLEEP);
649 reset->rm_type = htole32(REMOTE_NDIS_RESET_MSG); 649 reset->rm_type = htole32(REMOTE_NDIS_RESET_MSG);
650 reset->rm_len = htole32(sizeof(*reset)); 650 reset->rm_len = htole32(sizeof(*reset));
651 reset->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */ 651 reset->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */
652 652
653 DPRINTF(("%s: urndis_ctrl_reset send: type %u len %u rid %u\n", 653 DPRINTF(("%s: urndis_ctrl_reset send: type %u len %u rid %u\n",
654 DEVNAME(un), 654 DEVNAME(un),
655 le32toh(reset->rm_type), 655 le32toh(reset->rm_type),
656 le32toh(reset->rm_len), 656 le32toh(reset->rm_len),
657 le32toh(reset->rm_rid))); 657 le32toh(reset->rm_rid)));
658 658
659 rval = urndis_ctrl_send(un, reset, sizeof(*reset)); 659 rval = urndis_ctrl_send(un, reset, sizeof(*reset));
660 kmem_free(reset, sizeof(*reset)); 660 kmem_free(reset, sizeof(*reset));
661 661
662 if (rval != RNDIS_STATUS_SUCCESS) { 662 if (rval != RNDIS_STATUS_SUCCESS) {
663 printf("%s: reset failed\n", DEVNAME(un)); 663 printf("%s: reset failed\n", DEVNAME(un));
664 return rval; 664 return rval;
665 } 665 }
666 666
667 if ((hdr = urndis_ctrl_recv(un)) == NULL) { 667 if ((hdr = urndis_ctrl_recv(un)) == NULL) {
668 printf("%s: unable to get reset response\n", DEVNAME(un)); 668 printf("%s: unable to get reset response\n", DEVNAME(un));
669 return RNDIS_STATUS_FAILURE; 669 return RNDIS_STATUS_FAILURE;
670 } 670 }
671 rval = urndis_ctrl_handle(un, hdr, NULL, NULL); 671 rval = urndis_ctrl_handle(un, hdr, NULL, NULL);
672 672
673 return rval; 673 return rval;
674} 674}
675 675
676static uint32_t 676static uint32_t
677urndis_ctrl_keepalive(struct usbnet *un) 677urndis_ctrl_keepalive(struct usbnet *un)
678{ 678{
679 struct rndis_keepalive_req *keep; 679 struct rndis_keepalive_req *keep;
680 uint32_t rval; 680 uint32_t rval;
681 struct rndis_comp_hdr *hdr; 681 struct rndis_comp_hdr *hdr;
682 682
683 keep = kmem_alloc(sizeof(*keep), KM_SLEEP); 683 keep = kmem_alloc(sizeof(*keep), KM_SLEEP);
684 keep->rm_type = htole32(REMOTE_NDIS_KEEPALIVE_MSG); 684 keep->rm_type = htole32(REMOTE_NDIS_KEEPALIVE_MSG);
685 keep->rm_len = htole32(sizeof(*keep)); 685 keep->rm_len = htole32(sizeof(*keep));
686 keep->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */ 686 keep->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */
687 687
688 DPRINTF(("%s: urndis_ctrl_keepalive: type %u len %u rid %u\n", 688 DPRINTF(("%s: urndis_ctrl_keepalive: type %u len %u rid %u\n",
689 DEVNAME(un), 689 DEVNAME(un),
690 le32toh(keep->rm_type), 690 le32toh(keep->rm_type),
691 le32toh(keep->rm_len), 691 le32toh(keep->rm_len),
692 le32toh(keep->rm_rid))); 692 le32toh(keep->rm_rid)));
693 693
694 rval = urndis_ctrl_send(un, keep, sizeof(*keep)); 694 rval = urndis_ctrl_send(un, keep, sizeof(*keep));
695 kmem_free(keep, sizeof(*keep)); 695 kmem_free(keep, sizeof(*keep));
696 696
697 if (rval != RNDIS_STATUS_SUCCESS) { 697 if (rval != RNDIS_STATUS_SUCCESS) {
698 printf("%s: keepalive failed\n", DEVNAME(un)); 698 printf("%s: keepalive failed\n", DEVNAME(un));
699 return rval; 699 return rval;
700 } 700 }
701 701
702 if ((hdr = urndis_ctrl_recv(un)) == NULL) { 702 if ((hdr = urndis_ctrl_recv(un)) == NULL) {
703 printf("%s: unable to get keepalive response\n", DEVNAME(un)); 703 printf("%s: unable to get keepalive response\n", DEVNAME(un));
704 return RNDIS_STATUS_FAILURE; 704 return RNDIS_STATUS_FAILURE;
705 } 705 }
706 rval = urndis_ctrl_handle(un, hdr, NULL, NULL); 706 rval = urndis_ctrl_handle(un, hdr, NULL, NULL);
707 if (rval != RNDIS_STATUS_SUCCESS) { 707 if (rval != RNDIS_STATUS_SUCCESS) {
708 printf("%s: keepalive failed %#x\n", DEVNAME(un), rval); 708 printf("%s: keepalive failed %#x\n", DEVNAME(un), rval);
709 urndis_ctrl_reset(un); 709 urndis_ctrl_reset(un);
710 } 710 }
711 711
712 return rval; 712 return rval;
713} 713}
714#endif 714#endif
715 715
716static unsigned 716static unsigned
717urndis_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 717urndis_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
718{ 718{
719 struct rndis_packet_msg *msg; 719 struct rndis_packet_msg *msg;
720 720
721 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(*msg)) 721 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(*msg))
722 return 0; 722 return 0;
723 723
724 msg = (struct rndis_packet_msg *)c->unc_buf; 724 msg = (struct rndis_packet_msg *)c->unc_buf;
725 725
726 memset(msg, 0, sizeof(*msg)); 726 memset(msg, 0, sizeof(*msg));
727 msg->rm_type = htole32(REMOTE_NDIS_PACKET_MSG); 727 msg->rm_type = htole32(REMOTE_NDIS_PACKET_MSG);
728 msg->rm_len = htole32(sizeof(*msg) + m->m_pkthdr.len); 728 msg->rm_len = htole32(sizeof(*msg) + m->m_pkthdr.len);
729 729
730 msg->rm_dataoffset = htole32(RNDIS_DATA_OFFSET); 730 msg->rm_dataoffset = htole32(RNDIS_DATA_OFFSET);
731 msg->rm_datalen = htole32(m->m_pkthdr.len); 731 msg->rm_datalen = htole32(m->m_pkthdr.len);
732 732
733 m_copydata(m, 0, m->m_pkthdr.len, 733 m_copydata(m, 0, m->m_pkthdr.len,
734 ((char*)msg + RNDIS_DATA_OFFSET + RNDIS_HEADER_OFFSET)); 734 ((char*)msg + RNDIS_DATA_OFFSET + RNDIS_HEADER_OFFSET));
735 735
736 DPRINTF(("%s: %s type %#x len %u data(off %u len %u)\n", 736 DPRINTF(("%s: %s type %#x len %u data(off %u len %u)\n",
737 __func__, 737 __func__,
738 DEVNAME(un), 738 DEVNAME(un),
739 le32toh(msg->rm_type), 739 le32toh(msg->rm_type),
740 le32toh(msg->rm_len), 740 le32toh(msg->rm_len),
741 le32toh(msg->rm_dataoffset), 741 le32toh(msg->rm_dataoffset),
742 le32toh(msg->rm_datalen))); 742 le32toh(msg->rm_datalen)));
743 743
744 return le32toh(msg->rm_len); 744 return le32toh(msg->rm_len);
745} 745}
746 746
747static void 747static void
748urndis_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, 748urndis_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c,
749 uint32_t total_len) 749 uint32_t total_len)
750{ 750{
751 struct rndis_packet_msg *msg; 751 struct rndis_packet_msg *msg;
752 struct ifnet *ifp = usbnet_ifp(un); 752 struct ifnet *ifp = usbnet_ifp(un);
753 int offset; 753 int offset;
754 754
755 offset = 0; 755 offset = 0;
756 756
757 while (total_len > 1) { 757 while (total_len > 1) {
758 msg = (struct rndis_packet_msg *)((char*)c->unc_buf + offset); 758 msg = (struct rndis_packet_msg *)((char*)c->unc_buf + offset);
759 759
760 DPRINTF(("%s: %s buffer size left %u\n", DEVNAME(un), __func__, 760 DPRINTF(("%s: %s buffer size left %u\n", DEVNAME(un), __func__,
761 total_len)); 761 total_len));
762 762
763 if (total_len < sizeof(*msg)) { 763 if (total_len < sizeof(*msg)) {
764 printf("%s: urndis_decap invalid buffer total_len %u < " 764 printf("%s: urndis_decap invalid buffer total_len %u < "
765 "minimum header %zu\n", 765 "minimum header %zu\n",
766 DEVNAME(un), 766 DEVNAME(un),
767 total_len, 767 total_len,
768 sizeof(*msg)); 768 sizeof(*msg));
769 return; 769 return;
770 } 770 }
771 771
772 DPRINTF(("%s: urndis_decap total_len %u data(off:%u len:%u) " 772 DPRINTF(("%s: urndis_decap total_len %u data(off:%u len:%u) "
773 "oobdata(off:%u len:%u nb:%u) perpacket(off:%u len:%u)\n", 773 "oobdata(off:%u len:%u nb:%u) perpacket(off:%u len:%u)\n",
774 DEVNAME(un), 774 DEVNAME(un),
775 le32toh(msg->rm_len), 775 le32toh(msg->rm_len),
776 le32toh(msg->rm_dataoffset), 776 le32toh(msg->rm_dataoffset),
777 le32toh(msg->rm_datalen), 777 le32toh(msg->rm_datalen),
778 le32toh(msg->rm_oobdataoffset), 778 le32toh(msg->rm_oobdataoffset),
779 le32toh(msg->rm_oobdatalen), 779 le32toh(msg->rm_oobdatalen),
780 le32toh(msg->rm_oobdataelements), 780 le32toh(msg->rm_oobdataelements),
781 le32toh(msg->rm_pktinfooffset), 781 le32toh(msg->rm_pktinfooffset),
782 le32toh(msg->rm_pktinfooffset))); 782 le32toh(msg->rm_pktinfooffset)));
783 783
784 if (le32toh(msg->rm_type) != REMOTE_NDIS_PACKET_MSG) { 784 if (le32toh(msg->rm_type) != REMOTE_NDIS_PACKET_MSG) {
785 printf("%s: urndis_decap invalid type %#x != %#x\n", 785 printf("%s: urndis_decap invalid type %#x != %#x\n",
786 DEVNAME(un), 786 DEVNAME(un),
787 le32toh(msg->rm_type), 787 le32toh(msg->rm_type),
788 REMOTE_NDIS_PACKET_MSG); 788 REMOTE_NDIS_PACKET_MSG);
789 return; 789 return;
790 } 790 }
791 if (le32toh(msg->rm_len) < sizeof(*msg)) { 791 if (le32toh(msg->rm_len) < sizeof(*msg)) {
792 printf("%s: urndis_decap invalid msg len %u < %zu\n", 792 printf("%s: urndis_decap invalid msg len %u < %zu\n",
793 DEVNAME(un), 793 DEVNAME(un),
794 le32toh(msg->rm_len), 794 le32toh(msg->rm_len),
795 sizeof(*msg)); 795 sizeof(*msg));
796 return; 796 return;
797 } 797 }
798 if (le32toh(msg->rm_len) > total_len) { 798 if (le32toh(msg->rm_len) > total_len) {
799 printf("%s: urndis_decap invalid msg len %u > buffer " 799 printf("%s: urndis_decap invalid msg len %u > buffer "
800 "total_len %u\n", 800 "total_len %u\n",
801 DEVNAME(un), 801 DEVNAME(un),
802 le32toh(msg->rm_len), 802 le32toh(msg->rm_len),
803 total_len); 803 total_len);
804 return; 804 return;
805 } 805 }
806 806
807 if (le32toh(msg->rm_dataoffset) + 807 if (le32toh(msg->rm_dataoffset) +
808 le32toh(msg->rm_datalen) + RNDIS_HEADER_OFFSET 808 le32toh(msg->rm_datalen) + RNDIS_HEADER_OFFSET
809 > le32toh(msg->rm_len)) { 809 > le32toh(msg->rm_len)) {
810 printf("%s: urndis_decap invalid data " 810 printf("%s: urndis_decap invalid data "
811 "len/offset/end_position(%u/%u/%u) -> " 811 "len/offset/end_position(%u/%u/%u) -> "
812 "go out of receive buffer limit %u\n", 812 "go out of receive buffer limit %u\n",
813 DEVNAME(un), 813 DEVNAME(un),
814 le32toh(msg->rm_datalen), 814 le32toh(msg->rm_datalen),
815 le32toh(msg->rm_dataoffset), 815 le32toh(msg->rm_dataoffset),
816 le32toh(msg->rm_dataoffset) + 816 le32toh(msg->rm_dataoffset) +
817 le32toh(msg->rm_datalen) + (uint32_t)RNDIS_HEADER_OFFSET, 817 le32toh(msg->rm_datalen) + (uint32_t)RNDIS_HEADER_OFFSET,
818 le32toh(msg->rm_len)); 818 le32toh(msg->rm_len));
819 return; 819 return;
820 } 820 }
821 821
822 if (le32toh(msg->rm_datalen) < sizeof(struct ether_header)) { 822 if (le32toh(msg->rm_datalen) < sizeof(struct ether_header)) {
823 if_statinc(ifp, if_ierrors); 823 if_statinc(ifp, if_ierrors);
824 printf("%s: urndis_decap invalid ethernet size " 824 printf("%s: urndis_decap invalid ethernet size "
825 "%d < %zu\n", 825 "%d < %zu\n",
826 DEVNAME(un), 826 DEVNAME(un),
827 le32toh(msg->rm_datalen), 827 le32toh(msg->rm_datalen),
828 sizeof(struct ether_header)); 828 sizeof(struct ether_header));
829 return; 829 return;
830 } 830 }
831 831
832 usbnet_enqueue(un, 832 usbnet_enqueue(un,
833 ((char*)&msg->rm_dataoffset + le32toh(msg->rm_dataoffset)), 833 ((char*)&msg->rm_dataoffset + le32toh(msg->rm_dataoffset)),
834 le32toh(msg->rm_datalen), 0, 0, 0); 834 le32toh(msg->rm_datalen), 0, 0, 0);
835 835
836 offset += le32toh(msg->rm_len); 836 offset += le32toh(msg->rm_len);
837 total_len -= le32toh(msg->rm_len); 837 total_len -= le32toh(msg->rm_len);
838 } 838 }
839} 839}
840 840
841#if 0 841#if 0
842static void 842static void
843urndis_watchdog(struct ifnet *ifp) 843urndis_watchdog(struct ifnet *ifp)
844{ 844{
845 struct urndis_softc *sc = usbnet_softc(un); 845 struct urndis_softc *sc = usbnet_softc(un);
846 846
847 if (un->un_dying) 847 if (un->un_dying)
848 return; 848 return;
849 849
850 if_statinc(ifp, if_oerrors); 850 if_statinc(ifp, if_oerrors);
851 printf("%s: watchdog timeout\n", DEVNAME(un)); 851 printf("%s: watchdog timeout\n", DEVNAME(un));
852 852
853 urndis_ctrl_keepalive(un); 853 urndis_ctrl_keepalive(un);
854} 854}
855#endif 855#endif
856 856
857static int 857static int
858urndis_init_un(struct ifnet *ifp, struct usbnet *un) 858urndis_init_un(struct ifnet *ifp, struct usbnet *un)
859{ 859{
860 int err; 860 int err;
861 861
862 if (ifp->if_flags & IFF_RUNNING) 
863 return 0; 
864 
865 err = urndis_ctrl_init(un); 862 err = urndis_ctrl_init(un);
866 if (err != RNDIS_STATUS_SUCCESS) 863 if (err != RNDIS_STATUS_SUCCESS)
867 return EIO; 864 return EIO;
868 865
869 return err; 866 return err;
870} 867}
871 868
872static int 869static int
873urndis_uno_init(struct ifnet *ifp) 870urndis_uno_init(struct ifnet *ifp)
874{ 871{
875 struct usbnet *un = ifp->if_softc; 872 struct usbnet *un = ifp->if_softc;
876 int error; 873 int error;
877 874
878 KASSERT(IFNET_LOCKED(ifp)); 875 KASSERT(IFNET_LOCKED(ifp));
879 876
880 error = urndis_init_un(ifp, un); 877 error = urndis_init_un(ifp, un);
881 if (error) 878 if (error)
882 return EIO; /* XXX */ 879 return EIO; /* XXX */
883 error = usbnet_init_rx_tx(un); 880 error = usbnet_init_rx_tx(un);
884 usbnet_set_link(un, error == 0); 881 usbnet_set_link(un, error == 0);
885 882
886 return error; 883 return error;
887} 884}
888 885
889static int 886static int
890urndis_match(device_t parent, cfdata_t match, void *aux) 887urndis_match(device_t parent, cfdata_t match, void *aux)
891{ 888{
892 struct usbif_attach_arg *uiaa = aux; 889 struct usbif_attach_arg *uiaa = aux;
893 usb_interface_descriptor_t *id; 890 usb_interface_descriptor_t *id;
894 891
895 if (!uiaa->uiaa_iface) 892 if (!uiaa->uiaa_iface)
896 return UMATCH_NONE; 893 return UMATCH_NONE;
897 894
898 id = usbd_get_interface_descriptor(uiaa->uiaa_iface); 895 id = usbd_get_interface_descriptor(uiaa->uiaa_iface);
899 if (id == NULL) 896 if (id == NULL)
900 return UMATCH_NONE; 897 return UMATCH_NONE;
901 898
902 if (id->bInterfaceClass == UICLASS_WIRELESS && 899 if (id->bInterfaceClass == UICLASS_WIRELESS &&
903 id->bInterfaceSubClass == UISUBCLASS_RF && 900 id->bInterfaceSubClass == UISUBCLASS_RF &&
904 id->bInterfaceProtocol == UIPROTO_RNDIS) 901 id->bInterfaceProtocol == UIPROTO_RNDIS)
905 return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; 902 return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO;
906 903
907 return usb_lookup(urndis_devs, uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL ? 904 return usb_lookup(urndis_devs, uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL ?
908 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 905 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
909} 906}
910 907
911static void 908static void
912urndis_attach(device_t parent, device_t self, void *aux) 909urndis_attach(device_t parent, device_t self, void *aux)
913{ 910{
914 struct urndis_softc *sc = device_private(self); 911 struct urndis_softc *sc = device_private(self);
915 struct usbnet * const un = &sc->sc_un; 912 struct usbnet * const un = &sc->sc_un;
916 struct usbif_attach_arg *uiaa = aux; 913 struct usbif_attach_arg *uiaa = aux;
917 struct usbd_device *dev = uiaa->uiaa_device; 914 struct usbd_device *dev = uiaa->uiaa_device;
918 usb_interface_descriptor_t *id; 915 usb_interface_descriptor_t *id;
919 usb_endpoint_descriptor_t *ed; 916 usb_endpoint_descriptor_t *ed;
920 usb_config_descriptor_t *cd; 917 usb_config_descriptor_t *cd;
921 struct usbd_interface *iface_ctl; 918 struct usbd_interface *iface_ctl;
922 const usb_cdc_union_descriptor_t *ud; 919 const usb_cdc_union_descriptor_t *ud;
923 const usb_cdc_header_descriptor_t *desc; 920 const usb_cdc_header_descriptor_t *desc;
924 usbd_desc_iter_t iter; 921 usbd_desc_iter_t iter;
925 int if_ctl, if_data; 922 int if_ctl, if_data;
926 int i, j, altcnt; 923 int i, j, altcnt;
927 void *buf; 924 void *buf;
928 size_t bufsz; 925 size_t bufsz;
929 uint32_t filter; 926 uint32_t filter;
930 char *devinfop; 927 char *devinfop;
931 928
932 KASSERT((void *)sc == un); 929 KASSERT((void *)sc == un);
933 930
934 aprint_naive("\n"); 931 aprint_naive("\n");
935 aprint_normal("\n"); 932 aprint_normal("\n");
936 devinfop = usbd_devinfo_alloc(dev, 0); 933 devinfop = usbd_devinfo_alloc(dev, 0);
937 aprint_normal_dev(self, "%s\n", devinfop); 934 aprint_normal_dev(self, "%s\n", devinfop);
938 usbd_devinfo_free(devinfop); 935 usbd_devinfo_free(devinfop);
939 936
940 un->un_dev = self; 937 un->un_dev = self;
941 un->un_udev = dev; 938 un->un_udev = dev;
942 un->un_sc = sc; 939 un->un_sc = sc;
943 un->un_ops = &urndis_ops; 940 un->un_ops = &urndis_ops;
944 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 941 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
945 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 942 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
946 un->un_rx_list_cnt = RNDIS_RX_LIST_CNT; 943 un->un_rx_list_cnt = RNDIS_RX_LIST_CNT;
947 un->un_tx_list_cnt = RNDIS_TX_LIST_CNT; 944 un->un_tx_list_cnt = RNDIS_TX_LIST_CNT;
948 un->un_rx_bufsz = RNDIS_BUFSZ; 945 un->un_rx_bufsz = RNDIS_BUFSZ;
949 un->un_tx_bufsz = RNDIS_BUFSZ; 946 un->un_tx_bufsz = RNDIS_BUFSZ;
950 947
951 iface_ctl = uiaa->uiaa_iface; 948 iface_ctl = uiaa->uiaa_iface;
952 un->un_iface = uiaa->uiaa_iface; 949 un->un_iface = uiaa->uiaa_iface;
953 id = usbd_get_interface_descriptor(iface_ctl); 950 id = usbd_get_interface_descriptor(iface_ctl);
954 if_ctl = id->bInterfaceNumber; 951 if_ctl = id->bInterfaceNumber;
955 sc->sc_ifaceno_ctl = if_ctl; 952 sc->sc_ifaceno_ctl = if_ctl;
956 if_data = -1; 953 if_data = -1;
957 954
958 usb_desc_iter_init(un->un_udev, &iter); 955 usb_desc_iter_init(un->un_udev, &iter);
959 while ((desc = (const void *)usb_desc_iter_next(&iter)) != NULL) { 956 while ((desc = (const void *)usb_desc_iter_next(&iter)) != NULL) {
960 957
961 if (desc->bDescriptorType != UDESC_CS_INTERFACE) { 958 if (desc->bDescriptorType != UDESC_CS_INTERFACE) {
962 continue; 959 continue;
963 } 960 }
964 switch (desc->bDescriptorSubtype) { 961 switch (desc->bDescriptorSubtype) {
965 case UDESCSUB_CDC_UNION: 962 case UDESCSUB_CDC_UNION:
966 /* XXX bail out when found first? */ 963 /* XXX bail out when found first? */
967 ud = (const usb_cdc_union_descriptor_t *)desc; 964 ud = (const usb_cdc_union_descriptor_t *)desc;
968 if (if_data == -1) 965 if (if_data == -1)
969 if_data = ud->bSlaveInterface[0]; 966 if_data = ud->bSlaveInterface[0];
970 break; 967 break;
971 } 968 }
972 } 969 }
973 970
974 if (if_data == -1) { 971 if (if_data == -1) {
975 DPRINTF(("urndis_attach: no union interface\n")); 972 DPRINTF(("urndis_attach: no union interface\n"));
976 un->un_iface = iface_ctl; 973 un->un_iface = iface_ctl;
977 } else { 974 } else {
978 DPRINTF(("urndis_attach: union interface: ctl %u, data %u\n", 975 DPRINTF(("urndis_attach: union interface: ctl %u, data %u\n",
979 if_ctl, if_data)); 976 if_ctl, if_data));
980 for (i = 0; i < uiaa->uiaa_nifaces; i++) { 977 for (i = 0; i < uiaa->uiaa_nifaces; i++) {
981 if (uiaa->uiaa_ifaces[i] != NULL) { 978 if (uiaa->uiaa_ifaces[i] != NULL) {
982 id = usbd_get_interface_descriptor( 979 id = usbd_get_interface_descriptor(
983 uiaa->uiaa_ifaces[i]); 980 uiaa->uiaa_ifaces[i]);
984 if (id != NULL && id->bInterfaceNumber == 981 if (id != NULL && id->bInterfaceNumber ==
985 if_data) { 982 if_data) {
986 un->un_iface = uiaa->uiaa_ifaces[i]; 983 un->un_iface = uiaa->uiaa_ifaces[i];
987 uiaa->uiaa_ifaces[i] = NULL; 984 uiaa->uiaa_ifaces[i] = NULL;
988 } 985 }
989 } 986 }
990 } 987 }
991 } 988 }
992 989
993 if (un->un_iface == NULL) { 990 if (un->un_iface == NULL) {
994 aprint_error("%s: no data interface\n", DEVNAME(un)); 991 aprint_error("%s: no data interface\n", DEVNAME(un));
995 return; 992 return;
996 } 993 }
997 994
998 id = usbd_get_interface_descriptor(un->un_iface); 995 id = usbd_get_interface_descriptor(un->un_iface);
999 cd = usbd_get_config_descriptor(un->un_udev); 996 cd = usbd_get_config_descriptor(un->un_udev);
1000 altcnt = usbd_get_no_alts(cd, id->bInterfaceNumber); 997 altcnt = usbd_get_no_alts(cd, id->bInterfaceNumber);
1001 998
1002 for (j = 0; j < altcnt; j++) { 999 for (j = 0; j < altcnt; j++) {
1003 if (usbd_set_interface(un->un_iface, j)) { 1000 if (usbd_set_interface(un->un_iface, j)) {
1004 aprint_error("%s: interface alternate setting %u " 1001 aprint_error("%s: interface alternate setting %u "
1005 "failed\n", DEVNAME(un), j); 1002 "failed\n", DEVNAME(un), j);
1006 return; 1003 return;
1007 } 1004 }
1008 /* Find endpoints. */ 1005 /* Find endpoints. */
1009 id = usbd_get_interface_descriptor(un->un_iface); 1006 id = usbd_get_interface_descriptor(un->un_iface);
1010 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] = 0; 1007 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] = 0;
1011 for (i = 0; i < id->bNumEndpoints; i++) { 1008 for (i = 0; i < id->bNumEndpoints; i++) {
1012 ed = usbd_interface2endpoint_descriptor( 1009 ed = usbd_interface2endpoint_descriptor(
1013 un->un_iface, i); 1010 un->un_iface, i);
1014 if (!ed) { 1011 if (!ed) {
1015 aprint_error("%s: no descriptor for bulk " 1012 aprint_error("%s: no descriptor for bulk "
1016 "endpoint %u\n", DEVNAME(un), i); 1013 "endpoint %u\n", DEVNAME(un), i);
1017 return; 1014 return;
1018 } 1015 }
1019 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 1016 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1020 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1017 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1021 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 1018 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
1022 } 1019 }
1023 else if ( 1020 else if (
1024 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 1021 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
1025 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1022 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1026 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 1023 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
1027 } 1024 }
1028 } 1025 }
1029 1026
1030 if (un->un_ed[USBNET_ENDPT_RX] != 0 && un->un_ed[USBNET_ENDPT_TX] != 0) { 1027 if (un->un_ed[USBNET_ENDPT_RX] != 0 && un->un_ed[USBNET_ENDPT_TX] != 0) {
1031 DPRINTF(("%s: in=%#x, out=%#x\n", 1028 DPRINTF(("%s: in=%#x, out=%#x\n",
1032 DEVNAME(un), 1029 DEVNAME(un),
1033 un->un_ed[USBNET_ENDPT_RX], 1030 un->un_ed[USBNET_ENDPT_RX],
1034 un->un_ed[USBNET_ENDPT_TX])); 1031 un->un_ed[USBNET_ENDPT_TX]));
1035 break; 1032 break;
1036 } 1033 }
1037 } 1034 }
1038 1035
1039 if (un->un_ed[USBNET_ENDPT_RX] == 0) 1036 if (un->un_ed[USBNET_ENDPT_RX] == 0)
1040 aprint_error("%s: could not find data bulk in\n", DEVNAME(un)); 1037 aprint_error("%s: could not find data bulk in\n", DEVNAME(un));
1041 if (un->un_ed[USBNET_ENDPT_TX] == 0) 1038 if (un->un_ed[USBNET_ENDPT_TX] == 0)
1042 aprint_error("%s: could not find data bulk out\n",DEVNAME(un)); 1039 aprint_error("%s: could not find data bulk out\n",DEVNAME(un));
1043 if (un->un_ed[USBNET_ENDPT_RX] == 0 || un->un_ed[USBNET_ENDPT_TX] == 0) 1040 if (un->un_ed[USBNET_ENDPT_RX] == 0 || un->un_ed[USBNET_ENDPT_TX] == 0)
1044 return; 1041 return;
1045 1042
1046#if 0 1043#if 0
1047 ifp->if_watchdog = urndis_watchdog; 1044 ifp->if_watchdog = urndis_watchdog;
1048#endif 1045#endif
1049 1046
1050 usbnet_attach(un, "urndisdet"); 1047 usbnet_attach(un, "urndisdet");
1051 1048
1052 struct ifnet *ifp = usbnet_ifp(un); 1049 struct ifnet *ifp = usbnet_ifp(un);
1053 urndis_init_un(ifp, un); 1050 urndis_init_un(ifp, un);
1054 1051
1055 if (urndis_ctrl_query(un, OID_802_3_PERMANENT_ADDRESS, NULL, 0, 1052 if (urndis_ctrl_query(un, OID_802_3_PERMANENT_ADDRESS, NULL, 0,
1056 &buf, &bufsz) != RNDIS_STATUS_SUCCESS) { 1053 &buf, &bufsz) != RNDIS_STATUS_SUCCESS) {
1057 aprint_error("%s: unable to get hardware address\n", 1054 aprint_error("%s: unable to get hardware address\n",
1058 DEVNAME(un)); 1055 DEVNAME(un));
1059 return; 1056 return;
1060 } 1057 }
1061 1058
1062 if (bufsz == ETHER_ADDR_LEN) { 1059 if (bufsz == ETHER_ADDR_LEN) {
1063 memcpy(un->un_eaddr, buf, ETHER_ADDR_LEN); 1060 memcpy(un->un_eaddr, buf, ETHER_ADDR_LEN);
1064 kmem_free(buf, bufsz); 1061 kmem_free(buf, bufsz);
1065 } else { 1062 } else {
1066 aprint_error("%s: invalid address\n", DEVNAME(un)); 1063 aprint_error("%s: invalid address\n", DEVNAME(un));
1067 if (buf && bufsz) 1064 if (buf && bufsz)
1068 kmem_free(buf, bufsz); 1065 kmem_free(buf, bufsz);
1069 return; 1066 return;
1070 } 1067 }
1071 1068
1072 /* Initialize packet filter */ 1069 /* Initialize packet filter */
1073 sc->sc_filter = RNDIS_PACKET_TYPE_BROADCAST; 1070 sc->sc_filter = RNDIS_PACKET_TYPE_BROADCAST;
1074 sc->sc_filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; 1071 sc->sc_filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
1075 filter = htole32(sc->sc_filter); 1072 filter = htole32(sc->sc_filter);
1076 if (urndis_ctrl_set(un, OID_GEN_CURRENT_PACKET_FILTER, &filter, 1073 if (urndis_ctrl_set(un, OID_GEN_CURRENT_PACKET_FILTER, &filter,
1077 sizeof(filter)) != RNDIS_STATUS_SUCCESS) { 1074 sizeof(filter)) != RNDIS_STATUS_SUCCESS) {
1078 aprint_error("%s: unable to set data filters\n", DEVNAME(un)); 1075 aprint_error("%s: unable to set data filters\n", DEVNAME(un));
1079 return; 1076 return;
1080 } 1077 }
1081 1078
1082 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 1079 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
1083 0, NULL); 1080 0, NULL);
1084} 1081}
1085 1082
1086#ifdef _MODULE 1083#ifdef _MODULE
1087#include "ioconf.c" 1084#include "ioconf.c"
1088#endif 1085#endif
1089 1086
1090USBNET_MODULE(urndis) 1087USBNET_MODULE(urndis)