if_axe.c (187970) | if_axe.c (188412) |
---|---|
1/*- 2 * Copyright (c) 1997, 1998, 1999, 2000-2003 3 * Bill Paul <wpaul@windriver.com>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 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 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 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997, 1998, 1999, 2000-2003 3 * Bill Paul <wpaul@windriver.com>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 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 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 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/dev/usb2/ethernet/if_axe2.c 187970 2009-02-01 00:51:25Z thompsa $"); | 34__FBSDID("$FreeBSD: head/sys/dev/usb2/ethernet/if_axe2.c 188412 2009-02-09 22:02:38Z thompsa $"); |
35 36/* | 35 36/* |
37 * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver. Used in the 38 * LinkSys USB200M and various other adapters. | 37 * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver. 38 * Used in the LinkSys USB200M and various other adapters. |
39 * 40 * Manuals available from: 41 * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF 42 * Note: you need the manual for the AX88170 chip (USB 1.x ethernet 43 * controller) to find the definitions for the RX control register. 44 * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF 45 * 46 * Written by Bill Paul <wpaul@windriver.com> --- 24 unchanged lines hidden (view full) --- 71 * Ax88178 and Ax88772 support backported from the OpenBSD driver. 72 * 2007/02/12, J.R. Oldroyd, fbsd@opal.com 73 * 74 * Manual here: 75 * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf 76 * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf 77 */ 78 | 39 * 40 * Manuals available from: 41 * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF 42 * Note: you need the manual for the AX88170 chip (USB 1.x ethernet 43 * controller) to find the definitions for the RX control register. 44 * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF 45 * 46 * Written by Bill Paul <wpaul@windriver.com> --- 24 unchanged lines hidden (view full) --- 71 * Ax88178 and Ax88772 support backported from the OpenBSD driver. 72 * 2007/02/12, J.R. Oldroyd, fbsd@opal.com 73 * 74 * Manual here: 75 * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf 76 * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf 77 */ 78 |
79/* 80 * NOTE: all function names beginning like "axe_cfg_" can only 81 * be called from within the config thread function ! 82 */ 83 | |
84#include <dev/usb2/include/usb2_devid.h> 85#include <dev/usb2/include/usb2_standard.h> 86#include <dev/usb2/include/usb2_mfunc.h> 87#include <dev/usb2/include/usb2_error.h> 88 | 79#include <dev/usb2/include/usb2_devid.h> 80#include <dev/usb2/include/usb2_standard.h> 81#include <dev/usb2/include/usb2_mfunc.h> 82#include <dev/usb2/include/usb2_error.h> 83 |
89#define usb2_config_td_cc usb2_ether_cc 90#define usb2_config_td_softc axe_softc 91 | |
92#define USB_DEBUG_VAR axe_debug 93 94#include <dev/usb2/core/usb2_core.h> 95#include <dev/usb2/core/usb2_lookup.h> 96#include <dev/usb2/core/usb2_process.h> | 84#define USB_DEBUG_VAR axe_debug 85 86#include <dev/usb2/core/usb2_core.h> 87#include <dev/usb2/core/usb2_lookup.h> 88#include <dev/usb2/core/usb2_process.h> |
97#include <dev/usb2/core/usb2_config_td.h> | |
98#include <dev/usb2/core/usb2_debug.h> 99#include <dev/usb2/core/usb2_request.h> 100#include <dev/usb2/core/usb2_busdma.h> 101#include <dev/usb2/core/usb2_util.h> 102 103#include <dev/usb2/ethernet/usb2_ethernet.h> 104#include <dev/usb2/ethernet/if_axereg.h> 105 | 89#include <dev/usb2/core/usb2_debug.h> 90#include <dev/usb2/core/usb2_request.h> 91#include <dev/usb2/core/usb2_busdma.h> 92#include <dev/usb2/core/usb2_util.h> 93 94#include <dev/usb2/ethernet/usb2_ethernet.h> 95#include <dev/usb2/ethernet/if_axereg.h> 96 |
106MODULE_DEPEND(axe, usb2_ethernet, 1, 1, 1); 107MODULE_DEPEND(axe, usb2_core, 1, 1, 1); 108MODULE_DEPEND(axe, ether, 1, 1, 1); 109MODULE_DEPEND(axe, miibus, 1, 1, 1); | 97/* 98 * AXE_178_MAX_FRAME_BURST 99 * max frame burst size for Ax88178 and Ax88772 100 * 0 2048 bytes 101 * 1 4096 bytes 102 * 2 8192 bytes 103 * 3 16384 bytes 104 * use the largest your system can handle without USB stalling. 105 * 106 * NB: 88772 parts appear to generate lots of input errors with 107 * a 2K rx buffer and 8K is only slightly faster than 4K on an 108 * EHCI port on a T42 so change at your own risk. 109 */ 110#define AXE_178_MAX_FRAME_BURST 1 |
110 111#if USB_DEBUG 112static int axe_debug = 0; 113 114SYSCTL_NODE(_hw_usb2, OID_AUTO, axe, CTLFLAG_RW, 0, "USB axe"); 115SYSCTL_INT(_hw_usb2_axe, OID_AUTO, debug, CTLFLAG_RW, &axe_debug, 0, 116 "Debug level"); 117#endif --- 29 unchanged lines hidden (view full) --- 147 {USB_VPI(USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL, 0)}, 148}; 149 150static device_probe_t axe_probe; 151static device_attach_t axe_attach; 152static device_detach_t axe_detach; 153static device_shutdown_t axe_shutdown; 154 | 111 112#if USB_DEBUG 113static int axe_debug = 0; 114 115SYSCTL_NODE(_hw_usb2, OID_AUTO, axe, CTLFLAG_RW, 0, "USB axe"); 116SYSCTL_INT(_hw_usb2_axe, OID_AUTO, debug, CTLFLAG_RW, &axe_debug, 0, 117 "Debug level"); 118#endif --- 29 unchanged lines hidden (view full) --- 148 {USB_VPI(USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL, 0)}, 149}; 150 151static device_probe_t axe_probe; 152static device_attach_t axe_attach; 153static device_detach_t axe_detach; 154static device_shutdown_t axe_shutdown; 155 |
155static usb2_callback_t axe_intr_clear_stall_callback; | |
156static usb2_callback_t axe_intr_callback; | 156static usb2_callback_t axe_intr_callback; |
157static usb2_callback_t axe_bulk_read_clear_stall_callback; | |
158static usb2_callback_t axe_bulk_read_callback; | 157static usb2_callback_t axe_bulk_read_callback; |
159static usb2_callback_t axe_bulk_write_clear_stall_callback; | |
160static usb2_callback_t axe_bulk_write_callback; 161 | 158static usb2_callback_t axe_bulk_write_callback; 159 |
162static miibus_readreg_t axe_cfg_miibus_readreg; 163static miibus_writereg_t axe_cfg_miibus_writereg; 164static miibus_statchg_t axe_cfg_miibus_statchg; | 160static miibus_readreg_t axe_miibus_readreg; 161static miibus_writereg_t axe_miibus_writereg; 162static miibus_statchg_t axe_miibus_statchg; |
165 | 163 |
166static usb2_config_td_command_t axe_cfg_ifmedia_upd; 167static usb2_config_td_command_t axe_config_copy; 168static usb2_config_td_command_t axe_cfg_setmulti; 169static usb2_config_td_command_t axe_cfg_first_time_setup; 170static usb2_config_td_command_t axe_cfg_tick; 171static usb2_config_td_command_t axe_cfg_pre_init; 172static usb2_config_td_command_t axe_cfg_init; 173static usb2_config_td_command_t axe_cfg_promisc_upd; 174static usb2_config_td_command_t axe_cfg_pre_stop; 175static usb2_config_td_command_t axe_cfg_stop; | 164static usb2_ether_fn_t axe_attach_post; 165static usb2_ether_fn_t axe_init; 166static usb2_ether_fn_t axe_stop; 167static usb2_ether_fn_t axe_start; 168static usb2_ether_fn_t axe_tick; 169static usb2_ether_fn_t axe_setmulti; 170static usb2_ether_fn_t axe_setpromisc; |
176 | 171 |
177static int axe_ifmedia_upd_cb(struct ifnet *); 178static void axe_ifmedia_sts_cb(struct ifnet *, struct ifmediareq *); 179static void axe_cfg_reset(struct axe_softc *); 180static void axe_start_cb(struct ifnet *); 181static void axe_start_transfers(struct axe_softc *); 182static void axe_init_cb(void *); 183static int axe_ioctl_cb(struct ifnet *, u_long, caddr_t); 184static void axe_watchdog(void *); 185static void axe_cfg_cmd(struct axe_softc *, uint16_t, uint16_t, uint16_t, 186 void *); 187static void axe_cfg_ax88178_init(struct axe_softc *); 188static void axe_cfg_ax88772_init(struct axe_softc *); | 172static int axe_ifmedia_upd(struct ifnet *); 173static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *); 174static int axe_cmd(struct axe_softc *, int, int, int, void *); 175static void axe_ax88178_init(struct axe_softc *); 176static void axe_ax88772_init(struct axe_softc *); |
189static int axe_get_phyno(struct axe_softc *, int); 190 191static const struct usb2_config axe_config[AXE_N_TRANSFER] = { 192 193 [AXE_BULK_DT_WR] = { 194 .type = UE_BULK, 195 .endpoint = UE_ADDR_ANY, 196 .direction = UE_DIR_OUT, 197 .mh.bufsize = AXE_BULK_BUF_SIZE, 198 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,}, | 177static int axe_get_phyno(struct axe_softc *, int); 178 179static const struct usb2_config axe_config[AXE_N_TRANSFER] = { 180 181 [AXE_BULK_DT_WR] = { 182 .type = UE_BULK, 183 .endpoint = UE_ADDR_ANY, 184 .direction = UE_DIR_OUT, 185 .mh.bufsize = AXE_BULK_BUF_SIZE, 186 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,}, |
199 .mh.callback = &axe_bulk_write_callback, | 187 .mh.callback = axe_bulk_write_callback, |
200 .mh.timeout = 10000, /* 10 seconds */ 201 }, 202 203 [AXE_BULK_DT_RD] = { 204 .type = UE_BULK, 205 .endpoint = UE_ADDR_ANY, 206 .direction = UE_DIR_IN, 207#if (MCLBYTES < 2048) 208#error "(MCLBYTES < 2048)" 209#endif 210 .mh.bufsize = MCLBYTES, 211 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, | 188 .mh.timeout = 10000, /* 10 seconds */ 189 }, 190 191 [AXE_BULK_DT_RD] = { 192 .type = UE_BULK, 193 .endpoint = UE_ADDR_ANY, 194 .direction = UE_DIR_IN, 195#if (MCLBYTES < 2048) 196#error "(MCLBYTES < 2048)" 197#endif 198 .mh.bufsize = MCLBYTES, 199 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, |
212 .mh.callback = &axe_bulk_read_callback, | 200 .mh.callback = axe_bulk_read_callback, |
213 .mh.timeout = 0, /* no timeout */ 214 }, 215 | 201 .mh.timeout = 0, /* no timeout */ 202 }, 203 |
216 [AXE_BULK_CS_WR] = { 217 .type = UE_CONTROL, 218 .endpoint = 0x00, /* Control pipe */ 219 .direction = UE_DIR_ANY, 220 .mh.bufsize = sizeof(struct usb2_device_request), 221 .mh.flags = {}, 222 .mh.callback = &axe_bulk_write_clear_stall_callback, 223 .mh.timeout = 1000, /* 1 second */ 224 .mh.interval = 50, /* 50ms */ 225 }, 226 227 [AXE_BULK_CS_RD] = { 228 .type = UE_CONTROL, 229 .endpoint = 0x00, /* Control pipe */ 230 .direction = UE_DIR_ANY, 231 .mh.bufsize = sizeof(struct usb2_device_request), 232 .mh.flags = {}, 233 .mh.callback = &axe_bulk_read_clear_stall_callback, 234 .mh.timeout = 1000, /* 1 second */ 235 .mh.interval = 50, /* 50ms */ 236 }, 237 | |
238 [AXE_INTR_DT_RD] = { 239 .type = UE_INTERRUPT, 240 .endpoint = UE_ADDR_ANY, 241 .direction = UE_DIR_IN, 242 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 243 .mh.bufsize = 0, /* use wMaxPacketSize */ | 204 [AXE_INTR_DT_RD] = { 205 .type = UE_INTERRUPT, 206 .endpoint = UE_ADDR_ANY, 207 .direction = UE_DIR_IN, 208 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 209 .mh.bufsize = 0, /* use wMaxPacketSize */ |
244 .mh.callback = &axe_intr_callback, | 210 .mh.callback = axe_intr_callback, |
245 }, | 211 }, |
246 247 [AXE_INTR_CS_RD] = { 248 .type = UE_CONTROL, 249 .endpoint = 0x00, /* Control pipe */ 250 .direction = UE_DIR_ANY, 251 .mh.bufsize = sizeof(struct usb2_device_request), 252 .mh.flags = {}, 253 .mh.callback = &axe_intr_clear_stall_callback, 254 .mh.timeout = 1000, /* 1 second */ 255 .mh.interval = 50, /* 50ms */ 256 }, | |
257}; 258 259static device_method_t axe_methods[] = { 260 /* Device interface */ 261 DEVMETHOD(device_probe, axe_probe), 262 DEVMETHOD(device_attach, axe_attach), 263 DEVMETHOD(device_detach, axe_detach), 264 DEVMETHOD(device_shutdown, axe_shutdown), 265 266 /* bus interface */ 267 DEVMETHOD(bus_print_child, bus_generic_print_child), 268 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 269 270 /* MII interface */ | 212}; 213 214static device_method_t axe_methods[] = { 215 /* Device interface */ 216 DEVMETHOD(device_probe, axe_probe), 217 DEVMETHOD(device_attach, axe_attach), 218 DEVMETHOD(device_detach, axe_detach), 219 DEVMETHOD(device_shutdown, axe_shutdown), 220 221 /* bus interface */ 222 DEVMETHOD(bus_print_child, bus_generic_print_child), 223 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 224 225 /* MII interface */ |
271 DEVMETHOD(miibus_readreg, axe_cfg_miibus_readreg), 272 DEVMETHOD(miibus_writereg, axe_cfg_miibus_writereg), 273 DEVMETHOD(miibus_statchg, axe_cfg_miibus_statchg), | 226 DEVMETHOD(miibus_readreg, axe_miibus_readreg), 227 DEVMETHOD(miibus_writereg, axe_miibus_writereg), 228 DEVMETHOD(miibus_statchg, axe_miibus_statchg), |
274 275 {0, 0} 276}; 277 278static driver_t axe_driver = { 279 .name = "axe", 280 .methods = axe_methods, 281 .size = sizeof(struct axe_softc), 282}; 283 284static devclass_t axe_devclass; 285 286DRIVER_MODULE(axe, ushub, axe_driver, axe_devclass, NULL, 0); 287DRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0); | 229 230 {0, 0} 231}; 232 233static driver_t axe_driver = { 234 .name = "axe", 235 .methods = axe_methods, 236 .size = sizeof(struct axe_softc), 237}; 238 239static devclass_t axe_devclass; 240 241DRIVER_MODULE(axe, ushub, axe_driver, axe_devclass, NULL, 0); 242DRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0); |
243MODULE_DEPEND(axe, usb2_ethernet, 1, 1, 1); 244MODULE_DEPEND(axe, usb2_core, 1, 1, 1); 245MODULE_DEPEND(axe, ether, 1, 1, 1); 246MODULE_DEPEND(axe, miibus, 1, 1, 1); |
|
288 | 247 |
289static void 290axe_cfg_cmd(struct axe_softc *sc, uint16_t cmd, uint16_t index, 291 uint16_t val, void *buf) | 248static const struct usb2_ether_methods axe_ue_methods = { 249 .ue_attach_post = axe_attach_post, 250 .ue_start = axe_start, 251 .ue_init = axe_init, 252 .ue_stop = axe_stop, 253 .ue_tick = axe_tick, 254 .ue_setmulti = axe_setmulti, 255 .ue_setpromisc = axe_setpromisc, 256 .ue_mii_upd = axe_ifmedia_upd, 257 .ue_mii_sts = axe_ifmedia_sts, 258}; 259 260static int 261axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf) |
292{ 293 struct usb2_device_request req; 294 usb2_error_t err; | 262{ 263 struct usb2_device_request req; 264 usb2_error_t err; |
295 uint16_t length = AXE_CMD_LEN(cmd); | |
296 | 265 |
266 AXE_LOCK_ASSERT(sc, MA_OWNED); 267 |
|
297 req.bmRequestType = (AXE_CMD_IS_WRITE(cmd) ? 298 UT_WRITE_VENDOR_DEVICE : 299 UT_READ_VENDOR_DEVICE); 300 req.bRequest = AXE_CMD_CMD(cmd); 301 USETW(req.wValue, val); 302 USETW(req.wIndex, index); | 268 req.bmRequestType = (AXE_CMD_IS_WRITE(cmd) ? 269 UT_WRITE_VENDOR_DEVICE : 270 UT_READ_VENDOR_DEVICE); 271 req.bRequest = AXE_CMD_CMD(cmd); 272 USETW(req.wValue, val); 273 USETW(req.wIndex, index); |
303 USETW(req.wLength, length); | 274 USETW(req.wLength, AXE_CMD_LEN(cmd)); |
304 | 275 |
305 if (usb2_config_td_is_gone(&sc->sc_config_td)) { 306 goto error; 307 } 308 err = usb2_do_request_flags 309 (sc->sc_udev, &sc->sc_mtx, &req, buf, 0, NULL, 1000); | 276 err = usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000); |
310 | 277 |
311 if (err) { 312 313 DPRINTFN(0, "device request failed, err=%s " 314 "(ignored)\n", usb2_errstr(err)); 315 316error: 317 318 if ((req.bmRequestType & UT_READ) && length) { 319 bzero(buf, length); 320 } 321 } | 278 return (err); |
322} 323 324static int | 279} 280 281static int |
325axe_cfg_miibus_readreg(device_t dev, int phy, int reg) | 282axe_miibus_readreg(device_t dev, int phy, int reg) |
326{ 327 struct axe_softc *sc = device_get_softc(dev); 328 uint16_t val; | 283{ 284 struct axe_softc *sc = device_get_softc(dev); 285 uint16_t val; |
329 uint8_t do_unlock; | 286 int locked; |
330 | 287 |
331 /* avoid recursive locking */ 332 if (mtx_owned(&sc->sc_mtx)) { 333 do_unlock = 0; 334 } else { 335 mtx_lock(&sc->sc_mtx); 336 do_unlock = 1; 337 } | 288 if (sc->sc_phyno != phy) 289 return (0); |
338 | 290 |
339 if (sc->sc_phyno != phy) { 340 val = 0; 341 goto done; 342 } | 291 locked = mtx_owned(&sc->sc_mtx); 292 if (!locked) 293 AXE_LOCK(sc); |
343 | 294 |
344 axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 345 axe_cfg_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &val); 346 axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); | 295 axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 296 axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &val); 297 axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); |
347 348 val = le16toh(val); 349 if ((sc->sc_flags & AXE_FLAG_772) != 0 && reg == MII_BMSR) { 350 /* 351 * BMSR of AX88772 indicates that it supports extended 352 * capability but the extended status register is 353 * revered for embedded ethernet PHY. So clear the 354 * extended capability bit of BMSR. 355 */ 356 val &= ~BMSR_EXTCAP; 357 } 358 | 298 299 val = le16toh(val); 300 if ((sc->sc_flags & AXE_FLAG_772) != 0 && reg == MII_BMSR) { 301 /* 302 * BMSR of AX88772 indicates that it supports extended 303 * capability but the extended status register is 304 * revered for embedded ethernet PHY. So clear the 305 * extended capability bit of BMSR. 306 */ 307 val &= ~BMSR_EXTCAP; 308 } 309 |
359done: 360 if (do_unlock) { 361 mtx_unlock(&sc->sc_mtx); 362 } | 310 if (!locked) 311 AXE_UNLOCK(sc); |
363 return (val); 364} 365 366static int | 312 return (val); 313} 314 315static int |
367axe_cfg_miibus_writereg(device_t dev, int phy, int reg, int val) | 316axe_miibus_writereg(device_t dev, int phy, int reg, int val) |
368{ 369 struct axe_softc *sc = device_get_softc(dev); | 317{ 318 struct axe_softc *sc = device_get_softc(dev); |
370 uint8_t do_unlock; | 319 int locked; |
371 372 val = htole16(val); 373 | 320 321 val = htole16(val); 322 |
374 /* avoid recursive locking */ 375 if (mtx_owned(&sc->sc_mtx)) { 376 do_unlock = 0; 377 } else { 378 mtx_lock(&sc->sc_mtx); 379 do_unlock = 1; 380 } 381 | |
382 if (sc->sc_phyno != phy) | 323 if (sc->sc_phyno != phy) |
383 goto done; | 324 return (0); |
384 | 325 |
385 axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 386 axe_cfg_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val); 387 axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); | 326 locked = mtx_owned(&sc->sc_mtx); 327 if (!locked) 328 AXE_LOCK(sc); |
388 | 329 |
389done: 390 if (do_unlock) { 391 mtx_unlock(&sc->sc_mtx); 392 } | 330 axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 331 axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val); 332 axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); 333 334 if (!locked) 335 AXE_UNLOCK(sc); |
393 return (0); 394} 395 396static void | 336 return (0); 337} 338 339static void |
397axe_cfg_miibus_statchg(device_t dev) | 340axe_miibus_statchg(device_t dev) |
398{ 399 struct axe_softc *sc = device_get_softc(dev); 400 struct mii_data *mii = GET_MII(sc); | 341{ 342 struct axe_softc *sc = device_get_softc(dev); 343 struct mii_data *mii = GET_MII(sc); |
401 struct ifnet *ifp; | |
402 uint16_t val; | 344 uint16_t val; |
403 uint8_t do_unlock; | 345 int err, locked; |
404 | 346 |
405 /* avoid recursive locking */ 406 if (mtx_owned(&sc->sc_mtx)) { 407 do_unlock = 0; 408 } else { 409 mtx_lock(&sc->sc_mtx); 410 do_unlock = 1; 411 } | 347 locked = mtx_owned(&sc->sc_mtx); 348 if (!locked) 349 AXE_LOCK(sc); |
412 | 350 |
413 ifp = sc->sc_ifp; 414 if (mii == NULL || ifp == NULL || 415 (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 416 goto done; 417 418 sc->sc_flags &= ~AXE_FLAG_LINK; 419 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 420 (IFM_ACTIVE | IFM_AVALID)) { 421 switch (IFM_SUBTYPE(mii->mii_media_active)) { 422 case IFM_10_T: 423 case IFM_100_TX: 424 sc->sc_flags |= AXE_FLAG_LINK; 425 break; 426 case IFM_1000_T: 427 if ((sc->sc_flags & AXE_FLAG_178) == 0) 428 break; 429 sc->sc_flags |= AXE_FLAG_LINK; 430 break; 431 default: 432 break; 433 } 434 } 435 436 /* Lost link, do nothing. */ 437 if ((sc->sc_flags & AXE_FLAG_LINK) == 0) 438 goto done; 439 440 val = 0; 441 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) 442 val |= AXE_MEDIA_FULL_DUPLEX; | 351 val = (mii->mii_media_active & IFM_GMASK) == IFM_FDX ? 352 AXE_MEDIA_FULL_DUPLEX : 0; |
443 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) { 444 val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC; | 353 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) { 354 val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC; |
445 if ((sc->sc_flags & AXE_FLAG_178) != 0) 446 val |= AXE_178_MEDIA_ENCK; | 355 |
447 switch (IFM_SUBTYPE(mii->mii_media_active)) { 448 case IFM_1000_T: 449 val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK; 450 break; 451 case IFM_100_TX: 452 val |= AXE_178_MEDIA_100TX; 453 break; 454 case IFM_10_T: 455 /* doesn't need to be handled */ 456 break; 457 } 458 } | 356 switch (IFM_SUBTYPE(mii->mii_media_active)) { 357 case IFM_1000_T: 358 val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK; 359 break; 360 case IFM_100_TX: 361 val |= AXE_178_MEDIA_100TX; 362 break; 363 case IFM_10_T: 364 /* doesn't need to be handled */ 365 break; 366 } 367 } |
459 axe_cfg_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL); 460done: 461 if (do_unlock) { 462 mtx_unlock(&sc->sc_mtx); 463 } | 368 err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL); 369 if (err) 370 device_printf(dev, "media change failed, error %d\n", err); 371 372 if (!locked) 373 AXE_UNLOCK(sc); |
464} 465 466/* 467 * Set media options. 468 */ 469static int | 374} 375 376/* 377 * Set media options. 378 */ 379static int |
470axe_ifmedia_upd_cb(struct ifnet *ifp) | 380axe_ifmedia_upd(struct ifnet *ifp) |
471{ 472 struct axe_softc *sc = ifp->if_softc; | 381{ 382 struct axe_softc *sc = ifp->if_softc; |
473 474 mtx_lock(&sc->sc_mtx); 475 usb2_config_td_queue_command 476 (&sc->sc_config_td, NULL, &axe_cfg_ifmedia_upd, 0, 0); 477 mtx_unlock(&sc->sc_mtx); 478 479 return (0); 480} 481 482static void 483axe_cfg_ifmedia_upd(struct axe_softc *sc, 484 struct usb2_config_td_cc *cc, uint16_t refcount) 485{ 486 struct ifnet *ifp = sc->sc_ifp; | |
487 struct mii_data *mii = GET_MII(sc); 488 | 383 struct mii_data *mii = GET_MII(sc); 384 |
489 if ((ifp == NULL) || 490 (mii == NULL)) { 491 /* not ready */ 492 return; 493 } | 385 AXE_LOCK_ASSERT(sc, MA_OWNED); |
494 | 386 |
387 sc->sc_flags &= ~AXE_FLAG_LINK; |
|
495 if (mii->mii_instance) { 496 struct mii_softc *miisc; 497 | 388 if (mii->mii_instance) { 389 struct mii_softc *miisc; 390 |
498 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { | 391 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) |
499 mii_phy_reset(miisc); | 392 mii_phy_reset(miisc); |
500 } | |
501 } 502 mii_mediachg(mii); | 393 } 394 mii_mediachg(mii); |
395 return (0); |
|
503} 504 505/* 506 * Report current media status. 507 */ 508static void | 396} 397 398/* 399 * Report current media status. 400 */ 401static void |
509axe_ifmedia_sts_cb(struct ifnet *ifp, struct ifmediareq *ifmr) | 402axe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) |
510{ 511 struct axe_softc *sc = ifp->if_softc; | 403{ 404 struct axe_softc *sc = ifp->if_softc; |
405 struct mii_data *mii = GET_MII(sc); |
|
512 | 406 |
513 mtx_lock(&sc->sc_mtx); 514 ifmr->ifm_active = sc->sc_media_active; 515 ifmr->ifm_status = sc->sc_media_status; 516 mtx_unlock(&sc->sc_mtx); | 407 AXE_LOCK(sc); 408 mii_pollstat(mii); 409 AXE_UNLOCK(sc); 410 ifmr->ifm_active = mii->mii_media_active; 411 ifmr->ifm_status = mii->mii_media_status; |
517} 518 519static void | 412} 413 414static void |
520axe_mchash(struct usb2_config_td_cc *cc, const uint8_t *ptr) | 415axe_setmulti(struct usb2_ether *ue) |
521{ | 416{ |
522 uint8_t h; 523 524 h = (ether_crc32_be(ptr, ETHER_ADDR_LEN) >> 26); 525 cc->if_hash[(h >> 3)] |= (1 << (h & 7)); 526} 527 528static void 529axe_config_copy(struct axe_softc *sc, 530 struct usb2_config_td_cc *cc, uint16_t refcount) 531{ 532 bzero(cc, sizeof(*cc)); 533 usb2_ether_cc(sc->sc_ifp, &axe_mchash, cc); 534} 535 536static void 537axe_cfg_setmulti(struct axe_softc *sc, 538 struct usb2_config_td_cc *cc, uint16_t refcount) 539{ | 417 struct axe_softc *sc = usb2_ether_getsc(ue); 418 struct ifnet *ifp = usb2_ether_getifp(ue); 419 struct ifmultiaddr *ifma; 420 uint32_t h = 0; |
540 uint16_t rxmode; | 421 uint16_t rxmode; |
422 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
|
541 | 423 |
542 axe_cfg_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode); | 424 AXE_LOCK_ASSERT(sc, MA_OWNED); |
543 | 425 |
426 axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode); |
|
544 rxmode = le16toh(rxmode); 545 | 427 rxmode = le16toh(rxmode); 428 |
546 if (cc->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { | 429 if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { |
547 rxmode |= AXE_RXCMD_ALLMULTI; | 430 rxmode |= AXE_RXCMD_ALLMULTI; |
548 axe_cfg_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); | 431 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); |
549 return; 550 } 551 rxmode &= ~AXE_RXCMD_ALLMULTI; 552 | 432 return; 433 } 434 rxmode &= ~AXE_RXCMD_ALLMULTI; 435 |
553 axe_cfg_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, cc->if_hash); 554 axe_cfg_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 555} 556 557static void 558axe_cfg_reset(struct axe_softc *sc) 559{ 560 struct usb2_config_descriptor *cd; 561 usb2_error_t err; 562 563 cd = usb2_get_config_descriptor(sc->sc_udev); 564 565 err = usb2_req_set_config(sc->sc_udev, &sc->sc_mtx, 566 cd->bConfigurationValue); 567 if (err) { 568 DPRINTF("reset failed (ignored)\n"); | 436 IF_ADDR_LOCK(ifp); 437 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) 438 { 439 if (ifma->ifma_addr->sa_family != AF_LINK) 440 continue; 441 h = ether_crc32_be(LLADDR((struct sockaddr_dl *) 442 ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 443 hashtbl[h / 8] |= 1 << (h % 8); |
569 } | 444 } |
570 /* 571 * wait a little while for the chip to get its brains in order: 572 */ 573 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 100); | 445 IF_ADDR_UNLOCK(ifp); 446 447 axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl); 448 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); |
574} 575 576static int 577axe_get_phyno(struct axe_softc *sc, int sel) 578{ | 449} 450 451static int 452axe_get_phyno(struct axe_softc *sc, int sel) 453{ |
579 int phyno; | 454 int phyno; |
580 581 switch (AXE_PHY_TYPE(sc->sc_phyaddrs[sel])) { 582 case PHY_TYPE_100_HOME: 583 case PHY_TYPE_GIG: | 455 456 switch (AXE_PHY_TYPE(sc->sc_phyaddrs[sel])) { 457 case PHY_TYPE_100_HOME: 458 case PHY_TYPE_GIG: |
584 phyno = AXE_PHY_NO(sc->sc_phyaddrs[sel]); | 459 phyno = AXE_PHY_NO(sc->sc_phyaddrs[sel]); |
585 break; 586 case PHY_TYPE_SPECIAL: 587 /* FALLTHROUGH */ 588 case PHY_TYPE_RSVD: 589 /* FALLTHROUGH */ 590 case PHY_TYPE_NON_SUP: 591 /* FALLTHROUGH */ 592 default: 593 phyno = -1; 594 break; 595 } 596 597 return (phyno); 598} 599 | 460 break; 461 case PHY_TYPE_SPECIAL: 462 /* FALLTHROUGH */ 463 case PHY_TYPE_RSVD: 464 /* FALLTHROUGH */ 465 case PHY_TYPE_NON_SUP: 466 /* FALLTHROUGH */ 467 default: 468 phyno = -1; 469 break; 470 } 471 472 return (phyno); 473} 474 |
600/* 601 * Probe for a AX88172 chip. 602 */ 603static int 604axe_probe(device_t dev) 605{ 606 struct usb2_attach_arg *uaa = device_get_ivars(dev); 607 608 if (uaa->usb2_mode != USB_MODE_HOST) { 609 return (ENXIO); 610 } 611 if (uaa->info.bConfigIndex != AXE_CONFIG_IDX) { 612 return (ENXIO); 613 } 614 if (uaa->info.bIfaceIndex != AXE_IFACE_IDX) { 615 return (ENXIO); 616 } 617 return (usb2_lookup_id_by_uaa(axe_devs, sizeof(axe_devs), uaa)); 618} 619 620/* 621 * Attach the interface. Allocate softc structures, do ifmedia 622 * setup and ethernet/BPF attach. 623 */ 624static int 625axe_attach(device_t dev) 626{ 627 struct usb2_attach_arg *uaa = device_get_ivars(dev); 628 struct axe_softc *sc = device_get_softc(dev); 629 int32_t error; 630 uint8_t iface_index; 631 632 sc->sc_udev = uaa->device; 633 sc->sc_dev = dev; 634 sc->sc_unit = device_get_unit(dev); 635 sc->sc_flags = USB_GET_DRIVER_INFO(uaa); 636 637 device_set_usb2_desc(dev); 638 639 snprintf(sc->sc_name, sizeof(sc->sc_name), "%s", 640 device_get_nameunit(dev)); 641 642 mtx_init(&sc->sc_mtx, "axe lock", NULL, MTX_DEF | MTX_RECURSE); 643 644 usb2_callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); 645 646 iface_index = AXE_IFACE_IDX; 647 error = usb2_transfer_setup(uaa->device, &iface_index, 648 sc->sc_xfer, axe_config, AXE_N_TRANSFER, 649 sc, &sc->sc_mtx); 650 if (error) { 651 device_printf(dev, "allocating USB " 652 "transfers failed!\n"); 653 goto detach; 654 } 655 error = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_mtx, 656 NULL, sizeof(struct usb2_config_td_cc), 16); 657 if (error) { 658 device_printf(dev, "could not setup config " 659 "thread!\n"); 660 goto detach; 661 } 662 mtx_lock(&sc->sc_mtx); 663 664 /* start setup */ 665 666 usb2_config_td_queue_command 667 (&sc->sc_config_td, NULL, &axe_cfg_first_time_setup, 0, 0); 668 669 axe_watchdog(sc); 670 mtx_unlock(&sc->sc_mtx); 671 return (0); /* success */ 672 673detach: 674 axe_detach(dev); 675 return (ENXIO); /* failure */ 676} 677 | |
678static void | 475static void |
679axe_cfg_ax88178_init(struct axe_softc *sc) | 476axe_ax88178_init(struct axe_softc *sc) |
680{ | 477{ |
478 int gpio0 = 0, phymode = 0; |
|
681 uint16_t eeprom; | 479 uint16_t eeprom; |
682 uint16_t phymode; 683 uint16_t gpio0; 684 uint8_t err; | |
685 | 480 |
686 DPRINTF("\n"); 687 688 axe_cfg_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL); | 481 axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL); |
689 /* XXX magic */ | 482 /* XXX magic */ |
690 axe_cfg_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom); 691 axe_cfg_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL); 692 693 /* For big-endian machines: */ | 483 axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom); |
694 eeprom = le16toh(eeprom); | 484 eeprom = le16toh(eeprom); |
485 axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL); |
|
695 696 /* if EEPROM is invalid we have to use to GPIO0 */ 697 if (eeprom == 0xffff) { 698 phymode = 0; 699 gpio0 = 1; 700 } else { | 486 487 /* if EEPROM is invalid we have to use to GPIO0 */ 488 if (eeprom == 0xffff) { 489 phymode = 0; 490 gpio0 = 1; 491 } else { |
701 phymode = (eeprom & 7); | 492 phymode = eeprom & 7; |
702 gpio0 = (eeprom & 0x80) ? 0 : 1; 703 } 704 | 493 gpio0 = (eeprom & 0x80) ? 0 : 1; 494 } 495 |
705 axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL); 706 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 16); | 496 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL); 497 usb2_ether_pause(&sc->sc_ue, hz / 16); |
707 708 if ((eeprom >> 8) != 0x01) { | 498 499 if ((eeprom >> 8) != 0x01) { |
709 axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); 710 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 32); | 500 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); 501 usb2_ether_pause(&sc->sc_ue, hz / 32); |
711 | 502 |
712 axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL); 713 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 3); | 503 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL); 504 usb2_ether_pause(&sc->sc_ue, hz / 3); |
714 | 505 |
715 axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); 716 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 32); | 506 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); 507 usb2_ether_pause(&sc->sc_ue, hz / 32); |
717 } else { | 508 } else { |
718 axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL); 719 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 32); | 509 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL); 510 usb2_ether_pause(&sc->sc_ue, hz / 32); |
720 | 511 |
721 axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL); 722 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 32); | 512 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL); 513 usb2_ether_pause(&sc->sc_ue, hz / 32); |
723 } 724 725 /* soft reset */ | 514 } 515 516 /* soft reset */ |
726 axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); 727 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 4); | 517 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); 518 usb2_ether_pause(&sc->sc_ue, hz / 4); |
728 | 519 |
729 axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, | 520 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, |
730 AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL); | 521 AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL); |
731 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 4); | 522 usb2_ether_pause(&sc->sc_ue, hz / 4); |
732 /* Enable MII/GMII/RGMII interface to work with external PHY. */ | 523 /* Enable MII/GMII/RGMII interface to work with external PHY. */ |
733 axe_cfg_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL); 734 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 4); | 524 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL); 525 usb2_ether_pause(&sc->sc_ue, hz / 4); |
735 | 526 |
736 axe_cfg_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); | 527 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); |
737} 738 739static void | 528} 529 530static void |
740axe_cfg_ax88772_init(struct axe_softc *sc) | 531axe_ax88772_init(struct axe_softc *sc) |
741{ | 532{ |
742 uint8_t err; | 533 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL); 534 usb2_ether_pause(&sc->sc_ue, hz / 16); |
743 | 535 |
744 DPRINTF("\n"); 745 746 axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL); 747 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 16); 748 | |
749 if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) { 750 /* ask for the embedded PHY */ | 536 if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) { 537 /* ask for the embedded PHY */ |
751 axe_cfg_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL); 752 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 64); | 538 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL); 539 usb2_ether_pause(&sc->sc_ue, hz / 64); |
753 754 /* power down and reset state, pin reset state */ | 540 541 /* power down and reset state, pin reset state */ |
755 axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, | 542 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, |
756 AXE_SW_RESET_CLEAR, NULL); | 543 AXE_SW_RESET_CLEAR, NULL); |
757 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 16); | 544 usb2_ether_pause(&sc->sc_ue, hz / 16); |
758 759 /* power down/reset state, pin operating state */ | 545 546 /* power down/reset state, pin operating state */ |
760 axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, | 547 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, |
761 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); | 548 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); |
762 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 4); | 549 usb2_ether_pause(&sc->sc_ue, hz / 4); |
763 764 /* power up, reset */ | 550 551 /* power up, reset */ |
765 axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 766 AXE_SW_RESET_PRL, NULL); | 552 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL); |
767 768 /* power up, operating */ | 553 554 /* power up, operating */ |
769 axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, | 555 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, |
770 AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL); 771 } else { 772 /* ask for external PHY */ | 556 AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL); 557 } else { 558 /* ask for external PHY */ |
773 axe_cfg_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL); 774 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 64); | 559 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL); 560 usb2_ether_pause(&sc->sc_ue, hz / 64); |
775 776 /* power down internal PHY */ | 561 562 /* power down internal PHY */ |
777 axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, | 563 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, |
778 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); 779 } 780 | 564 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); 565 } 566 |
781 err = usb2_config_td_sleep(&sc->sc_config_td, hz / 4); 782 axe_cfg_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); | 567 usb2_ether_pause(&sc->sc_ue, hz / 4); 568 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); |
783} 784 785static void | 569} 570 571static void |
786axe_cfg_first_time_setup(struct axe_softc *sc, 787 struct usb2_config_td_cc *cc, uint16_t refcount) | 572axe_reset(struct axe_softc *sc) |
788{ | 573{ |
789 struct ifnet *ifp; 790 int error; 791 uint8_t eaddr[min(ETHER_ADDR_LEN, 6)]; | 574 struct usb2_config_descriptor *cd; 575 usb2_error_t err; |
792 | 576 |
793 /* set default value */ 794 bzero(eaddr, sizeof(eaddr)); | 577 cd = usb2_get_config_descriptor(sc->sc_ue.ue_udev); |
795 | 578 |
579 err = usb2_req_set_config(sc->sc_ue.ue_udev, &sc->sc_mtx, 580 cd->bConfigurationValue); 581 if (err) 582 DPRINTF("reset failed (ignored)\n"); 583 584 /* Wait a little while for the chip to get its brains in order. */ 585 usb2_ether_pause(&sc->sc_ue, hz / 100); 586} 587 588static void 589axe_attach_post(struct usb2_ether *ue) 590{ 591 struct axe_softc *sc = usb2_ether_getsc(ue); 592 |
|
796 /* 797 * Load PHY indexes first. Needed by axe_xxx_init(). 798 */ | 593 /* 594 * Load PHY indexes first. Needed by axe_xxx_init(). 595 */ |
799 axe_cfg_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs); | 596 axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs); |
800#if 1 | 597#if 1 |
801 device_printf(sc->sc_dev, "PHYADDR 0x%02x:0x%02x\n", | 598 device_printf(sc->sc_ue.ue_dev, "PHYADDR 0x%02x:0x%02x\n", |
802 sc->sc_phyaddrs[0], sc->sc_phyaddrs[1]); 803#endif 804 sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI); 805 if (sc->sc_phyno == -1) 806 sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC); 807 if (sc->sc_phyno == -1) { | 599 sc->sc_phyaddrs[0], sc->sc_phyaddrs[1]); 600#endif 601 sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI); 602 if (sc->sc_phyno == -1) 603 sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC); 604 if (sc->sc_phyno == -1) { |
808 device_printf(sc->sc_dev, 809 "no valid PHY address found, " 810 "assuming PHY address 0\n"); | 605 device_printf(sc->sc_ue.ue_dev, 606 "no valid PHY address found, assuming PHY address 0\n"); |
811 sc->sc_phyno = 0; 812 } 813 | 607 sc->sc_phyno = 0; 608 } 609 |
814 if (sc->sc_flags & AXE_FLAG_178) { 815 axe_cfg_ax88178_init(sc); 816 } else if (sc->sc_flags & AXE_FLAG_772) { 817 axe_cfg_ax88772_init(sc); 818 } | 610 if (sc->sc_flags & AXE_FLAG_178) 611 axe_ax88178_init(sc); 612 else if (sc->sc_flags & AXE_FLAG_772) 613 axe_ax88772_init(sc); 614 |
819 /* 820 * Get station address. 821 */ 822 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) | 615 /* 616 * Get station address. 617 */ 618 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) |
823 axe_cfg_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, eaddr); | 619 axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr); |
824 else | 620 else |
825 axe_cfg_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, eaddr); | 621 axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, ue->ue_eaddr); |
826 827 /* 828 * Fetch IPG values. 829 */ | 622 623 /* 624 * Fetch IPG values. 625 */ |
830 axe_cfg_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs); | 626 axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs); 627} |
831 | 628 |
832 mtx_unlock(&sc->sc_mtx); | 629/* 630 * Probe for a AX88172 chip. 631 */ 632static int 633axe_probe(device_t dev) 634{ 635 struct usb2_attach_arg *uaa = device_get_ivars(dev); |
833 | 636 |
834 ifp = if_alloc(IFT_ETHER); | 637 if (uaa->usb2_mode != USB_MODE_HOST) 638 return (ENXIO); 639 if (uaa->info.bConfigIndex != AXE_CONFIG_IDX) 640 return (ENXIO); 641 if (uaa->info.bIfaceIndex != AXE_IFACE_IDX) 642 return (ENXIO); |
835 | 643 |
836 mtx_lock(&sc->sc_mtx); | 644 return (usb2_lookup_id_by_uaa(axe_devs, sizeof(axe_devs), uaa)); 645} |
837 | 646 |
838 if (ifp == NULL) { 839 printf("%s: could not if_alloc()\n", 840 sc->sc_name); 841 goto done; 842 } | 647/* 648 * Attach the interface. Allocate softc structures, do ifmedia 649 * setup and ethernet/BPF attach. 650 */ 651static int 652axe_attach(device_t dev) 653{ 654 struct usb2_attach_arg *uaa = device_get_ivars(dev); 655 struct axe_softc *sc = device_get_softc(dev); 656 struct usb2_ether *ue = &sc->sc_ue; 657 uint8_t iface_index; 658 int error; |
843 | 659 |
844 ifp->if_softc = sc; 845 if_initname(ifp, "axe", sc->sc_unit); 846 ifp->if_mtu = ETHERMTU; 847 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 848 ifp->if_ioctl = axe_ioctl_cb; 849 ifp->if_start = axe_start_cb; 850 ifp->if_watchdog = NULL; 851 ifp->if_init = axe_init_cb; 852 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 853 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 854 IFQ_SET_READY(&ifp->if_snd); | 660 sc->sc_flags = USB_GET_DRIVER_INFO(uaa); |
855 | 661 |
856 /* 857 * XXX need Giant when accessing the device structures ! 858 */ | 662 device_set_usb2_desc(dev); |
859 | 663 |
860 mtx_unlock(&sc->sc_mtx); | 664 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); |
861 | 665 |
862 mtx_lock(&Giant); | 666 iface_index = AXE_IFACE_IDX; 667 error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, 668 axe_config, AXE_N_TRANSFER, sc, &sc->sc_mtx); 669 if (error) { 670 device_printf(dev, "allocating USB transfers failed!\n"); 671 goto detach; 672 } |
863 | 673 |
864 error = mii_phy_probe(sc->sc_dev, &sc->sc_miibus, 865 &axe_ifmedia_upd_cb, 866 &axe_ifmedia_sts_cb); 867 mtx_unlock(&Giant); | 674 ue->ue_sc = sc; 675 ue->ue_dev = dev; 676 ue->ue_udev = uaa->device; 677 ue->ue_mtx = &sc->sc_mtx; 678 ue->ue_methods = &axe_ue_methods; |
868 | 679 |
869 mtx_lock(&sc->sc_mtx); 870 | 680 error = usb2_ether_ifattach(ue); |
871 if (error) { | 681 if (error) { |
872 printf("%s: MII without any PHY!\n", 873 sc->sc_name); 874 if_free(ifp); 875 goto done; | 682 device_printf(dev, "could not attach interface\n"); 683 goto detach; |
876 } | 684 } |
877 sc->sc_ifp = ifp; | 685 return (0); /* success */ |
878 | 686 |
879 mtx_unlock(&sc->sc_mtx); 880 881 /* 882 * Call MI attach routine. 883 */ 884 885 ether_ifattach(ifp, eaddr); 886 887 mtx_lock(&sc->sc_mtx); 888 889done: 890 return; | 687detach: 688 axe_detach(dev); 689 return (ENXIO); /* failure */ |
891} 892 893static int 894axe_detach(device_t dev) 895{ 896 struct axe_softc *sc = device_get_softc(dev); | 690} 691 692static int 693axe_detach(device_t dev) 694{ 695 struct axe_softc *sc = device_get_softc(dev); |
897 struct ifnet *ifp; | 696 struct usb2_ether *ue = &sc->sc_ue; |
898 | 697 |
899 usb2_config_td_drain(&sc->sc_config_td); 900 901 mtx_lock(&sc->sc_mtx); 902 903 usb2_callout_stop(&sc->sc_watchdog); 904 905 axe_cfg_pre_stop(sc, NULL, 0); 906 907 ifp = sc->sc_ifp; 908 909 mtx_unlock(&sc->sc_mtx); 910 911 /* stop all USB transfers first */ | |
912 usb2_transfer_unsetup(sc->sc_xfer, AXE_N_TRANSFER); | 698 usb2_transfer_unsetup(sc->sc_xfer, AXE_N_TRANSFER); |
913 914 /* get rid of any late children */ 915 bus_generic_detach(dev); 916 917 if (ifp) { 918 ether_ifdetach(ifp); 919 if_free(ifp); 920 } 921 usb2_config_td_unsetup(&sc->sc_config_td); 922 923 usb2_callout_drain(&sc->sc_watchdog); 924 | 699 usb2_ether_ifdetach(ue); |
925 mtx_destroy(&sc->sc_mtx); 926 927 return (0); 928} 929 930static void | 700 mtx_destroy(&sc->sc_mtx); 701 702 return (0); 703} 704 705static void |
931axe_intr_clear_stall_callback(struct usb2_xfer *xfer) 932{ 933 struct axe_softc *sc = xfer->priv_sc; 934 struct usb2_xfer *xfer_other = sc->sc_xfer[AXE_INTR_DT_RD]; 935 936 if (usb2_clear_stall_callback(xfer, xfer_other)) { 937 DPRINTF("stall cleared\n"); 938 sc->sc_flags &= ~AXE_FLAG_INTR_STALL; 939 usb2_transfer_start(xfer_other); 940 } 941} 942 943static void | |
944axe_intr_callback(struct usb2_xfer *xfer) 945{ | 706axe_intr_callback(struct usb2_xfer *xfer) 707{ |
946 struct axe_softc *sc = xfer->priv_sc; 947 | |
948 switch (USB_GET_STATE(xfer)) { 949 case USB_ST_TRANSFERRED: | 708 switch (USB_GET_STATE(xfer)) { 709 case USB_ST_TRANSFERRED: |
950 951 /* do nothing */ 952 | |
953 case USB_ST_SETUP: | 710 case USB_ST_SETUP: |
954 if (sc->sc_flags & AXE_FLAG_INTR_STALL) { 955 usb2_transfer_start(sc->sc_xfer[AXE_INTR_CS_RD]); 956 } else { 957 xfer->frlengths[0] = xfer->max_data_length; 958 usb2_start_hardware(xfer); 959 } | 711tr_setup: 712 xfer->frlengths[0] = xfer->max_data_length; 713 usb2_start_hardware(xfer); |
960 return; 961 962 default: /* Error */ 963 if (xfer->error != USB_ERR_CANCELLED) { | 714 return; 715 716 default: /* Error */ 717 if (xfer->error != USB_ERR_CANCELLED) { |
964 /* start clear stall */ 965 sc->sc_flags |= AXE_FLAG_INTR_STALL; 966 usb2_transfer_start(sc->sc_xfer[AXE_INTR_CS_RD]); | 718 /* try to clear stall first */ 719 xfer->flags.stall_pipe = 1; 720 goto tr_setup; |
967 } 968 return; 969 } 970} 971 | 721 } 722 return; 723 } 724} 725 |
972static void 973axe_bulk_read_clear_stall_callback(struct usb2_xfer *xfer) 974{ 975 struct axe_softc *sc = xfer->priv_sc; 976 struct usb2_xfer *xfer_other = sc->sc_xfer[AXE_BULK_DT_RD]; 977 978 if (usb2_clear_stall_callback(xfer, xfer_other)) { 979 DPRINTF("stall cleared\n"); 980 sc->sc_flags &= ~AXE_FLAG_READ_STALL; 981 usb2_transfer_start(xfer_other); 982 } 983} 984 | |
985#if (AXE_BULK_BUF_SIZE >= 0x10000) 986#error "Please update axe_bulk_read_callback()!" 987#endif 988 989static void 990axe_bulk_read_callback(struct usb2_xfer *xfer) 991{ 992 struct axe_softc *sc = xfer->priv_sc; | 726#if (AXE_BULK_BUF_SIZE >= 0x10000) 727#error "Please update axe_bulk_read_callback()!" 728#endif 729 730static void 731axe_bulk_read_callback(struct usb2_xfer *xfer) 732{ 733 struct axe_softc *sc = xfer->priv_sc; |
734 struct usb2_ether *ue = &sc->sc_ue; 735 struct ifnet *ifp = usb2_ether_getifp(ue); |
|
993 struct axe_sframe_hdr hdr; | 736 struct axe_sframe_hdr hdr; |
994 struct ifnet *ifp = sc->sc_ifp; 995 struct mbuf *m; 996 struct { /* mini-queue */ 997 struct mbuf *ifq_head; 998 struct mbuf *ifq_tail; 999 uint16_t ifq_len; 1000 } mq = { 1001 NULL, NULL, 0 1002 }; 1003 uint16_t pos; 1004 uint16_t len; 1005 uint16_t adjust; | 737 int error, pos, len, adjust; |
1006 1007 switch (USB_GET_STATE(xfer)) { 1008 case USB_ST_TRANSFERRED: | 738 739 switch (USB_GET_STATE(xfer)) { 740 case USB_ST_TRANSFERRED: |
1009 | |
1010 pos = 0; | 741 pos = 0; |
1011 | |
1012 while (1) { | 742 while (1) { |
1013 | |
1014 if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) { | 743 if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) { |
1015 | |
1016 if (xfer->actlen < sizeof(hdr)) { 1017 /* too little data */ 1018 break; 1019 } 1020 usb2_copy_out(xfer->frbuffers, pos, &hdr, sizeof(hdr)); 1021 1022 if ((hdr.len ^ hdr.ilen) != 0xFFFF) { 1023 /* we lost sync */ --- 8 unchanged lines hidden (view full) --- 1032 break; 1033 } 1034 adjust = (len & 1); 1035 1036 } else { 1037 len = xfer->actlen; 1038 adjust = 0; 1039 } | 744 if (xfer->actlen < sizeof(hdr)) { 745 /* too little data */ 746 break; 747 } 748 usb2_copy_out(xfer->frbuffers, pos, &hdr, sizeof(hdr)); 749 750 if ((hdr.len ^ hdr.ilen) != 0xFFFF) { 751 /* we lost sync */ --- 8 unchanged lines hidden (view full) --- 760 break; 761 } 762 adjust = (len & 1); 763 764 } else { 765 len = xfer->actlen; 766 adjust = 0; 767 } |
1040 1041 if (len < sizeof(struct ether_header)) { 1042 ifp->if_ierrors++; 1043 goto skip; 1044 } 1045 m = usb2_ether_get_mbuf(); 1046 if (m == NULL) { 1047 /* we are out of memory */ | 768 error = usb2_ether_rxbuf(ue, xfer->frbuffers, pos, len); 769 if (error) |
1048 break; | 770 break; |
1049 } 1050 if (m->m_len > len) { 1051 m->m_len = len; 1052 } 1053 usb2_copy_out(xfer->frbuffers, pos, m->m_data, m->m_len); | |
1054 | 771 |
1055 ifp->if_ipackets++; 1056 m->m_pkthdr.rcvif = ifp; 1057 m->m_pkthdr.len = m->m_len; 1058 1059 /* enqueue */ 1060 _IF_ENQUEUE(&mq, m); 1061 1062 skip: 1063 | |
1064 pos += len; 1065 xfer->actlen -= len; 1066 1067 if (xfer->actlen <= adjust) { 1068 /* we are finished */ 1069 goto tr_setup; 1070 } 1071 pos += adjust; 1072 xfer->actlen -= adjust; 1073 } 1074 1075 /* count an error */ 1076 ifp->if_ierrors++; 1077 | 772 pos += len; 773 xfer->actlen -= len; 774 775 if (xfer->actlen <= adjust) { 776 /* we are finished */ 777 goto tr_setup; 778 } 779 pos += adjust; 780 xfer->actlen -= adjust; 781 } 782 783 /* count an error */ 784 ifp->if_ierrors++; 785 |
786 /* FALLTHROUGH */ |
|
1078 case USB_ST_SETUP: 1079tr_setup: | 787 case USB_ST_SETUP: 788tr_setup: |
1080 1081 if (sc->sc_flags & AXE_FLAG_READ_STALL) { 1082 usb2_transfer_start(sc->sc_xfer[AXE_BULK_CS_RD]); 1083 } else { 1084 xfer->frlengths[0] = xfer->max_data_length; 1085 usb2_start_hardware(xfer); 1086 } 1087 1088 /* 1089 * At the end of a USB callback it is always safe to unlock 1090 * the private mutex of a device! That is why we do the 1091 * "if_input" here, and not some lines up! 1092 */ 1093 if (mq.ifq_head) { 1094 1095 mtx_unlock(&sc->sc_mtx); 1096 1097 while (1) { 1098 1099 _IF_DEQUEUE(&mq, m); 1100 1101 if (m == NULL) 1102 break; 1103 1104 (ifp->if_input) (ifp, m); 1105 } 1106 1107 mtx_lock(&sc->sc_mtx); 1108 } | 789 xfer->frlengths[0] = xfer->max_data_length; 790 usb2_start_hardware(xfer); 791 usb2_ether_rxflush(ue); |
1109 return; 1110 1111 default: /* Error */ | 792 return; 793 794 default: /* Error */ |
795 DPRINTF("bulk read error, %s\n", 796 usb2_errstr(xfer->error)); 797 |
|
1112 if (xfer->error != USB_ERR_CANCELLED) { 1113 /* try to clear stall first */ | 798 if (xfer->error != USB_ERR_CANCELLED) { 799 /* try to clear stall first */ |
1114 sc->sc_flags |= AXE_FLAG_READ_STALL; 1115 usb2_transfer_start(sc->sc_xfer[AXE_BULK_CS_RD]); | 800 xfer->flags.stall_pipe = 1; 801 goto tr_setup; |
1116 } | 802 } |
1117 DPRINTF("bulk read error, %s\n", 1118 usb2_errstr(xfer->error)); | |
1119 return; 1120 1121 } 1122} 1123 | 803 return; 804 805 } 806} 807 |
1124static void 1125axe_bulk_write_clear_stall_callback(struct usb2_xfer *xfer) 1126{ 1127 struct axe_softc *sc = xfer->priv_sc; 1128 struct usb2_xfer *xfer_other = sc->sc_xfer[AXE_BULK_DT_WR]; 1129 1130 if (usb2_clear_stall_callback(xfer, xfer_other)) { 1131 DPRINTF("stall cleared\n"); 1132 sc->sc_flags &= ~AXE_FLAG_WRITE_STALL; 1133 usb2_transfer_start(xfer_other); 1134 } 1135} 1136 | |
1137#if ((AXE_BULK_BUF_SIZE >= 0x10000) || (AXE_BULK_BUF_SIZE < (MCLBYTES+4))) 1138#error "Please update axe_bulk_write_callback()!" 1139#endif 1140 1141static void 1142axe_bulk_write_callback(struct usb2_xfer *xfer) 1143{ 1144 struct axe_softc *sc = xfer->priv_sc; 1145 struct axe_sframe_hdr hdr; | 808#if ((AXE_BULK_BUF_SIZE >= 0x10000) || (AXE_BULK_BUF_SIZE < (MCLBYTES+4))) 809#error "Please update axe_bulk_write_callback()!" 810#endif 811 812static void 813axe_bulk_write_callback(struct usb2_xfer *xfer) 814{ 815 struct axe_softc *sc = xfer->priv_sc; 816 struct axe_sframe_hdr hdr; |
1146 struct ifnet *ifp = sc->sc_ifp; | 817 struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue); |
1147 struct mbuf *m; | 818 struct mbuf *m; |
1148 uint16_t pos; | 819 int pos; |
1149 1150 switch (USB_GET_STATE(xfer)) { 1151 case USB_ST_TRANSFERRED: 1152 DPRINTFN(11, "transfer complete\n"); | 820 821 switch (USB_GET_STATE(xfer)) { 822 case USB_ST_TRANSFERRED: 823 DPRINTFN(11, "transfer complete\n"); |
1153 | |
1154 ifp->if_opackets++; | 824 ifp->if_opackets++; |
1155 | 825 /* FALLTHROUGH */ |
1156 case USB_ST_SETUP: | 826 case USB_ST_SETUP: |
1157 1158 if (sc->sc_flags & AXE_FLAG_WRITE_STALL) { 1159 usb2_transfer_start(sc->sc_xfer[AXE_BULK_CS_WR]); 1160 goto done; 1161 } | 827tr_setup: |
1162 if ((sc->sc_flags & AXE_FLAG_LINK) == 0) { 1163 /* 1164 * don't send anything if there is no link ! 1165 */ | 828 if ((sc->sc_flags & AXE_FLAG_LINK) == 0) { 829 /* 830 * don't send anything if there is no link ! 831 */ |
1166 goto done; | 832 return; |
1167 } 1168 pos = 0; 1169 1170 while (1) { 1171 1172 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1173 1174 if (m == NULL) { 1175 if (pos > 0) 1176 break; /* send out data */ | 833 } 834 pos = 0; 835 836 while (1) { 837 838 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 839 840 if (m == NULL) { 841 if (pos > 0) 842 break; /* send out data */ |
1177 else 1178 goto done; | 843 return; |
1179 } 1180 if (m->m_pkthdr.len > MCLBYTES) { 1181 m->m_pkthdr.len = MCLBYTES; 1182 } 1183 if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) { 1184 1185 hdr.len = htole16(m->m_pkthdr.len); 1186 hdr.ilen = ~hdr.len; --- 11 unchanged lines hidden (view full) --- 1198 */ 1199 } 1200 usb2_m_copy_in(xfer->frbuffers, pos, 1201 m, 0, m->m_pkthdr.len); 1202 1203 pos += m->m_pkthdr.len; 1204 1205 /* | 844 } 845 if (m->m_pkthdr.len > MCLBYTES) { 846 m->m_pkthdr.len = MCLBYTES; 847 } 848 if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) { 849 850 hdr.len = htole16(m->m_pkthdr.len); 851 hdr.ilen = ~hdr.len; --- 11 unchanged lines hidden (view full) --- 863 */ 864 } 865 usb2_m_copy_in(xfer->frbuffers, pos, 866 m, 0, m->m_pkthdr.len); 867 868 pos += m->m_pkthdr.len; 869 870 /* |
1206 * if there's a BPF listener, bounce a copy 1207 * of this frame to him: 1208 */ | 871 * if there's a BPF listener, bounce a copy 872 * of this frame to him: 873 */ |
1209 BPF_MTAP(ifp, m); 1210 1211 m_freem(m); 1212 1213 if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) { 1214 if (pos > (AXE_BULK_BUF_SIZE - MCLBYTES - sizeof(hdr))) { 1215 /* send out frame(s) */ 1216 break; 1217 } 1218 } else { 1219 /* send out frame */ 1220 break; 1221 } 1222 } 1223 1224 xfer->frlengths[0] = pos; 1225 usb2_start_hardware(xfer); | 874 BPF_MTAP(ifp, m); 875 876 m_freem(m); 877 878 if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) { 879 if (pos > (AXE_BULK_BUF_SIZE - MCLBYTES - sizeof(hdr))) { 880 /* send out frame(s) */ 881 break; 882 } 883 } else { 884 /* send out frame */ 885 break; 886 } 887 } 888 889 xfer->frlengths[0] = pos; 890 usb2_start_hardware(xfer); |
1226 1227done: | |
1228 return; 1229 1230 default: /* Error */ 1231 DPRINTFN(11, "transfer error, %s\n", 1232 usb2_errstr(xfer->error)); 1233 | 891 return; 892 893 default: /* Error */ 894 DPRINTFN(11, "transfer error, %s\n", 895 usb2_errstr(xfer->error)); 896 |
897 ifp->if_oerrors++; 898 |
|
1234 if (xfer->error != USB_ERR_CANCELLED) { 1235 /* try to clear stall first */ | 899 if (xfer->error != USB_ERR_CANCELLED) { 900 /* try to clear stall first */ |
1236 sc->sc_flags |= AXE_FLAG_WRITE_STALL; 1237 usb2_transfer_start(sc->sc_xfer[AXE_BULK_CS_WR]); | 901 xfer->flags.stall_pipe = 1; 902 goto tr_setup; |
1238 } | 903 } |
1239 ifp->if_oerrors++; | |
1240 return; 1241 1242 } 1243} 1244 1245static void | 904 return; 905 906 } 907} 908 909static void |
1246axe_cfg_tick(struct axe_softc *sc, 1247 struct usb2_config_td_cc *cc, uint16_t refcount) | 910axe_tick(struct usb2_ether *ue) |
1248{ | 911{ |
1249 struct ifnet *ifp = sc->sc_ifp; | 912 struct axe_softc *sc = usb2_ether_getsc(ue); |
1250 struct mii_data *mii = GET_MII(sc); 1251 | 913 struct mii_data *mii = GET_MII(sc); 914 |
1252 if ((ifp == NULL) || 1253 (mii == NULL)) { 1254 /* not ready */ 1255 return; 1256 } | 915 AXE_LOCK_ASSERT(sc, MA_OWNED); 916 |
1257 mii_tick(mii); | 917 mii_tick(mii); |
1258 sc->sc_media_active = mii->mii_media_active; 1259 sc->sc_media_status = mii->mii_media_status; 1260 if ((sc->sc_flags & AXE_FLAG_LINK) == 0) { 1261 axe_cfg_miibus_statchg(sc->sc_dev); 1262 /* XXX */ 1263 if ((sc->sc_flags & AXE_FLAG_LINK) == 0) { 1264 sc->sc_media_active = IFM_ETHER | IFM_NONE; 1265 sc->sc_media_status = IFM_AVALID; 1266 } | 918 if ((sc->sc_flags & AXE_FLAG_LINK) == 0 919 && mii->mii_media_status & IFM_ACTIVE && 920 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 921 sc->sc_flags |= AXE_FLAG_LINK; 922 axe_start(ue); |
1267 } | 923 } |
1268 /* start stopped transfers, if any */ 1269 axe_start_transfers(sc); | |
1270} 1271 1272static void | 924} 925 926static void |
1273axe_start_cb(struct ifnet *ifp) | 927axe_start(struct usb2_ether *ue) |
1274{ | 928{ |
1275 struct axe_softc *sc = ifp->if_softc; | 929 struct axe_softc *sc = usb2_ether_getsc(ue); |
1276 | 930 |
1277 mtx_lock(&sc->sc_mtx); 1278 1279 axe_start_transfers(sc); 1280 1281 mtx_unlock(&sc->sc_mtx); | 931 /* 932 * start the USB transfers, if not already started: 933 */ 934 usb2_transfer_start(sc->sc_xfer[AXE_INTR_DT_RD]); 935 usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_RD]); 936 usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_WR]); |
1282} 1283 1284static void | 937} 938 939static void |
1285axe_start_transfers(struct axe_softc *sc) | 940axe_init(struct usb2_ether *ue) |
1286{ | 941{ |
1287 if ((sc->sc_flags & AXE_FLAG_LL_READY) && 1288 (sc->sc_flags & AXE_FLAG_HL_READY)) { 1289 1290 /* 1291 * start the USB transfers, if not already started: 1292 */ 1293 usb2_transfer_start(sc->sc_xfer[AXE_INTR_DT_RD]); 1294 usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_RD]); 1295 usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_WR]); 1296 } 1297} 1298 1299static void 1300axe_init_cb(void *arg) 1301{ 1302 struct axe_softc *sc = arg; 1303 1304 mtx_lock(&sc->sc_mtx); 1305 usb2_config_td_queue_command 1306 (&sc->sc_config_td, &axe_cfg_pre_init, &axe_cfg_init, 0, 0); 1307 mtx_unlock(&sc->sc_mtx); 1308} 1309 1310static void 1311axe_cfg_pre_init(struct axe_softc *sc, 1312 struct usb2_config_td_cc *cc, uint16_t refcount) 1313{ 1314 struct ifnet *ifp = sc->sc_ifp; 1315 1316 /* immediate configuration */ 1317 1318 axe_cfg_pre_stop(sc, cc, 0); 1319 1320 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1321 1322 sc->sc_flags |= AXE_FLAG_HL_READY; 1323} 1324 1325static void 1326axe_cfg_init(struct axe_softc *sc, 1327 struct usb2_config_td_cc *cc, uint16_t refcount) 1328{ 1329 struct mii_data *mii = GET_MII(sc); | 942 struct axe_softc *sc = usb2_ether_getsc(ue); 943 struct ifnet *ifp = usb2_ether_getifp(ue); |
1330 uint16_t rxmode; 1331 | 944 uint16_t rxmode; 945 |
1332 /* 1333 * Cancel pending I/O 1334 */ | 946 AXE_LOCK_ASSERT(sc, MA_OWNED); |
1335 | 947 |
1336 axe_cfg_stop(sc, cc, 0); | 948 /* Cancel pending I/O */ 949 axe_stop(ue); |
1337 | 950 |
1338#if 0 | 951#ifdef notdef |
1339 /* Set MAC address */ | 952 /* Set MAC address */ |
1340 axe_mac(sc, cc->if_lladdr); | 953 axe_mac(sc, IF_LLADDR(ifp), 1); |
1341#endif 1342 1343 /* Set transmitter IPG values */ 1344 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) { | 954#endif 955 956 /* Set transmitter IPG values */ 957 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) { |
1345 axe_cfg_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->sc_ipgs[2], | 958 axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->sc_ipgs[2], |
1346 (sc->sc_ipgs[1] << 8) | (sc->sc_ipgs[0]), NULL); 1347 } else { | 959 (sc->sc_ipgs[1] << 8) | (sc->sc_ipgs[0]), NULL); 960 } else { |
1348 axe_cfg_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->sc_ipgs[0], NULL); 1349 axe_cfg_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->sc_ipgs[1], NULL); 1350 axe_cfg_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->sc_ipgs[2], NULL); | 961 axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->sc_ipgs[0], NULL); 962 axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->sc_ipgs[1], NULL); 963 axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->sc_ipgs[2], NULL); |
1351 } 1352 1353 /* Enable receiver, set RX mode */ 1354 rxmode = (AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE); 1355 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) { 1356 rxmode |= AXE_178_RXCMD_MFB_2048; /* chip default */ 1357 } else { 1358 rxmode |= AXE_172_RXCMD_UNICAST; 1359 } 1360 1361 /* If we want promiscuous mode, set the allframes bit. */ | 964 } 965 966 /* Enable receiver, set RX mode */ 967 rxmode = (AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE); 968 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) { 969 rxmode |= AXE_178_RXCMD_MFB_2048; /* chip default */ 970 } else { 971 rxmode |= AXE_172_RXCMD_UNICAST; 972 } 973 974 /* If we want promiscuous mode, set the allframes bit. */ |
1362 if (cc->if_flags & IFF_PROMISC) { | 975 if (ifp->if_flags & IFF_PROMISC) |
1363 rxmode |= AXE_RXCMD_PROMISC; | 976 rxmode |= AXE_RXCMD_PROMISC; |
1364 } 1365 if (cc->if_flags & IFF_BROADCAST) { | 977 978 if (ifp->if_flags & IFF_BROADCAST) |
1366 rxmode |= AXE_RXCMD_BROADCAST; | 979 rxmode |= AXE_RXCMD_BROADCAST; |
1367 } 1368 axe_cfg_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); | |
1369 | 980 |
981 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 982 |
|
1370 /* Load the multicast filter. */ | 983 /* Load the multicast filter. */ |
1371 axe_cfg_setmulti(sc, cc, 0); | 984 axe_setmulti(ue); |
1372 | 985 |
1373 mii_mediachg(mii); | 986 usb2_transfer_set_stall(sc->sc_xfer[AXE_BULK_DT_WR]); |
1374 | 987 |
1375 sc->sc_flags |= (AXE_FLAG_READ_STALL | 1376 AXE_FLAG_WRITE_STALL | 1377 AXE_FLAG_LL_READY); 1378 1379 axe_start_transfers(sc); | 988 ifp->if_drv_flags |= IFF_DRV_RUNNING; 989 axe_start(ue); |
1380} 1381 1382static void | 990} 991 992static void |
1383axe_cfg_promisc_upd(struct axe_softc *sc, 1384 struct usb2_config_td_cc *cc, uint16_t refcount) | 993axe_setpromisc(struct usb2_ether *ue) |
1385{ | 994{ |
995 struct axe_softc *sc = usb2_ether_getsc(ue); 996 struct ifnet *ifp = usb2_ether_getifp(ue); |
|
1386 uint16_t rxmode; 1387 | 997 uint16_t rxmode; 998 |
1388 axe_cfg_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode); | 999 axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode); |
1389 1390 rxmode = le16toh(rxmode); 1391 | 1000 1001 rxmode = le16toh(rxmode); 1002 |
1392 if (cc->if_flags & IFF_PROMISC) { | 1003 if (ifp->if_flags & IFF_PROMISC) { |
1393 rxmode |= AXE_RXCMD_PROMISC; 1394 } else { 1395 rxmode &= ~AXE_RXCMD_PROMISC; 1396 } 1397 | 1004 rxmode |= AXE_RXCMD_PROMISC; 1005 } else { 1006 rxmode &= ~AXE_RXCMD_PROMISC; 1007 } 1008 |
1398 axe_cfg_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); | 1009 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); |
1399 | 1010 |
1400 axe_cfg_setmulti(sc, cc, 0); | 1011 axe_setmulti(ue); |
1401} 1402 | 1012} 1013 |
1403static int 1404axe_ioctl_cb(struct ifnet *ifp, u_long command, caddr_t data) 1405{ 1406 struct axe_softc *sc = ifp->if_softc; 1407 struct mii_data *mii; 1408 int error = 0; 1409 1410 switch (command) { 1411 case SIOCSIFFLAGS: 1412 mtx_lock(&sc->sc_mtx); 1413 if (ifp->if_flags & IFF_UP) { 1414 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1415 usb2_config_td_queue_command 1416 (&sc->sc_config_td, &axe_config_copy, 1417 &axe_cfg_promisc_upd, 0, 0); 1418 } else { 1419 usb2_config_td_queue_command 1420 (&sc->sc_config_td, &axe_cfg_pre_init, 1421 &axe_cfg_init, 0, 0); 1422 } 1423 } else { 1424 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1425 usb2_config_td_queue_command 1426 (&sc->sc_config_td, &axe_cfg_pre_stop, 1427 &axe_cfg_stop, 0, 0); 1428 } 1429 } 1430 mtx_unlock(&sc->sc_mtx); 1431 break; 1432 1433 case SIOCADDMULTI: 1434 case SIOCDELMULTI: 1435 mtx_lock(&sc->sc_mtx); 1436 usb2_config_td_queue_command 1437 (&sc->sc_config_td, &axe_config_copy, 1438 &axe_cfg_setmulti, 0, 0); 1439 mtx_unlock(&sc->sc_mtx); 1440 break; 1441 1442 case SIOCGIFMEDIA: 1443 case SIOCSIFMEDIA: 1444 mii = GET_MII(sc); 1445 if (mii == NULL) { 1446 error = EINVAL; 1447 } else { 1448 error = ifmedia_ioctl 1449 (ifp, (void *)data, &mii->mii_media, command); 1450 } 1451 break; 1452 1453 default: 1454 error = ether_ioctl(ifp, command, data); 1455 break; 1456 } 1457 return (error); 1458} 1459 | |
1460static void | 1014static void |
1461axe_watchdog(void *arg) | 1015axe_stop(struct usb2_ether *ue) |
1462{ | 1016{ |
1463 struct axe_softc *sc = arg; | 1017 struct axe_softc *sc = usb2_ether_getsc(ue); 1018 struct ifnet *ifp = usb2_ether_getifp(ue); |
1464 | 1019 |
1465 mtx_assert(&sc->sc_mtx, MA_OWNED); | 1020 AXE_LOCK_ASSERT(sc, MA_OWNED); |
1466 | 1021 |
1467 usb2_config_td_queue_command 1468 (&sc->sc_config_td, NULL, &axe_cfg_tick, 0, 0); 1469 1470 usb2_callout_reset(&sc->sc_watchdog, 1471 hz, &axe_watchdog, sc); 1472} 1473 1474/* 1475 * NOTE: can be called when "ifp" is NULL 1476 */ 1477static void 1478axe_cfg_pre_stop(struct axe_softc *sc, 1479 struct usb2_config_td_cc *cc, uint16_t refcount) 1480{ 1481 struct ifnet *ifp = sc->sc_ifp; 1482 1483 if (cc) { 1484 /* copy the needed configuration */ 1485 axe_config_copy(sc, cc, refcount); 1486 } 1487 /* immediate configuration */ 1488 1489 if (ifp) { 1490 /* clear flags */ 1491 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1492 } 1493 sc->sc_flags &= ~(AXE_FLAG_HL_READY | 1494 AXE_FLAG_LL_READY); 1495 | 1022 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; |
1496 sc->sc_flags &= ~AXE_FLAG_LINK; 1497 1498 /* 1499 * stop all the transfers, if not already stopped: 1500 */ 1501 usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_WR]); 1502 usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_RD]); | 1023 sc->sc_flags &= ~AXE_FLAG_LINK; 1024 1025 /* 1026 * stop all the transfers, if not already stopped: 1027 */ 1028 usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_WR]); 1029 usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_RD]); |
1503 usb2_transfer_stop(sc->sc_xfer[AXE_BULK_CS_WR]); 1504 usb2_transfer_stop(sc->sc_xfer[AXE_BULK_CS_RD]); | |
1505 usb2_transfer_stop(sc->sc_xfer[AXE_INTR_DT_RD]); | 1030 usb2_transfer_stop(sc->sc_xfer[AXE_INTR_DT_RD]); |
1506 usb2_transfer_stop(sc->sc_xfer[AXE_INTR_CS_RD]); 1507} | |
1508 | 1031 |
1509static void 1510axe_cfg_stop(struct axe_softc *sc, 1511 struct usb2_config_td_cc *cc, uint16_t refcount) 1512{ 1513 axe_cfg_reset(sc); | 1032 axe_reset(sc); |
1514} 1515 1516/* 1517 * Stop all chip I/O so that the kernel's probe routines don't 1518 * get confused by errant DMAs when rebooting. 1519 */ 1520static int 1521axe_shutdown(device_t dev) 1522{ 1523 struct axe_softc *sc = device_get_softc(dev); 1524 | 1033} 1034 1035/* 1036 * Stop all chip I/O so that the kernel's probe routines don't 1037 * get confused by errant DMAs when rebooting. 1038 */ 1039static int 1040axe_shutdown(device_t dev) 1041{ 1042 struct axe_softc *sc = device_get_softc(dev); 1043 |
1525 mtx_lock(&sc->sc_mtx); | 1044 usb2_ether_ifshutdown(&sc->sc_ue); |
1526 | 1045 |
1527 usb2_config_td_queue_command 1528 (&sc->sc_config_td, &axe_cfg_pre_stop, 1529 &axe_cfg_stop, 0, 0); 1530 1531 mtx_unlock(&sc->sc_mtx); 1532 | |
1533 return (0); 1534} | 1046 return (0); 1047} |