Thu Mar 3 05:55:01 2022 UTC ()
usbnet drivers: Omit needless isdying tests in *_uno_init.

usbnet(9) already checks this immediately before calling *_uno_init.


(riastradh)
diff -r1.186 -r1.187 src/sys/dev/usb/if_aue.c
diff -r1.145 -r1.146 src/sys/dev/usb/if_axe.c
diff -r1.89 -r1.90 src/sys/dev/usb/if_axen.c
diff -r1.74 -r1.75 src/sys/dev/usb/if_cdce.c
diff -r1.102 -r1.103 src/sys/dev/usb/if_cue.c
diff -r1.114 -r1.115 src/sys/dev/usb/if_kue.c
diff -r1.17 -r1.18 src/sys/dev/usb/if_mos.c
diff -r1.77 -r1.78 src/sys/dev/usb/if_mue.c
diff -r1.87 -r1.88 src/sys/dev/usb/if_smsc.c
diff -r1.92 -r1.93 src/sys/dev/usb/if_udav.c
diff -r1.72 -r1.73 src/sys/dev/usb/if_upl.c
diff -r1.52 -r1.53 src/sys/dev/usb/if_ure.c
diff -r1.91 -r1.92 src/sys/dev/usb/if_url.c

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

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

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

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

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

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

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

--- src/sys/dev/usb/if_cdce.c 2022/03/03 05:52:20 1.74
+++ src/sys/dev/usb/if_cdce.c 2022/03/03 05:55:01 1.75
@@ -1,320 +1,316 @@ @@ -1,320 +1,316 @@
1/* $NetBSD: if_cdce.c,v 1.74 2022/03/03 05:52:20 riastradh Exp $ */ 1/* $NetBSD: if_cdce.c,v 1.75 2022/03/03 05:55:01 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com> 4 * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com>
5 * Copyright (c) 2003 Craig Boston 5 * Copyright (c) 2003 Craig Boston
6 * Copyright (c) 2004 Daniel Hartmeier 6 * Copyright (c) 2004 Daniel Hartmeier
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement: 18 * must display the following acknowledgement:
19 * This product includes software developed by Bill Paul. 19 * This product includes software developed by Bill Paul.
20 * 4. Neither the name of the author nor the names of any co-contributors 20 * 4. Neither the name of the author nor the names of any co-contributors
21 * may be used to endorse or promote products derived from this software 21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 22 * without specific prior written permission.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 24 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul, THE VOICES IN HIS HEAD OR 27 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul, THE VOICES IN HIS HEAD OR
28 * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
31 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
33 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
34 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37/* 37/*
38 * USB Communication Device Class (Ethernet Networking Control Model) 38 * USB Communication Device Class (Ethernet Networking Control Model)
39 * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf 39 * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
40 */ 40 */
41 41
42#include <sys/cdefs.h> 42#include <sys/cdefs.h>
43__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.74 2022/03/03 05:52:20 riastradh Exp $"); 43__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.75 2022/03/03 05:55:01 riastradh Exp $");
44 44
45#include <sys/param.h> 45#include <sys/param.h>
46 46
47#include <dev/usb/usbnet.h> 47#include <dev/usb/usbnet.h>
48#include <dev/usb/usbcdc.h> 48#include <dev/usb/usbcdc.h>
49 49
50#include <dev/usb/if_cdcereg.h> 50#include <dev/usb/if_cdcereg.h>
51 51
52struct cdce_type { 52struct cdce_type {
53 struct usb_devno cdce_dev; 53 struct usb_devno cdce_dev;
54 uint16_t cdce_flags; 54 uint16_t cdce_flags;
55#define CDCE_ZAURUS 1 55#define CDCE_ZAURUS 1
56#define CDCE_NO_UNION 2 56#define CDCE_NO_UNION 2
57}; 57};
58 58
59static const struct cdce_type cdce_devs[] = { 59static const struct cdce_type cdce_devs[] = {
60 {{ USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632 }, CDCE_NO_UNION }, 60 {{ USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632 }, CDCE_NO_UNION },
61 {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX }, CDCE_NO_UNION }, 61 {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX }, CDCE_NO_UNION },
62 {{ USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00 }, CDCE_NO_UNION }, 62 {{ USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00 }, CDCE_NO_UNION },
63 {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN }, CDCE_ZAURUS | CDCE_NO_UNION }, 63 {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN }, CDCE_ZAURUS | CDCE_NO_UNION },
64 {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2 }, CDCE_ZAURUS | CDCE_NO_UNION }, 64 {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2 }, CDCE_ZAURUS | CDCE_NO_UNION },
65 {{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501 }, CDCE_NO_UNION }, 65 {{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501 }, CDCE_NO_UNION },
66 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500 }, CDCE_ZAURUS }, 66 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500 }, CDCE_ZAURUS },
67 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_A300 }, CDCE_ZAURUS | CDCE_NO_UNION }, 67 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_A300 }, CDCE_ZAURUS | CDCE_NO_UNION },
68 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600 }, CDCE_ZAURUS | CDCE_NO_UNION }, 68 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600 }, CDCE_ZAURUS | CDCE_NO_UNION },
69 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C700 }, CDCE_ZAURUS | CDCE_NO_UNION }, 69 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C700 }, CDCE_ZAURUS | CDCE_NO_UNION },
70 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C750 }, CDCE_ZAURUS | CDCE_NO_UNION }, 70 {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C750 }, CDCE_ZAURUS | CDCE_NO_UNION },
71}; 71};
72#define cdce_lookup(v, p) \ 72#define cdce_lookup(v, p) \
73 ((const struct cdce_type *)usb_lookup(cdce_devs, v, p)) 73 ((const struct cdce_type *)usb_lookup(cdce_devs, v, p))
74 74
75static int cdce_match(device_t, cfdata_t, void *); 75static int cdce_match(device_t, cfdata_t, void *);
76static void cdce_attach(device_t, device_t, void *); 76static void cdce_attach(device_t, device_t, void *);
77 77
78CFATTACH_DECL_NEW(cdce, sizeof(struct usbnet), cdce_match, cdce_attach, 78CFATTACH_DECL_NEW(cdce, sizeof(struct usbnet), cdce_match, cdce_attach,
79 usbnet_detach, usbnet_activate); 79 usbnet_detach, usbnet_activate);
80 80
81static void cdce_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 81static void cdce_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
82 uint32_t); 82 uint32_t);
83static unsigned cdce_uno_tx_prepare(struct usbnet *, struct mbuf *, 83static unsigned cdce_uno_tx_prepare(struct usbnet *, struct mbuf *,
84 struct usbnet_chain *); 84 struct usbnet_chain *);
85static int cdce_uno_init(struct ifnet *); 85static int cdce_uno_init(struct ifnet *);
86 86
87static const struct usbnet_ops cdce_ops = { 87static const struct usbnet_ops cdce_ops = {
88 .uno_tx_prepare = cdce_uno_tx_prepare, 88 .uno_tx_prepare = cdce_uno_tx_prepare,
89 .uno_rx_loop = cdce_uno_rx_loop, 89 .uno_rx_loop = cdce_uno_rx_loop,
90 .uno_init = cdce_uno_init, 90 .uno_init = cdce_uno_init,
91}; 91};
92 92
93static int 93static int
94cdce_match(device_t parent, cfdata_t match, void *aux) 94cdce_match(device_t parent, cfdata_t match, void *aux)
95{ 95{
96 struct usbif_attach_arg *uiaa = aux; 96 struct usbif_attach_arg *uiaa = aux;
97 97
98 if (cdce_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL) 98 if (cdce_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL)
99 return UMATCH_VENDOR_PRODUCT; 99 return UMATCH_VENDOR_PRODUCT;
100 100
101 if (uiaa->uiaa_class == UICLASS_CDC && uiaa->uiaa_subclass == 101 if (uiaa->uiaa_class == UICLASS_CDC && uiaa->uiaa_subclass ==
102 UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL) 102 UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL)
103 return UMATCH_IFACECLASS_GENERIC; 103 return UMATCH_IFACECLASS_GENERIC;
104 104
105 return UMATCH_NONE; 105 return UMATCH_NONE;
106} 106}
107 107
108static void 108static void
109cdce_attach(device_t parent, device_t self, void *aux) 109cdce_attach(device_t parent, device_t self, void *aux)
110{ 110{
111 struct usbnet * const un = device_private(self); 111 struct usbnet * const un = device_private(self);
112 struct usbif_attach_arg *uiaa = aux; 112 struct usbif_attach_arg *uiaa = aux;
113 char *devinfop; 113 char *devinfop;
114 struct usbd_device *dev = uiaa->uiaa_device; 114 struct usbd_device *dev = uiaa->uiaa_device;
115 const struct cdce_type *t; 115 const struct cdce_type *t;
116 usb_interface_descriptor_t *id; 116 usb_interface_descriptor_t *id;
117 usb_endpoint_descriptor_t *ed; 117 usb_endpoint_descriptor_t *ed;
118 const usb_cdc_union_descriptor_t *ud; 118 const usb_cdc_union_descriptor_t *ud;
119 usb_config_descriptor_t *cd; 119 usb_config_descriptor_t *cd;
120 int data_ifcno; 120 int data_ifcno;
121 int i, j, numalts; 121 int i, j, numalts;
122 const usb_cdc_ethernet_descriptor_t *ue; 122 const usb_cdc_ethernet_descriptor_t *ue;
123 char eaddr_str[USB_MAX_ENCODED_STRING_LEN]; 123 char eaddr_str[USB_MAX_ENCODED_STRING_LEN];
124 124
125 aprint_naive("\n"); 125 aprint_naive("\n");
126 aprint_normal("\n"); 126 aprint_normal("\n");
127 devinfop = usbd_devinfo_alloc(dev, 0); 127 devinfop = usbd_devinfo_alloc(dev, 0);
128 aprint_normal_dev(self, "%s\n", devinfop); 128 aprint_normal_dev(self, "%s\n", devinfop);
129 usbd_devinfo_free(devinfop); 129 usbd_devinfo_free(devinfop);
130 130
131 un->un_dev = self; 131 un->un_dev = self;
132 un->un_udev = dev; 132 un->un_udev = dev;
133 un->un_sc = un; 133 un->un_sc = un;
134 un->un_ops = &cdce_ops; 134 un->un_ops = &cdce_ops;
135 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 135 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
136 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 136 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
137 un->un_rx_list_cnt = CDCE_RX_LIST_CNT; 137 un->un_rx_list_cnt = CDCE_RX_LIST_CNT;
138 un->un_tx_list_cnt = CDCE_TX_LIST_CNT; 138 un->un_tx_list_cnt = CDCE_TX_LIST_CNT;
139 un->un_rx_bufsz = CDCE_BUFSZ; 139 un->un_rx_bufsz = CDCE_BUFSZ;
140 un->un_tx_bufsz = CDCE_BUFSZ; 140 un->un_tx_bufsz = CDCE_BUFSZ;
141 141
142 t = cdce_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product); 142 t = cdce_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product);
143 if (t) 143 if (t)
144 un->un_flags = t->cdce_flags; 144 un->un_flags = t->cdce_flags;
145 145
146 if (un->un_flags & CDCE_NO_UNION) 146 if (un->un_flags & CDCE_NO_UNION)
147 un->un_iface = uiaa->uiaa_iface; 147 un->un_iface = uiaa->uiaa_iface;
148 else { 148 else {
149 ud = (const usb_cdc_union_descriptor_t *)usb_find_desc_if(un->un_udev, 149 ud = (const usb_cdc_union_descriptor_t *)usb_find_desc_if(un->un_udev,
150 UDESC_CS_INTERFACE, UDESCSUB_CDC_UNION, 150 UDESC_CS_INTERFACE, UDESCSUB_CDC_UNION,
151 usbd_get_interface_descriptor(uiaa->uiaa_iface)); 151 usbd_get_interface_descriptor(uiaa->uiaa_iface));
152 if (ud == NULL) { 152 if (ud == NULL) {
153 aprint_error_dev(self, "no union descriptor\n"); 153 aprint_error_dev(self, "no union descriptor\n");
154 return; 154 return;
155 } 155 }
156 data_ifcno = ud->bSlaveInterface[0]; 156 data_ifcno = ud->bSlaveInterface[0];
157 157
158 for (i = 0; i < uiaa->uiaa_nifaces; i++) { 158 for (i = 0; i < uiaa->uiaa_nifaces; i++) {
159 if (uiaa->uiaa_ifaces[i] != NULL) { 159 if (uiaa->uiaa_ifaces[i] != NULL) {
160 id = usbd_get_interface_descriptor( 160 id = usbd_get_interface_descriptor(
161 uiaa->uiaa_ifaces[i]); 161 uiaa->uiaa_ifaces[i]);
162 if (id != NULL && id->bInterfaceNumber == 162 if (id != NULL && id->bInterfaceNumber ==
163 data_ifcno) { 163 data_ifcno) {
164 un->un_iface = uiaa->uiaa_ifaces[i]; 164 un->un_iface = uiaa->uiaa_ifaces[i];
165 uiaa->uiaa_ifaces[i] = NULL; 165 uiaa->uiaa_ifaces[i] = NULL;
166 } 166 }
167 } 167 }
168 } 168 }
169 } 169 }
170 if (un->un_iface == NULL) { 170 if (un->un_iface == NULL) {
171 aprint_error_dev(self, "no data interface\n"); 171 aprint_error_dev(self, "no data interface\n");
172 return; 172 return;
173 } 173 }
174 174
175 /* 175 /*
176 * <quote> 176 * <quote>
177 * The Data Class interface of a networking device shall have a minimum 177 * The Data Class interface of a networking device shall have a minimum
178 * of two interface settings. The first setting (the default interface 178 * of two interface settings. The first setting (the default interface
179 * setting) includes no endpoints and therefore no networking traffic is 179 * setting) includes no endpoints and therefore no networking traffic is
180 * exchanged whenever the default interface setting is selected. One or 180 * exchanged whenever the default interface setting is selected. One or
181 * more additional interface settings are used for normal operation, and 181 * more additional interface settings are used for normal operation, and
182 * therefore each includes a pair of endpoints (one IN, and one OUT) to 182 * therefore each includes a pair of endpoints (one IN, and one OUT) to
183 * exchange network traffic. Select an alternate interface setting to 183 * exchange network traffic. Select an alternate interface setting to
184 * initialize the network aspects of the device and to enable the 184 * initialize the network aspects of the device and to enable the
185 * exchange of network traffic. 185 * exchange of network traffic.
186 * </quote> 186 * </quote>
187 * 187 *
188 * Some devices, most notably cable modems, include interface settings 188 * Some devices, most notably cable modems, include interface settings
189 * that have no IN or OUT endpoint, therefore loop through the list of all 189 * that have no IN or OUT endpoint, therefore loop through the list of all
190 * available interface settings looking for one with both IN and OUT 190 * available interface settings looking for one with both IN and OUT
191 * endpoints. 191 * endpoints.
192 */ 192 */
193 id = usbd_get_interface_descriptor(un->un_iface); 193 id = usbd_get_interface_descriptor(un->un_iface);
194 cd = usbd_get_config_descriptor(un->un_udev); 194 cd = usbd_get_config_descriptor(un->un_udev);
195 numalts = usbd_get_no_alts(cd, id->bInterfaceNumber); 195 numalts = usbd_get_no_alts(cd, id->bInterfaceNumber);
196 196
197 for (j = 0; j < numalts; j++) { 197 for (j = 0; j < numalts; j++) {
198 if (usbd_set_interface(un->un_iface, j)) { 198 if (usbd_set_interface(un->un_iface, j)) {
199 aprint_error_dev(un->un_dev, 199 aprint_error_dev(un->un_dev,
200 "setting alternate interface failed\n"); 200 "setting alternate interface failed\n");
201 return; 201 return;
202 } 202 }
203 /* Find endpoints. */ 203 /* Find endpoints. */
204 id = usbd_get_interface_descriptor(un->un_iface); 204 id = usbd_get_interface_descriptor(un->un_iface);
205 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] = 0; 205 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] = 0;
206 for (i = 0; i < id->bNumEndpoints; i++) { 206 for (i = 0; i < id->bNumEndpoints; i++) {
207 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 207 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
208 if (!ed) { 208 if (!ed) {
209 aprint_error_dev(self, 209 aprint_error_dev(self,
210 "could not read endpoint descriptor\n"); 210 "could not read endpoint descriptor\n");
211 return; 211 return;
212 } 212 }
213 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 213 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
214 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 214 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
215 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 215 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
216 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 216 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
217 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 217 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
218 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 218 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
219 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 219 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
220 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 220 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
221 /* XXX: CDC spec defines an interrupt pipe, but it is not 221 /* XXX: CDC spec defines an interrupt pipe, but it is not
222 * needed for simple host-to-host applications. */ 222 * needed for simple host-to-host applications. */
223 } else { 223 } else {
224 aprint_error_dev(self, "unexpected endpoint\n"); 224 aprint_error_dev(self, "unexpected endpoint\n");
225 } 225 }
226 } 226 }
227 /* If we found something, try and use it... */ 227 /* If we found something, try and use it... */
228 if (un->un_ed[USBNET_ENDPT_RX] != 0 && un->un_ed[USBNET_ENDPT_TX] != 0) 228 if (un->un_ed[USBNET_ENDPT_RX] != 0 && un->un_ed[USBNET_ENDPT_TX] != 0)
229 break; 229 break;
230 } 230 }
231 231
232 if (un->un_ed[USBNET_ENDPT_RX] == 0) { 232 if (un->un_ed[USBNET_ENDPT_RX] == 0) {
233 aprint_error_dev(self, "could not find data bulk in\n"); 233 aprint_error_dev(self, "could not find data bulk in\n");
234 return; 234 return;
235 } 235 }
236 if (un->un_ed[USBNET_ENDPT_TX] == 0) { 236 if (un->un_ed[USBNET_ENDPT_TX] == 0) {
237 aprint_error_dev(self, "could not find data bulk out\n"); 237 aprint_error_dev(self, "could not find data bulk out\n");
238 return; 238 return;
239 } 239 }
240 240
241 ue = (const usb_cdc_ethernet_descriptor_t *)usb_find_desc_if(dev, 241 ue = (const usb_cdc_ethernet_descriptor_t *)usb_find_desc_if(dev,
242 UDESC_CS_INTERFACE, UDESCSUB_CDC_ENF, 242 UDESC_CS_INTERFACE, UDESCSUB_CDC_ENF,
243 usbd_get_interface_descriptor(uiaa->uiaa_iface)); 243 usbd_get_interface_descriptor(uiaa->uiaa_iface));
244 if (!ue || usbd_get_string(dev, ue->iMacAddress, eaddr_str) || 244 if (!ue || usbd_get_string(dev, ue->iMacAddress, eaddr_str) ||
245 ether_aton_r(un->un_eaddr, sizeof(un->un_eaddr), eaddr_str)) { 245 ether_aton_r(un->un_eaddr, sizeof(un->un_eaddr), eaddr_str)) {
246 aprint_normal_dev(self, "faking address\n"); 246 aprint_normal_dev(self, "faking address\n");
247 un->un_eaddr[0] = 0x2a; 247 un->un_eaddr[0] = 0x2a;
248 uint32_t ticks = getticks(); 248 uint32_t ticks = getticks();
249 memcpy(&un->un_eaddr[1], &ticks, sizeof(ticks)); 249 memcpy(&un->un_eaddr[1], &ticks, sizeof(ticks));
250 un->un_eaddr[5] = (uint8_t)(device_unit(un->un_dev)); 250 un->un_eaddr[5] = (uint8_t)(device_unit(un->un_dev));
251 } 251 }
252 252
253 usbnet_attach(un, "cdcedet"); 253 usbnet_attach(un, "cdcedet");
254 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 254 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
255 0, NULL); 255 0, NULL);
256} 256}
257 257
258static int 258static int
259cdce_uno_init(struct ifnet *ifp) 259cdce_uno_init(struct ifnet *ifp)
260{ 260{
261 struct usbnet *un = ifp->if_softc; 261 struct usbnet *un = ifp->if_softc;
262 int rv; 262 int rv;
263 263
264 if (usbnet_isdying(un)) 264 usbnet_stop(un, ifp, 1);
265 rv = EIO; 265 rv = usbnet_init_rx_tx(un);
266 else { 266 usbnet_set_link(un, rv == 0);
267 usbnet_stop(un, ifp, 1); 
268 rv = usbnet_init_rx_tx(un); 
269 usbnet_set_link(un, rv == 0); 
270 } 
271 267
272 return rv; 268 return rv;
273} 269}
274 270
275static void 271static void
276cdce_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len) 272cdce_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
277{ 273{
278 struct ifnet *ifp = usbnet_ifp(un); 274 struct ifnet *ifp = usbnet_ifp(un);
279 275
280 /* Strip off CRC added by Zaurus, if present */ 276 /* Strip off CRC added by Zaurus, if present */
281 if (un->un_flags & CDCE_ZAURUS && total_len > 4) 277 if (un->un_flags & CDCE_ZAURUS && total_len > 4)
282 total_len -= 4; 278 total_len -= 4;
283 279
284 if (total_len < sizeof(struct ether_header)) { 280 if (total_len < sizeof(struct ether_header)) {
285 if_statinc(ifp, if_ierrors); 281 if_statinc(ifp, if_ierrors);
286 return; 282 return;
287 } 283 }
288 284
289 usbnet_enqueue(un, c->unc_buf, total_len, 0, 0, 0); 285 usbnet_enqueue(un, c->unc_buf, total_len, 0, 0, 0);
290} 286}
291 287
292static unsigned 288static unsigned
293cdce_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 289cdce_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
294{ 290{
295 /* Zaurus wants a 32-bit CRC appended to every frame */ 291 /* Zaurus wants a 32-bit CRC appended to every frame */
296 uint32_t crc; 292 uint32_t crc;
297 unsigned extra = 0; 293 unsigned extra = 0;
298 unsigned length; 294 unsigned length;
299 295
300 if (un->un_flags & CDCE_ZAURUS) 296 if (un->un_flags & CDCE_ZAURUS)
301 extra = sizeof(crc); 297 extra = sizeof(crc);
302 298
303 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - extra) 299 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - extra)
304 return 0; 300 return 0;
305 length = m->m_pkthdr.len + extra; 301 length = m->m_pkthdr.len + extra;
306 302
307 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf); 303 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf);
308 if (un->un_flags & CDCE_ZAURUS) { 304 if (un->un_flags & CDCE_ZAURUS) {
309 crc = htole32(~ether_crc32_le(c->unc_buf, m->m_pkthdr.len)); 305 crc = htole32(~ether_crc32_le(c->unc_buf, m->m_pkthdr.len));
310 memcpy(c->unc_buf + m->m_pkthdr.len, &crc, sizeof(crc)); 306 memcpy(c->unc_buf + m->m_pkthdr.len, &crc, sizeof(crc));
311 } 307 }
312 308
313 return length; 309 return length;
314} 310}
315 311
316#ifdef _MODULE 312#ifdef _MODULE
317#include "ioconf.c" 313#include "ioconf.c"
318#endif 314#endif
319 315
320USBNET_MODULE(cdce) 316USBNET_MODULE(cdce)

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

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

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

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

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

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

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

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

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

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

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

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

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

--- src/sys/dev/usb/if_upl.c 2022/03/03 05:50:22 1.72
+++ src/sys/dev/usb/if_upl.c 2022/03/03 05:55:01 1.73
@@ -1,320 +1,317 @@ @@ -1,320 +1,317 @@
1/* $NetBSD: if_upl.c,v 1.72 2022/03/03 05:50:22 riastradh Exp $ */ 1/* $NetBSD: if_upl.c,v 1.73 2022/03/03 05:55:01 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000 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 Lennart Augustsson (lennart@augustsson.net) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology. 9 * Carlstedt Research & Technology.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Prolific PL2301/PL2302 driver 34 * Prolific PL2301/PL2302 driver
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.72 2022/03/03 05:50:22 riastradh Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.73 2022/03/03 05:55:01 riastradh Exp $");
39 39
40#ifdef _KERNEL_OPT 40#ifdef _KERNEL_OPT
41#include "opt_inet.h" 41#include "opt_inet.h"
42#include "opt_usb.h" 42#include "opt_usb.h"
43#endif 43#endif
44 44
45#include <sys/param.h> 45#include <sys/param.h>
46 46
47#include <dev/usb/usbnet.h> 47#include <dev/usb/usbnet.h>
48 48
49#include <net/if_types.h> 49#include <net/if_types.h>
50 50
51#ifdef INET 51#ifdef INET
52#include <netinet/in.h> 52#include <netinet/in.h>
53#include <netinet/in_var.h> 53#include <netinet/in_var.h>
54#include <netinet/if_inarp.h> 54#include <netinet/if_inarp.h>
55#endif 55#endif
56 56
57/* 57/*
58 * 7 6 5 4 3 2 1 0 58 * 7 6 5 4 3 2 1 0
59 * tx rx 1 0 59 * tx rx 1 0
60 * 1110 0000 rxdata 60 * 1110 0000 rxdata
61 * 1010 0000 idle 61 * 1010 0000 idle
62 * 0010 0000 tx over 62 * 0010 0000 tx over
63 * 0110 tx over + rxd 63 * 0110 tx over + rxd
64 */ 64 */
65 65
66#define UPL_RXDATA 0x40 66#define UPL_RXDATA 0x40
67#define UPL_TXOK 0x80 67#define UPL_TXOK 0x80
68 68
69#define UPL_CONFIG_NO 1 69#define UPL_CONFIG_NO 1
70#define UPL_IFACE_IDX 0 70#define UPL_IFACE_IDX 0
71 71
72/***/ 72/***/
73 73
74#define UPL_INTR_INTERVAL 20 74#define UPL_INTR_INTERVAL 20
75 75
76#define UPL_BUFSZ 1024 76#define UPL_BUFSZ 1024
77 77
78#define UPL_RX_LIST_CNT 1 78#define UPL_RX_LIST_CNT 1
79#define UPL_TX_LIST_CNT 1 79#define UPL_TX_LIST_CNT 1
80 80
81#ifdef UPL_DEBUG 81#ifdef UPL_DEBUG
82#define DPRINTF(x) if (upldebug) printf x 82#define DPRINTF(x) if (upldebug) printf x
83#define DPRINTFN(n,x) if (upldebug >= (n)) printf x 83#define DPRINTFN(n,x) if (upldebug >= (n)) printf x
84int upldebug = 0; 84int upldebug = 0;
85#else 85#else
86#define DPRINTF(x) 86#define DPRINTF(x)
87#define DPRINTFN(n,x) 87#define DPRINTFN(n,x)
88#endif 88#endif
89 89
90/* 90/*
91 * Various supported device vendors/products. 91 * Various supported device vendors/products.
92 */ 92 */
93static const struct usb_devno sc_devs[] = { 93static const struct usb_devno sc_devs[] = {
94 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301 }, 94 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301 },
95 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302 }, 95 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302 },
96 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL25A1 }, 96 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL25A1 },
97 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U258 }, 97 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U258 },
98 { USB_VENDOR_NI, USB_PRODUCT_NI_HTOH_7825 } 98 { USB_VENDOR_NI, USB_PRODUCT_NI_HTOH_7825 }
99}; 99};
100 100
101static int upl_match(device_t, cfdata_t, void *); 101static int upl_match(device_t, cfdata_t, void *);
102static void upl_attach(device_t, device_t, void *); 102static void upl_attach(device_t, device_t, void *);
103 103
104CFATTACH_DECL_NEW(upl, sizeof(struct usbnet), upl_match, upl_attach, 104CFATTACH_DECL_NEW(upl, sizeof(struct usbnet), upl_match, upl_attach,
105 usbnet_detach, usbnet_activate); 105 usbnet_detach, usbnet_activate);
106 106
107#if 0 107#if 0
108static void upl_uno_intr(struct usbnet *, usbd_status); 108static void upl_uno_intr(struct usbnet *, usbd_status);
109#endif 109#endif
110static void upl_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 110static void upl_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
111static unsigned upl_uno_tx_prepare(struct usbnet *, struct mbuf *, 111static unsigned upl_uno_tx_prepare(struct usbnet *, struct mbuf *,
112 struct usbnet_chain *); 112 struct usbnet_chain *);
113static int upl_uno_ioctl(struct ifnet *, u_long, void *); 113static int upl_uno_ioctl(struct ifnet *, u_long, void *);
114static int upl_uno_init(struct ifnet *); 114static int upl_uno_init(struct ifnet *);
115 115
116static const struct usbnet_ops upl_ops = { 116static const struct usbnet_ops upl_ops = {
117 .uno_init = upl_uno_init, 117 .uno_init = upl_uno_init,
118 .uno_tx_prepare = upl_uno_tx_prepare, 118 .uno_tx_prepare = upl_uno_tx_prepare,
119 .uno_rx_loop = upl_uno_rx_loop, 119 .uno_rx_loop = upl_uno_rx_loop,
120 .uno_ioctl = upl_uno_ioctl, 120 .uno_ioctl = upl_uno_ioctl,
121#if 0 121#if 0
122 .uno_intr = upl_uno_intr, 122 .uno_intr = upl_uno_intr,
123#endif 123#endif
124}; 124};
125 125
126static int upl_output(struct ifnet *, struct mbuf *, const struct sockaddr *, 126static int upl_output(struct ifnet *, struct mbuf *, const struct sockaddr *,
127 const struct rtentry *); 127 const struct rtentry *);
128static void upl_input(struct ifnet *, struct mbuf *); 128static void upl_input(struct ifnet *, struct mbuf *);
129 129
130/* 130/*
131 * Probe for a Prolific chip. 131 * Probe for a Prolific chip.
132 */ 132 */
133static int 133static int
134upl_match(device_t parent, cfdata_t match, void *aux) 134upl_match(device_t parent, cfdata_t match, void *aux)
135{ 135{
136 struct usb_attach_arg *uaa = aux; 136 struct usb_attach_arg *uaa = aux;
137 137
138 return usb_lookup(sc_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ? 138 return usb_lookup(sc_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ?
139 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 139 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
140} 140}
141 141
142static void 142static void
143upl_attach(device_t parent, device_t self, void *aux) 143upl_attach(device_t parent, device_t self, void *aux)
144{ 144{
145 struct usbnet * const un = device_private(self); 145 struct usbnet * const un = device_private(self);
146 struct usb_attach_arg *uaa = aux; 146 struct usb_attach_arg *uaa = aux;
147 char *devinfop; 147 char *devinfop;
148 struct usbd_device * dev = uaa->uaa_device; 148 struct usbd_device * dev = uaa->uaa_device;
149 usbd_status err; 149 usbd_status err;
150 usb_interface_descriptor_t *id; 150 usb_interface_descriptor_t *id;
151 usb_endpoint_descriptor_t *ed; 151 usb_endpoint_descriptor_t *ed;
152 int i; 152 int i;
153 153
154 DPRINTFN(5,(" : upl_attach: un=%p, dev=%p", un, dev)); 154 DPRINTFN(5,(" : upl_attach: un=%p, dev=%p", un, dev));
155 155
156 aprint_naive("\n"); 156 aprint_naive("\n");
157 aprint_normal("\n"); 157 aprint_normal("\n");
158 devinfop = usbd_devinfo_alloc(dev, 0); 158 devinfop = usbd_devinfo_alloc(dev, 0);
159 aprint_normal_dev(self, "%s\n", devinfop); 159 aprint_normal_dev(self, "%s\n", devinfop);
160 usbd_devinfo_free(devinfop); 160 usbd_devinfo_free(devinfop);
161 161
162 un->un_dev = self; 162 un->un_dev = self;
163 un->un_udev = dev; 163 un->un_udev = dev;
164 un->un_sc = un; 164 un->un_sc = un;
165 un->un_ops = &upl_ops; 165 un->un_ops = &upl_ops;
166 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 166 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
167 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 167 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
168 un->un_rx_list_cnt = UPL_RX_LIST_CNT; 168 un->un_rx_list_cnt = UPL_RX_LIST_CNT;
169 un->un_tx_list_cnt = UPL_TX_LIST_CNT; 169 un->un_tx_list_cnt = UPL_TX_LIST_CNT;
170 un->un_rx_bufsz = UPL_BUFSZ; 170 un->un_rx_bufsz = UPL_BUFSZ;
171 un->un_tx_bufsz = UPL_BUFSZ; 171 un->un_tx_bufsz = UPL_BUFSZ;
172 172
173 err = usbd_set_config_no(dev, UPL_CONFIG_NO, 1); 173 err = usbd_set_config_no(dev, UPL_CONFIG_NO, 1);
174 if (err) { 174 if (err) {
175 aprint_error_dev(self, "failed to set configuration" 175 aprint_error_dev(self, "failed to set configuration"
176 ", err=%s\n", usbd_errstr(err)); 176 ", err=%s\n", usbd_errstr(err));
177 return; 177 return;
178 } 178 }
179 179
180 err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &un->un_iface); 180 err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &un->un_iface);
181 if (err) { 181 if (err) {
182 aprint_error_dev(self, "getting interface handle failed\n"); 182 aprint_error_dev(self, "getting interface handle failed\n");
183 return; 183 return;
184 } 184 }
185 185
186 id = usbd_get_interface_descriptor(un->un_iface); 186 id = usbd_get_interface_descriptor(un->un_iface);
187 187
188 /* Find endpoints. */ 188 /* Find endpoints. */
189 for (i = 0; i < id->bNumEndpoints; i++) { 189 for (i = 0; i < id->bNumEndpoints; i++) {
190 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 190 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
191 if (ed == NULL) { 191 if (ed == NULL) {
192 aprint_error_dev(self, "couldn't get ep %d\n", i); 192 aprint_error_dev(self, "couldn't get ep %d\n", i);
193 return; 193 return;
194 } 194 }
195 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 195 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
196 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 196 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
197 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 197 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
198 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 198 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
199 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 199 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
200 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 200 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
201 } 201 }
202 } 202 }
203 203
204 if (un->un_ed[USBNET_ENDPT_RX] == 0 || un->un_ed[USBNET_ENDPT_TX] == 0 /*|| 204 if (un->un_ed[USBNET_ENDPT_RX] == 0 || un->un_ed[USBNET_ENDPT_TX] == 0 /*||
205 un->un_ed[USBNET_ENDPT_INTR] == 0*/) { 205 un->un_ed[USBNET_ENDPT_INTR] == 0*/) {
206 aprint_error_dev(self, "missing endpoint\n"); 206 aprint_error_dev(self, "missing endpoint\n");
207 return; 207 return;
208 } 208 }
209 209
210 usbnet_attach(un, "upldet"); 210 usbnet_attach(un, "upldet");
211 211
212 /* Initialize interface info.*/ 212 /* Initialize interface info.*/
213 struct ifnet *ifp = usbnet_ifp(un); 213 struct ifnet *ifp = usbnet_ifp(un);
214 ifp->if_mtu = UPL_BUFSZ; 214 ifp->if_mtu = UPL_BUFSZ;
215 ifp->if_type = IFT_OTHER; 215 ifp->if_type = IFT_OTHER;
216 ifp->if_addrlen = 0; 216 ifp->if_addrlen = 0;
217 ifp->if_hdrlen = 0; 217 ifp->if_hdrlen = 0;
218 ifp->if_output = upl_output; 218 ifp->if_output = upl_output;
219 ifp->_if_input = upl_input; 219 ifp->_if_input = upl_input;
220 ifp->if_baudrate = 12000000; 220 ifp->if_baudrate = 12000000;
221 ifp->if_dlt = DLT_RAW; 221 ifp->if_dlt = DLT_RAW;
222 222
223 usbnet_attach_ifp(un, IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX, 223 usbnet_attach_ifp(un, IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX,
224 0, NULL); 224 0, NULL);
225} 225}
226 226
227static void 227static void
228upl_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len) 228upl_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
229{ 229{
230 230
231 DPRINTFN(9,("%s: %s: enter length=%d\n", 231 DPRINTFN(9,("%s: %s: enter length=%d\n",
232 device_xname(un->un_dev), __func__, total_len)); 232 device_xname(un->un_dev), __func__, total_len));
233 233
234 usbnet_input(un, c->unc_buf, total_len); 234 usbnet_input(un, c->unc_buf, total_len);
235} 235}
236 236
237static unsigned 237static unsigned
238upl_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 238upl_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
239{ 239{
240 int total_len; 240 int total_len;
241 241
242 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz) 242 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz)
243 return 0; 243 return 0;
244 244
245 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf); 245 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf);
246 total_len = m->m_pkthdr.len; 246 total_len = m->m_pkthdr.len;
247 247
248 DPRINTFN(10,("%s: %s: total_len=%d\n", 248 DPRINTFN(10,("%s: %s: total_len=%d\n",
249 device_xname(un->un_dev), __func__, total_len)); 249 device_xname(un->un_dev), __func__, total_len));
250 250
251 return total_len; 251 return total_len;
252} 252}
253 253
254static int 254static int
255upl_uno_init(struct ifnet *ifp) 255upl_uno_init(struct ifnet *ifp)
256{ 256{
257 struct usbnet * const un = ifp->if_softc; 257 struct usbnet * const un = ifp->if_softc;
258 int rv; 258 int rv;
259 259
260 if (usbnet_isdying(un)) 260 rv = usbnet_init_rx_tx(un);
261 rv = EIO; 
262 else 
263 rv = usbnet_init_rx_tx(un); 
264 261
265 return rv; 262 return rv;
266} 263}
267 264
268static int 265static int
269upl_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 266upl_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
270{ 267{
271 if (cmd == SIOCSIFMTU) { 268 if (cmd == SIOCSIFMTU) {
272 struct ifreq *ifr = data; 269 struct ifreq *ifr = data;
273 270
274 if (ifr->ifr_mtu > UPL_BUFSZ) 271 if (ifr->ifr_mtu > UPL_BUFSZ)
275 return EINVAL; 272 return EINVAL;
276 } 273 }
277 return 0; 274 return 0;
278} 275}
279 276
280static int 277static int
281upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 278upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
282 const struct rtentry *rt0) 279 const struct rtentry *rt0)
283{ 280{
284 struct usbnet * const un __unused = ifp->if_softc; 281 struct usbnet * const un __unused = ifp->if_softc;
285 282
286 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 283 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev), __func__));
287 284
288 /* If the queueing discipline needs packet classification, do it now. */ 285 /* If the queueing discipline needs packet classification, do it now. */
289 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 286 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
290 287
291 /* 288 /*
292 * Queue message on interface, and start output if interface 289 * Queue message on interface, and start output if interface
293 * not yet active. 290 * not yet active.
294 */ 291 */
295 return if_transmit_lock(ifp, m); 292 return if_transmit_lock(ifp, m);
296} 293}
297 294
298static void 295static void
299upl_input(struct ifnet *ifp, struct mbuf *m) 296upl_input(struct ifnet *ifp, struct mbuf *m)
300{ 297{
301#ifdef INET 298#ifdef INET
302 size_t pktlen = m->m_len; 299 size_t pktlen = m->m_len;
303 int s; 300 int s;
304 301
305 s = splnet(); 302 s = splnet();
306 if (__predict_false(!pktq_enqueue(ip_pktq, m, 0))) { 303 if (__predict_false(!pktq_enqueue(ip_pktq, m, 0))) {
307 if_statinc(ifp, if_iqdrops); 304 if_statinc(ifp, if_iqdrops);
308 m_freem(m); 305 m_freem(m);
309 } else { 306 } else {
310 if_statadd2(ifp, if_ipackets, 1, if_ibytes, pktlen); 307 if_statadd2(ifp, if_ipackets, 1, if_ibytes, pktlen);
311 } 308 }
312 splx(s); 309 splx(s);
313#endif 310#endif
314} 311}
315 312
316#ifdef _MODULE 313#ifdef _MODULE
317#include "ioconf.c" 314#include "ioconf.c"
318#endif 315#endif
319 316
320USBNET_MODULE(upl) 317USBNET_MODULE(upl)

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

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

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

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