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