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


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

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

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

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

--- src/sys/dev/usb/uchcom.c 2021/07/14 07:34:16 1.38
+++ src/sys/dev/usb/uchcom.c 2021/07/15 03:25:50 1.39
@@ -1,962 +1,962 @@ @@ -1,962 +1,962 @@
1/* $NetBSD: uchcom.c,v 1.38 2021/07/14 07:34:16 nisimura Exp $ */ 1/* $NetBSD: uchcom.c,v 1.39 2021/07/15 03:25:50 nisimura Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Takuya SHIOZAKI (tshiozak@netbsd.org). 8 * by Takuya SHIOZAKI (tshiozak@netbsd.org).
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.38 2021/07/14 07:34:16 nisimura Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.39 2021/07/15 03:25:50 nisimura Exp $");
34 34
35#ifdef _KERNEL_OPT 35#ifdef _KERNEL_OPT
36#include "opt_usb.h" 36#include "opt_usb.h"
37#endif 37#endif
38 38
39/* 39/*
40 * driver for WinChipHead CH341/340, the worst USB-serial chip in the world. 40 * driver for WinChipHead CH341/340, the worst USB-serial chip in the world.
41 */ 41 */
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/kmem.h> 46#include <sys/kmem.h>
47#include <sys/ioctl.h> 47#include <sys/ioctl.h>
48#include <sys/conf.h> 48#include <sys/conf.h>
49#include <sys/tty.h> 49#include <sys/tty.h>
50#include <sys/file.h> 50#include <sys/file.h>
51#include <sys/select.h> 51#include <sys/select.h>
52#include <sys/proc.h> 52#include <sys/proc.h>
53#include <sys/device.h> 53#include <sys/device.h>
54#include <sys/poll.h> 54#include <sys/poll.h>
55 55
56#include <dev/usb/usb.h> 56#include <dev/usb/usb.h>
57 57
58#include <dev/usb/usbdi.h> 58#include <dev/usb/usbdi.h>
59#include <dev/usb/usbdi_util.h> 59#include <dev/usb/usbdi_util.h>
60#include <dev/usb/usbdevs.h> 60#include <dev/usb/usbdevs.h>
61 61
62#include <dev/usb/ucomvar.h> 62#include <dev/usb/ucomvar.h>
63 63
64#ifdef UCHCOM_DEBUG 64#ifdef UCHCOM_DEBUG
65#define DPRINTFN(n, x) if (uchcomdebug > (n)) printf x 65#define DPRINTFN(n, x) if (uchcomdebug > (n)) printf x
66int uchcomdebug = 0; 66int uchcomdebug = 0;
67#else 67#else
68#define DPRINTFN(n, x) 68#define DPRINTFN(n, x)
69#endif 69#endif
70#define DPRINTF(x) DPRINTFN(0, x) 70#define DPRINTF(x) DPRINTFN(0, x)
71 71
72#define UCHCOM_IFACE_INDEX 0 72#define UCHCOM_IFACE_INDEX 0
73#define UCHCOM_CONFIG_INDEX 0 73#define UCHCOM_CONFIG_INDEX 0
74 74
75#define UCHCOM_INPUT_BUF_SIZE 8 75#define UCHCOM_INPUT_BUF_SIZE 8
76 76
77#define UCHCOM_REQ_GET_VERSION 0x5F 77#define UCHCOM_REQ_GET_VERSION 0x5F
78#define UCHCOM_REQ_READ_REG 0x95 78#define UCHCOM_REQ_READ_REG 0x95
79#define UCHCOM_REQ_WRITE_REG 0x9A 79#define UCHCOM_REQ_WRITE_REG 0x9A
80#define UCHCOM_REQ_RESET 0xA1 80#define UCHCOM_REQ_RESET 0xA1
81#define UCHCOM_REQ_SET_DTRRTS 0xA4 81#define UCHCOM_REQ_SET_DTRRTS 0xA4
82 82
83#define UCHCOM_REG_STAT1 0x06 83#define UCHCOM_REG_STAT1 0x06
84#define UCHCOM_REG_STAT2 0x07 84#define UCHCOM_REG_STAT2 0x07
85#define UCHCOM_REG_BPS_PRE 0x12 85#define UCHCOM_REG_BPS_PRE 0x12
86#define UCHCOM_REG_BPS_DIV 0x13 86#define UCHCOM_REG_BPS_DIV 0x13
87#define UCHCOM_REG_BREAK 0x05 87#define UCHCOM_REG_BREAK 0x05
88#define UCHCOM_REG_LCR 0x18 88#define UCHCOM_REG_LCR 0x18
89#define UCHCOM_REG_LCR2 0x25 89#define UCHCOM_REG_LCR2 0x25
90 90
91#define UCHCOM_VER_20 0x20 91#define UCHCOM_VER_20 0x20
92#define UCHCOM_VER_30 0x30 92#define UCHCOM_VER_30 0x30
93 93
94#define UCHCOM_BPS_PRE_IMM 0x80 /* CH341: immediate RX forwarding */ 94#define UCHCOM_BPS_PRE_IMM 0x80 /* CH341: immediate RX forwarding */
95 95
96#define UCHCOM_DTR_MASK 0x20 96#define UCHCOM_DTR_MASK 0x20
97#define UCHCOM_RTS_MASK 0x40 97#define UCHCOM_RTS_MASK 0x40
98 98
99#define UCHCOM_BREAK_MASK 0x01 99#define UCHCOM_BREAK_MASK 0x01
100 100
101#define UCHCOM_LCR_CS5 0x00 101#define UCHCOM_LCR_CS5 0x00
102#define UCHCOM_LCR_CS6 0x01 102#define UCHCOM_LCR_CS6 0x01
103#define UCHCOM_LCR_CS7 0x02 103#define UCHCOM_LCR_CS7 0x02
104#define UCHCOM_LCR_CS8 0x03 104#define UCHCOM_LCR_CS8 0x03
105#define UCHCOM_LCR_STOPB 0x04 105#define UCHCOM_LCR_STOPB 0x04
106#define UCHCOM_LCR_PARENB 0x08 106#define UCHCOM_LCR_PARENB 0x08
107#define UCHCOM_LCR_PARODD 0x00 107#define UCHCOM_LCR_PARODD 0x00
108#define UCHCOM_LCR_PAREVEN 0x10 108#define UCHCOM_LCR_PAREVEN 0x10
109#define UCHCOM_LCR_PARMARK 0x20 109#define UCHCOM_LCR_PARMARK 0x20
110#define UCHCOM_LCR_PARSPACE 0x30 110#define UCHCOM_LCR_PARSPACE 0x30
111#define UCHCOM_LCR_TXE 0x40 111#define UCHCOM_LCR_TXE 0x40
112#define UCHCOM_LCR_RXE 0x80 112#define UCHCOM_LCR_RXE 0x80
113 113
114#define UCHCOM_INTR_STAT1 0x02 114#define UCHCOM_INTR_STAT1 0x02
115#define UCHCOM_INTR_STAT2 0x03 115#define UCHCOM_INTR_STAT2 0x03
116#define UCHCOM_INTR_LEAST 4 116#define UCHCOM_INTR_LEAST 4
117 117
118#define UCHCOMIBUFSIZE 256 118#define UCHCOMIBUFSIZE 256
119#define UCHCOMOBUFSIZE 256 119#define UCHCOMOBUFSIZE 256
120 120
121struct uchcom_softc 121struct uchcom_softc
122{ 122{
123 device_t sc_dev; 123 device_t sc_dev;
124 struct usbd_device * sc_udev; 124 struct usbd_device * sc_udev;
125 device_t sc_subdev; 125 device_t sc_subdev;
126 struct usbd_interface * sc_iface; 126 struct usbd_interface * sc_iface;
127 bool sc_dying; 127 bool sc_dying;
128 /* */ 128 /* */
129 int sc_intr_endpoint; 129 int sc_intr_endpoint;
130 int sc_intr_size; 130 int sc_intr_size;
131 struct usbd_pipe * sc_intr_pipe; 131 struct usbd_pipe * sc_intr_pipe;
132 u_char *sc_intr_buf; 132 u_char *sc_intr_buf;
133 /* */ 133 /* */
134 uint8_t sc_version; 134 uint8_t sc_version;
135 int sc_dtr; 135 int sc_dtr;
136 int sc_rts; 136 int sc_rts;
137 u_char sc_lsr; 137 u_char sc_lsr;
138 u_char sc_msr; 138 u_char sc_msr;
139}; 139};
140 140
141struct uchcom_endpoints 141struct uchcom_endpoints
142{ 142{
143 int ep_bulkin; 143 int ep_bulkin;
144 int ep_bulkout; 144 int ep_bulkout;
145 int ep_intr; 145 int ep_intr;
146 int ep_intr_size; 146 int ep_intr_size;
147}; 147};
148 148
149struct uchcom_divider 149struct uchcom_divider
150{ 150{
151 uint8_t dv_prescaler; 151 uint8_t dv_prescaler;
152 uint8_t dv_div; 152 uint8_t dv_div;
153}; 153};
154 154
155/* 0,1,2,3,7 are prescale factors for given 4x 12000000 clock formula */ 155/* 0,1,2,3,7 are prescale factors for given 4x 12000000 clock formula */
156static const uint32_t rates4x[8] = { 156static const uint32_t rates4x[8] = {
157 [0] = 4 * 12000000 / 1024, 157 [0] = 4 * 12000000 / 1024,
158 [1] = 4 * 12000000 / 128, 158 [1] = 4 * 12000000 / 128,
159 [2] = 4 * 12000000 / 16, 159 [2] = 4 * 12000000 / 16,
160 [3] = 4 * 12000000 / 2, 160 [3] = 4 * 12000000 / 2,
161 [7] = 4 * 12000000, 161 [7] = 4 * 12000000,
162}; 162};
163 163
164static const struct usb_devno uchcom_devs[] = { 164static const struct usb_devno uchcom_devs[] = {
165 { USB_VENDOR_QINHENG2, USB_PRODUCT_QINHENG2_CH341SER }, 165 { USB_VENDOR_QINHENG2, USB_PRODUCT_QINHENG2_CH341SER },
166 { USB_VENDOR_QINHENG, USB_PRODUCT_QINHENG_CH340 }, 166 { USB_VENDOR_QINHENG, USB_PRODUCT_QINHENG_CH340 },
167 { USB_VENDOR_QINHENG, USB_PRODUCT_QINHENG_CH341_ASP }, 167 { USB_VENDOR_QINHENG, USB_PRODUCT_QINHENG_CH341_ASP },
168}; 168};
169#define uchcom_lookup(v, p) usb_lookup(uchcom_devs, v, p) 169#define uchcom_lookup(v, p) usb_lookup(uchcom_devs, v, p)
170 170
171static void uchcom_get_status(void *, int, u_char *, u_char *); 171static void uchcom_get_status(void *, int, u_char *, u_char *);
172static void uchcom_set(void *, int, int, int); 172static void uchcom_set(void *, int, int, int);
173static int uchcom_param(void *, int, struct termios *); 173static int uchcom_param(void *, int, struct termios *);
174static int uchcom_open(void *, int); 174static int uchcom_open(void *, int);
175static void uchcom_close(void *, int); 175static void uchcom_close(void *, int);
176static void uchcom_intr(struct usbd_xfer *, void *, 176static void uchcom_intr(struct usbd_xfer *, void *,
177 usbd_status); 177 usbd_status);
178 178
179static int set_config(struct uchcom_softc *); 179static int set_config(struct uchcom_softc *);
180static int find_ifaces(struct uchcom_softc *, struct usbd_interface **); 180static int find_ifaces(struct uchcom_softc *, struct usbd_interface **);
181static int find_endpoints(struct uchcom_softc *, 181static int find_endpoints(struct uchcom_softc *,
182 struct uchcom_endpoints *); 182 struct uchcom_endpoints *);
183static void close_intr_pipe(struct uchcom_softc *); 183static void close_intr_pipe(struct uchcom_softc *);
184 184
185 185
186static const struct ucom_methods uchcom_methods = { 186static const struct ucom_methods uchcom_methods = {
187 .ucom_get_status = uchcom_get_status, 187 .ucom_get_status = uchcom_get_status,
188 .ucom_set = uchcom_set, 188 .ucom_set = uchcom_set,
189 .ucom_param = uchcom_param, 189 .ucom_param = uchcom_param,
190 .ucom_open = uchcom_open, 190 .ucom_open = uchcom_open,
191 .ucom_close = uchcom_close, 191 .ucom_close = uchcom_close,
192}; 192};
193 193
194static int uchcom_match(device_t, cfdata_t, void *); 194static int uchcom_match(device_t, cfdata_t, void *);
195static void uchcom_attach(device_t, device_t, void *); 195static void uchcom_attach(device_t, device_t, void *);
196static void uchcom_childdet(device_t, device_t); 196static void uchcom_childdet(device_t, device_t);
197static int uchcom_detach(device_t, int); 197static int uchcom_detach(device_t, int);
198 198
199CFATTACH_DECL2_NEW(uchcom, 199CFATTACH_DECL2_NEW(uchcom,
200 sizeof(struct uchcom_softc), 200 sizeof(struct uchcom_softc),
201 uchcom_match, 201 uchcom_match,
202 uchcom_attach, 202 uchcom_attach,
203 uchcom_detach, 203 uchcom_detach,
204 NULL, 204 NULL,
205 NULL, 205 NULL,
206 uchcom_childdet); 206 uchcom_childdet);
207 207
208/* ---------------------------------------------------------------------- 208/* ----------------------------------------------------------------------
209 * driver entry points 209 * driver entry points
210 */ 210 */
211 211
212static int 212static int
213uchcom_match(device_t parent, cfdata_t match, void *aux) 213uchcom_match(device_t parent, cfdata_t match, void *aux)
214{ 214{
215 struct usb_attach_arg *uaa = aux; 215 struct usb_attach_arg *uaa = aux;
216 216
217 return (uchcom_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 217 return (uchcom_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
218 UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 218 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
219} 219}
220 220
221static void 221static void
222uchcom_attach(device_t parent, device_t self, void *aux) 222uchcom_attach(device_t parent, device_t self, void *aux)
223{ 223{
224 struct uchcom_softc *sc = device_private(self); 224 struct uchcom_softc *sc = device_private(self);
225 struct usb_attach_arg *uaa = aux; 225 struct usb_attach_arg *uaa = aux;
226 struct usbd_device *dev = uaa->uaa_device; 226 struct usbd_device *dev = uaa->uaa_device;
227 char *devinfop; 227 char *devinfop;
228 struct uchcom_endpoints endpoints; 228 struct uchcom_endpoints endpoints;
229 struct ucom_attach_args ucaa; 229 struct ucom_attach_args ucaa;
230 230
231 aprint_naive("\n"); 231 aprint_naive("\n");
232 aprint_normal("\n"); 232 aprint_normal("\n");
233 233
234 devinfop = usbd_devinfo_alloc(dev, 0); 234 devinfop = usbd_devinfo_alloc(dev, 0);
235 aprint_normal_dev(self, "%s\n", devinfop); 235 aprint_normal_dev(self, "%s\n", devinfop);
236 usbd_devinfo_free(devinfop); 236 usbd_devinfo_free(devinfop);
237 237
238 sc->sc_dev = self; 238 sc->sc_dev = self;
239 sc->sc_udev = dev; 239 sc->sc_udev = dev;
240 sc->sc_dying = false; 240 sc->sc_dying = false;
241 sc->sc_dtr = sc->sc_rts = -1; 241 sc->sc_dtr = sc->sc_rts = -1;
242 sc->sc_lsr = sc->sc_msr = 0; 242 sc->sc_lsr = sc->sc_msr = 0;
243 243
244 DPRINTF(("\n\nuchcom attach: sc=%p\n", sc)); 244 DPRINTF(("\n\nuchcom attach: sc=%p\n", sc));
245 245
246 if (set_config(sc)) 246 if (set_config(sc))
247 goto failed; 247 goto failed;
248 248
249 if (find_ifaces(sc, &sc->sc_iface)) 249 if (find_ifaces(sc, &sc->sc_iface))
250 goto failed; 250 goto failed;
251 251
252 if (find_endpoints(sc, &endpoints)) 252 if (find_endpoints(sc, &endpoints))
253 goto failed; 253 goto failed;
254 254
255 sc->sc_intr_endpoint = endpoints.ep_intr; 255 sc->sc_intr_endpoint = endpoints.ep_intr;
256 sc->sc_intr_size = endpoints.ep_intr_size; 256 sc->sc_intr_size = endpoints.ep_intr_size;
257 257
258 /* setup ucom layer */ 258 /* setup ucom layer */
259 ucaa.ucaa_portno = UCOM_UNK_PORTNO; 259 ucaa.ucaa_portno = UCOM_UNK_PORTNO;
260 ucaa.ucaa_bulkin = endpoints.ep_bulkin; 260 ucaa.ucaa_bulkin = endpoints.ep_bulkin;
261 ucaa.ucaa_bulkout = endpoints.ep_bulkout; 261 ucaa.ucaa_bulkout = endpoints.ep_bulkout;
262 ucaa.ucaa_ibufsize = UCHCOMIBUFSIZE; 262 ucaa.ucaa_ibufsize = UCHCOMIBUFSIZE;
263 ucaa.ucaa_obufsize = UCHCOMOBUFSIZE; 263 ucaa.ucaa_obufsize = UCHCOMOBUFSIZE;
264 ucaa.ucaa_ibufsizepad = UCHCOMIBUFSIZE; 264 ucaa.ucaa_ibufsizepad = UCHCOMIBUFSIZE;
265 ucaa.ucaa_opkthdrlen = 0; 265 ucaa.ucaa_opkthdrlen = 0;
266 ucaa.ucaa_device = dev; 266 ucaa.ucaa_device = dev;
267 ucaa.ucaa_iface = sc->sc_iface; 267 ucaa.ucaa_iface = sc->sc_iface;
268 ucaa.ucaa_methods = &uchcom_methods; 268 ucaa.ucaa_methods = &uchcom_methods;
269 ucaa.ucaa_arg = sc; 269 ucaa.ucaa_arg = sc;
270 ucaa.ucaa_info = NULL; 270 ucaa.ucaa_info = NULL;
271 271
272 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 272 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
273 273
274 sc->sc_subdev = config_found(self, &ucaa, ucomprint, 274 sc->sc_subdev = config_found(self, &ucaa, ucomprint,
275 CFARG_SUBMATCH, ucomsubmatch, 275 CFARG_SUBMATCH, ucomsubmatch,
276 CFARG_EOL); 276 CFARG_EOL);
277 277
278 return; 278 return;
279 279
280failed: 280failed:
281 sc->sc_dying = true; 281 sc->sc_dying = true;
282 return; 282 return;
283} 283}
284 284
285static void 285static void
286uchcom_childdet(device_t self, device_t child) 286uchcom_childdet(device_t self, device_t child)
287{ 287{
288 struct uchcom_softc *sc = device_private(self); 288 struct uchcom_softc *sc = device_private(self);
289 289
290 KASSERT(sc->sc_subdev == child); 290 KASSERT(sc->sc_subdev == child);
291 sc->sc_subdev = NULL; 291 sc->sc_subdev = NULL;
292} 292}
293 293
294static int 294static int
295uchcom_detach(device_t self, int flags) 295uchcom_detach(device_t self, int flags)
296{ 296{
297 struct uchcom_softc *sc = device_private(self); 297 struct uchcom_softc *sc = device_private(self);
298 int rv = 0; 298 int rv = 0;
299 299
300 DPRINTF(("uchcom_detach: sc=%p flags=%d\n", sc, flags)); 300 DPRINTF(("uchcom_detach: sc=%p flags=%d\n", sc, flags));
301 301
302 close_intr_pipe(sc); 302 close_intr_pipe(sc);
303 303
304 sc->sc_dying = true; 304 sc->sc_dying = true;
305 305
306 if (sc->sc_subdev != NULL) { 306 if (sc->sc_subdev != NULL) {
307 rv = config_detach(sc->sc_subdev, flags); 307 rv = config_detach(sc->sc_subdev, flags);
308 sc->sc_subdev = NULL; 308 sc->sc_subdev = NULL;
309 } 309 }
310 310
311 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 311 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
312 312
313 return rv; 313 return rv;
314} 314}
315 315
316static int 316static int
317set_config(struct uchcom_softc *sc) 317set_config(struct uchcom_softc *sc)
318{ 318{
319 usbd_status err; 319 usbd_status err;
320 320
321 err = usbd_set_config_index(sc->sc_udev, UCHCOM_CONFIG_INDEX, 1); 321 err = usbd_set_config_index(sc->sc_udev, UCHCOM_CONFIG_INDEX, 1);
322 if (err) { 322 if (err) {
323 aprint_error_dev(sc->sc_dev, 323 aprint_error_dev(sc->sc_dev,
324 "failed to set configuration: %s\n", usbd_errstr(err)); 324 "failed to set configuration: %s\n", usbd_errstr(err));
325 return -1; 325 return -1;
326 } 326 }
327 327
328 return 0; 328 return 0;
329} 329}
330 330
331static int 331static int
332find_ifaces(struct uchcom_softc *sc, struct usbd_interface **riface) 332find_ifaces(struct uchcom_softc *sc, struct usbd_interface **riface)
333{ 333{
334 usbd_status err; 334 usbd_status err;
335 335
336 err = usbd_device2interface_handle(sc->sc_udev, UCHCOM_IFACE_INDEX, 336 err = usbd_device2interface_handle(sc->sc_udev, UCHCOM_IFACE_INDEX,
337 riface); 337 riface);
338 if (err) { 338 if (err) {
339 aprint_error("\n%s: failed to get interface: %s\n", 339 aprint_error("\n%s: failed to get interface: %s\n",
340 device_xname(sc->sc_dev), usbd_errstr(err)); 340 device_xname(sc->sc_dev), usbd_errstr(err));
341 return -1; 341 return -1;
342 } 342 }
343 343
344 return 0; 344 return 0;
345} 345}
346 346
347static int 347static int
348find_endpoints(struct uchcom_softc *sc, struct uchcom_endpoints *endpoints) 348find_endpoints(struct uchcom_softc *sc, struct uchcom_endpoints *endpoints)
349{ 349{
350 int i, bin=-1, bout=-1, intr=-1, isize=0; 350 int i, bin=-1, bout=-1, intr=-1, isize=0;
351 usb_interface_descriptor_t *id; 351 usb_interface_descriptor_t *id;
352 usb_endpoint_descriptor_t *ed; 352 usb_endpoint_descriptor_t *ed;
353 353
354 id = usbd_get_interface_descriptor(sc->sc_iface); 354 id = usbd_get_interface_descriptor(sc->sc_iface);
355 355
356 for (i = 0; i < id->bNumEndpoints; i++) { 356 for (i = 0; i < id->bNumEndpoints; i++) {
357 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); 357 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
358 if (ed == NULL) { 358 if (ed == NULL) {
359 aprint_error_dev(sc->sc_dev, 359 aprint_error_dev(sc->sc_dev,
360 "no endpoint descriptor for %d\n", i); 360 "no endpoint descriptor for %d\n", i);
361 return -1; 361 return -1;
362 } 362 }
363 363
364 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 364 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
365 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 365 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
366 intr = ed->bEndpointAddress; 366 intr = ed->bEndpointAddress;
367 isize = UGETW(ed->wMaxPacketSize); 367 isize = UGETW(ed->wMaxPacketSize);
368 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 368 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
369 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 369 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
370 bin = ed->bEndpointAddress; 370 bin = ed->bEndpointAddress;
371 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 371 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
372 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 372 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
373 bout = ed->bEndpointAddress; 373 bout = ed->bEndpointAddress;
374 } 374 }
375 } 375 }
376 376
377 if (intr == -1 || bin == -1 || bout == -1) { 377 if (intr == -1 || bin == -1 || bout == -1) {
378 if (intr == -1) { 378 if (intr == -1) {
379 aprint_error_dev(sc->sc_dev, 379 aprint_error_dev(sc->sc_dev,
380 "no interrupt end point\n"); 380 "no interrupt end point\n");
381 } 381 }
382 if (bin == -1) { 382 if (bin == -1) {
383 aprint_error_dev(sc->sc_dev, 383 aprint_error_dev(sc->sc_dev,
384 "no data bulk in end point\n"); 384 "no data bulk in end point\n");
385 } 385 }
386 if (bout == -1) { 386 if (bout == -1) {
387 aprint_error_dev(sc->sc_dev, 387 aprint_error_dev(sc->sc_dev,
388 "no data bulk out end point\n"); 388 "no data bulk out end point\n");
389 } 389 }
390 return -1; 390 return -1;
391 } 391 }
392 if (isize < UCHCOM_INTR_LEAST) { 392 if (isize < UCHCOM_INTR_LEAST) {
393 aprint_error_dev(sc->sc_dev, "intr pipe is too short\n"); 393 aprint_error_dev(sc->sc_dev, "intr pipe is too short\n");
394 return -1; 394 return -1;
395 } 395 }
396 396
397 DPRINTF(("%s: bulkin=%d, bulkout=%d, intr=%d, isize=%d\n", 397 DPRINTF(("%s: bulkin=%d, bulkout=%d, intr=%d, isize=%d\n",
398 device_xname(sc->sc_dev), bin, bout, intr, isize)); 398 device_xname(sc->sc_dev), bin, bout, intr, isize));
399 399
400 endpoints->ep_intr = intr; 400 endpoints->ep_intr = intr;
401 endpoints->ep_intr_size = isize; 401 endpoints->ep_intr_size = isize;
402 endpoints->ep_bulkin = bin; 402 endpoints->ep_bulkin = bin;
403 endpoints->ep_bulkout = bout; 403 endpoints->ep_bulkout = bout;
404 404
405 return 0; 405 return 0;
406} 406}
407 407
408 408
409/* ---------------------------------------------------------------------- 409/* ----------------------------------------------------------------------
410 * low level i/o 410 * low level i/o
411 */ 411 */
412 412
413static __inline usbd_status 413static __inline usbd_status
414generic_control_out(struct uchcom_softc *sc, uint8_t reqno, 414generic_control_out(struct uchcom_softc *sc, uint8_t reqno,
415 uint16_t value, uint16_t index) 415 uint16_t value, uint16_t index)
416{ 416{
417 usb_device_request_t req; 417 usb_device_request_t req;
418 418
419 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 419 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
420 req.bRequest = reqno; 420 req.bRequest = reqno;
421 USETW(req.wValue, value); 421 USETW(req.wValue, value);
422 USETW(req.wIndex, index); 422 USETW(req.wIndex, index);
423 USETW(req.wLength, 0); 423 USETW(req.wLength, 0);
424 424
425 return usbd_do_request(sc->sc_udev, &req, 0); 425 return usbd_do_request(sc->sc_udev, &req, 0);
426} 426}
427 427
428static __inline usbd_status 428static __inline usbd_status
429generic_control_in(struct uchcom_softc *sc, uint8_t reqno, 429generic_control_in(struct uchcom_softc *sc, uint8_t reqno,
430 uint16_t value, uint16_t index, void *buf, int buflen, 430 uint16_t value, uint16_t index, void *buf, int buflen,
431 int *actlen) 431 int *actlen)
432{ 432{
433 usb_device_request_t req; 433 usb_device_request_t req;
434 434
435 req.bmRequestType = UT_READ_VENDOR_DEVICE; 435 req.bmRequestType = UT_READ_VENDOR_DEVICE;
436 req.bRequest = reqno; 436 req.bRequest = reqno;
437 USETW(req.wValue, value); 437 USETW(req.wValue, value);
438 USETW(req.wIndex, index); 438 USETW(req.wIndex, index);
439 USETW(req.wLength, (uint16_t)buflen); 439 USETW(req.wLength, (uint16_t)buflen);
440 440
441 return usbd_do_request_flags(sc->sc_udev, &req, buf, 441 return usbd_do_request_flags(sc->sc_udev, &req, buf,
442 USBD_SHORT_XFER_OK, actlen, 442 USBD_SHORT_XFER_OK, actlen,
443 USBD_DEFAULT_TIMEOUT); 443 USBD_DEFAULT_TIMEOUT);
444} 444}
445 445
446static __inline usbd_status 446static __inline usbd_status
447write_reg(struct uchcom_softc *sc, 447write_reg(struct uchcom_softc *sc,
448 uint8_t reg1, uint8_t val1, uint8_t reg2, uint8_t val2) 448 uint8_t reg1, uint8_t val1, uint8_t reg2, uint8_t val2)
449{ 449{
450 DPRINTF(("%s: write reg 0x%02X<-0x%02X, 0x%02X<-0x%02X\n", 450 DPRINTF(("%s: write reg 0x%02X<-0x%02X, 0x%02X<-0x%02X\n",
451 device_xname(sc->sc_dev), 451 device_xname(sc->sc_dev),
452 (unsigned)reg1, (unsigned)val1, 452 (unsigned)reg1, (unsigned)val1,
453 (unsigned)reg2, (unsigned)val2)); 453 (unsigned)reg2, (unsigned)val2));
454 return generic_control_out( 454 return generic_control_out(
455 sc, UCHCOM_REQ_WRITE_REG, 455 sc, UCHCOM_REQ_WRITE_REG,
456 reg1|((uint16_t)reg2<<8), val1|((uint16_t)val2<<8)); 456 reg1|((uint16_t)reg2<<8), val1|((uint16_t)val2<<8));
457} 457}
458 458
459static __inline usbd_status 459static __inline usbd_status
460read_reg(struct uchcom_softc *sc, 460read_reg(struct uchcom_softc *sc,
461 uint8_t reg1, uint8_t *rval1, uint8_t reg2, uint8_t *rval2) 461 uint8_t reg1, uint8_t *rval1, uint8_t reg2, uint8_t *rval2)
462{ 462{
463 uint8_t buf[UCHCOM_INPUT_BUF_SIZE]; 463 uint8_t buf[UCHCOM_INPUT_BUF_SIZE];
464 usbd_status err; 464 usbd_status err;
465 int actin; 465 int actin;
466 466
467 err = generic_control_in( 467 err = generic_control_in(
468 sc, UCHCOM_REQ_READ_REG, 468 sc, UCHCOM_REQ_READ_REG,
469 reg1|((uint16_t)reg2<<8), 0, buf, sizeof(buf), &actin); 469 reg1|((uint16_t)reg2<<8), 0, buf, sizeof(buf), &actin);
470 if (err) 470 if (err)
471 return err; 471 return err;
472 472
473 DPRINTF(("%s: read reg 0x%02X->0x%02X, 0x%02X->0x%02X\n", 473 DPRINTF(("%s: read reg 0x%02X->0x%02X, 0x%02X->0x%02X\n",
474 device_xname(sc->sc_dev), 474 device_xname(sc->sc_dev),
475 (unsigned)reg1, (unsigned)buf[0], 475 (unsigned)reg1, (unsigned)buf[0],
476 (unsigned)reg2, (unsigned)buf[1])); 476 (unsigned)reg2, (unsigned)buf[1]));
477 477
478 if (rval1) *rval1 = buf[0]; 478 if (rval1) *rval1 = buf[0];
479 if (rval2) *rval2 = buf[1]; 479 if (rval2) *rval2 = buf[1];
480 480
481 return USBD_NORMAL_COMPLETION; 481 return USBD_NORMAL_COMPLETION;
482} 482}
483 483
484static __inline usbd_status 484static __inline usbd_status
485get_version(struct uchcom_softc *sc, uint8_t *rver) 485get_version(struct uchcom_softc *sc, uint8_t *rver)
486{ 486{
487 uint8_t buf[UCHCOM_INPUT_BUF_SIZE]; 487 uint8_t buf[UCHCOM_INPUT_BUF_SIZE];
488 usbd_status err; 488 usbd_status err;
489 int actin; 489 int actin;
490 490
491 err = generic_control_in( 491 err = generic_control_in(
492 sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof(buf), &actin); 492 sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof(buf), &actin);
493 if (err) 493 if (err)
494 return err; 494 return err;
495 495
496 if (rver) *rver = buf[0]; 496 if (rver) *rver = buf[0];
497 497
498 return USBD_NORMAL_COMPLETION; 498 return USBD_NORMAL_COMPLETION;
499} 499}
500 500
501static __inline usbd_status 501static __inline usbd_status
502get_status(struct uchcom_softc *sc, uint8_t *rval) 502get_status(struct uchcom_softc *sc, uint8_t *rval)
503{ 503{
504 return read_reg(sc, UCHCOM_REG_STAT1, rval, UCHCOM_REG_STAT2, NULL); 504 return read_reg(sc, UCHCOM_REG_STAT1, rval, UCHCOM_REG_STAT2, NULL);
505} 505}
506 506
507static __inline usbd_status 507static __inline usbd_status
508set_dtrrts_10(struct uchcom_softc *sc, uint8_t val) 508set_dtrrts_10(struct uchcom_softc *sc, uint8_t val)
509{ 509{
510 return write_reg(sc, UCHCOM_REG_STAT1, val, UCHCOM_REG_STAT1, val); 510 return write_reg(sc, UCHCOM_REG_STAT1, val, UCHCOM_REG_STAT1, val);
511} 511}
512 512
513static __inline usbd_status 513static __inline usbd_status
514set_dtrrts_20(struct uchcom_softc *sc, uint8_t val) 514set_dtrrts_20(struct uchcom_softc *sc, uint8_t val)
515{ 515{
516 return generic_control_out(sc, UCHCOM_REQ_SET_DTRRTS, val, 0); 516 return generic_control_out(sc, UCHCOM_REQ_SET_DTRRTS, val, 0);
517} 517}
518 518
519 519
520/* ---------------------------------------------------------------------- 520/* ----------------------------------------------------------------------
521 * middle layer 521 * middle layer
522 */ 522 */
523 523
524static int 524static int
525update_version(struct uchcom_softc *sc) 525update_version(struct uchcom_softc *sc)
526{ 526{
527 usbd_status err; 527 usbd_status err;
528 528
529 err = get_version(sc, &sc->sc_version); 529 err = get_version(sc, &sc->sc_version);
530 if (err) { 530 if (err) {
531 device_printf(sc->sc_dev, "cannot get version: %s\n", 531 device_printf(sc->sc_dev, "cannot get version: %s\n",
532 usbd_errstr(err)); 532 usbd_errstr(err));
533 return EIO; 533 return EIO;
534 } 534 }
535 DPRINTF(("%s: update_version %d\n", device_xname(sc->sc_dev), sc->sc_version)); 535 DPRINTF(("%s: update_version %d\n", device_xname(sc->sc_dev), sc->sc_version));
536 536
537 return 0; 537 return 0;
538} 538}
539 539
540static void 540static void
541convert_status(struct uchcom_softc *sc, uint8_t cur) 541convert_status(struct uchcom_softc *sc, uint8_t cur)
542{ 542{
543 sc->sc_dtr = !(cur & UCHCOM_DTR_MASK); 543 sc->sc_dtr = !(cur & UCHCOM_DTR_MASK);
544 sc->sc_rts = !(cur & UCHCOM_RTS_MASK); 544 sc->sc_rts = !(cur & UCHCOM_RTS_MASK);
545 545
546 cur = ~cur & 0x0F; 546 cur = ~cur & 0x0F;
547 sc->sc_msr = (cur << 4) | ((sc->sc_msr >> 4) ^ cur); 547 sc->sc_msr = (cur << 4) | ((sc->sc_msr >> 4) ^ cur);
548} 548}
549 549
550static int 550static int
551update_status(struct uchcom_softc *sc) 551update_status(struct uchcom_softc *sc)
552{ 552{
553 usbd_status err; 553 usbd_status err;
554 uint8_t cur; 554 uint8_t cur;
555 555
556 err = get_status(sc, &cur); 556 err = get_status(sc, &cur);
557 if (err) { 557 if (err) {
558 device_printf(sc->sc_dev, 558 device_printf(sc->sc_dev,
559 "cannot update status: %s\n", usbd_errstr(err)); 559 "cannot update status: %s\n", usbd_errstr(err));
560 return EIO; 560 return EIO;
561 } 561 }
562 convert_status(sc, cur); 562 convert_status(sc, cur);
563 563
564 return 0; 564 return 0;
565} 565}
566 566
567 567
568static int 568static int
569set_dtrrts(struct uchcom_softc *sc, int dtr, int rts) 569set_dtrrts(struct uchcom_softc *sc, int dtr, int rts)
570{ 570{
571 usbd_status err; 571 usbd_status err;
572 uint8_t val = 0; 572 uint8_t val = 0;
573 573
574 if (dtr) val |= UCHCOM_DTR_MASK; 574 if (dtr) val |= UCHCOM_DTR_MASK;
575 if (rts) val |= UCHCOM_RTS_MASK; 575 if (rts) val |= UCHCOM_RTS_MASK;
576 576
577 if (sc->sc_version < UCHCOM_VER_20) 577 if (sc->sc_version < UCHCOM_VER_20)
578 err = set_dtrrts_10(sc, ~val); 578 err = set_dtrrts_10(sc, ~val);
579 else 579 else
580 err = set_dtrrts_20(sc, ~val); 580 err = set_dtrrts_20(sc, ~val);
581 581
582 if (err) { 582 if (err) {
583 device_printf(sc->sc_dev, "cannot set DTR/RTS: %s\n", 583 device_printf(sc->sc_dev, "cannot set DTR/RTS: %s\n",
584 usbd_errstr(err)); 584 usbd_errstr(err));
585 return EIO; 585 return EIO;
586 } 586 }
587 587
588 return 0; 588 return 0;
589} 589}
590 590
591static int 591static int
592set_break(struct uchcom_softc *sc, int onoff) 592set_break(struct uchcom_softc *sc, int onoff)
593{ 593{
594 usbd_status err; 594 usbd_status err;
595 uint8_t brk, lcr; 595 uint8_t brk, lcr;
596 596
597 err = read_reg(sc, UCHCOM_REG_BREAK, &brk, UCHCOM_REG_LCR, &lcr); 597 err = read_reg(sc, UCHCOM_REG_BREAK, &brk, UCHCOM_REG_LCR, &lcr);
598 if (err) 598 if (err)
599 return EIO; 599 return EIO;
600 if (onoff) { 600 if (onoff) {
601 /* on - clear bits */ 601 /* on - clear bits */
602 brk &= ~UCHCOM_BREAK_MASK; 602 brk &= ~UCHCOM_BREAK_MASK;
603 lcr &= ~UCHCOM_LCR_TXE; 603 lcr &= ~UCHCOM_LCR_TXE;
604 } else { 604 } else {
605 /* off - set bits */ 605 /* off - set bits */
606 brk |= UCHCOM_BREAK_MASK; 606 brk |= UCHCOM_BREAK_MASK;
607 lcr |= UCHCOM_LCR_TXE; 607 lcr |= UCHCOM_LCR_TXE;
608 } 608 }
609 err = write_reg(sc, UCHCOM_REG_BREAK, brk, UCHCOM_REG_LCR, lcr); 609 err = write_reg(sc, UCHCOM_REG_BREAK, brk, UCHCOM_REG_LCR, lcr);
610 if (err) 610 if (err)
611 return EIO; 611 return EIO;
612 612
613 return 0; 613 return 0;
614} 614}
615 615
616static int 616static int
617calc_divider_settings(struct uchcom_divider *dp, uint32_t rate) 617calc_divider_settings(struct uchcom_divider *dp, uint32_t rate)
618{ 618{
619/* 619/*
620 * combined with rates4x[] defined above, this routine generates, 620 * combined with rates4x[] defined above, this routine generates,
621 * 1200: prescale = 1/0x1, divisor = 178/0xb2 621 * 1200: prescale = 1/0x1, divisor = 178/0xb2
622 * 2400: prescale = 1/0x1, divisor = 217/0xd9 622 * 2400: prescale = 1/0x1, divisor = 217/0xd9
623 * 4800: prescale = 2/0x2, divisor = 100/0x64 623 * 4800: prescale = 2/0x2, divisor = 100/0x64
624 * 9600: prescale = 2/0x2, divisor = 178/0xb2 624 * 9600: prescale = 2/0x2, divisor = 178/0xb2
625 * 19200: prescale = 2/0x2, divisor = 217/0xd9 625 * 19200: prescale = 2/0x2, divisor = 217/0xd9
626 * 38400: prescale = 3/0x3, divisor = 100/0x64 626 * 38400: prescale = 3/0x3, divisor = 100/0x64
627 * 57600: prescale = 2/0x2, divisor = 243/0xf3 627 * 57600: prescale = 2/0x2, divisor = 243/0xf3
628 * 115200: prescale = 3/0x3, divisor = 204/0xcc 628 * 115200: prescale = 3/0x3, divisor = 204/0xcc
629 * 921600: prescale = 7/0x7, divisor = 243/0xf3 629 * 921600: prescale = 7/0x7, divisor = 243/0xf3
630 * 500000: prescale = 3/0x3, divisor = 244/0xf4 630 * 500000: prescale = 3/0x3, divisor = 244/0xf4
631 * 1000000: prescale = 3/0x3, divisor = 250/0xfa 631 * 1000000: prescale = 3/0x3, divisor = 250/0xfa
632 * 1500000: prescale = 3/0x3, divisor = 252/0xfc 632 * 1500000: prescale = 3/0x3, divisor = 252/0xfc
633 * 2000000: prescale = 3/0x3, divisor = 253/0xfd 633 * 2000000: prescale = 3/0x3, divisor = 253/0xfd
634 * 2500000: unsupported 634 * 2500000: unsupported
635 * 3000000: prescale = 3/0x3, divisor = 254/0xfe 635 * 3000000: prescale = 3/0x3, divisor = 254/0xfe
636 */ 636 */
637 size_t i; 637 size_t i;
638 uint32_t best, div, pre; 638 uint32_t best, div, pre;
639 const uint32_t rate4x = rate * 4U; 639 const uint32_t rate4x = rate * 4U;
640 640
641 if (rate == 0 || rate > 3000000) 641 if (rate == 0 || rate > 3000000)
642 return -1; 642 return -1;
643 643
644 pre = __arraycount(rates4x); 644 pre = __arraycount(rates4x);
645 best = UINT32_MAX; 645 best = UINT32_MAX;
646 646
647 for (i = 0; i < __arraycount(rates4x); i++) { 647 for (i = 0; i < __arraycount(rates4x); i++) {
648 uint32_t score, try; 648 uint32_t score, try;
649 try = rates4x[i] * 2 / rate4x; 649 try = rates4x[i] * 2 / rate4x;
650 try = (try / 2) + (try & 1); 650 try = (try / 2) + (try & 1);
651 if (try < 2) 651 if (try < 2)
652 continue; 652 continue;
653 if (try > 255) 653 if (try > 255)
654 try = 255; 654 try = 255;
655 score = abs((int)rate4x - rates4x[i] / try); 655 score = abs((int)rate4x - rates4x[i] / try);
656 if (score < best) { 656 if (score < best) {
657 best = score; 657 best = score;
658 pre = i; 658 pre = i;
659 div = try; 659 div = try;
660 } 660 }
661 } 661 }
662 662
663 if (pre >= __arraycount(rates4x)) 663 if (pre >= __arraycount(rates4x))
664 return -1; 664 return -1;
665 if ((rates4x[pre] / div / 4) < (rate * 99 / 100)) 665 if ((rates4x[pre] / div / 4) < (rate * 99 / 100))
666 return -1; 666 return -1;
667 if ((rates4x[pre] / div / 4) > (rate * 101 / 100)) 667 if ((rates4x[pre] / div / 4) > (rate * 101 / 100))
668 return -1; 668 return -1;
669 669
670 dp->dv_prescaler = pre; 670 dp->dv_prescaler = pre;
671 dp->dv_div = 256 - div; 671 dp->dv_div = 256 - div;
672 672
673 return 0; 673 return 0;
674} 674}
675 675
676static int 676static int
677set_dte_rate(struct uchcom_softc *sc, uint32_t rate) 677set_dte_rate(struct uchcom_softc *sc, uint32_t rate)
678{ 678{
679 usbd_status err; 679 usbd_status err;
680 struct uchcom_divider dv; 680 struct uchcom_divider dv;
681 681
682 if (calc_divider_settings(&dv, rate)) 682 if (calc_divider_settings(&dv, rate))
683 return EINVAL; 683 return EINVAL;
684 684
685 if ((err = write_reg(sc, 685 if ((err = write_reg(sc,
686 UCHCOM_REG_BPS_PRE, 686 UCHCOM_REG_BPS_PRE,
687 dv.dv_prescaler | UCHCOM_BPS_PRE_IMM, 687 dv.dv_prescaler | UCHCOM_BPS_PRE_IMM,
688 UCHCOM_REG_BPS_DIV, dv.dv_div))) { 688 UCHCOM_REG_BPS_DIV, dv.dv_div))) {
689 device_printf(sc->sc_dev, "cannot set DTE rate: %s\n", 689 device_printf(sc->sc_dev, "cannot set DTE rate: %s\n",
690 usbd_errstr(err)); 690 usbd_errstr(err));
691 return EIO; 691 return EIO;
692 } 692 }
693 693
694 return 0; 694 return 0;
695} 695}
696 696
697static int 697static int
698set_line_control(struct uchcom_softc *sc, tcflag_t cflag) 698set_line_control(struct uchcom_softc *sc, tcflag_t cflag)
699{ 699{
700 usbd_status err; 700 usbd_status err;
701 uint8_t lcr = 0, lcr2 = 0; 701 uint8_t lcr = 0, lcr2 = 0;
702 702
703 err = read_reg(sc, UCHCOM_REG_LCR, &lcr, UCHCOM_REG_LCR2, &lcr2); 703 err = read_reg(sc, UCHCOM_REG_LCR, &lcr, UCHCOM_REG_LCR2, &lcr2);
704 if (err) { 704 if (err) {
705 device_printf(sc->sc_dev, "cannot get LCR: %s\n", 705 device_printf(sc->sc_dev, "cannot get LCR: %s\n",
706 usbd_errstr(err)); 706 usbd_errstr(err));
707 return EIO; 707 return EIO;
708 } 708 }
709 709
710 lcr = UCHCOM_LCR_RXE | UCHCOM_LCR_TXE; 710 lcr = UCHCOM_LCR_RXE | UCHCOM_LCR_TXE;
711 711
712 switch (ISSET(cflag, CSIZE)) { 712 switch (ISSET(cflag, CSIZE)) {
713 case CS5: 713 case CS5:
714 lcr |= UCHCOM_LCR_CS5; 714 lcr |= UCHCOM_LCR_CS5;
715 break; 715 break;
716 case CS6: 716 case CS6:
717 lcr |= UCHCOM_LCR_CS6; 717 lcr |= UCHCOM_LCR_CS6;
718 break; 718 break;
719 case CS7: 719 case CS7:
720 lcr |= UCHCOM_LCR_CS7; 720 lcr |= UCHCOM_LCR_CS7;
721 break; 721 break;
722 case CS8: 722 case CS8:
723 lcr |= UCHCOM_LCR_CS8; 723 lcr |= UCHCOM_LCR_CS8;
724 break; 724 break;
725 } 725 }
726 726
727 if (ISSET(cflag, PARENB)) { 727 if (ISSET(cflag, PARENB)) {
728 lcr |= UCHCOM_LCR_PARENB; 728 lcr |= UCHCOM_LCR_PARENB;
729 if (!ISSET(cflag, PARODD)) 729 if (!ISSET(cflag, PARODD))
730 lcr |= UCHCOM_LCR_PAREVEN; 730 lcr |= UCHCOM_LCR_PAREVEN;
731 } 731 }
732 732
733 if (ISSET(cflag, CSTOPB)) { 733 if (ISSET(cflag, CSTOPB)) {
734 lcr |= UCHCOM_LCR_STOPB; 734 lcr |= UCHCOM_LCR_STOPB;
735 } 735 }
736 736
737 err = write_reg(sc, UCHCOM_REG_LCR, lcr, UCHCOM_REG_LCR2, lcr2); 737 err = write_reg(sc, UCHCOM_REG_LCR, lcr, UCHCOM_REG_LCR2, lcr2);
738 if (err) { 738 if (err) {
739 device_printf(sc->sc_dev, "cannot set LCR: %s\n", 739 device_printf(sc->sc_dev, "cannot set LCR: %s\n",
740 usbd_errstr(err)); 740 usbd_errstr(err));
741 return EIO; 741 return EIO;
742 } 742 }
743 743
744 return 0; 744 return 0;
745} 745}
746 746
747static int 747static int
748clear_chip(struct uchcom_softc *sc) 748clear_chip(struct uchcom_softc *sc)
749{ 749{
750 usbd_status err; 750 usbd_status err;
751 751
752 DPRINTF(("%s: clear\n", device_xname(sc->sc_dev))); 752 DPRINTF(("%s: clear\n", device_xname(sc->sc_dev)));
753 err = generic_control_out(sc, UCHCOM_REQ_RESET, 0, 0); 753 err = generic_control_out(sc, UCHCOM_REQ_RESET, 0, 0);
754 if (err) { 754 if (err) {
755 device_printf(sc->sc_dev, "cannot clear: %s\n", 755 device_printf(sc->sc_dev, "cannot clear: %s\n",
756 usbd_errstr(err)); 756 usbd_errstr(err));
757 return EIO; 757 return EIO;
758 } 758 }
759 /* 759 /*
760 * this REQ_RESET call ends up with 760 * this REQ_RESET call ends up with
761 * LCR=0xc0 (8N1) 761 * LCR=0xc0 (8N1)
762 * PRE=0x02, DIV=0xb2 (19200) 762 * PRE=0x02, DIV=0xd9 (19200)
763 */ 763 */
764 return 0; 764 return 0;
765} 765}
766 766
767static int 767static int
768setup_comm(struct uchcom_softc *sc) 768setup_comm(struct uchcom_softc *sc)
769{ 769{
770 int ret; 770 int ret;
771 771
772 ret = update_version(sc); 772 ret = update_version(sc);
773 if (ret) 773 if (ret)
774 return ret; 774 return ret;
775 775
776 ret = clear_chip(sc); 776 ret = clear_chip(sc);
777 if (ret) 777 if (ret)
778 return ret; 778 return ret;
779 779
780 ret = set_dte_rate(sc, TTYDEF_SPEED); 780 ret = set_dte_rate(sc, TTYDEF_SPEED);
781 if (ret) 781 if (ret)
782 return ret; 782 return ret;
783 783
784 ret = set_line_control(sc, CS8); 784 ret = set_line_control(sc, CS8);
785 if (ret) 785 if (ret)
786 return ret; 786 return ret;
787 787
788 ret = update_status(sc); 788 ret = update_status(sc);
789 if (ret) 789 if (ret)
790 return ret; 790 return ret;
791 791
792 sc->sc_dtr = sc->sc_rts = 1; 792 sc->sc_dtr = sc->sc_rts = 1;
793 ret = set_dtrrts(sc, sc->sc_dtr, sc->sc_rts); 793 ret = set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
794 if (ret) 794 if (ret)
795 return ret; 795 return ret;
796 796
797 return 0; 797 return 0;
798} 798}
799 799
800static int 800static int
801setup_intr_pipe(struct uchcom_softc *sc) 801setup_intr_pipe(struct uchcom_softc *sc)
802{ 802{
803 usbd_status err; 803 usbd_status err;
804 804
805 if (sc->sc_intr_endpoint != -1 && sc->sc_intr_pipe == NULL) { 805 if (sc->sc_intr_endpoint != -1 && sc->sc_intr_pipe == NULL) {
806 sc->sc_intr_buf = kmem_alloc(sc->sc_intr_size, KM_SLEEP); 806 sc->sc_intr_buf = kmem_alloc(sc->sc_intr_size, KM_SLEEP);
807 err = usbd_open_pipe_intr(sc->sc_iface, 807 err = usbd_open_pipe_intr(sc->sc_iface,
808 sc->sc_intr_endpoint, 808 sc->sc_intr_endpoint,
809 USBD_SHORT_XFER_OK, 809 USBD_SHORT_XFER_OK,
810 &sc->sc_intr_pipe, sc, 810 &sc->sc_intr_pipe, sc,
811 sc->sc_intr_buf, 811 sc->sc_intr_buf,
812 sc->sc_intr_size, 812 sc->sc_intr_size,
813 uchcom_intr, USBD_DEFAULT_INTERVAL); 813 uchcom_intr, USBD_DEFAULT_INTERVAL);
814 if (err) { 814 if (err) {
815 device_printf(sc->sc_dev, 815 device_printf(sc->sc_dev,
816 "cannot open interrupt pipe: %s\n", 816 "cannot open interrupt pipe: %s\n",
817 usbd_errstr(err)); 817 usbd_errstr(err));
818 return EIO; 818 return EIO;
819 } 819 }
820 } 820 }
821 return 0; 821 return 0;
822} 822}
823 823
824static void 824static void
825close_intr_pipe(struct uchcom_softc *sc) 825close_intr_pipe(struct uchcom_softc *sc)
826{ 826{
827 827
828 if (sc->sc_intr_pipe != NULL) { 828 if (sc->sc_intr_pipe != NULL) {
829 usbd_abort_pipe(sc->sc_intr_pipe); 829 usbd_abort_pipe(sc->sc_intr_pipe);
830 usbd_close_pipe(sc->sc_intr_pipe); 830 usbd_close_pipe(sc->sc_intr_pipe);
831 sc->sc_intr_pipe = NULL; 831 sc->sc_intr_pipe = NULL;
832 } 832 }
833 if (sc->sc_intr_buf != NULL) { 833 if (sc->sc_intr_buf != NULL) {
834 kmem_free(sc->sc_intr_buf, sc->sc_intr_size); 834 kmem_free(sc->sc_intr_buf, sc->sc_intr_size);
835 sc->sc_intr_buf = NULL; 835 sc->sc_intr_buf = NULL;
836 } 836 }
837} 837}
838 838
839 839
840/* ---------------------------------------------------------------------- 840/* ----------------------------------------------------------------------
841 * methods for ucom 841 * methods for ucom
842 */ 842 */
843static void 843static void
844uchcom_get_status(void *arg, int portno, u_char *rlsr, u_char *rmsr) 844uchcom_get_status(void *arg, int portno, u_char *rlsr, u_char *rmsr)
845{ 845{
846 struct uchcom_softc *sc = arg; 846 struct uchcom_softc *sc = arg;
847 847
848 if (sc->sc_dying) 848 if (sc->sc_dying)
849 return; 849 return;
850 850
851 *rlsr = sc->sc_lsr; 851 *rlsr = sc->sc_lsr;
852 *rmsr = sc->sc_msr; 852 *rmsr = sc->sc_msr;
853} 853}
854 854
855static void 855static void
856uchcom_set(void *arg, int portno, int reg, int onoff) 856uchcom_set(void *arg, int portno, int reg, int onoff)
857{ 857{
858 struct uchcom_softc *sc = arg; 858 struct uchcom_softc *sc = arg;
859 859
860 if (sc->sc_dying) 860 if (sc->sc_dying)
861 return; 861 return;
862 862
863 switch (reg) { 863 switch (reg) {
864 case UCOM_SET_DTR: 864 case UCOM_SET_DTR:
865 sc->sc_dtr = !!onoff; 865 sc->sc_dtr = !!onoff;
866 set_dtrrts(sc, sc->sc_dtr, sc->sc_rts); 866 set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
867 break; 867 break;
868 case UCOM_SET_RTS: 868 case UCOM_SET_RTS:
869 sc->sc_rts = !!onoff; 869 sc->sc_rts = !!onoff;
870 set_dtrrts(sc, sc->sc_dtr, sc->sc_rts); 870 set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
871 break; 871 break;
872 case UCOM_SET_BREAK: 872 case UCOM_SET_BREAK:
873 set_break(sc, onoff); 873 set_break(sc, onoff);
874 break; 874 break;
875 } 875 }
876} 876}
877 877
878static int 878static int
879uchcom_param(void *arg, int portno, struct termios *t) 879uchcom_param(void *arg, int portno, struct termios *t)
880{ 880{
881 struct uchcom_softc *sc = arg; 881 struct uchcom_softc *sc = arg;
882 int ret; 882 int ret;
883 883
884 if (sc->sc_dying) 884 if (sc->sc_dying)
885 return EIO; 885 return EIO;
886 886
887 ret = set_line_control(sc, t->c_cflag); 887 ret = set_line_control(sc, t->c_cflag);
888 if (ret) 888 if (ret)
889 return ret; 889 return ret;
890 890
891 ret = set_dte_rate(sc, t->c_ospeed); 891 ret = set_dte_rate(sc, t->c_ospeed);
892 if (ret) 892 if (ret)
893 return ret; 893 return ret;
894 894
895 return 0; 895 return 0;
896} 896}
897 897
898static int 898static int
899uchcom_open(void *arg, int portno) 899uchcom_open(void *arg, int portno)
900{ 900{
901 int ret; 901 int ret;
902 struct uchcom_softc *sc = arg; 902 struct uchcom_softc *sc = arg;
903 903
904 if (sc->sc_dying) 904 if (sc->sc_dying)
905 return EIO; 905 return EIO;
906 906
907 ret = setup_intr_pipe(sc); 907 ret = setup_intr_pipe(sc);
908 if (ret) 908 if (ret)
909 return ret; 909 return ret;
910 910
911 ret = setup_comm(sc); 911 ret = setup_comm(sc);
912 if (ret) 912 if (ret)
913 return ret; 913 return ret;
914 914
915 return 0; 915 return 0;
916} 916}
917 917
918static void 918static void
919uchcom_close(void *arg, int portno) 919uchcom_close(void *arg, int portno)
920{ 920{
921 struct uchcom_softc *sc = arg; 921 struct uchcom_softc *sc = arg;
922 922
923 if (sc->sc_dying) 923 if (sc->sc_dying)
924 return; 924 return;
925 925
926 close_intr_pipe(sc); 926 close_intr_pipe(sc);
927} 927}
928 928
929 929
930/* ---------------------------------------------------------------------- 930/* ----------------------------------------------------------------------
931 * callback when the modem status is changed. 931 * callback when the modem status is changed.
932 */ 932 */
933static void 933static void
934uchcom_intr(struct usbd_xfer *xfer, void * priv, 934uchcom_intr(struct usbd_xfer *xfer, void * priv,
935 usbd_status status) 935 usbd_status status)
936{ 936{
937 struct uchcom_softc *sc = priv; 937 struct uchcom_softc *sc = priv;
938 u_char *buf = sc->sc_intr_buf; 938 u_char *buf = sc->sc_intr_buf;
939 939
940 if (sc->sc_dying) 940 if (sc->sc_dying)
941 return; 941 return;
942 942
943 if (status != USBD_NORMAL_COMPLETION) { 943 if (status != USBD_NORMAL_COMPLETION) {
944 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 944 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
945 return; 945 return;
946 946
947 DPRINTF(("%s: abnormal status: %s\n", 947 DPRINTF(("%s: abnormal status: %s\n",
948 device_xname(sc->sc_dev), usbd_errstr(status))); 948 device_xname(sc->sc_dev), usbd_errstr(status)));
949 usbd_clear_endpoint_stall_async(sc->sc_intr_pipe); 949 usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
950 return; 950 return;
951 } 951 }
952 DPRINTF(("%s: intr: 0x%02X 0x%02X 0x%02X 0x%02X " 952 DPRINTF(("%s: intr: 0x%02X 0x%02X 0x%02X 0x%02X "
953 "0x%02X 0x%02X 0x%02X 0x%02X\n", 953 "0x%02X 0x%02X 0x%02X 0x%02X\n",
954 device_xname(sc->sc_dev), 954 device_xname(sc->sc_dev),
955 (unsigned)buf[0], (unsigned)buf[1], 955 (unsigned)buf[0], (unsigned)buf[1],
956 (unsigned)buf[2], (unsigned)buf[3], 956 (unsigned)buf[2], (unsigned)buf[3],
957 (unsigned)buf[4], (unsigned)buf[5], 957 (unsigned)buf[4], (unsigned)buf[5],
958 (unsigned)buf[6], (unsigned)buf[7])); 958 (unsigned)buf[6], (unsigned)buf[7]));
959 959
960 convert_status(sc, buf[UCHCOM_INTR_STAT1]); 960 convert_status(sc, buf[UCHCOM_INTR_STAT1]);
961 ucom_status_change(device_private(sc->sc_subdev)); 961 ucom_status_change(device_private(sc->sc_subdev));
962} 962}