version 1.42, 2019/06/18 09:34:57 |
version 1.43, 2019/06/20 10:46:24 |
Line 112 struct axen_softc { |
|
Line 112 struct axen_softc { |
|
|
|
struct usb_task axen_tick_task; |
struct usb_task axen_tick_task; |
|
|
krwlock_t axen_mii_lock; |
kmutex_t axen_mii_lock; |
|
|
int axen_link; |
int axen_link; |
|
|
Line 178 static int axen_cmd(struct axen_softc *, |
|
Line 178 static int axen_cmd(struct axen_softc *, |
|
static int axen_ifmedia_upd(struct ifnet *); |
static int axen_ifmedia_upd(struct ifnet *); |
static void axen_ifmedia_sts(struct ifnet *, struct ifmediareq *); |
static void axen_ifmedia_sts(struct ifnet *, struct ifmediareq *); |
static void axen_reset(struct axen_softc *); |
static void axen_reset(struct axen_softc *); |
#if 0 |
static int axen_get_eaddr(struct axen_softc *, void *); |
static int axen_ax88179_eeprom(struct axen_softc *, void *); |
|
#endif |
|
|
|
static void axen_iff(struct axen_softc *); |
static void axen_iff(struct axen_softc *); |
static void axen_lock_mii(struct axen_softc *); |
|
static void axen_unlock_mii(struct axen_softc *); |
|
|
|
static void axen_ax88179_init(struct axen_softc *); |
static void axen_ax88179_init(struct axen_softc *); |
static void axen_setcoe(struct axen_softc *); |
static void axen_setcoe(struct axen_softc *); |
|
|
Line 195 axen_lock_mii(struct axen_softc *sc) |
|
Line 189 axen_lock_mii(struct axen_softc *sc) |
|
{ |
{ |
|
|
sc->axen_refcnt++; |
sc->axen_refcnt++; |
rw_enter(&sc->axen_mii_lock, RW_WRITER); |
mutex_enter(&sc->axen_mii_lock); |
} |
} |
|
|
static void |
static void |
axen_unlock_mii(struct axen_softc *sc) |
axen_unlock_mii(struct axen_softc *sc) |
{ |
{ |
|
|
rw_exit(&sc->axen_mii_lock); |
mutex_exit(&sc->axen_mii_lock); |
if (--sc->axen_refcnt < 0) |
if (--sc->axen_refcnt < 0) |
usb_detach_wakeupold(sc->axen_dev); |
usb_detach_wakeupold(sc->axen_dev); |
} |
} |
Line 213 axen_cmd(struct axen_softc *sc, int cmd, |
|
Line 207 axen_cmd(struct axen_softc *sc, int cmd, |
|
usb_device_request_t req; |
usb_device_request_t req; |
usbd_status err; |
usbd_status err; |
|
|
KASSERT(rw_lock_held(&sc->axen_mii_lock)); |
KASSERT(mutex_owned(&sc->axen_mii_lock)); |
|
|
if (sc->axen_dying) |
if (sc->axen_dying) |
return 0; |
return 0; |
Line 232 axen_cmd(struct axen_softc *sc, int cmd, |
|
Line 226 axen_cmd(struct axen_softc *sc, int cmd, |
|
cmd, val, AXEN_CMD_LEN(cmd))); |
cmd, val, AXEN_CMD_LEN(cmd))); |
|
|
if (err) { |
if (err) { |
DPRINTF(("axen_cmd err: cmd: %d, error: %d\n", cmd, err)); |
DPRINTF(("%s: cmd: %d, error: %d\n", __func__, cmd, err)); |
return -1; |
return -1; |
} |
} |
|
|
Line 242 axen_cmd(struct axen_softc *sc, int cmd, |
|
Line 236 axen_cmd(struct axen_softc *sc, int cmd, |
|
static int |
static int |
axen_miibus_readreg(device_t dev, int phy, int reg, uint16_t *val) |
axen_miibus_readreg(device_t dev, int phy, int reg, uint16_t *val) |
{ |
{ |
struct axen_softc *sc = device_private(dev); |
struct axen_softc * const sc = device_private(dev); |
usbd_status err; |
usbd_status err; |
uint16_t data; |
uint16_t data; |
|
|
Line 259 axen_miibus_readreg(device_t dev, int ph |
|
Line 253 axen_miibus_readreg(device_t dev, int ph |
|
axen_unlock_mii(sc); |
axen_unlock_mii(sc); |
|
|
if (err) { |
if (err) { |
aprint_error_dev(sc->axen_dev, "read PHY failed\n"); |
aprint_error_dev(sc->axen_dev, "read PHY failed: %d\n", err); |
return err; |
return err; |
} |
} |
|
|
Line 277 axen_miibus_readreg(device_t dev, int ph |
|
Line 271 axen_miibus_readreg(device_t dev, int ph |
|
static int |
static int |
axen_miibus_writereg(device_t dev, int phy, int reg, uint16_t val) |
axen_miibus_writereg(device_t dev, int phy, int reg, uint16_t val) |
{ |
{ |
struct axen_softc *sc = device_private(dev); |
struct axen_softc * const sc = device_private(dev); |
usbd_status err; |
usbd_status err; |
uint16_t uval; |
uint16_t uval; |
|
|
Line 291 axen_miibus_writereg(device_t dev, int p |
|
Line 285 axen_miibus_writereg(device_t dev, int p |
|
axen_lock_mii(sc); |
axen_lock_mii(sc); |
err = axen_cmd(sc, AXEN_CMD_MII_WRITE_REG, reg, phy, &uval); |
err = axen_cmd(sc, AXEN_CMD_MII_WRITE_REG, reg, phy, &uval); |
axen_unlock_mii(sc); |
axen_unlock_mii(sc); |
|
|
DPRINTFN(2, ("axen_miibus_writereg: phy 0x%x reg 0x%x val 0x%04hx\n", |
DPRINTFN(2, ("axen_miibus_writereg: phy 0x%x reg 0x%x val 0x%04hx\n", |
phy, reg, val)); |
phy, reg, val)); |
|
|
if (err) { |
if (err) { |
aprint_error_dev(sc->axen_dev, "write PHY failed\n"); |
aprint_error_dev(sc->axen_dev, "write PHY failed: %d\n", err); |
return err; |
return err; |
} |
} |
|
|
Line 305 axen_miibus_writereg(device_t dev, int p |
|
Line 300 axen_miibus_writereg(device_t dev, int p |
|
static void |
static void |
axen_miibus_statchg(struct ifnet *ifp) |
axen_miibus_statchg(struct ifnet *ifp) |
{ |
{ |
struct axen_softc *sc = ifp->if_softc; |
struct axen_softc * const sc = ifp->if_softc; |
struct mii_data *mii = GET_MII(sc); |
struct mii_data *mii = GET_MII(sc); |
int err; |
int err; |
uint16_t val; |
uint16_t val; |
uint16_t wval; |
uint16_t wval; |
|
|
|
if (sc->axen_dying) |
|
return; |
|
|
sc->axen_link = 0; |
sc->axen_link = 0; |
if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == |
if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == |
(IFM_ACTIVE | IFM_AVALID)) { |
(IFM_ACTIVE | IFM_AVALID)) { |
Line 349 axen_miibus_statchg(struct ifnet *ifp) |
|
Line 347 axen_miibus_statchg(struct ifnet *ifp) |
|
break; |
break; |
} |
} |
|
|
DPRINTF(("axen_miibus_statchg: val=0x%x\n", val)); |
DPRINTF(("%s: val=0x%x\n", __func__, val)); |
wval = htole16(val); |
wval = htole16(val); |
axen_lock_mii(sc); |
axen_lock_mii(sc); |
err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval); |
err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval); |
Line 366 axen_miibus_statchg(struct ifnet *ifp) |
|
Line 364 axen_miibus_statchg(struct ifnet *ifp) |
|
static int |
static int |
axen_ifmedia_upd(struct ifnet *ifp) |
axen_ifmedia_upd(struct ifnet *ifp) |
{ |
{ |
struct axen_softc *sc = ifp->if_softc; |
struct axen_softc * const sc = ifp->if_softc; |
struct mii_data *mii = GET_MII(sc); |
struct mii_data *mii = GET_MII(sc); |
int rc; |
int rc; |
|
|
Line 390 axen_ifmedia_upd(struct ifnet *ifp) |
|
Line 388 axen_ifmedia_upd(struct ifnet *ifp) |
|
static void |
static void |
axen_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) |
axen_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) |
{ |
{ |
struct axen_softc *sc = ifp->if_softc; |
struct axen_softc * const sc = ifp->if_softc; |
struct mii_data *mii = GET_MII(sc); |
struct mii_data *mii = GET_MII(sc); |
|
|
mii_pollstat(mii); |
mii_pollstat(mii); |
Line 474 axen_reset(struct axen_softc *sc) |
|
Line 472 axen_reset(struct axen_softc *sc) |
|
DELAY(1000); |
DELAY(1000); |
} |
} |
|
|
#if 0 /* not used */ |
|
#define AXEN_GPIO_WRITE(x, y) do { \ |
#define AXEN_GPIO_WRITE(x, y) do { \ |
axen_cmd(sc, AXEN_CMD_WRITE_GPIO, 0, (x), NULL); \ |
axen_cmd(sc, AXEN_CMD_WRITE_GPIO, 0, (x), NULL); \ |
usbd_delay_ms(sc->axen_udev, (y)); \ |
usbd_delay_ms(sc->axen_udev, (y)); \ |
} while (/*CONSTCOND*/0) |
} while (/*CONSTCOND*/0) |
|
|
static int |
static int |
axen_ax88179_eeprom(struct axen_softc *sc, void *addr) |
axen_get_eaddr(struct axen_softc *sc, void *addr) |
{ |
{ |
|
#if 1 |
|
return axen_cmd(sc, AXEN_CMD_MAC_READ_ETHER, 6, AXEN_CMD_MAC_NODE_ID, |
|
addr); |
|
#else |
int i, retry; |
int i, retry; |
uint8_t eeprom[20]; |
uint8_t eeprom[20]; |
uint16_t csum; |
uint16_t csum; |
Line 528 axen_ax88179_eeprom(struct axen_softc *s |
|
Line 529 axen_ax88179_eeprom(struct axen_softc *s |
|
|
|
memcpy(addr, eeprom, ETHER_ADDR_LEN); |
memcpy(addr, eeprom, ETHER_ADDR_LEN); |
return 0; |
return 0; |
} |
|
#endif |
#endif |
|
} |
|
|
static void |
static void |
axen_ax88179_init(struct axen_softc *sc) |
axen_ax88179_init(struct axen_softc *sc) |
Line 738 axen_match(device_t parent, cfdata_t mat |
|
Line 739 axen_match(device_t parent, cfdata_t mat |
|
static void |
static void |
axen_attach(device_t parent, device_t self, void *aux) |
axen_attach(device_t parent, device_t self, void *aux) |
{ |
{ |
struct axen_softc *sc = device_private(self); |
struct axen_softc * const sc = device_private(self); |
struct usb_attach_arg *uaa = aux; |
struct usb_attach_arg *uaa = aux; |
struct usbd_device *dev = uaa->uaa_device; |
struct usbd_device *dev = uaa->uaa_device; |
usbd_status err; |
usbd_status err; |
Line 770 axen_attach(device_t parent, device_t se |
|
Line 771 axen_attach(device_t parent, device_t se |
|
|
|
sc->axen_flags = axen_lookup(uaa->uaa_vendor, uaa->uaa_product)->axen_flags; |
sc->axen_flags = axen_lookup(uaa->uaa_vendor, uaa->uaa_product)->axen_flags; |
|
|
rw_init(&sc->axen_mii_lock); |
|
usb_init_task(&sc->axen_tick_task, axen_tick_task, sc, 0); |
usb_init_task(&sc->axen_tick_task, axen_tick_task, sc, 0); |
|
|
err = usbd_device2interface_handle(dev, AXEN_IFACE_IDX,&sc->axen_iface); |
err = usbd_device2interface_handle(dev, AXEN_IFACE_IDX,&sc->axen_iface); |
Line 820 axen_attach(device_t parent, device_t se |
|
Line 820 axen_attach(device_t parent, device_t se |
|
} |
} |
} |
} |
|
|
|
/* Set these up now for axen_cmd(). */ |
|
mutex_init(&sc->axen_mii_lock, MUTEX_DEFAULT, IPL_NONE); |
|
|
s = splnet(); |
s = splnet(); |
|
|
sc->axen_phyno = AXEN_PHY_ID; |
sc->axen_phyno = AXEN_PHY_ID; |
DPRINTF(("%s: phyno %d\n", device_xname(self), sc->axen_phyno)); |
DPRINTF(("%s: phyno %d\n", device_xname(self), sc->axen_phyno)); |
|
|
/* |
/* Get station address. */ |
* Get station address. |
axen_lock_mii(sc); |
*/ |
if (axen_get_eaddr(sc, &eaddr)) { |
#if 0 /* read from eeprom */ |
axen_unlock_mii(sc); |
if (axen_ax88179_eeprom(sc, &eaddr)) { |
|
printf("EEPROM checksum error\n"); |
printf("EEPROM checksum error\n"); |
|
mutex_destroy(&sc->axen_mii_lock); |
return; |
return; |
} |
} |
#else /* use MAC command */ |
|
axen_lock_mii(sc); |
|
axen_cmd(sc, AXEN_CMD_MAC_READ_ETHER, 6, AXEN_CMD_MAC_NODE_ID, &eaddr); |
|
axen_unlock_mii(sc); |
axen_unlock_mii(sc); |
#endif |
|
axen_ax88179_init(sc); |
axen_ax88179_init(sc); |
|
|
/* |
/* |
Line 912 axen_attach(device_t parent, device_t se |
|
Line 912 axen_attach(device_t parent, device_t se |
|
static int |
static int |
axen_detach(device_t self, int flags) |
axen_detach(device_t self, int flags) |
{ |
{ |
struct axen_softc *sc = device_private(self); |
struct axen_softc * const sc = device_private(self); |
struct ifnet *ifp = GET_IFP(sc); |
struct ifnet *ifp = GET_IFP(sc); |
int s; |
int s; |
|
|
Line 959 axen_detach(device_t self, int flags) |
|
Line 959 axen_detach(device_t self, int flags) |
|
|
|
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->axen_udev,sc->axen_dev); |
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->axen_udev,sc->axen_dev); |
|
|
rw_destroy(&sc->axen_mii_lock); |
mutex_destroy(&sc->axen_mii_lock); |
|
|
return 0; |
return 0; |
} |
} |
Line 967 axen_detach(device_t self, int flags) |
|
Line 967 axen_detach(device_t self, int flags) |
|
static int |
static int |
axen_activate(device_t self, devact_t act) |
axen_activate(device_t self, devact_t act) |
{ |
{ |
struct axen_softc *sc = device_private(self); |
struct axen_softc * const sc = device_private(self); |
struct ifnet *ifp = GET_IFP(sc); |
struct ifnet *ifp = GET_IFP(sc); |
|
|
DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->axen_dev), __func__)); |
DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->axen_dev), __func__)); |
|
|
axen_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status) |
axen_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status) |
{ |
{ |
struct axen_chain *c = (struct axen_chain *)priv; |
struct axen_chain *c = (struct axen_chain *)priv; |
struct axen_softc *sc = c->axen_sc; |
struct axen_softc * const sc = c->axen_sc; |
struct ifnet *ifp = GET_IFP(sc); |
struct ifnet *ifp = GET_IFP(sc); |
uint8_t *buf = c->axen_buf; |
uint8_t *buf = c->axen_buf; |
struct mbuf *m; |
struct mbuf *m; |
|
|
axen_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status) |
axen_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status) |
{ |
{ |
struct axen_chain *c = (struct axen_chain *)priv; |
struct axen_chain *c = (struct axen_chain *)priv; |
struct axen_softc *sc = c->axen_sc; |
struct axen_softc * const sc = c->axen_sc; |
struct axen_cdata *cd = &sc->axen_cdata; |
struct axen_cdata *cd = &sc->axen_cdata; |
struct ifnet *ifp = GET_IFP(sc); |
struct ifnet *ifp = GET_IFP(sc); |
int s; |
int s; |
Line 1302 axen_txeof(struct usbd_xfer *xfer, void |
|
Line 1302 axen_txeof(struct usbd_xfer *xfer, void |
|
static void |
static void |
axen_tick(void *xsc) |
axen_tick(void *xsc) |
{ |
{ |
struct axen_softc *sc = xsc; |
struct axen_softc * const sc = xsc; |
|
|
if (sc == NULL) |
if (sc == NULL) |
return; |
return; |
Line 1319 axen_tick(void *xsc) |
|
Line 1319 axen_tick(void *xsc) |
|
static void |
static void |
axen_tick_task(void *xsc) |
axen_tick_task(void *xsc) |
{ |
{ |
int s; |
struct axen_softc * const sc = xsc; |
struct axen_softc *sc; |
|
struct ifnet *ifp; |
struct ifnet *ifp; |
struct mii_data *mii; |
struct mii_data *mii; |
|
int s; |
sc = xsc; |
|
|
|
if (sc == NULL) |
if (sc == NULL) |
return; |
return; |
Line 1359 axen_encap(struct axen_softc *sc, struct |
|
Line 1357 axen_encap(struct axen_softc *sc, struct |
|
|
|
c = &sc->axen_cdata.axen_tx_chain[idx]; |
c = &sc->axen_cdata.axen_tx_chain[idx]; |
|
|
/* XXX Is this need? */ |
/* XXX Is this needed? wMaxPacketSize? */ |
switch (sc->axen_udev->ud_speed) { |
switch (sc->axen_udev->ud_speed) { |
case USB_SPEED_SUPER: |
case USB_SPEED_SUPER: |
boundary = 4096; |
boundary = 4096; |
Line 1407 axen_encap(struct axen_softc *sc, struct |
|
Line 1405 axen_encap(struct axen_softc *sc, struct |
|
static void |
static void |
axen_start(struct ifnet *ifp) |
axen_start(struct ifnet *ifp) |
{ |
{ |
struct axen_softc *sc = ifp->if_softc; |
struct axen_softc * const sc = ifp->if_softc; |
struct mbuf *m; |
struct mbuf *m; |
struct axen_cdata *cd = &sc->axen_cdata; |
struct axen_cdata *cd = &sc->axen_cdata; |
int idx; |
int idx; |
Line 1455 axen_start(struct ifnet *ifp) |
|
Line 1453 axen_start(struct ifnet *ifp) |
|
static int |
static int |
axen_init(struct ifnet *ifp) |
axen_init(struct ifnet *ifp) |
{ |
{ |
struct axen_softc *sc = ifp->if_softc; |
struct axen_softc * const sc = ifp->if_softc; |
struct axen_chain *c; |
struct axen_chain *c; |
usbd_status err; |
usbd_status err; |
int i, s; |
int i, s; |
Line 1548 axen_init(struct ifnet *ifp) |
|
Line 1546 axen_init(struct ifnet *ifp) |
|
static int |
static int |
axen_ioctl(struct ifnet *ifp, u_long cmd, void *data) |
axen_ioctl(struct ifnet *ifp, u_long cmd, void *data) |
{ |
{ |
struct axen_softc *sc = ifp->if_softc; |
struct axen_softc * const sc = ifp->if_softc; |
int s; |
int s; |
int error = 0; |
int error = 0; |
|
|
Line 1602 axen_ioctl(struct ifnet *ifp, u_long cmd |
|
Line 1600 axen_ioctl(struct ifnet *ifp, u_long cmd |
|
static void |
static void |
axen_watchdog(struct ifnet *ifp) |
axen_watchdog(struct ifnet *ifp) |
{ |
{ |
struct axen_softc *sc; |
struct axen_softc * const sc = ifp->if_softc; |
struct axen_chain *c; |
struct axen_chain *c; |
usbd_status stat; |
usbd_status stat; |
int s; |
int s; |
|
|
sc = ifp->if_softc; |
|
|
|
ifp->if_oerrors++; |
ifp->if_oerrors++; |
aprint_error_dev(sc->axen_dev, "watchdog timeout\n"); |
aprint_error_dev(sc->axen_dev, "watchdog timeout\n"); |
|
|
Line 1629 axen_watchdog(struct ifnet *ifp) |
|
Line 1625 axen_watchdog(struct ifnet *ifp) |
|
static void |
static void |
axen_stop(struct ifnet *ifp, int disable) |
axen_stop(struct ifnet *ifp, int disable) |
{ |
{ |
struct axen_softc *sc = ifp->if_softc; |
struct axen_softc * const sc = ifp->if_softc; |
struct axen_chain *c; |
struct axen_chain *c; |
usbd_status err; |
usbd_status err; |
int i; |
int i; |