diff --git a/sys/dev/usb/if_zyd.c b/sys/dev/usb/if_zyd.c index fa17945fb7cd..fdbe7273bc01 100644 --- a/sys/dev/usb/if_zyd.c +++ b/sys/dev/usb/if_zyd.c @@ -66,14 +66,32 @@ #include #include -#define ZYD_DEBUG #ifdef ZYD_DEBUG -#define DPRINTF(x) do { if (zyddebug > 0) printf x; } while (0) -#define DPRINTFN(n, x) do { if (zyddebug > (n)) printf x; } while (0) -int zyddebug = 0; +SYSCTL_NODE(_hw_usb, OID_AUTO, zyd, CTLFLAG_RW, 0, "ZyDAS zd1211/zd1211b"); +int zyd_debug = 0; +SYSCTL_INT(_hw_usb_zyd, OID_AUTO, debug, CTLFLAG_RW, &zyd_debug, 0, + "control debugging printfs"); +TUNABLE_INT("hw.usb.zyd.debug", &zyd_debug); +enum { + ZYD_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ + ZYD_DEBUG_RECV = 0x00000002, /* basic recv operation */ + ZYD_DEBUG_RESET = 0x00000004, /* reset processing */ + ZYD_DEBUG_INIT = 0x00000008, /* device init */ + ZYD_DEBUG_TX_PROC = 0x00000010, /* tx ISR proc */ + ZYD_DEBUG_RX_PROC = 0x00000020, /* rx ISR proc */ + ZYD_DEBUG_STATE = 0x00000040, /* 802.11 state transitions */ + ZYD_DEBUG_STAT = 0x00000080, /* statistic */ + ZYD_DEBUG_FW = 0x00000100, /* firmware */ + ZYD_DEBUG_ANY = 0xffffffff +}; +#define DPRINTF(sc, m, fmt, ...) do { \ + if (sc->sc_debug & (m)) \ + printf(fmt, __VA_ARGS__); \ +} while (0) #else -#define DPRINTF(x) -#define DPRINTFN(n, x) +#define DPRINTF(sc, m, fmt, ...) do { \ + (void) sc; \ +} while (0) #endif static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY; @@ -144,8 +162,28 @@ static const struct zyd_type { ZYD_ZD1211B_DEV(ZYXEL, M202), ZYD_ZD1211B_DEV(ZYXEL, G220V2), }; -#define zyd_lookup(v, p) \ +#define zyd_lookup(v, p) \ ((const struct zyd_type *)usb_lookup(zyd_devs, v, p)) +#define zyd_read16_m(sc, val, data) do { \ + error = zyd_read16(sc, val, data); \ + if (error != 0) \ + goto fail; \ +} while (0) +#define zyd_write16_m(sc, val, data) do { \ + error = zyd_write16(sc, val, data); \ + if (error != 0) \ + goto fail; \ +} while (0) +#define zyd_read32_m(sc, val, data) do { \ + error = zyd_read32(sc, val, data); \ + if (error != 0) \ + goto fail; \ +} while (0) +#define zyd_write32_m(sc, val, data) do { \ + error = zyd_write32(sc, val, data); \ + if (error != 0) \ + goto fail; \ +} while (0) static device_probe_t zyd_match; static device_attach_t zyd_attach; @@ -156,8 +194,6 @@ static struct ieee80211vap *zyd_vap_create(struct ieee80211com *, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]); static void zyd_vap_delete(struct ieee80211vap *); -static int zyd_attachhook(struct zyd_softc *); -static int zyd_complete_attach(struct zyd_softc *); static int zyd_open_pipes(struct zyd_softc *); static void zyd_close_pipes(struct zyd_softc *); static int zyd_alloc_tx_list(struct zyd_softc *); @@ -175,38 +211,18 @@ static int zyd_read32(struct zyd_softc *, uint16_t, uint32_t *); static int zyd_write16(struct zyd_softc *, uint16_t, uint16_t); static int zyd_write32(struct zyd_softc *, uint16_t, uint32_t); static int zyd_rfwrite(struct zyd_softc *, uint32_t); -static void zyd_lock_phy(struct zyd_softc *); -static void zyd_unlock_phy(struct zyd_softc *); -static int zyd_rfmd_init(struct zyd_rf *); -static int zyd_rfmd_switch_radio(struct zyd_rf *, int); -static int zyd_rfmd_set_channel(struct zyd_rf *, uint8_t); -static int zyd_al2230_init(struct zyd_rf *); -static int zyd_al2230_switch_radio(struct zyd_rf *, int); -static int zyd_al2230_set_channel(struct zyd_rf *, uint8_t); -static int zyd_al2230_init_b(struct zyd_rf *); -static int zyd_al7230B_init(struct zyd_rf *); -static int zyd_al7230B_switch_radio(struct zyd_rf *, int); -static int zyd_al7230B_set_channel(struct zyd_rf *, uint8_t); -static int zyd_al2210_init(struct zyd_rf *); -static int zyd_al2210_switch_radio(struct zyd_rf *, int); -static int zyd_al2210_set_channel(struct zyd_rf *, uint8_t); -static int zyd_gct_init(struct zyd_rf *); -static int zyd_gct_switch_radio(struct zyd_rf *, int); -static int zyd_gct_set_channel(struct zyd_rf *, uint8_t); -static int zyd_maxim_init(struct zyd_rf *); -static int zyd_maxim_switch_radio(struct zyd_rf *, int); -static int zyd_maxim_set_channel(struct zyd_rf *, uint8_t); -static int zyd_maxim2_init(struct zyd_rf *); -static int zyd_maxim2_switch_radio(struct zyd_rf *, int); -static int zyd_maxim2_set_channel(struct zyd_rf *, uint8_t); +static int zyd_lock_phy(struct zyd_softc *); +static int zyd_unlock_phy(struct zyd_softc *); static int zyd_rf_attach(struct zyd_softc *, uint8_t); static const char *zyd_rf_name(uint8_t); static int zyd_hw_init(struct zyd_softc *); +static int zyd_read_pod(struct zyd_softc *); static int zyd_read_eeprom(struct zyd_softc *); +static int zyd_get_macaddr(struct zyd_softc *); static int zyd_set_macaddr(struct zyd_softc *, const uint8_t *); static int zyd_set_bssid(struct zyd_softc *, const uint8_t *); static int zyd_switch_radio(struct zyd_softc *, int); -static void zyd_set_led(struct zyd_softc *, int, int); +static int zyd_set_led(struct zyd_softc *, int, int); static void zyd_set_multi(void *); static void zyd_update_mcast(struct ifnet *); static int zyd_set_rxfilter(struct zyd_softc *); @@ -228,13 +244,36 @@ static int zyd_ioctl(struct ifnet *, u_long, caddr_t); static void zyd_init_locked(struct zyd_softc *); static void zyd_init(void *); static void zyd_stop(struct zyd_softc *, int); -static int zyd_loadfirmware(struct zyd_softc *, u_char *, size_t); +static int zyd_loadfirmware(struct zyd_softc *); static void zyd_newassoc(struct ieee80211_node *, int); static void zyd_scantask(void *); static void zyd_scan_start(struct ieee80211com *); static void zyd_scan_end(struct ieee80211com *); static void zyd_set_channel(struct ieee80211com *); static void zyd_wakeup(struct zyd_softc *); +static int zyd_rfmd_init(struct zyd_rf *); +static int zyd_rfmd_switch_radio(struct zyd_rf *, int); +static int zyd_rfmd_set_channel(struct zyd_rf *, uint8_t); +static int zyd_al2230_init(struct zyd_rf *); +static int zyd_al2230_switch_radio(struct zyd_rf *, int); +static int zyd_al2230_set_channel(struct zyd_rf *, uint8_t); +static int zyd_al2230_set_channel_b(struct zyd_rf *, uint8_t); +static int zyd_al2230_init_b(struct zyd_rf *); +static int zyd_al7230B_init(struct zyd_rf *); +static int zyd_al7230B_switch_radio(struct zyd_rf *, int); +static int zyd_al7230B_set_channel(struct zyd_rf *, uint8_t); +static int zyd_al2210_init(struct zyd_rf *); +static int zyd_al2210_switch_radio(struct zyd_rf *, int); +static int zyd_al2210_set_channel(struct zyd_rf *, uint8_t); +static int zyd_gct_init(struct zyd_rf *); +static int zyd_gct_switch_radio(struct zyd_rf *, int); +static int zyd_gct_set_channel(struct zyd_rf *, uint8_t); +static int zyd_maxim_init(struct zyd_rf *); +static int zyd_maxim_switch_radio(struct zyd_rf *, int); +static int zyd_maxim_set_channel(struct zyd_rf *, uint8_t); +static int zyd_maxim2_init(struct zyd_rf *); +static int zyd_maxim2_switch_radio(struct zyd_rf *, int); +static int zyd_maxim2_set_channel(struct zyd_rf *, uint8_t); static int zyd_match(device_t dev) @@ -242,68 +281,57 @@ zyd_match(device_t dev) struct usb_attach_arg *uaa = device_get_ivars(dev); if (!uaa->iface) - return UMATCH_NONE; + return (UMATCH_NONE); return (zyd_lookup(uaa->vendor, uaa->product) != NULL) ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE; -} - -static int -zyd_attachhook(struct zyd_softc *sc) -{ - u_char *firmware; - int len, error; - - if (sc->mac_rev == ZYD_ZD1211) { - firmware = (u_char *)zd1211_firmware; - len = sizeof(zd1211_firmware); - } else { - firmware = (u_char *)zd1211b_firmware; - len = sizeof(zd1211b_firmware); - } - - error = zyd_loadfirmware(sc, firmware, len); - if (error != 0) { - device_printf(sc->sc_dev, - "could not load firmware (error=%d)\n", error); - return error; - } - - sc->sc_flags |= ZYD_FLAG_FWLOADED; - - /* complete the attach process */ - return zyd_complete_attach(sc); + (UMATCH_VENDOR_PRODUCT) : (UMATCH_NONE); } static int zyd_attach(device_t dev) { int error = ENXIO; - struct zyd_softc *sc = device_get_softc(dev); - struct usb_attach_arg *uaa = device_get_ivars(dev); - usb_device_descriptor_t* ddesc; + struct ieee80211com *ic; struct ifnet *ifp; + struct usb_attach_arg *uaa = device_get_ivars(dev); + struct zyd_softc *sc = device_get_softc(dev); + usb_device_descriptor_t* ddesc; + uint8_t bands; sc->sc_dev = dev; - - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - return ENXIO; - } - sc->sc_udev = uaa->device; - sc->sc_flags = 0; - sc->mac_rev = zyd_lookup(uaa->vendor, uaa->product)->rev; + sc->sc_macrev = zyd_lookup(uaa->vendor, uaa->product)->rev; +#ifdef ZYD_DEBUG + sc->sc_debug = zyd_debug; +#endif ddesc = usbd_get_device_descriptor(sc->sc_udev); if (UGETW(ddesc->bcdDevice) < 0x4330) { device_printf(dev, "device version mismatch: 0x%x " "(only >= 43.30 supported)\n", UGETW(ddesc->bcdDevice)); - goto bad; + return (ENXIO); } + if ((error = zyd_get_macaddr(sc)) != 0) { + device_printf(sc->sc_dev, "could not read EEPROM\n"); + return (ENXIO); + } + + mtx_init(&sc->sc_txmtx, device_get_nameunit(sc->sc_dev), + MTX_NETWORK_LOCK, MTX_DEF); + usb_init_task(&sc->sc_mcasttask, zyd_set_multi, sc); + usb_init_task(&sc->sc_scantask, zyd_scantask, sc); + usb_init_task(&sc->sc_task, zyd_task, sc); + callout_init(&sc->sc_watchdog_ch, 0); + STAILQ_INIT(&sc->sc_rqh); + + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(dev, "can not if_alloc()\n"); + error = ENXIO; + goto fail0; + } ifp->if_softc = sc; if_initname(ifp, "zyd", device_get_unit(sc->sc_dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | @@ -314,89 +342,18 @@ zyd_attach(device_t dev) IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); IFQ_SET_READY(&ifp->if_snd); - STAILQ_INIT(&sc->sc_rqh); - - error = zyd_attachhook(sc); - if (error != 0) { -bad: - if_free(ifp); - return error; - } - - return 0; -} - -static int -zyd_complete_attach(struct zyd_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - usbd_status error; - uint8_t bands; - - mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - - usb_init_task(&sc->sc_scantask, zyd_scantask, sc); - usb_init_task(&sc->sc_task, zyd_task, sc); - usb_init_task(&sc->sc_mcasttask, zyd_set_multi, sc); - - callout_init(&sc->sc_watchdog_ch, 0); - - error = usbd_set_config_no(sc->sc_udev, ZYD_CONFIG_NO, 1); - if (error != 0) { - device_printf(sc->sc_dev, "setting config no failed\n"); - error = ENXIO; - goto fail; - } - - error = usbd_device2interface_handle(sc->sc_udev, ZYD_IFACE_INDEX, - &sc->sc_iface); - if (error != 0) { - device_printf(sc->sc_dev, "getting interface handle failed\n"); - error = ENXIO; - goto fail; - } - - if ((error = zyd_open_pipes(sc)) != 0) { - device_printf(sc->sc_dev, "could not open pipes\n"); - goto fail; - } - - if ((error = zyd_read_eeprom(sc)) != 0) { - device_printf(sc->sc_dev, "could not read EEPROM\n"); - goto fail; - } - - if ((error = zyd_rf_attach(sc, sc->rf_rev)) != 0) { - device_printf(sc->sc_dev, "could not attach RF, rev 0x%x\n", - sc->rf_rev); - goto fail; - } - - if ((error = zyd_hw_init(sc)) != 0) { - device_printf(sc->sc_dev, "hardware initialization failed\n"); - goto fail; - } - - device_printf(sc->sc_dev, - "HMAC ZD1211%s, FW %02x.%02x, RF %s, PA %x, address %s\n", - (sc->mac_rev == ZYD_ZD1211) ? "": "B", - sc->fw_rev >> 8, sc->fw_rev & 0xff, zyd_rf_name(sc->rf_rev), - sc->pa_rev, ether_sprintf(ic->ic_myaddr)); - - IEEE80211_ADDR_COPY(sc->sc_bssid, ic->ic_myaddr); - + ic = ifp->if_l2com; ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ ic->ic_opmode = IEEE80211_M_STA; + IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid); /* set device capabilities */ ic->ic_caps = IEEE80211_C_STA /* station mode */ | IEEE80211_C_MONITOR /* monitor mode */ | IEEE80211_C_SHPREAMBLE /* short preamble supported */ - | IEEE80211_C_SHSLOT /* short slot time supported */ + | IEEE80211_C_SHSLOT /* short slot time supported */ | IEEE80211_C_BGSCAN /* capable of bg scanning */ | IEEE80211_C_WPA /* 802.11i */ ; @@ -420,11 +377,9 @@ zyd_complete_attach(struct zyd_softc *sc) bpfattach(ifp, DLT_IEEE802_11_RADIO, sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap)); - sc->sc_rxtap_len = sizeof(sc->sc_rxtap); sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof(sc->sc_txtap); sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT); @@ -434,12 +389,10 @@ zyd_complete_attach(struct zyd_softc *sc) usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - return error; + return (0); -fail: - mtx_destroy(&sc->sc_mtx); - - return error; +fail0: mtx_destroy(&sc->sc_txmtx); + return (error); } static int @@ -450,31 +403,24 @@ zyd_detach(device_t dev) struct ieee80211com *ic = ifp->if_l2com; if (!device_is_attached(dev)) - return 0; + return (0); - /* protect a race when we have listeners related with the driver. */ - ifp->if_flags &= ~IFF_UP; + /* set a flag to indicate we're detaching. */ + sc->sc_flags |= ZYD_FLAG_DETACHING; zyd_stop(sc, 1); bpfdetach(ifp); ieee80211_ifdetach(ic); - /* set a flag to indicate we're detaching. */ - sc->sc_flags |= ZYD_FLAG_DETACHING; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - usb_rem_task(sc->sc_udev, &sc->sc_task); - callout_stop(&sc->sc_watchdog_ch); - zyd_wakeup(sc); zyd_close_pipes(sc); if_free(ifp); - mtx_destroy(&sc->sc_mtx); + mtx_destroy(&sc->sc_txmtx); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return 0; + return (0); } static struct ieee80211vap * @@ -487,11 +433,11 @@ zyd_vap_create(struct ieee80211com *ic, struct ieee80211vap *vap; if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ - return NULL; + return (NULL); zvp = (struct zyd_vap *) malloc(sizeof(struct zyd_vap), M_80211_VAP, M_NOWAIT | M_ZERO); if (zvp == NULL) - return NULL; + return (NULL); vap = &zvp->vap; /* enable s/w bmiss handling for sta mode */ ieee80211_vap_setup(ic, vap, name, unit, opmode, @@ -507,9 +453,10 @@ zyd_vap_create(struct ieee80211com *ic, 1000 /* 1 sec */); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status); ic->ic_opmode = opmode; - return vap; + return (vap); } static void @@ -532,18 +479,18 @@ zyd_open_pipes(struct zyd_softc *sc) /* interrupt in */ edesc = usbd_get_endpoint_descriptor(sc->sc_iface, 0x83); if (edesc == NULL) - return EINVAL; + return (EINVAL); isize = UGETW(edesc->wMaxPacketSize); if (isize == 0) /* should not happen */ - return EINVAL; + return (EINVAL); - sc->ibuf = malloc(isize, M_USBDEV, M_NOWAIT); - if (sc->ibuf == NULL) - return ENOMEM; + sc->sc_ibuf = malloc(isize, M_USBDEV, M_NOWAIT); + if (sc->sc_ibuf == NULL) + return (ENOMEM); error = usbd_open_pipe_intr(sc->sc_iface, 0x83, USBD_SHORT_XFER_OK, - &sc->zyd_ep[ZYD_ENDPT_IIN], sc, sc->ibuf, isize, zyd_intr, + &sc->sc_ep[ZYD_ENDPT_IIN], sc, sc->sc_ibuf, isize, zyd_intr, USBD_DEFAULT_INTERVAL); if (error != 0) { device_printf(sc->sc_dev, "open rx intr pipe failed: %s\n", @@ -553,7 +500,7 @@ zyd_open_pipes(struct zyd_softc *sc) /* interrupt out (not necessarily an interrupt pipe) */ error = usbd_open_pipe(sc->sc_iface, 0x04, USBD_EXCLUSIVE_USE, - &sc->zyd_ep[ZYD_ENDPT_IOUT]); + &sc->sc_ep[ZYD_ENDPT_IOUT]); if (error != 0) { device_printf(sc->sc_dev, "open tx intr pipe failed: %s\n", usbd_errstr(error)); @@ -562,7 +509,7 @@ zyd_open_pipes(struct zyd_softc *sc) /* bulk in */ error = usbd_open_pipe(sc->sc_iface, 0x82, USBD_EXCLUSIVE_USE, - &sc->zyd_ep[ZYD_ENDPT_BIN]); + &sc->sc_ep[ZYD_ENDPT_BIN]); if (error != 0) { device_printf(sc->sc_dev, "open rx pipe failed: %s\n", usbd_errstr(error)); @@ -571,17 +518,17 @@ zyd_open_pipes(struct zyd_softc *sc) /* bulk out */ error = usbd_open_pipe(sc->sc_iface, 0x01, USBD_EXCLUSIVE_USE, - &sc->zyd_ep[ZYD_ENDPT_BOUT]); + &sc->sc_ep[ZYD_ENDPT_BOUT]); if (error != 0) { device_printf(sc->sc_dev, "open tx pipe failed: %s\n", usbd_errstr(error)); goto fail; } - return 0; + return (0); fail: zyd_close_pipes(sc); - return ENXIO; + return (ENXIO); } static void @@ -590,15 +537,15 @@ zyd_close_pipes(struct zyd_softc *sc) int i; for (i = 0; i < ZYD_ENDPT_CNT; i++) { - if (sc->zyd_ep[i] != NULL) { - usbd_abort_pipe(sc->zyd_ep[i]); - usbd_close_pipe(sc->zyd_ep[i]); - sc->zyd_ep[i] = NULL; + if (sc->sc_ep[i] != NULL) { + usbd_abort_pipe(sc->sc_ep[i]); + usbd_close_pipe(sc->sc_ep[i]); + sc->sc_ep[i] = NULL; } } - if (sc->ibuf != NULL) { - free(sc->ibuf, M_USBDEV); - sc->ibuf = NULL; + if (sc->sc_ibuf != NULL) { + free(sc->sc_ibuf, M_USBDEV); + sc->sc_ibuf = NULL; } } @@ -607,10 +554,10 @@ zyd_alloc_tx_list(struct zyd_softc *sc) { int i, error; - sc->tx_queued = 0; + sc->sc_txqueued = 0; for (i = 0; i < ZYD_TX_LIST_CNT; i++) { - struct zyd_tx_data *data = &sc->tx_data[i]; + struct zyd_tx_data *data = &sc->sc_txdata[i]; data->sc = sc; /* backpointer for callbacks */ @@ -632,10 +579,10 @@ zyd_alloc_tx_list(struct zyd_softc *sc) /* clear Tx descriptor */ bzero(data->buf, sizeof(struct zyd_tx_desc)); } - return 0; + return (0); fail: zyd_free_tx_list(sc); - return error; + return (error); } static void @@ -644,7 +591,7 @@ zyd_free_tx_list(struct zyd_softc *sc) int i; for (i = 0; i < ZYD_TX_LIST_CNT; i++) { - struct zyd_tx_data *data = &sc->tx_data[i]; + struct zyd_tx_data *data = &sc->sc_txdata[i]; if (data->xfer != NULL) { usbd_free_xfer(data->xfer); @@ -663,7 +610,7 @@ zyd_alloc_rx_list(struct zyd_softc *sc) int i, error; for (i = 0; i < ZYD_RX_LIST_CNT; i++) { - struct zyd_rx_data *data = &sc->rx_data[i]; + struct zyd_rx_data *data = &sc->sc_rxdata[i]; data->sc = sc; /* backpointer for callbacks */ @@ -682,10 +629,10 @@ zyd_alloc_rx_list(struct zyd_softc *sc) goto fail; } } - return 0; + return (0); fail: zyd_free_rx_list(sc); - return error; + return (error); } static void @@ -694,7 +641,7 @@ zyd_free_rx_list(struct zyd_softc *sc) int i; for (i = 0; i < ZYD_RX_LIST_CNT; i++) { - struct zyd_rx_data *data = &sc->rx_data[i]; + struct zyd_rx_data *data = &sc->sc_rxdata[i]; if (data->xfer != NULL) { usbd_free_xfer(data->xfer); @@ -711,41 +658,44 @@ zyd_node_alloc(struct ieee80211vap *vap __unused, struct zyd_node *zn; zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO); - return zn != NULL ? &zn->ni : NULL; + return (zn != NULL) ? (&zn->ni) : (NULL); } static void zyd_task(void *arg) { + int error; struct zyd_softc *sc = arg; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ieee80211_node *ni = vap->iv_bss; struct zyd_vap *zvp = ZYD_VAP(vap); switch (sc->sc_state) { - case IEEE80211_S_RUN: - { - struct ieee80211_node *ni = vap->iv_bss; - + case IEEE80211_S_AUTH: zyd_set_chan(sc, ic->ic_curchan); - - if (vap->iv_opmode != IEEE80211_M_MONITOR) { - /* turn link LED on */ - zyd_set_led(sc, ZYD_LED1, 1); - - /* make data LED blink upon Tx */ - zyd_write32(sc, sc->fwbase + ZYD_FW_LINK_STATUS, 1); - - IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); - zyd_set_bssid(sc, sc->sc_bssid); - } break; - } + case IEEE80211_S_RUN: + if (vap->iv_opmode == IEEE80211_M_MONITOR) + break; + + /* turn link LED on */ + error = zyd_set_led(sc, ZYD_LED1, 1); + if (error != 0) + goto fail; + + /* make data LED blink upon Tx */ + zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1); + + IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); + zyd_set_bssid(sc, sc->sc_bssid); + break; default: break; } +fail: IEEE80211_LOCK(ic); zvp->newstate(vap, sc->sc_state, sc->sc_arg); if (vap->iv_newstate_cb != NULL) @@ -760,6 +710,10 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) struct ieee80211com *ic = vap->iv_ic; struct zyd_softc *sc = ic->ic_ifp->if_softc; + DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__, + ieee80211_state_name[vap->iv_state], + ieee80211_state_name[nstate]); + usb_rem_task(sc->sc_udev, &sc->sc_scantask); usb_rem_task(sc->sc_udev, &sc->sc_task); callout_stop(&sc->sc_watchdog_ch); @@ -770,10 +724,10 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) if (nstate == IEEE80211_S_INIT) { zvp->newstate(vap, nstate, arg); - return 0; + return (0); } else { usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return EINPROGRESS; + return (EINPROGRESS); } } @@ -783,15 +737,15 @@ zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, { usbd_xfer_handle xfer; struct zyd_cmd cmd; - struct rq rq; + struct zyd_rq rq; uint16_t xferflags; usbd_status error; if (sc->sc_flags & ZYD_FLAG_DETACHING) - return ENXIO; + return (ENXIO); if ((xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) - return ENOMEM; + return (ENOMEM); cmd.code = htole16(code); bcopy(idata, cmd.data, ilen); @@ -806,27 +760,27 @@ zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, STAILQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq); } - usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_IOUT], 0, &cmd, + usbd_setup_xfer(xfer, sc->sc_ep[ZYD_ENDPT_IOUT], 0, &cmd, sizeof(uint16_t) + ilen, xferflags, ZYD_INTR_TIMEOUT, NULL); error = usbd_transfer(xfer); if (error != USBD_IN_PROGRESS && error != 0) { device_printf(sc->sc_dev, "could not send command (error=%s)\n", usbd_errstr(error)); (void)usbd_free_xfer(xfer); - return EIO; + return (EIO); } if (!(flags & ZYD_CMD_FLAG_READ)) { (void)usbd_free_xfer(xfer); - return 0; /* write: don't wait for reply */ + return (0); /* write: don't wait for reply */ } /* wait at most one second for command reply */ error = tsleep(odata, PCATCH, "zydcmd", hz); if (error == EWOULDBLOCK) device_printf(sc->sc_dev, "zyd_read sleep timeout\n"); - STAILQ_REMOVE(&sc->sc_rqh, &rq, rq, rq); + STAILQ_REMOVE(&sc->sc_rqh, &rq, zyd_rq, rq); (void)usbd_free_xfer(xfer); - return error; + return (error); } static int @@ -840,7 +794,7 @@ zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val) ZYD_CMD_FLAG_READ); if (error == 0) *val = le16toh(tmp.val); - return error; + return (error); } static int @@ -856,7 +810,7 @@ zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val) ZYD_CMD_FLAG_READ); if (error == 0) *val = le16toh(tmp[0].val) << 16 | le16toh(tmp[1].val); - return error; + return (error); } static int @@ -887,11 +841,11 @@ static int zyd_rfwrite(struct zyd_softc *sc, uint32_t val) { struct zyd_rf *rf = &sc->sc_rf; - struct zyd_rfwrite req; + struct zyd_rfwrite_cmd req; uint16_t cr203; - int i; + int error, i; - (void)zyd_read16(sc, ZYD_CR203, &cr203); + zyd_read16_m(sc, ZYD_CR203, &cr203); cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA); req.code = htole16(2); @@ -901,27 +855,47 @@ zyd_rfwrite(struct zyd_softc *sc, uint32_t val) if (val & (1 << (rf->width - 1 - i))) req.bit[i] |= htole16(ZYD_RF_DATA); } - return zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0); + error = zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0); +fail: + return (error); } -static void +static int +zyd_rfwrite_cr(struct zyd_softc *sc, uint32_t val) +{ + int error; + + zyd_write16_m(sc, ZYD_CR244, (val >> 16) & 0xff); + zyd_write16_m(sc, ZYD_CR243, (val >> 8) & 0xff); + zyd_write16_m(sc, ZYD_CR242, (val >> 0) & 0xff); +fail: + return (error); +} + +static int zyd_lock_phy(struct zyd_softc *sc) { + int error; uint32_t tmp; - (void)zyd_read32(sc, ZYD_MAC_MISC, &tmp); + zyd_read32_m(sc, ZYD_MAC_MISC, &tmp); tmp &= ~ZYD_UNLOCK_PHY_REGS; - (void)zyd_write32(sc, ZYD_MAC_MISC, tmp); + zyd_write32_m(sc, ZYD_MAC_MISC, tmp); +fail: + return (error); } -static void +static int zyd_unlock_phy(struct zyd_softc *sc) { + int error; uint32_t tmp; - (void)zyd_read32(sc, ZYD_MAC_MISC, &tmp); + zyd_read32_m(sc, ZYD_MAC_MISC, &tmp); tmp |= ZYD_UNLOCK_PHY_REGS; - (void)zyd_write32(sc, ZYD_MAC_MISC, tmp); + zyd_write32_m(sc, ZYD_MAC_MISC, tmp); +fail: + return (error); } /* @@ -938,43 +912,49 @@ zyd_rfmd_init(struct zyd_rf *rf) /* init RF-dependent PHY registers */ for (i = 0; i < N(phyini); i++) { - error = zyd_write16(sc, phyini[i].reg, phyini[i].val); - if (error != 0) - return error; + zyd_write16_m(sc, phyini[i].reg, phyini[i].val); } /* init RFMD radio */ for (i = 0; i < N(rfini); i++) { if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return error; + return (error); } - return 0; +fail: + return (error); #undef N } static int zyd_rfmd_switch_radio(struct zyd_rf *rf, int on) { + int error; struct zyd_softc *sc = rf->rf_sc; - (void)zyd_write16(sc, ZYD_CR10, on ? 0x89 : 0x15); - (void)zyd_write16(sc, ZYD_CR11, on ? 0x00 : 0x81); - - return 0; + zyd_write16_m(sc, ZYD_CR10, on ? 0x89 : 0x15); + zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x81); +fail: + return (error); } static int zyd_rfmd_set_channel(struct zyd_rf *rf, uint8_t chan) { + int error; struct zyd_softc *sc = rf->rf_sc; static const struct { uint32_t r1, r2; } rfprog[] = ZYD_RFMD_CHANTABLE; - (void)zyd_rfwrite(sc, rfprog[chan - 1].r1); - (void)zyd_rfwrite(sc, rfprog[chan - 1].r2); + error = zyd_rfwrite(sc, rfprog[chan - 1].r1); + if (error != 0) + goto fail; + error = zyd_rfwrite(sc, rfprog[chan - 1].r2); + if (error != 0) + goto fail; - return 0; +fail: + return (error); } /* @@ -986,22 +966,75 @@ zyd_al2230_init(struct zyd_rf *rf) #define N(a) (sizeof(a) / sizeof((a)[0])) struct zyd_softc *sc = rf->rf_sc; static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY; - static const uint32_t rfini[] = ZYD_AL2230_RF; + static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT; + static const struct zyd_phy_pair phypll[] = { + { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x3f }, + { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 } + }; + static const uint32_t rfini1[] = ZYD_AL2230_RF_PART1; + static const uint32_t rfini2[] = ZYD_AL2230_RF_PART2; + static const uint32_t rfini3[] = ZYD_AL2230_RF_PART3; int i, error; /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) { - error = zyd_write16(sc, phyini[i].reg, phyini[i].val); - if (error != 0) - return error; + for (i = 0; i < N(phyini); i++) + zyd_write16_m(sc, phyini[i].reg, phyini[i].val); + + if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) { + for (i = 0; i < N(phy2230s); i++) + zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val); } /* init AL2230 radio */ - for (i = 0; i < N(rfini); i++) { - if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return error; + for (i = 0; i < N(rfini1); i++) { + error = zyd_rfwrite(sc, rfini1[i]); + if (error != 0) + goto fail; } - return 0; + + if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) + error = zyd_rfwrite(sc, 0x000824); + else + error = zyd_rfwrite(sc, 0x0005a4); + if (error != 0) + goto fail; + + for (i = 0; i < N(rfini2); i++) { + error = zyd_rfwrite(sc, rfini2[i]); + if (error != 0) + goto fail; + } + + for (i = 0; i < N(phypll); i++) + zyd_write16_m(sc, phypll[i].reg, phypll[i].val); + + for (i = 0; i < N(rfini3); i++) { + error = zyd_rfwrite(sc, rfini3[i]); + if (error != 0) + goto fail; + } +fail: + return (error); +#undef N +} + +static int +zyd_al2230_fini(struct zyd_rf *rf) +{ +#define N(a) (sizeof(a) / sizeof((a)[0])) + int error, i; + struct zyd_softc *sc = rf->rf_sc; + static const struct zyd_phy_pair phy[] = ZYD_AL2230_PHY_FINI_PART1; + + for (i = 0; i < N(phy); i++) + zyd_write16_m(sc, phy[i].reg, phy[i].val); + + if (sc->sc_newphy != 0) + zyd_write16_m(sc, ZYD_CR9, 0xe1); + + zyd_write16_m(sc, ZYD_CR203, 0x6); +fail: + return (error); #undef N } @@ -1010,23 +1043,67 @@ zyd_al2230_init_b(struct zyd_rf *rf) { #define N(a) (sizeof(a) / sizeof((a)[0])) struct zyd_softc *sc = rf->rf_sc; + static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1; + static const struct zyd_phy_pair phy2[] = ZYD_AL2230_PHY_PART2; + static const struct zyd_phy_pair phy3[] = ZYD_AL2230_PHY_PART3; + static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT; static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B; - static const uint32_t rfini[] = ZYD_AL2230_RF_B; + static const uint32_t rfini_part1[] = ZYD_AL2230_RF_B_PART1; + static const uint32_t rfini_part2[] = ZYD_AL2230_RF_B_PART2; + static const uint32_t rfini_part3[] = ZYD_AL2230_RF_B_PART3; + static const uint32_t zyd_al2230_chtable[][3] = ZYD_AL2230_CHANTABLE; int i, error; + for (i = 0; i < N(phy1); i++) + zyd_write16_m(sc, phy1[i].reg, phy1[i].val); + /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) { - error = zyd_write16(sc, phyini[i].reg, phyini[i].val); + for (i = 0; i < N(phyini); i++) + zyd_write16_m(sc, phyini[i].reg, phyini[i].val); + + if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) + zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val); + + for (i = 0; i < 3; i++) { + error = zyd_rfwrite_cr(sc, zyd_al2230_chtable[0][i]); if (error != 0) - return error; + return (error); } - /* init AL2230 radio */ - for (i = 0; i < N(rfini); i++) { - if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return error; + for (i = 0; i < N(rfini_part1); i++) { + error = zyd_rfwrite_cr(sc, rfini_part1[i]); + if (error != 0) + return (error); } - return 0; + + if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) + error = zyd_rfwrite(sc, 0x241000); + else + error = zyd_rfwrite(sc, 0x25a000); + if (error != 0) + goto fail; + + for (i = 0; i < N(rfini_part2); i++) { + error = zyd_rfwrite_cr(sc, rfini_part2[i]); + if (error != 0) + return (error); + } + + for (i = 0; i < N(phy2); i++) + zyd_write16_m(sc, phy2[i].reg, phy2[i].val); + + for (i = 0; i < N(rfini_part3); i++) { + error = zyd_rfwrite_cr(sc, rfini_part3[i]); + if (error != 0) + return (error); + } + + for (i = 0; i < N(phy3); i++) + zyd_write16_m(sc, phy3[i].reg, phy3[i].val); + + error = zyd_al2230_fini(rf); +fail: + return (error); #undef N } @@ -1034,30 +1111,98 @@ static int zyd_al2230_switch_radio(struct zyd_rf *rf, int on) { struct zyd_softc *sc = rf->rf_sc; - int on251 = (sc->mac_rev == ZYD_ZD1211) ? 0x3f : 0x7f; + int error, on251 = (sc->sc_macrev == ZYD_ZD1211) ? 0x3f : 0x7f; - (void)zyd_write16(sc, ZYD_CR11, on ? 0x00 : 0x04); - (void)zyd_write16(sc, ZYD_CR251, on ? on251 : 0x2f); - - return 0; + zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04); + zyd_write16_m(sc, ZYD_CR251, on ? on251 : 0x2f); +fail: + return (error); } static int zyd_al2230_set_channel(struct zyd_rf *rf, uint8_t chan) { +#define N(a) (sizeof(a) / sizeof((a)[0])) + int error, i; struct zyd_softc *sc = rf->rf_sc; + static const struct zyd_phy_pair phy1[] = { + { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 }, + }; static const struct { uint32_t r1, r2, r3; } rfprog[] = ZYD_AL2230_CHANTABLE; - (void)zyd_rfwrite(sc, rfprog[chan - 1].r1); - (void)zyd_rfwrite(sc, rfprog[chan - 1].r2); - (void)zyd_rfwrite(sc, rfprog[chan - 1].r3); + error = zyd_rfwrite(sc, rfprog[chan - 1].r1); + if (error != 0) + goto fail; + error = zyd_rfwrite(sc, rfprog[chan - 1].r2); + if (error != 0) + goto fail; + error = zyd_rfwrite(sc, rfprog[chan - 1].r3); + if (error != 0) + goto fail; - (void)zyd_write16(sc, ZYD_CR138, 0x28); - (void)zyd_write16(sc, ZYD_CR203, 0x06); + for (i = 0; i < N(phy1); i++) + zyd_write16_m(sc, phy1[i].reg, phy1[i].val); +fail: + return (error); +#undef N +} - return 0; +static int +zyd_al2230_set_channel_b(struct zyd_rf *rf, uint8_t chan) +{ +#define N(a) (sizeof(a) / sizeof((a)[0])) + int error, i; + struct zyd_softc *sc = rf->rf_sc; + static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1; + static const struct { + uint32_t r1, r2, r3; + } rfprog[] = ZYD_AL2230_CHANTABLE_B; + + for (i = 0; i < N(phy1); i++) + zyd_write16_m(sc, phy1[i].reg, phy1[i].val); + + error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r1); + if (error != 0) + goto fail; + error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r2); + if (error != 0) + goto fail; + error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r3); + if (error != 0) + goto fail; + error = zyd_al2230_fini(rf); +fail: + return (error); +#undef N +} + +#define ZYD_AL2230_PHY_BANDEDGE6 \ +{ \ + { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \ + { ZYD_CR47, 0x1e } \ +} + +static int +zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c) +{ +#define N(a) (sizeof(a) / sizeof((a)[0])) + int error = 0, i; + struct zyd_softc *sc = rf->rf_sc; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6; + u_int chan = ieee80211_chan2ieee(ic, c); + + if (chan == 1 || chan == 11) + r[0].val = 0x12; + + for (i = 0; i < N(r); i++) + zyd_write16_m(sc, r[i].reg, r[i].val); +fail: + return (error); +#undef N } /* @@ -1078,47 +1223,41 @@ zyd_al7230B_init(struct zyd_rf *rf) /* for AL7230B, PHY and RF need to be initialized in "phases" */ /* init RF-dependent PHY registers, part one */ - for (i = 0; i < N(phyini_1); i++) { - error = zyd_write16(sc, phyini_1[i].reg, phyini_1[i].val); - if (error != 0) - return error; - } + for (i = 0; i < N(phyini_1); i++) + zyd_write16_m(sc, phyini_1[i].reg, phyini_1[i].val); + /* init AL7230B radio, part one */ for (i = 0; i < N(rfini_1); i++) { if ((error = zyd_rfwrite(sc, rfini_1[i])) != 0) - return error; + return (error); } /* init RF-dependent PHY registers, part two */ - for (i = 0; i < N(phyini_2); i++) { - error = zyd_write16(sc, phyini_2[i].reg, phyini_2[i].val); - if (error != 0) - return error; - } + for (i = 0; i < N(phyini_2); i++) + zyd_write16_m(sc, phyini_2[i].reg, phyini_2[i].val); + /* init AL7230B radio, part two */ for (i = 0; i < N(rfini_2); i++) { if ((error = zyd_rfwrite(sc, rfini_2[i])) != 0) - return error; + return (error); } /* init RF-dependent PHY registers, part three */ - for (i = 0; i < N(phyini_3); i++) { - error = zyd_write16(sc, phyini_3[i].reg, phyini_3[i].val); - if (error != 0) - return error; - } - - return 0; + for (i = 0; i < N(phyini_3); i++) + zyd_write16_m(sc, phyini_3[i].reg, phyini_3[i].val); +fail: + return (error); #undef N } static int zyd_al7230B_switch_radio(struct zyd_rf *rf, int on) { + int error; struct zyd_softc *sc = rf->rf_sc; - (void)zyd_write16(sc, ZYD_CR11, on ? 0x00 : 0x04); - (void)zyd_write16(sc, ZYD_CR251, on ? 0x3f : 0x2f); - - return 0; + zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04); + zyd_write16_m(sc, ZYD_CR251, on ? 0x3f : 0x2f); +fail: + return (error); } static int @@ -1132,29 +1271,35 @@ zyd_al7230B_set_channel(struct zyd_rf *rf, uint8_t chan) static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL; int i, error; - (void)zyd_write16(sc, ZYD_CR240, 0x57); - (void)zyd_write16(sc, ZYD_CR251, 0x2f); + zyd_write16_m(sc, ZYD_CR240, 0x57); + zyd_write16_m(sc, ZYD_CR251, 0x2f); for (i = 0; i < N(rfsc); i++) { if ((error = zyd_rfwrite(sc, rfsc[i])) != 0) - return error; + return (error); } - (void)zyd_write16(sc, ZYD_CR128, 0x14); - (void)zyd_write16(sc, ZYD_CR129, 0x12); - (void)zyd_write16(sc, ZYD_CR130, 0x10); - (void)zyd_write16(sc, ZYD_CR38, 0x38); - (void)zyd_write16(sc, ZYD_CR136, 0xdf); + zyd_write16_m(sc, ZYD_CR128, 0x14); + zyd_write16_m(sc, ZYD_CR129, 0x12); + zyd_write16_m(sc, ZYD_CR130, 0x10); + zyd_write16_m(sc, ZYD_CR38, 0x38); + zyd_write16_m(sc, ZYD_CR136, 0xdf); - (void)zyd_rfwrite(sc, rfprog[chan - 1].r1); - (void)zyd_rfwrite(sc, rfprog[chan - 1].r2); - (void)zyd_rfwrite(sc, 0x3c9000); + error = zyd_rfwrite(sc, rfprog[chan - 1].r1); + if (error != 0) + goto fail; + error = zyd_rfwrite(sc, rfprog[chan - 1].r2); + if (error != 0) + goto fail; + error = zyd_rfwrite(sc, 0x3c9000); + if (error != 0) + goto fail; - (void)zyd_write16(sc, ZYD_CR251, 0x3f); - (void)zyd_write16(sc, ZYD_CR203, 0x06); - (void)zyd_write16(sc, ZYD_CR240, 0x08); - - return 0; + zyd_write16_m(sc, ZYD_CR251, 0x3f); + zyd_write16_m(sc, ZYD_CR203, 0x06); + zyd_write16_m(sc, ZYD_CR240, 0x08); +fail: + return (error); #undef N } @@ -1171,29 +1316,27 @@ zyd_al2210_init(struct zyd_rf *rf) uint32_t tmp; int i, error; - (void)zyd_write32(sc, ZYD_CR18, 2); + zyd_write32_m(sc, ZYD_CR18, 2); /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) { - error = zyd_write16(sc, phyini[i].reg, phyini[i].val); - if (error != 0) - return error; - } + for (i = 0; i < N(phyini); i++) + zyd_write16_m(sc, phyini[i].reg, phyini[i].val); + /* init AL2210 radio */ for (i = 0; i < N(rfini); i++) { if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return error; + return (error); } - (void)zyd_write16(sc, ZYD_CR47, 0x1e); - (void)zyd_read32(sc, ZYD_CR_RADIO_PD, &tmp); - (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1); - (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp | 1); - (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x05); - (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x00); - (void)zyd_write16(sc, ZYD_CR47, 0x1e); - (void)zyd_write32(sc, ZYD_CR18, 3); - - return 0; + zyd_write16_m(sc, ZYD_CR47, 0x1e); + zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp); + zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1); + zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1); + zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05); + zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00); + zyd_write16_m(sc, ZYD_CR47, 0x1e); + zyd_write32_m(sc, ZYD_CR18, 3); +fail: + return (error); #undef N } @@ -1202,32 +1345,34 @@ zyd_al2210_switch_radio(struct zyd_rf *rf, int on) { /* vendor driver does nothing for this RF chip */ - return 0; + return (0); } static int zyd_al2210_set_channel(struct zyd_rf *rf, uint8_t chan) { + int error; struct zyd_softc *sc = rf->rf_sc; static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE; uint32_t tmp; - (void)zyd_write32(sc, ZYD_CR18, 2); - (void)zyd_write16(sc, ZYD_CR47, 0x1e); - (void)zyd_read32(sc, ZYD_CR_RADIO_PD, &tmp); - (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1); - (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp | 1); - (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x05); - - (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x00); - (void)zyd_write16(sc, ZYD_CR47, 0x1e); + zyd_write32_m(sc, ZYD_CR18, 2); + zyd_write16_m(sc, ZYD_CR47, 0x1e); + zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp); + zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1); + zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1); + zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05); + zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00); + zyd_write16_m(sc, ZYD_CR47, 0x1e); /* actually set the channel */ - (void)zyd_rfwrite(sc, rfprog[chan - 1]); + error = zyd_rfwrite(sc, rfprog[chan - 1]); + if (error != 0) + goto fail; - (void)zyd_write32(sc, ZYD_CR18, 3); - - return 0; + zyd_write32_m(sc, ZYD_CR18, 3); +fail: + return (error); } /* @@ -1243,17 +1388,16 @@ zyd_gct_init(struct zyd_rf *rf) int i, error; /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) { - error = zyd_write16(sc, phyini[i].reg, phyini[i].val); - if (error != 0) - return error; - } + for (i = 0; i < N(phyini); i++) + zyd_write16_m(sc, phyini[i].reg, phyini[i].val); + /* init cgt radio */ for (i = 0; i < N(rfini); i++) { if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return error; + return (error); } - return 0; +fail: + return (error); #undef N } @@ -1262,20 +1406,25 @@ zyd_gct_switch_radio(struct zyd_rf *rf, int on) { /* vendor driver does nothing for this RF chip */ - return 0; + return (0); } static int zyd_gct_set_channel(struct zyd_rf *rf, uint8_t chan) { + int error; struct zyd_softc *sc = rf->rf_sc; static const uint32_t rfprog[] = ZYD_GCT_CHANTABLE; - (void)zyd_rfwrite(sc, 0x1c0000); - (void)zyd_rfwrite(sc, rfprog[chan - 1]); - (void)zyd_rfwrite(sc, 0x1c0008); - - return 0; + error = zyd_rfwrite(sc, 0x1c0000); + if (error != 0) + goto fail; + error = zyd_rfwrite(sc, rfprog[chan - 1]); + if (error != 0) + goto fail; + error = zyd_rfwrite(sc, 0x1c0008); +fail: + return (error); } /* @@ -1292,32 +1441,30 @@ zyd_maxim_init(struct zyd_rf *rf) int i, error; /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) { - error = zyd_write16(sc, phyini[i].reg, phyini[i].val); - if (error != 0) - return error; - } - (void)zyd_read16(sc, ZYD_CR203, &tmp); - (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4)); + for (i = 0; i < N(phyini); i++) + zyd_write16_m(sc, phyini[i].reg, phyini[i].val); + + zyd_read16_m(sc, ZYD_CR203, &tmp); + zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); /* init maxim radio */ for (i = 0; i < N(rfini); i++) { if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return error; + return (error); } - (void)zyd_read16(sc, ZYD_CR203, &tmp); - (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4)); - - return 0; + zyd_read16_m(sc, ZYD_CR203, &tmp); + zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); +fail: + return (error); #undef N } static int zyd_maxim_switch_radio(struct zyd_rf *rf, int on) { - /* vendor driver does nothing for this RF chip */ - return 0; + /* vendor driver does nothing for this RF chip */ + return (0); } static int @@ -1339,27 +1486,29 @@ zyd_maxim_set_channel(struct zyd_rf *rf, uint8_t chan) */ /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) { - error = zyd_write16(sc, phyini[i].reg, phyini[i].val); - if (error != 0) - return error; - } - (void)zyd_read16(sc, ZYD_CR203, &tmp); - (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4)); + for (i = 0; i < N(phyini); i++) + zyd_write16_m(sc, phyini[i].reg, phyini[i].val); + + zyd_read16_m(sc, ZYD_CR203, &tmp); + zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); /* first two values taken from the chantables */ - (void)zyd_rfwrite(sc, rfprog[chan - 1].r1); - (void)zyd_rfwrite(sc, rfprog[chan - 1].r2); + error = zyd_rfwrite(sc, rfprog[chan - 1].r1); + if (error != 0) + goto fail; + error = zyd_rfwrite(sc, rfprog[chan - 1].r2); + if (error != 0) + goto fail; /* init maxim radio - skipping the two first values */ for (i = 2; i < N(rfini); i++) { if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return error; + return (error); } - (void)zyd_read16(sc, ZYD_CR203, &tmp); - (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4)); - - return 0; + zyd_read16_m(sc, ZYD_CR203, &tmp); + zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); +fail: + return (error); #undef N } @@ -1377,32 +1526,30 @@ zyd_maxim2_init(struct zyd_rf *rf) int i, error; /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) { - error = zyd_write16(sc, phyini[i].reg, phyini[i].val); - if (error != 0) - return error; - } - (void)zyd_read16(sc, ZYD_CR203, &tmp); - (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4)); + for (i = 0; i < N(phyini); i++) + zyd_write16_m(sc, phyini[i].reg, phyini[i].val); + + zyd_read16_m(sc, ZYD_CR203, &tmp); + zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); /* init maxim2 radio */ for (i = 0; i < N(rfini); i++) { if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return error; + return (error); } - (void)zyd_read16(sc, ZYD_CR203, &tmp); - (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4)); - - return 0; + zyd_read16_m(sc, ZYD_CR203, &tmp); + zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); +fail: + return (error); #undef N } static int zyd_maxim2_switch_radio(struct zyd_rf *rf, int on) { - /* vendor driver does nothing for this RF chip */ - return 0; + /* vendor driver does nothing for this RF chip */ + return (0); } static int @@ -1424,27 +1571,29 @@ zyd_maxim2_set_channel(struct zyd_rf *rf, uint8_t chan) */ /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) { - error = zyd_write16(sc, phyini[i].reg, phyini[i].val); - if (error != 0) - return error; - } - (void)zyd_read16(sc, ZYD_CR203, &tmp); - (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4)); + for (i = 0; i < N(phyini); i++) + zyd_write16_m(sc, phyini[i].reg, phyini[i].val); + + zyd_read16_m(sc, ZYD_CR203, &tmp); + zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); /* first two values taken from the chantables */ - (void)zyd_rfwrite(sc, rfprog[chan - 1].r1); - (void)zyd_rfwrite(sc, rfprog[chan - 1].r2); + error = zyd_rfwrite(sc, rfprog[chan - 1].r1); + if (error != 0) + goto fail; + error = zyd_rfwrite(sc, rfprog[chan - 1].r2); + if (error != 0) + goto fail; /* init maxim2 radio - skipping the two first values */ for (i = 2; i < N(rfini); i++) { if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return error; + return (error); } - (void)zyd_read16(sc, ZYD_CR203, &tmp); - (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4)); - - return 0; + zyd_read16_m(sc, ZYD_CR203, &tmp); + zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); +fail: + return (error); #undef N } @@ -1463,12 +1612,16 @@ zyd_rf_attach(struct zyd_softc *sc, uint8_t type) rf->width = 24; /* 24-bit RF values */ break; case ZYD_RF_AL2230: - if (sc->mac_rev == ZYD_ZD1211B) + case ZYD_RF_AL2230S: + if (sc->sc_macrev == ZYD_ZD1211B) { rf->init = zyd_al2230_init_b; - else + rf->set_channel = zyd_al2230_set_channel_b; + } else { rf->init = zyd_al2230_init; + rf->set_channel = zyd_al2230_set_channel; + } rf->switch_radio = zyd_al2230_switch_radio; - rf->set_channel = zyd_al2230_set_channel; + rf->bandedge6 = zyd_al2230_bandedge6; rf->width = 24; /* 24-bit RF values */ break; case ZYD_RF_AL7230B: @@ -1505,9 +1658,9 @@ zyd_rf_attach(struct zyd_softc *sc, uint8_t type) device_printf(sc->sc_dev, "sorry, radio \"%s\" is not supported yet\n", zyd_rf_name(type)); - return EINVAL; + return (EINVAL); } - return 0; + return (0); } static const char * @@ -1516,7 +1669,7 @@ zyd_rf_name(uint8_t type) static const char * const zyd_rfs[] = { "unknown", "unknown", "UW2451", "UCHIP", "AL2230", "AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT", - "PV2000", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2", + "AL2230S", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2", "PHILIPS" }; @@ -1526,173 +1679,211 @@ zyd_rf_name(uint8_t type) static int zyd_hw_init(struct zyd_softc *sc) { - struct zyd_rf *rf = &sc->sc_rf; - const struct zyd_phy_pair *phyp; - uint32_t tmp; int error; + const struct zyd_phy_pair *phyp; + struct zyd_rf *rf = &sc->sc_rf; + uint16_t val; /* specify that the plug and play is finished */ - (void)zyd_write32(sc, ZYD_MAC_AFTER_PNP, 1); - - (void)zyd_read16(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->fwbase); - DPRINTF(("firmware base address=0x%04x\n", sc->fwbase)); + zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1); + zyd_read16_m(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->sc_fwbase); + DPRINTF(sc, ZYD_DEBUG_FW, "firmware base address=0x%04x\n", + sc->sc_fwbase); /* retrieve firmware revision number */ - (void)zyd_read16(sc, sc->fwbase + ZYD_FW_FIRMWARE_REV, &sc->fw_rev); - - (void)zyd_write32(sc, ZYD_CR_GPI_EN, 0); - (void)zyd_write32(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f); + zyd_read16_m(sc, sc->sc_fwbase + ZYD_FW_FIRMWARE_REV, &sc->sc_fwrev); + zyd_write32_m(sc, ZYD_CR_GPI_EN, 0); + zyd_write32_m(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f); + /* set mandatory rates - XXX assumes 802.11b/g */ + zyd_write32_m(sc, ZYD_MAC_MAN_RATE, 0x150f); /* disable interrupts */ - (void)zyd_write32(sc, ZYD_CR_INTERRUPT, 0); + zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0); - /* PHY init */ - zyd_lock_phy(sc); - phyp = (sc->mac_rev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy; - for (; phyp->reg != 0; phyp++) { - if ((error = zyd_write16(sc, phyp->reg, phyp->val)) != 0) - goto fail; + if ((error = zyd_read_pod(sc)) != 0) { + device_printf(sc->sc_dev, "could not read EEPROM\n"); + goto fail; } - if (sc->fix_cr157) { - if (zyd_read32(sc, ZYD_EEPROM_PHY_REG, &tmp) == 0) - (void)zyd_write32(sc, ZYD_CR157, tmp >> 8); + + /* PHY init (resetting) */ + error = zyd_lock_phy(sc); + if (error != 0) + goto fail; + phyp = (sc->sc_macrev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy; + for (; phyp->reg != 0; phyp++) + zyd_write16_m(sc, phyp->reg, phyp->val); + if (sc->sc_macrev == ZYD_ZD1211 && sc->sc_fix_cr157 != 0) { + zyd_read16_m(sc, ZYD_EEPROM_PHY_REG, &val); + zyd_write32_m(sc, ZYD_CR157, val >> 8); } - zyd_unlock_phy(sc); + error = zyd_unlock_phy(sc); + if (error != 0) + goto fail; /* HMAC init */ - zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000020); - zyd_write32(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808); + zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000020); + zyd_write32_m(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808); + zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0x00000000); + zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0x00000000); + zyd_write32_m(sc, ZYD_MAC_GHTBL, 0x00000000); + zyd_write32_m(sc, ZYD_MAC_GHTBH, 0x80000000); + zyd_write32_m(sc, ZYD_MAC_MISC, 0x000000a4); + zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f); + zyd_write32_m(sc, ZYD_MAC_BCNCFG, 0x00f00401); + zyd_write32_m(sc, ZYD_MAC_PHY_DELAY2, 0x00000000); + zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000080); + zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000); + zyd_write32_m(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100); + zyd_write32_m(sc, ZYD_CR_RX_PE_DELAY, 0x00000070); + zyd_write32_m(sc, ZYD_CR_PS_CTRL, 0x10000000); + zyd_write32_m(sc, ZYD_MAC_RTSCTSRATE, 0x02030203); + zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1); + zyd_write32_m(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114); + zyd_write32_m(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0a47c032); + zyd_write32_m(sc, ZYD_MAC_CAM_MODE, 0x3); - if (sc->mac_rev == ZYD_ZD1211) { - zyd_write32(sc, ZYD_MAC_RETRY, 0x00000002); + if (sc->sc_macrev == ZYD_ZD1211) { + zyd_write32_m(sc, ZYD_MAC_RETRY, 0x00000002); + zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640); } else { - zyd_write32(sc, ZYD_MACB_MAX_RETRY, 0x02020202); - zyd_write32(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f); - zyd_write32(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f); - zyd_write32(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f); - zyd_write32(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f); - zyd_write32(sc, ZYD_MACB_AIFS_CTL1, 0x00280028); - zyd_write32(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C); - zyd_write32(sc, ZYD_MACB_TXOP, 0x01800824); - } - - zyd_write32(sc, ZYD_MAC_SNIFFER, 0x00000000); - zyd_write32(sc, ZYD_MAC_RXFILTER, 0x00000000); - zyd_write32(sc, ZYD_MAC_GHTBL, 0x00000000); - zyd_write32(sc, ZYD_MAC_GHTBH, 0x80000000); - zyd_write32(sc, ZYD_MAC_MISC, 0x000000a4); - zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f); - zyd_write32(sc, ZYD_MAC_BCNCFG, 0x00f00401); - zyd_write32(sc, ZYD_MAC_PHY_DELAY2, 0x00000000); - zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000080); - zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000); - zyd_write32(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100); - zyd_write32(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0547c032); - zyd_write32(sc, ZYD_CR_RX_PE_DELAY, 0x00000070); - zyd_write32(sc, ZYD_CR_PS_CTRL, 0x10000000); - zyd_write32(sc, ZYD_MAC_RTSCTSRATE, 0x02030203); - zyd_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640); - zyd_write32(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114); - - /* RF chip init */ - zyd_lock_phy(sc); - error = (*rf->init)(rf); - zyd_unlock_phy(sc); - if (error != 0) { - device_printf(sc->sc_dev, - "radio initialization failed, error %d\n", error); - goto fail; + zyd_write32_m(sc, ZYD_MACB_MAX_RETRY, 0x02020202); + zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f); + zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f); + zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f); + zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f); + zyd_write32_m(sc, ZYD_MACB_AIFS_CTL1, 0x00280028); + zyd_write32_m(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C); + zyd_write32_m(sc, ZYD_MACB_TXOP, 0x01800824); + zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0eff); } /* init beacon interval to 100ms */ if ((error = zyd_set_beacon_interval(sc, 100)) != 0) goto fail; -fail: return error; + if ((error = zyd_rf_attach(sc, sc->sc_rfrev)) != 0) { + device_printf(sc->sc_dev, "could not attach RF, rev 0x%x\n", + sc->sc_rfrev); + goto fail; + } + + /* RF chip init */ + error = zyd_lock_phy(sc); + if (error != 0) + goto fail; + error = (*rf->init)(rf); + if (error != 0) { + device_printf(sc->sc_dev, + "radio initialization failed, error %d\n", error); + goto fail; + } + error = zyd_unlock_phy(sc); + if (error != 0) + goto fail; + + if ((error = zyd_read_eeprom(sc)) != 0) { + device_printf(sc->sc_dev, "could not read EEPROM\n"); + goto fail; + } + +fail: return (error); +} + +static int +zyd_read_pod(struct zyd_softc *sc) +{ + int error; + uint32_t tmp; + + zyd_read32_m(sc, ZYD_EEPROM_POD, &tmp); + sc->sc_rfrev = tmp & 0x0f; + sc->sc_ledtype = (tmp >> 4) & 0x01; + sc->sc_al2230s = (tmp >> 7) & 0x01; + sc->sc_cckgain = (tmp >> 8) & 0x01; + sc->sc_fix_cr157 = (tmp >> 13) & 0x01; + sc->sc_parev = (tmp >> 16) & 0x0f; + sc->sc_bandedge6 = (tmp >> 21) & 0x01; + sc->sc_newphy = (tmp >> 31) & 0x01; + sc->sc_txled = ((tmp & (1 << 24)) && (tmp & (1 << 29))) ? 0 : 1; +fail: + return (error); } static int zyd_read_eeprom(struct zyd_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint32_t tmp; uint16_t val; - int i; - - /* read MAC address */ - (void)zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P1, &tmp); - ic->ic_myaddr[0] = tmp & 0xff; - ic->ic_myaddr[1] = tmp >> 8; - ic->ic_myaddr[2] = tmp >> 16; - ic->ic_myaddr[3] = tmp >> 24; - (void)zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P2, &tmp); - ic->ic_myaddr[4] = tmp & 0xff; - ic->ic_myaddr[5] = tmp >> 8; - - (void)zyd_read32(sc, ZYD_EEPROM_POD, &tmp); - sc->rf_rev = tmp & 0x0f; - sc->fix_cr47 = (tmp >> 8 ) & 0x01; - sc->fix_cr157 = (tmp >> 13) & 0x01; - sc->pa_rev = (tmp >> 16) & 0x0f; - - /* read regulatory domain (currently unused) */ - (void)zyd_read32(sc, ZYD_EEPROM_SUBID, &tmp); - sc->regdomain = tmp >> 16; - DPRINTF(("regulatory domain %x\n", sc->regdomain)); - /* XXX propagate to net80211 after mapping to SKU */ + int error, i; /* read Tx power calibration tables */ for (i = 0; i < 7; i++) { - (void)zyd_read16(sc, ZYD_EEPROM_PWR_CAL + i, &val); - sc->pwr_cal[i * 2] = val >> 8; - sc->pwr_cal[i * 2 + 1] = val & 0xff; - - (void)zyd_read16(sc, ZYD_EEPROM_PWR_INT + i, &val); - sc->pwr_int[i * 2] = val >> 8; - sc->pwr_int[i * 2 + 1] = val & 0xff; - - (void)zyd_read16(sc, ZYD_EEPROM_36M_CAL + i, &val); - sc->ofdm36_cal[i * 2] = val >> 8; - sc->ofdm36_cal[i * 2 + 1] = val & 0xff; - - (void)zyd_read16(sc, ZYD_EEPROM_48M_CAL + i, &val); - sc->ofdm48_cal[i * 2] = val >> 8; - sc->ofdm48_cal[i * 2 + 1] = val & 0xff; - - (void)zyd_read16(sc, ZYD_EEPROM_54M_CAL + i, &val); - sc->ofdm54_cal[i * 2] = val >> 8; - sc->ofdm54_cal[i * 2 + 1] = val & 0xff; + zyd_read16_m(sc, ZYD_EEPROM_PWR_CAL + i, &val); + sc->sc_pwrcal[i * 2] = val >> 8; + sc->sc_pwrcal[i * 2 + 1] = val & 0xff; + zyd_read16_m(sc, ZYD_EEPROM_PWR_INT + i, &val); + sc->sc_pwrint[i * 2] = val >> 8; + sc->sc_pwrint[i * 2 + 1] = val & 0xff; + zyd_read16_m(sc, ZYD_EEPROM_36M_CAL + i, &val); + sc->sc_ofdm36_cal[i * 2] = val >> 8; + sc->sc_ofdm36_cal[i * 2 + 1] = val & 0xff; + zyd_read16_m(sc, ZYD_EEPROM_48M_CAL + i, &val); + sc->sc_ofdm48_cal[i * 2] = val >> 8; + sc->sc_ofdm48_cal[i * 2 + 1] = val & 0xff; + zyd_read16_m(sc, ZYD_EEPROM_54M_CAL + i, &val); + sc->sc_ofdm54_cal[i * 2] = val >> 8; + sc->sc_ofdm54_cal[i * 2 + 1] = val & 0xff; } - return 0; +fail: + return (error); +} + +static int +zyd_get_macaddr(struct zyd_softc *sc) +{ + usb_device_request_t req; + usbd_status error; + + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = ZYD_READFWDATAREQ; + USETW(req.wValue, ZYD_EEPROM_MAC_ADDR_P1); + USETW(req.wIndex, 0); + USETW(req.wLength, IEEE80211_ADDR_LEN); + + error = usbd_do_request(sc->sc_udev, &req, sc->sc_bssid); + if (error != 0) { + device_printf(sc->sc_dev, "could not read EEPROM: %s\n", + usbd_errstr(error)); + } + + return (error); } static int zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr) { + int error; uint32_t tmp; tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]; - (void)zyd_write32(sc, ZYD_MAC_MACADRL, tmp); - + zyd_write32_m(sc, ZYD_MAC_MACADRL, tmp); tmp = addr[5] << 8 | addr[4]; - (void)zyd_write32(sc, ZYD_MAC_MACADRH, tmp); - - return 0; + zyd_write32_m(sc, ZYD_MAC_MACADRH, tmp); +fail: + return (error); } static int zyd_set_bssid(struct zyd_softc *sc, const uint8_t *addr) { + int error; uint32_t tmp; tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]; - (void)zyd_write32(sc, ZYD_MAC_BSSADRL, tmp); - + zyd_write32_m(sc, ZYD_MAC_BSSADRL, tmp); tmp = addr[5] << 8 | addr[4]; - (void)zyd_write32(sc, ZYD_MAC_BSSADRH, tmp); - - return 0; + zyd_write32_m(sc, ZYD_MAC_BSSADRH, tmp); +fail: + return (error); } static int @@ -1701,28 +1892,36 @@ zyd_switch_radio(struct zyd_softc *sc, int on) struct zyd_rf *rf = &sc->sc_rf; int error; - zyd_lock_phy(sc); + error = zyd_lock_phy(sc); + if (error != 0) + goto fail; error = (*rf->switch_radio)(rf, on); - zyd_unlock_phy(sc); - - return error; + if (error != 0) + goto fail; + error = zyd_unlock_phy(sc); +fail: + return (error); } -static void +static int zyd_set_led(struct zyd_softc *sc, int which, int on) { + int error; uint32_t tmp; - (void)zyd_read32(sc, ZYD_MAC_TX_PE_CONTROL, &tmp); + zyd_read32_m(sc, ZYD_MAC_TX_PE_CONTROL, &tmp); tmp &= ~which; if (on) tmp |= which; - (void)zyd_write32(sc, ZYD_MAC_TX_PE_CONTROL, tmp); + zyd_write32_m(sc, ZYD_MAC_TX_PE_CONTROL, tmp); +fail: + return (error); } static void zyd_set_multi(void *arg) { + int error; struct zyd_softc *sc = arg; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; @@ -1756,8 +1955,12 @@ zyd_set_multi(void *arg) } /* reprogram multicast global hash table */ - zyd_write32(sc, ZYD_MAC_GHTBL, low); - zyd_write32(sc, ZYD_MAC_GHTBH, high); + zyd_write32_m(sc, ZYD_MAC_GHTBL, low); + zyd_write32_m(sc, ZYD_MAC_GHTBH, high); +fail: + if (error != 0) + device_printf(sc->sc_dev, + "could not set multicast hash table\n"); } static void @@ -1765,6 +1968,9 @@ zyd_update_mcast(struct ifnet *ifp) { struct zyd_softc *sc = ifp->if_softc; + if (!(sc->sc_flags & ZYD_FLAG_INITDONE)) + return; + usb_add_task(sc->sc_udev, &sc->sc_mcasttask, USB_TASKQ_DRIVER); } @@ -1788,7 +1994,7 @@ zyd_set_rxfilter(struct zyd_softc *sc) break; default: /* should not get there */ - return EINVAL; + return (EINVAL); } return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter); } @@ -1796,6 +2002,7 @@ zyd_set_rxfilter(struct zyd_softc *sc) static void zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c) { + int error; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; struct zyd_rf *rf = &sc->sc_rf; @@ -1810,49 +2017,73 @@ zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c) return; } - zyd_lock_phy(sc); + error = zyd_lock_phy(sc); + if (error != 0) + goto fail; - (*rf->set_channel)(rf, chan); + error = (*rf->set_channel)(rf, chan); + if (error != 0) + goto fail; /* update Tx power */ - (void)zyd_write16(sc, ZYD_CR31, sc->pwr_int[chan - 1]); + zyd_write16_m(sc, ZYD_CR31, sc->sc_pwrint[chan - 1]); - if (sc->mac_rev == ZYD_ZD1211B) { - (void)zyd_write16(sc, ZYD_CR67, sc->ofdm36_cal[chan - 1]); - (void)zyd_write16(sc, ZYD_CR66, sc->ofdm48_cal[chan - 1]); - (void)zyd_write16(sc, ZYD_CR65, sc->ofdm54_cal[chan - 1]); - - (void)zyd_write16(sc, ZYD_CR68, sc->pwr_cal[chan - 1]); - - (void)zyd_write16(sc, ZYD_CR69, 0x28); - (void)zyd_write16(sc, ZYD_CR69, 0x2a); + if (sc->sc_macrev == ZYD_ZD1211B) { + zyd_write16_m(sc, ZYD_CR67, sc->sc_ofdm36_cal[chan - 1]); + zyd_write16_m(sc, ZYD_CR66, sc->sc_ofdm48_cal[chan - 1]); + zyd_write16_m(sc, ZYD_CR65, sc->sc_ofdm54_cal[chan - 1]); + zyd_write16_m(sc, ZYD_CR68, sc->sc_pwrcal[chan - 1]); + zyd_write16_m(sc, ZYD_CR69, 0x28); + zyd_write16_m(sc, ZYD_CR69, 0x2a); } - - if (sc->fix_cr47) { + if (sc->sc_cckgain) { /* set CCK baseband gain from EEPROM */ if (zyd_read32(sc, ZYD_EEPROM_PHY_REG, &tmp) == 0) - (void)zyd_write16(sc, ZYD_CR47, tmp & 0xff); + zyd_write16_m(sc, ZYD_CR47, tmp & 0xff); } + if (sc->sc_bandedge6 && rf->bandedge6 != NULL) { + error = (*rf->bandedge6)(rf, c); + if (error != 0) + goto fail; + } + zyd_write32_m(sc, ZYD_CR_CONFIG_PHILIPS, 0); - (void)zyd_write32(sc, ZYD_CR_CONFIG_PHILIPS, 0); - - zyd_unlock_phy(sc); + error = zyd_unlock_phy(sc); + if (error != 0) + goto fail; sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq); sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags); +fail: + return; } static int zyd_set_beacon_interval(struct zyd_softc *sc, int bintval) { - /* XXX this is probably broken.. */ - (void)zyd_write32(sc, ZYD_CR_ATIM_WND_PERIOD, bintval - 2); - (void)zyd_write32(sc, ZYD_CR_PRE_TBTT, bintval - 1); - (void)zyd_write32(sc, ZYD_CR_BCN_INTERVAL, bintval); + int error; + uint32_t val; - return 0; + zyd_read32_m(sc, ZYD_CR_ATIM_WND_PERIOD, &val); + sc->sc_atim_wnd = val; + zyd_read32_m(sc, ZYD_CR_PRE_TBTT, &val); + sc->sc_pre_tbtt = val; + sc->sc_bcn_int = bintval; + + if (sc->sc_bcn_int <= 5) + sc->sc_bcn_int = 5; + if (sc->sc_pre_tbtt < 4 || sc->sc_pre_tbtt >= sc->sc_bcn_int) + sc->sc_pre_tbtt = sc->sc_bcn_int - 1; + if (sc->sc_atim_wnd >= sc->sc_pre_tbtt) + sc->sc_atim_wnd = sc->sc_pre_tbtt - 1; + + zyd_write32_m(sc, ZYD_CR_ATIM_WND_PERIOD, sc->sc_atim_wnd); + zyd_write32_m(sc, ZYD_CR_PRE_TBTT, sc->sc_pre_tbtt); + zyd_write32_m(sc, ZYD_CR_BCN_INTERVAL, sc->sc_bcn_int); +fail: + return (error); } static void @@ -1868,12 +2099,12 @@ zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) if (status == USBD_STALLED) { usbd_clear_endpoint_stall_async( - sc->zyd_ep[ZYD_ENDPT_IIN]); + sc->sc_ep[ZYD_ENDPT_IIN]); } return; } - cmd = (struct zyd_cmd *)sc->ibuf; + cmd = (struct zyd_cmd *)sc->sc_ibuf; if (le16toh(cmd->code) == ZYD_NOTIF_RETRYSTATUS) { struct zyd_notif_retry *retry = @@ -1883,9 +2114,10 @@ zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni; - DPRINTF(("retry intr: rate=0x%x addr=%s count=%d (0x%x)\n", + DPRINTF(sc, ZYD_DEBUG_TX_PROC, + "retry intr: rate=0x%x addr=%s count=%d (0x%x)\n", le16toh(retry->rate), ether_sprintf(retry->macaddr), - le16toh(retry->count) & 0xff, le16toh(retry->count))); + le16toh(retry->count) & 0xff, le16toh(retry->count)); /* * Find the node to which the packet was sent and update its @@ -1901,7 +2133,7 @@ zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) if (le16toh(retry->count) & 0x100) ifp->if_oerrors++; /* too many retries */ } else if (le16toh(cmd->code) == ZYD_NOTIF_IORD) { - struct rq *rqp; + struct zyd_rq *rqp; if (le16toh(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT) return; /* HMAC interrupt */ @@ -1949,8 +2181,8 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) int rlen, rssi, nf; if (len < ZYD_MIN_FRAGSZ) { - DPRINTF(("%s: frame too short (length=%d)\n", - device_get_nameunit(sc->sc_dev), len)); + DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n", + device_get_nameunit(sc->sc_dev), len); ifp->if_ierrors++; return; } @@ -1960,8 +2192,9 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) (buf + len - sizeof(struct zyd_rx_stat)); if (stat->flags & ZYD_RX_ERROR) { - DPRINTF(("%s: RX status indicated error (%x)\n", - device_get_nameunit(sc->sc_dev), stat->flags)); + DPRINTF(sc, ZYD_DEBUG_RECV, + "%s: RX status indicated error (%x)\n", + device_get_nameunit(sc->sc_dev), stat->flags); ifp->if_ierrors++; return; } @@ -1976,8 +2209,8 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) else m = m_gethdr(M_DONTWAIT, MT_DATA); if (m == NULL) { - DPRINTF(("%s: could not allocate rx mbuf\n", - device_get_nameunit(sc->sc_dev))); + DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n", + device_get_nameunit(sc->sc_dev)); ifp->if_ierrors++; return; } @@ -2008,10 +2241,10 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { - (void) ieee80211_input(ni, m, rssi, nf, 0); + (void)ieee80211_input(ni, m, rssi, nf, 0); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, rssi, nf, 0); + (void)ieee80211_input_all(ic, m, rssi, nf, 0); } static void @@ -2028,15 +2261,15 @@ zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) return; if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->zyd_ep[ZYD_ENDPT_BIN]); + usbd_clear_endpoint_stall(sc->sc_ep[ZYD_ENDPT_BIN]); goto skip; } usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); if (len < ZYD_MIN_RXBUFSZ) { - DPRINTFN(3, ("%s: xfer too short (length=%d)\n", - device_get_nameunit(sc->sc_dev), len)); + DPRINTF(sc, ZYD_DEBUG_RECV, "%s: xfer too short (length=%d)\n", + device_get_nameunit(sc->sc_dev), len); ifp->if_ierrors++; /* XXX not really errors */ goto skip; } @@ -2048,7 +2281,8 @@ zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) const uint8_t *p = data->buf, *end = p + len; int i; - DPRINTFN(3, ("received multi-frame transfer\n")); + DPRINTF(sc, ZYD_DEBUG_RECV, + "%s: received multi-frame transfer\n", __func__); for (i = 0; i < ZYD_MAX_RXFRAMECNT; i++) { const uint16_t len16 = UGETW(desc->len[i]); @@ -2061,13 +2295,14 @@ zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) p += (len16 + 3) & ~3; } } else { - DPRINTFN(3, ("received single-frame transfer\n")); + DPRINTF(sc, ZYD_DEBUG_RECV, + "%s: received single-frame transfer\n", __func__); zyd_rx_data(sc, data->buf, len); } skip: /* setup a new transfer */ - usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data, NULL, + usbd_setup_xfer(xfer, sc->sc_ep[ZYD_ENDPT_BIN], data, NULL, ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, zyd_rxeof); (void)usbd_transfer(xfer); @@ -2078,22 +2313,33 @@ zyd_plcp_signal(int rate) { switch (rate) { /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - + case 12: + return (0xb); + case 18: + return (0xf); + case 24: + return (0xa); + case 36: + return (0xe); + case 48: + return (0x9); + case 72: + return (0xd); + case 96: + return (0x8); + case 108: + return (0xc); /* CCK rates (NB: not IEEE std, device-specific) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; + case 2: + return (0x0); + case 4: + return (0x1); + case 11: + return (0x2); + case 22: + return (0x3); } - return 0xff; /* XXX unsupported/unknown rate */ + return (0xff); /* XXX unsupported/unknown rate */ } static int @@ -2106,11 +2352,14 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) struct zyd_tx_data *data; struct ieee80211_frame *wh; struct ieee80211_key *k; - int xferlen, totlen, rate; + int data_idx, rate, totlen, xferlen; uint16_t pktlen; usbd_status error; - data = &sc->tx_data[0]; + data_idx = sc->sc_txidx; + sc->sc_txidx = (sc->sc_txidx + 1) % ZYD_TX_LIST_CNT; + + data = &sc->sc_txdata[data_idx]; desc = (struct zyd_tx_desc *)data->buf; rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; @@ -2121,7 +2370,7 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); - return ENOBUFS; + return (ENOBUFS); } } @@ -2166,7 +2415,7 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) /* actual transmit length (XXX why +10?) */ pktlen = sizeof(struct zyd_tx_desc) + 10; - if (sc->mac_rev == ZYD_ZD1211) + if (sc->sc_macrev == ZYD_ZD1211) pktlen += totlen; desc->pktlen = htole16(pktlen); @@ -2190,21 +2439,22 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + sizeof(struct zyd_tx_desc)); - DPRINTFN(10, ("%s: sending mgt frame len=%zu rate=%u xferlen=%u\n", + DPRINTF(sc, ZYD_DEBUG_XMIT, + "%s: sending mgt frame len=%zu rate=%u xferlen=%u\n", device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len, - rate, xferlen)); + rate, xferlen); - usbd_setup_xfer(data->xfer, sc->zyd_ep[ZYD_ENDPT_BOUT], data, + usbd_setup_xfer(data->xfer, sc->sc_ep[ZYD_ENDPT_BOUT], data, data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ZYD_TX_TIMEOUT, zyd_txeof); error = usbd_transfer(data->xfer); if (error != USBD_IN_PROGRESS && error != 0) { ifp->if_oerrors++; - return EIO; + return (EIO); } - sc->tx_queued++; + sc->sc_txqueued++; - return 0; + return (0); } static void @@ -2225,7 +2475,7 @@ zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) if (status == USBD_STALLED) { usbd_clear_endpoint_stall_async( - sc->zyd_ep[ZYD_ENDPT_BOUT]); + sc->sc_ep[ZYD_ENDPT_BOUT]); } ifp->if_oerrors++; return; @@ -2250,11 +2500,13 @@ zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) ieee80211_free_node(ni); data->ni = NULL; - sc->tx_queued--; - ifp->if_opackets++; - - sc->tx_timer = 0; + ZYD_TX_LOCK(sc); + sc->sc_txqueued--; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ZYD_TX_UNLOCK(sc); + + ifp->if_opackets++; + sc->sc_txtimer = 0; zyd_start(ifp); } @@ -2269,12 +2521,15 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) struct ieee80211_frame *wh; const struct ieee80211_txparam *tp; struct ieee80211_key *k; - int xferlen, totlen, rate; + int data_idx, rate, totlen, xferlen; uint16_t pktlen; usbd_status error; + data_idx = sc->sc_txidx; + sc->sc_txidx = (sc->sc_txidx + 1) % ZYD_TX_LIST_CNT; + wh = mtod(m0, struct ieee80211_frame *); - data = &sc->tx_data[0]; + data = &sc->sc_txdata[data_idx]; desc = (struct zyd_tx_desc *)data->buf; desc->flags = ZYD_TX_FLAG_BACKOFF; @@ -2293,9 +2548,8 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); - return ENOBUFS; + return (ENOBUFS); } - /* packet header may have moved, reset our local pointer */ wh = mtod(m0, struct ieee80211_frame *); } @@ -2337,7 +2591,7 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) /* actual transmit length (XXX why +10?) */ pktlen = sizeof(struct zyd_tx_desc) + 10; - if (sc->mac_rev == ZYD_ZD1211) + if (sc->sc_macrev == ZYD_ZD1211) pktlen += totlen; desc->pktlen = htole16(pktlen); @@ -2363,23 +2617,24 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + sizeof(struct zyd_tx_desc)); - DPRINTFN(10, ("%s: sending data frame len=%zu rate=%u xferlen=%u\n", + DPRINTF(sc, ZYD_DEBUG_XMIT, + "%s: sending data frame len=%zu rate=%u xferlen=%u\n", device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len, - rate, xferlen)); + rate, xferlen); m_freem(m0); /* mbuf no longer needed */ - usbd_setup_xfer(data->xfer, sc->zyd_ep[ZYD_ENDPT_BOUT], data, + usbd_setup_xfer(data->xfer, sc->sc_ep[ZYD_ENDPT_BOUT], data, data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ZYD_TX_TIMEOUT, zyd_txeof); error = usbd_transfer(data->xfer); if (error != USBD_IN_PROGRESS && error != 0) { ifp->if_oerrors++; - return EIO; + return (EIO); } - sc->tx_queued++; + sc->sc_txqueued++; - return 0; + return (0); } static void @@ -2389,11 +2644,12 @@ zyd_start(struct ifnet *ifp) struct ieee80211_node *ni; struct mbuf *m; + ZYD_TX_LOCK(sc); for (;;) { IFQ_DRV_DEQUEUE(&ifp->if_snd, m); if (m == NULL) break; - if (sc->tx_queued >= ZYD_TX_LIST_CNT) { + if (sc->sc_txqueued >= ZYD_TX_LIST_CNT) { IFQ_DRV_PREPEND(&ifp->if_snd, m); ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; @@ -2411,9 +2667,9 @@ zyd_start(struct ifnet *ifp) break; } - sc->tx_timer = 5; - callout_reset(&sc->sc_watchdog_ch, hz, zyd_watchdog, sc); + sc->sc_txtimer = 5; } + ZYD_TX_UNLOCK(sc); } static int @@ -2428,32 +2684,32 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { m_freem(m); ieee80211_free_node(ni); - return ENETDOWN; + return (ENETDOWN); } - if (sc->tx_queued >= ZYD_TX_LIST_CNT) { + ZYD_TX_LOCK(sc); + if (sc->sc_txqueued >= ZYD_TX_LIST_CNT) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; m_freem(m); ieee80211_free_node(ni); - return ENOBUFS; /* XXX */ + return (ENOBUFS); /* XXX */ } - ifp->if_opackets++; - /* * Legacy path; interpret frame contents to decide * precisely how to send the frame. * XXX raw path */ - if (zyd_tx_mgt(sc, m, ni) != 0) - goto bad; - sc->tx_timer = 5; - callout_reset(&sc->sc_watchdog_ch, hz, zyd_watchdog, sc); + if (zyd_tx_mgt(sc, m, ni) != 0) { + ZYD_TX_UNLOCK(sc); + ifp->if_oerrors++; + ieee80211_free_node(ni); + return (EIO); + } - return 0; -bad: - ifp->if_oerrors++; - ieee80211_free_node(ni); - return EIO; /* XXX */ + ZYD_TX_UNLOCK(sc); + ifp->if_opackets++; + sc->sc_txtimer = 5; + return (0); } static void @@ -2462,8 +2718,8 @@ zyd_watchdog(void *arg) struct zyd_softc *sc = arg; struct ifnet *ifp = sc->sc_ifp; - if (sc->tx_timer > 0) { - if (--sc->tx_timer == 0) { + if (sc->sc_txtimer > 0) { + if (--sc->sc_txtimer == 0) { device_printf(sc->sc_dev, "device timeout\n"); /* zyd_init(ifp); XXX needs a process context ? */ ifp->if_oerrors++; @@ -2512,64 +2768,108 @@ zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) error = EINVAL; break; } - return error; + return (error); } static void zyd_init_locked(struct zyd_softc *sc) { + int error, i; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; - int i, error; + uint32_t val; - zyd_stop(sc, 0); + if (!(sc->sc_flags & ZYD_FLAG_INITONCE)) { + error = zyd_loadfirmware(sc); + if (error != 0) { + device_printf(sc->sc_dev, + "could not load firmware (error=%d)\n", error); + goto fail; + } + + error = usbd_set_config_no(sc->sc_udev, ZYD_CONFIG_NO, 1); + if (error != 0) { + device_printf(sc->sc_dev, "setting config no failed\n"); + goto fail; + } + error = usbd_device2interface_handle(sc->sc_udev, + ZYD_IFACE_INDEX, &sc->sc_iface); + if (error != 0) { + device_printf(sc->sc_dev, + "getting interface handle failed\n"); + goto fail; + } + + if ((error = zyd_open_pipes(sc)) != 0) { + device_printf(sc->sc_dev, "could not open pipes\n"); + goto fail; + } + if ((error = zyd_hw_init(sc)) != 0) { + device_printf(sc->sc_dev, + "hardware initialization failed\n"); + goto fail; + } + + device_printf(sc->sc_dev, + "HMAC ZD1211%s, FW %02x.%02x, RF %s S%x, PA%x LED %x " + "BE%x NP%x Gain%x F%x\n", + (sc->sc_macrev == ZYD_ZD1211) ? "": "B", + sc->sc_fwrev >> 8, sc->sc_fwrev & 0xff, + zyd_rf_name(sc->sc_rfrev), sc->sc_al2230s, sc->sc_parev, + sc->sc_ledtype, sc->sc_bandedge6, sc->sc_newphy, + sc->sc_cckgain, sc->sc_fix_cr157); + + /* read regulatory domain (currently unused) */ + zyd_read32_m(sc, ZYD_EEPROM_SUBID, &val); + sc->sc_regdomain = val >> 16; + DPRINTF(sc, ZYD_DEBUG_INIT, "regulatory domain %x\n", + sc->sc_regdomain); + + /* we'll do software WEP decryption for now */ + DPRINTF(sc, ZYD_DEBUG_INIT, "%s: setting encryption type\n", + __func__); + zyd_write32_m(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER); + + sc->sc_flags |= ZYD_FLAG_INITONCE; + } + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + zyd_stop(sc, 0); + + /* reset softc variables. */ + sc->sc_txidx = 0; IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - DPRINTF(("setting MAC address to %s\n", ether_sprintf(ic->ic_myaddr))); + DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %s\n", + ether_sprintf(ic->ic_myaddr)); error = zyd_set_macaddr(sc, ic->ic_myaddr); if (error != 0) return; - /* we'll do software WEP decryption for now */ - DPRINTF(("setting encryption type\n")); - error = zyd_write32(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER); - if (error != 0) - return; - - /* promiscuous mode */ - (void)zyd_write32(sc, ZYD_MAC_SNIFFER, 0); - - /* multicast setup */ - (void)zyd_set_multi(sc); - - (void)zyd_set_rxfilter(sc); - - /* switch radio transmitter ON */ - (void)zyd_switch_radio(sc, 1); - - /* XXX wrong, can't set here */ /* set basic rates */ if (ic->ic_curmode == IEEE80211_MODE_11B) - (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x0003); + zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x0003); else if (ic->ic_curmode == IEEE80211_MODE_11A) - (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x1500); + zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x1500); else /* assumes 802.11b/g */ - (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x000f); + zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0xff0f); - /* set mandatory rates */ - if (ic->ic_curmode == IEEE80211_MODE_11B) - (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x000f); - else if (ic->ic_curmode == IEEE80211_MODE_11A) - (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x1500); - else /* assumes 802.11b/g */ - (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x150f); + /* promiscuous mode */ + zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0); + /* multicast setup */ + zyd_set_multi(sc); + /* set RX filter */ + error = zyd_set_rxfilter(sc); + if (error != 0) + goto fail; + /* switch radio transmitter ON */ + error = zyd_switch_radio(sc, 1); + if (error != 0) + goto fail; /* set default BSS channel */ zyd_set_chan(sc, ic->ic_curchan); - /* enable interrupts */ - (void)zyd_write32(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK); - /* * Allocate Tx and Rx xfer queues. */ @@ -2586,9 +2886,9 @@ zyd_init_locked(struct zyd_softc *sc) * Start up the receive pipe. */ for (i = 0; i < ZYD_RX_LIST_CNT; i++) { - struct zyd_rx_data *data = &sc->rx_data[i]; + struct zyd_rx_data *data = &sc->sc_rxdata[i]; - usbd_setup_xfer(data->xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data, + usbd_setup_xfer(data->xfer, sc->sc_ep[ZYD_ENDPT_BIN], data, NULL, ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, zyd_rxeof); error = usbd_transfer(data->xfer); @@ -2599,8 +2899,14 @@ zyd_init_locked(struct zyd_softc *sc) } } + /* enable interrupts */ + zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= ZYD_FLAG_INITDONE; + + callout_reset(&sc->sc_watchdog_ch, hz, zyd_watchdog, sc); return; fail: zyd_stop(sc, 1); @@ -2625,35 +2931,53 @@ zyd_init(void *priv) static void zyd_stop(struct zyd_softc *sc, int disable) { + int error; struct ifnet *ifp = sc->sc_ifp; - sc->tx_timer = 0; + sc->sc_txtimer = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); /* switch radio transmitter OFF */ - (void)zyd_switch_radio(sc, 0); - + error = zyd_switch_radio(sc, 0); + if (error != 0) + goto fail; /* disable Rx */ - (void)zyd_write32(sc, ZYD_MAC_RXFILTER, 0); - + zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0); /* disable interrupts */ - (void)zyd_write32(sc, ZYD_CR_INTERRUPT, 0); + zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0); - usbd_abort_pipe(sc->zyd_ep[ZYD_ENDPT_BIN]); - usbd_abort_pipe(sc->zyd_ep[ZYD_ENDPT_BOUT]); + usb_rem_task(sc->sc_udev, &sc->sc_scantask); + usb_rem_task(sc->sc_udev, &sc->sc_task); + callout_stop(&sc->sc_watchdog_ch); + + usbd_abort_pipe(sc->sc_ep[ZYD_ENDPT_BIN]); + usbd_abort_pipe(sc->sc_ep[ZYD_ENDPT_BOUT]); zyd_free_rx_list(sc); zyd_free_tx_list(sc); +fail: + return; } static int -zyd_loadfirmware(struct zyd_softc *sc, u_char *fw, size_t size) +zyd_loadfirmware(struct zyd_softc *sc) { usb_device_request_t req; - uint16_t addr; + size_t size; + u_char *fw; uint8_t stat; + uint16_t addr; - DPRINTF(("firmware size=%zu\n", size)); + if (sc->sc_flags & ZYD_FLAG_FWLOADED) + return (0); + + if (sc->sc_macrev == ZYD_ZD1211) { + fw = (u_char *)zd1211_firmware; + size = sizeof(zd1211_firmware); + } else { + fw = (u_char *)zd1211b_firmware; + size = sizeof(zd1211b_firmware); + } req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = ZYD_DOWNLOADREQ; @@ -2661,24 +2985,20 @@ zyd_loadfirmware(struct zyd_softc *sc, u_char *fw, size_t size) addr = ZYD_FIRMWARE_START_ADDR; while (size > 0) { -#if 0 - const int mlen = min(size, 4096); -#else /* - * XXXX: When the transfer size is 4096 bytes, it is not + * When the transfer size is 4096 bytes, it is not * likely to be able to transfer it. * The cause is port or machine or chip? */ const int mlen = min(size, 64); -#endif - DPRINTF(("loading firmware block: len=%d, addr=0x%x\n", mlen, - addr)); + DPRINTF(sc, ZYD_DEBUG_FW, + "loading firmware block: len=%d, addr=0x%x\n", mlen, addr); USETW(req.wValue, addr); USETW(req.wLength, mlen); if (usbd_do_request(sc->sc_udev, &req, fw) != 0) - return EIO; + return (EIO); addr += mlen / 2; fw += mlen; @@ -2692,9 +3012,11 @@ zyd_loadfirmware(struct zyd_softc *sc, u_char *fw, size_t size) USETW(req.wIndex, 0); USETW(req.wLength, sizeof(stat)); if (usbd_do_request(sc->sc_udev, &req, &stat) != 0) - return EIO; + return (EIO); - return (stat & 0x80) ? EIO : 0; + sc->sc_flags |= ZYD_FLAG_FWLOADED; + + return (stat & 0x80) ? (EIO) : (0); } static void @@ -2735,7 +3057,6 @@ zyd_set_channel(struct ieee80211com *ic) struct zyd_softc *sc = ic->ic_ifp->if_softc; usb_rem_task(sc->sc_udev, &sc->sc_scantask); - /* do it in a process context */ sc->sc_scan_action = ZYD_SET_CHANNEL; usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); @@ -2755,18 +3076,13 @@ zyd_scantask(void *arg) /* want broadcast address while scanning */ zyd_set_bssid(sc, ifp->if_broadcastaddr); break; - case ZYD_SCAN_END: /* restore previous bssid */ zyd_set_bssid(sc, sc->sc_bssid); break; - case ZYD_SET_CHANNEL: - mtx_lock(&Giant); zyd_set_chan(sc, ic->ic_curchan); - mtx_unlock(&Giant); break; - default: device_printf(sc->sc_dev, "unknown scan action %d\n", sc->sc_scan_action); @@ -2779,11 +3095,10 @@ zyd_scantask(void *arg) static void zyd_wakeup(struct zyd_softc *sc) { - struct rq *rqp; + struct zyd_rq *rqp; - STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) { + STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) wakeup(rqp->odata); /* wakeup sleeping caller */ - } } static device_method_t zyd_methods[] = { diff --git a/sys/dev/usb/if_zydreg.h b/sys/dev/usb/if_zydreg.h index bd7d197f4187..feae22fc3db9 100644 --- a/sys/dev/usb/if_zydreg.h +++ b/sys/dev/usb/if_zydreg.h @@ -101,6 +101,7 @@ #define ZYD_MAC_CONT_WIN_LIMIT 0x96f0 /* Contention window limit */ #define ZYD_MAC_TX_PKT 0x96f4 /* Tx total packet count read */ #define ZYD_MAC_DL_CTRL 0x96f8 /* Download control */ +#define ZYD_MAC_CAM_MODE 0x9700 /* CAM: Continuous Access Mode */ #define ZYD_MACB_TXPWR_CTL1 0x9b00 #define ZYD_MACB_TXPWR_CTL2 0x9b04 #define ZYD_MACB_TXPWR_CTL3 0x9b08 @@ -127,8 +128,8 @@ #define ZYD_EEPROM_PWR_CAL 0xf81f /* Calibration */ #define ZYD_EEPROM_PWR_INT 0xf827 /* Calibration */ #define ZYD_EEPROM_ALLOWEDCHAN 0xf82f /* Allowed CH mask, 1 bit each */ -#define ZYD_EEPROM_PHY_REG 0xf831 /* PHY registers */ #define ZYD_EEPROM_DEVICE_VER 0xf837 /* Device version */ +#define ZYD_EEPROM_PHY_REG 0xf83c /* PHY registers */ #define ZYD_EEPROM_36M_CAL 0xf83f /* Calibration */ #define ZYD_EEPROM_11A_INT 0xf847 /* Interpolation */ #define ZYD_EEPROM_48M_CAL 0xf84f /* Calibration */ @@ -147,8 +148,8 @@ #define ZYD_FW_FLASH_CHK 0x0005 /* possible flags for register ZYD_FW_LINK_STATUS */ -#define ZYD_LED1 (1 << 8) -#define ZYD_LED2 (1 << 9) +#define ZYD_LED1 (1 << 8) +#define ZYD_LED2 (1 << 9) /* * RF IDs. @@ -161,7 +162,7 @@ #define ZYD_RF_AL2210 0x7 #define ZYD_RF_MAXIM_NEW 0x8 #define ZYD_RF_GCT 0x9 -#define ZYD_RF_PV2000 0xa /* not supported yet */ +#define ZYD_RF_AL2230S 0xa /* not supported yet */ #define ZYD_RF_RALINK 0xb /* not supported yet */ #define ZYD_RF_INTERSIL 0xc /* not supported yet */ #define ZYD_RF_RFMD 0xd @@ -171,257 +172,257 @@ /* * PHY registers (8 bits, not documented). */ -#define ZYD_CR0 0x9000 -#define ZYD_CR1 0x9004 -#define ZYD_CR2 0x9008 -#define ZYD_CR3 0x900c -#define ZYD_CR5 0x9010 -#define ZYD_CR6 0x9014 -#define ZYD_CR7 0x9018 -#define ZYD_CR8 0x901c -#define ZYD_CR4 0x9020 -#define ZYD_CR9 0x9024 -#define ZYD_CR10 0x9028 -#define ZYD_CR11 0x902c -#define ZYD_CR12 0x9030 -#define ZYD_CR13 0x9034 -#define ZYD_CR14 0x9038 -#define ZYD_CR15 0x903c -#define ZYD_CR16 0x9040 -#define ZYD_CR17 0x9044 -#define ZYD_CR18 0x9048 -#define ZYD_CR19 0x904c -#define ZYD_CR20 0x9050 -#define ZYD_CR21 0x9054 -#define ZYD_CR22 0x9058 -#define ZYD_CR23 0x905c -#define ZYD_CR24 0x9060 -#define ZYD_CR25 0x9064 -#define ZYD_CR26 0x9068 -#define ZYD_CR27 0x906c -#define ZYD_CR28 0x9070 -#define ZYD_CR29 0x9074 -#define ZYD_CR30 0x9078 -#define ZYD_CR31 0x907c -#define ZYD_CR32 0x9080 -#define ZYD_CR33 0x9084 -#define ZYD_CR34 0x9088 -#define ZYD_CR35 0x908c -#define ZYD_CR36 0x9090 -#define ZYD_CR37 0x9094 -#define ZYD_CR38 0x9098 -#define ZYD_CR39 0x909c -#define ZYD_CR40 0x90a0 -#define ZYD_CR41 0x90a4 -#define ZYD_CR42 0x90a8 -#define ZYD_CR43 0x90ac -#define ZYD_CR44 0x90b0 -#define ZYD_CR45 0x90b4 -#define ZYD_CR46 0x90b8 -#define ZYD_CR47 0x90bc -#define ZYD_CR48 0x90c0 -#define ZYD_CR49 0x90c4 -#define ZYD_CR50 0x90c8 -#define ZYD_CR51 0x90cc -#define ZYD_CR52 0x90d0 -#define ZYD_CR53 0x90d4 -#define ZYD_CR54 0x90d8 -#define ZYD_CR55 0x90dc -#define ZYD_CR56 0x90e0 -#define ZYD_CR57 0x90e4 -#define ZYD_CR58 0x90e8 -#define ZYD_CR59 0x90ec -#define ZYD_CR60 0x90f0 -#define ZYD_CR61 0x90f4 -#define ZYD_CR62 0x90f8 -#define ZYD_CR63 0x90fc -#define ZYD_CR64 0x9100 -#define ZYD_CR65 0x9104 -#define ZYD_CR66 0x9108 -#define ZYD_CR67 0x910c -#define ZYD_CR68 0x9110 -#define ZYD_CR69 0x9114 -#define ZYD_CR70 0x9118 -#define ZYD_CR71 0x911c -#define ZYD_CR72 0x9120 -#define ZYD_CR73 0x9124 -#define ZYD_CR74 0x9128 -#define ZYD_CR75 0x912c -#define ZYD_CR76 0x9130 -#define ZYD_CR77 0x9134 -#define ZYD_CR78 0x9138 -#define ZYD_CR79 0x913c -#define ZYD_CR80 0x9140 -#define ZYD_CR81 0x9144 -#define ZYD_CR82 0x9148 -#define ZYD_CR83 0x914c -#define ZYD_CR84 0x9150 -#define ZYD_CR85 0x9154 -#define ZYD_CR86 0x9158 -#define ZYD_CR87 0x915c -#define ZYD_CR88 0x9160 -#define ZYD_CR89 0x9164 -#define ZYD_CR90 0x9168 -#define ZYD_CR91 0x916c -#define ZYD_CR92 0x9170 -#define ZYD_CR93 0x9174 -#define ZYD_CR94 0x9178 -#define ZYD_CR95 0x917c -#define ZYD_CR96 0x9180 -#define ZYD_CR97 0x9184 -#define ZYD_CR98 0x9188 -#define ZYD_CR99 0x918c -#define ZYD_CR100 0x9190 -#define ZYD_CR101 0x9194 -#define ZYD_CR102 0x9198 -#define ZYD_CR103 0x919c -#define ZYD_CR104 0x91a0 -#define ZYD_CR105 0x91a4 -#define ZYD_CR106 0x91a8 -#define ZYD_CR107 0x91ac -#define ZYD_CR108 0x91b0 -#define ZYD_CR109 0x91b4 -#define ZYD_CR110 0x91b8 -#define ZYD_CR111 0x91bc -#define ZYD_CR112 0x91c0 -#define ZYD_CR113 0x91c4 -#define ZYD_CR114 0x91c8 -#define ZYD_CR115 0x91cc -#define ZYD_CR116 0x91d0 -#define ZYD_CR117 0x91d4 -#define ZYD_CR118 0x91d8 -#define ZYD_CR119 0x91dc -#define ZYD_CR120 0x91e0 -#define ZYD_CR121 0x91e4 -#define ZYD_CR122 0x91e8 -#define ZYD_CR123 0x91ec -#define ZYD_CR124 0x91f0 -#define ZYD_CR125 0x91f4 -#define ZYD_CR126 0x91f8 -#define ZYD_CR127 0x91fc -#define ZYD_CR128 0x9200 -#define ZYD_CR129 0x9204 -#define ZYD_CR130 0x9208 -#define ZYD_CR131 0x920c -#define ZYD_CR132 0x9210 -#define ZYD_CR133 0x9214 -#define ZYD_CR134 0x9218 -#define ZYD_CR135 0x921c -#define ZYD_CR136 0x9220 -#define ZYD_CR137 0x9224 -#define ZYD_CR138 0x9228 -#define ZYD_CR139 0x922c -#define ZYD_CR140 0x9230 -#define ZYD_CR141 0x9234 -#define ZYD_CR142 0x9238 -#define ZYD_CR143 0x923c -#define ZYD_CR144 0x9240 -#define ZYD_CR145 0x9244 -#define ZYD_CR146 0x9248 -#define ZYD_CR147 0x924c -#define ZYD_CR148 0x9250 -#define ZYD_CR149 0x9254 -#define ZYD_CR150 0x9258 -#define ZYD_CR151 0x925c -#define ZYD_CR152 0x9260 -#define ZYD_CR153 0x9264 -#define ZYD_CR154 0x9268 -#define ZYD_CR155 0x926c -#define ZYD_CR156 0x9270 -#define ZYD_CR157 0x9274 -#define ZYD_CR158 0x9278 -#define ZYD_CR159 0x927c -#define ZYD_CR160 0x9280 -#define ZYD_CR161 0x9284 -#define ZYD_CR162 0x9288 -#define ZYD_CR163 0x928c -#define ZYD_CR164 0x9290 -#define ZYD_CR165 0x9294 -#define ZYD_CR166 0x9298 -#define ZYD_CR167 0x929c -#define ZYD_CR168 0x92a0 -#define ZYD_CR169 0x92a4 -#define ZYD_CR170 0x92a8 -#define ZYD_CR171 0x92ac -#define ZYD_CR172 0x92b0 -#define ZYD_CR173 0x92b4 -#define ZYD_CR174 0x92b8 -#define ZYD_CR175 0x92bc -#define ZYD_CR176 0x92c0 -#define ZYD_CR177 0x92c4 -#define ZYD_CR178 0x92c8 -#define ZYD_CR179 0x92cc -#define ZYD_CR180 0x92d0 -#define ZYD_CR181 0x92d4 -#define ZYD_CR182 0x92d8 -#define ZYD_CR183 0x92dc -#define ZYD_CR184 0x92e0 -#define ZYD_CR185 0x92e4 -#define ZYD_CR186 0x92e8 -#define ZYD_CR187 0x92ec -#define ZYD_CR188 0x92f0 -#define ZYD_CR189 0x92f4 -#define ZYD_CR190 0x92f8 -#define ZYD_CR191 0x92fc -#define ZYD_CR192 0x9300 -#define ZYD_CR193 0x9304 -#define ZYD_CR194 0x9308 -#define ZYD_CR195 0x930c -#define ZYD_CR196 0x9310 -#define ZYD_CR197 0x9314 -#define ZYD_CR198 0x9318 -#define ZYD_CR199 0x931c -#define ZYD_CR200 0x9320 -#define ZYD_CR201 0x9324 -#define ZYD_CR202 0x9328 -#define ZYD_CR203 0x932c -#define ZYD_CR204 0x9330 -#define ZYD_CR205 0x9334 -#define ZYD_CR206 0x9338 -#define ZYD_CR207 0x933c -#define ZYD_CR208 0x9340 -#define ZYD_CR209 0x9344 -#define ZYD_CR210 0x9348 -#define ZYD_CR211 0x934c -#define ZYD_CR212 0x9350 -#define ZYD_CR213 0x9354 -#define ZYD_CR214 0x9358 -#define ZYD_CR215 0x935c -#define ZYD_CR216 0x9360 -#define ZYD_CR217 0x9364 -#define ZYD_CR218 0x9368 -#define ZYD_CR219 0x936c -#define ZYD_CR220 0x9370 -#define ZYD_CR221 0x9374 -#define ZYD_CR222 0x9378 -#define ZYD_CR223 0x937c -#define ZYD_CR224 0x9380 -#define ZYD_CR225 0x9384 -#define ZYD_CR226 0x9388 -#define ZYD_CR227 0x938c -#define ZYD_CR228 0x9390 -#define ZYD_CR229 0x9394 -#define ZYD_CR230 0x9398 -#define ZYD_CR231 0x939c -#define ZYD_CR232 0x93a0 -#define ZYD_CR233 0x93a4 -#define ZYD_CR234 0x93a8 -#define ZYD_CR235 0x93ac -#define ZYD_CR236 0x93b0 -#define ZYD_CR240 0x93c0 -#define ZYD_CR241 0x93c4 -#define ZYD_CR242 0x93c8 -#define ZYD_CR243 0x93cc -#define ZYD_CR244 0x93d0 -#define ZYD_CR245 0x93d4 -#define ZYD_CR251 0x93ec -#define ZYD_CR252 0x93f0 -#define ZYD_CR253 0x93f4 -#define ZYD_CR254 0x93f8 -#define ZYD_CR255 0x93fc +#define ZYD_CR0 0x9000 +#define ZYD_CR1 0x9004 +#define ZYD_CR2 0x9008 +#define ZYD_CR3 0x900c +#define ZYD_CR5 0x9010 +#define ZYD_CR6 0x9014 +#define ZYD_CR7 0x9018 +#define ZYD_CR8 0x901c +#define ZYD_CR4 0x9020 +#define ZYD_CR9 0x9024 +#define ZYD_CR10 0x9028 +#define ZYD_CR11 0x902c +#define ZYD_CR12 0x9030 +#define ZYD_CR13 0x9034 +#define ZYD_CR14 0x9038 +#define ZYD_CR15 0x903c +#define ZYD_CR16 0x9040 +#define ZYD_CR17 0x9044 +#define ZYD_CR18 0x9048 +#define ZYD_CR19 0x904c +#define ZYD_CR20 0x9050 +#define ZYD_CR21 0x9054 +#define ZYD_CR22 0x9058 +#define ZYD_CR23 0x905c +#define ZYD_CR24 0x9060 +#define ZYD_CR25 0x9064 +#define ZYD_CR26 0x9068 +#define ZYD_CR27 0x906c +#define ZYD_CR28 0x9070 +#define ZYD_CR29 0x9074 +#define ZYD_CR30 0x9078 +#define ZYD_CR31 0x907c +#define ZYD_CR32 0x9080 +#define ZYD_CR33 0x9084 +#define ZYD_CR34 0x9088 +#define ZYD_CR35 0x908c +#define ZYD_CR36 0x9090 +#define ZYD_CR37 0x9094 +#define ZYD_CR38 0x9098 +#define ZYD_CR39 0x909c +#define ZYD_CR40 0x90a0 +#define ZYD_CR41 0x90a4 +#define ZYD_CR42 0x90a8 +#define ZYD_CR43 0x90ac +#define ZYD_CR44 0x90b0 +#define ZYD_CR45 0x90b4 +#define ZYD_CR46 0x90b8 +#define ZYD_CR47 0x90bc +#define ZYD_CR48 0x90c0 +#define ZYD_CR49 0x90c4 +#define ZYD_CR50 0x90c8 +#define ZYD_CR51 0x90cc +#define ZYD_CR52 0x90d0 +#define ZYD_CR53 0x90d4 +#define ZYD_CR54 0x90d8 +#define ZYD_CR55 0x90dc +#define ZYD_CR56 0x90e0 +#define ZYD_CR57 0x90e4 +#define ZYD_CR58 0x90e8 +#define ZYD_CR59 0x90ec +#define ZYD_CR60 0x90f0 +#define ZYD_CR61 0x90f4 +#define ZYD_CR62 0x90f8 +#define ZYD_CR63 0x90fc +#define ZYD_CR64 0x9100 +#define ZYD_CR65 0x9104 +#define ZYD_CR66 0x9108 +#define ZYD_CR67 0x910c +#define ZYD_CR68 0x9110 +#define ZYD_CR69 0x9114 +#define ZYD_CR70 0x9118 +#define ZYD_CR71 0x911c +#define ZYD_CR72 0x9120 +#define ZYD_CR73 0x9124 +#define ZYD_CR74 0x9128 +#define ZYD_CR75 0x912c +#define ZYD_CR76 0x9130 +#define ZYD_CR77 0x9134 +#define ZYD_CR78 0x9138 +#define ZYD_CR79 0x913c +#define ZYD_CR80 0x9140 +#define ZYD_CR81 0x9144 +#define ZYD_CR82 0x9148 +#define ZYD_CR83 0x914c +#define ZYD_CR84 0x9150 +#define ZYD_CR85 0x9154 +#define ZYD_CR86 0x9158 +#define ZYD_CR87 0x915c +#define ZYD_CR88 0x9160 +#define ZYD_CR89 0x9164 +#define ZYD_CR90 0x9168 +#define ZYD_CR91 0x916c +#define ZYD_CR92 0x9170 +#define ZYD_CR93 0x9174 +#define ZYD_CR94 0x9178 +#define ZYD_CR95 0x917c +#define ZYD_CR96 0x9180 +#define ZYD_CR97 0x9184 +#define ZYD_CR98 0x9188 +#define ZYD_CR99 0x918c +#define ZYD_CR100 0x9190 +#define ZYD_CR101 0x9194 +#define ZYD_CR102 0x9198 +#define ZYD_CR103 0x919c +#define ZYD_CR104 0x91a0 +#define ZYD_CR105 0x91a4 +#define ZYD_CR106 0x91a8 +#define ZYD_CR107 0x91ac +#define ZYD_CR108 0x91b0 +#define ZYD_CR109 0x91b4 +#define ZYD_CR110 0x91b8 +#define ZYD_CR111 0x91bc +#define ZYD_CR112 0x91c0 +#define ZYD_CR113 0x91c4 +#define ZYD_CR114 0x91c8 +#define ZYD_CR115 0x91cc +#define ZYD_CR116 0x91d0 +#define ZYD_CR117 0x91d4 +#define ZYD_CR118 0x91d8 +#define ZYD_CR119 0x91dc +#define ZYD_CR120 0x91e0 +#define ZYD_CR121 0x91e4 +#define ZYD_CR122 0x91e8 +#define ZYD_CR123 0x91ec +#define ZYD_CR124 0x91f0 +#define ZYD_CR125 0x91f4 +#define ZYD_CR126 0x91f8 +#define ZYD_CR127 0x91fc +#define ZYD_CR128 0x9200 +#define ZYD_CR129 0x9204 +#define ZYD_CR130 0x9208 +#define ZYD_CR131 0x920c +#define ZYD_CR132 0x9210 +#define ZYD_CR133 0x9214 +#define ZYD_CR134 0x9218 +#define ZYD_CR135 0x921c +#define ZYD_CR136 0x9220 +#define ZYD_CR137 0x9224 +#define ZYD_CR138 0x9228 +#define ZYD_CR139 0x922c +#define ZYD_CR140 0x9230 +#define ZYD_CR141 0x9234 +#define ZYD_CR142 0x9238 +#define ZYD_CR143 0x923c +#define ZYD_CR144 0x9240 +#define ZYD_CR145 0x9244 +#define ZYD_CR146 0x9248 +#define ZYD_CR147 0x924c +#define ZYD_CR148 0x9250 +#define ZYD_CR149 0x9254 +#define ZYD_CR150 0x9258 +#define ZYD_CR151 0x925c +#define ZYD_CR152 0x9260 +#define ZYD_CR153 0x9264 +#define ZYD_CR154 0x9268 +#define ZYD_CR155 0x926c +#define ZYD_CR156 0x9270 +#define ZYD_CR157 0x9274 +#define ZYD_CR158 0x9278 +#define ZYD_CR159 0x927c +#define ZYD_CR160 0x9280 +#define ZYD_CR161 0x9284 +#define ZYD_CR162 0x9288 +#define ZYD_CR163 0x928c +#define ZYD_CR164 0x9290 +#define ZYD_CR165 0x9294 +#define ZYD_CR166 0x9298 +#define ZYD_CR167 0x929c +#define ZYD_CR168 0x92a0 +#define ZYD_CR169 0x92a4 +#define ZYD_CR170 0x92a8 +#define ZYD_CR171 0x92ac +#define ZYD_CR172 0x92b0 +#define ZYD_CR173 0x92b4 +#define ZYD_CR174 0x92b8 +#define ZYD_CR175 0x92bc +#define ZYD_CR176 0x92c0 +#define ZYD_CR177 0x92c4 +#define ZYD_CR178 0x92c8 +#define ZYD_CR179 0x92cc +#define ZYD_CR180 0x92d0 +#define ZYD_CR181 0x92d4 +#define ZYD_CR182 0x92d8 +#define ZYD_CR183 0x92dc +#define ZYD_CR184 0x92e0 +#define ZYD_CR185 0x92e4 +#define ZYD_CR186 0x92e8 +#define ZYD_CR187 0x92ec +#define ZYD_CR188 0x92f0 +#define ZYD_CR189 0x92f4 +#define ZYD_CR190 0x92f8 +#define ZYD_CR191 0x92fc +#define ZYD_CR192 0x9300 +#define ZYD_CR193 0x9304 +#define ZYD_CR194 0x9308 +#define ZYD_CR195 0x930c +#define ZYD_CR196 0x9310 +#define ZYD_CR197 0x9314 +#define ZYD_CR198 0x9318 +#define ZYD_CR199 0x931c +#define ZYD_CR200 0x9320 +#define ZYD_CR201 0x9324 +#define ZYD_CR202 0x9328 +#define ZYD_CR203 0x932c +#define ZYD_CR204 0x9330 +#define ZYD_CR205 0x9334 +#define ZYD_CR206 0x9338 +#define ZYD_CR207 0x933c +#define ZYD_CR208 0x9340 +#define ZYD_CR209 0x9344 +#define ZYD_CR210 0x9348 +#define ZYD_CR211 0x934c +#define ZYD_CR212 0x9350 +#define ZYD_CR213 0x9354 +#define ZYD_CR214 0x9358 +#define ZYD_CR215 0x935c +#define ZYD_CR216 0x9360 +#define ZYD_CR217 0x9364 +#define ZYD_CR218 0x9368 +#define ZYD_CR219 0x936c +#define ZYD_CR220 0x9370 +#define ZYD_CR221 0x9374 +#define ZYD_CR222 0x9378 +#define ZYD_CR223 0x937c +#define ZYD_CR224 0x9380 +#define ZYD_CR225 0x9384 +#define ZYD_CR226 0x9388 +#define ZYD_CR227 0x938c +#define ZYD_CR228 0x9390 +#define ZYD_CR229 0x9394 +#define ZYD_CR230 0x9398 +#define ZYD_CR231 0x939c +#define ZYD_CR232 0x93a0 +#define ZYD_CR233 0x93a4 +#define ZYD_CR234 0x93a8 +#define ZYD_CR235 0x93ac +#define ZYD_CR236 0x93b0 +#define ZYD_CR240 0x93c0 +#define ZYD_CR241 0x93c4 +#define ZYD_CR242 0x93c8 +#define ZYD_CR243 0x93cc +#define ZYD_CR244 0x93d0 +#define ZYD_CR245 0x93d4 +#define ZYD_CR251 0x93ec +#define ZYD_CR252 0x93f0 +#define ZYD_CR253 0x93f4 +#define ZYD_CR254 0x93f8 +#define ZYD_CR255 0x93fc /* copied nearly verbatim from the Linux driver rewrite */ -#define ZYD_DEF_PHY \ +#define ZYD_DEF_PHY \ { \ { ZYD_CR0, 0x0a }, { ZYD_CR1, 0x06 }, { ZYD_CR2, 0x26 }, \ { ZYD_CR3, 0x38 }, { ZYD_CR4, 0x80 }, { ZYD_CR9, 0xa0 }, \ @@ -437,7 +438,7 @@ { ZYD_CR37, 0x00 }, { ZYD_CR38, 0x38 }, { ZYD_CR39, 0x0c }, \ { ZYD_CR40, 0x84 }, { ZYD_CR41, 0x2a }, { ZYD_CR42, 0x80 }, \ { ZYD_CR43, 0x10 }, { ZYD_CR44, 0x12 }, { ZYD_CR46, 0xff }, \ - { ZYD_CR47, 0x08 }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \ + { ZYD_CR47, 0x1e }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \ { ZYD_CR64, 0xd0 }, { ZYD_CR65, 0x04 }, { ZYD_CR66, 0x58 }, \ { ZYD_CR67, 0xc9 }, { ZYD_CR68, 0x88 }, { ZYD_CR69, 0x41 }, \ { ZYD_CR70, 0x23 }, { ZYD_CR71, 0x10 }, { ZYD_CR72, 0xff }, \ @@ -459,7 +460,7 @@ { ZYD_CR5, 0x00 }, { ZYD_CR6, 0x00 }, { ZYD_CR7, 0x00 }, \ { ZYD_CR8, 0x00 }, { ZYD_CR9, 0x20 }, { ZYD_CR12, 0xf0 }, \ { ZYD_CR20, 0x0e }, { ZYD_CR21, 0x0e }, { ZYD_CR27, 0x10 }, \ - { ZYD_CR44, 0x33 }, { ZYD_CR47, 0x30 }, { ZYD_CR83, 0x24 }, \ + { ZYD_CR44, 0x33 }, { ZYD_CR47, 0x1E }, { ZYD_CR83, 0x24 }, \ { ZYD_CR84, 0x04 }, { ZYD_CR85, 0x00 }, { ZYD_CR86, 0x0C }, \ { ZYD_CR87, 0x12 }, { ZYD_CR88, 0x0C }, { ZYD_CR89, 0x00 }, \ { ZYD_CR90, 0x10 }, { ZYD_CR91, 0x08 }, { ZYD_CR93, 0x00 }, \ @@ -470,19 +471,18 @@ { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x27 }, { ZYD_CR113, 0x27 }, \ { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, { ZYD_CR116, 0x24 }, \ { ZYD_CR117, 0xfc }, { ZYD_CR118, 0xfa }, { ZYD_CR120, 0x4f }, \ - { ZYD_CR123, 0x27 }, { ZYD_CR125, 0xaa }, { ZYD_CR127, 0x03 }, \ - { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \ - { ZYD_CR131, 0x0C }, { ZYD_CR136, 0xdf }, { ZYD_CR137, 0x40 }, \ - { ZYD_CR138, 0xa0 }, { ZYD_CR139, 0xb0 }, { ZYD_CR140, 0x99 }, \ - { ZYD_CR141, 0x82 }, { ZYD_CR142, 0x54 }, { ZYD_CR143, 0x1c }, \ - { ZYD_CR144, 0x6c }, { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x4c }, \ - { ZYD_CR149, 0x50 }, { ZYD_CR150, 0x0e }, { ZYD_CR151, 0x18 }, \ - { ZYD_CR160, 0xfe }, { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, \ - { ZYD_CR163, 0xfa }, { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, \ - { ZYD_CR166, 0xbe }, { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, \ - { ZYD_CR169, 0xba }, { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, \ - { ZYD_CR204, 0x7d }, { ZYD_CR203, 0x30 }, \ - { 0, 0 } \ + { ZYD_CR125, 0xaa }, { ZYD_CR127, 0x03 }, { ZYD_CR128, 0x14 }, \ + { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, { ZYD_CR131, 0x0C }, \ + { ZYD_CR136, 0xdf }, { ZYD_CR137, 0x40 }, { ZYD_CR138, 0xa0 }, \ + { ZYD_CR139, 0xb0 }, { ZYD_CR140, 0x99 }, { ZYD_CR141, 0x82 }, \ + { ZYD_CR142, 0x54 }, { ZYD_CR143, 0x1c }, { ZYD_CR144, 0x6c }, \ + { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x4c }, { ZYD_CR149, 0x50 }, \ + { ZYD_CR150, 0x0e }, { ZYD_CR151, 0x18 }, { ZYD_CR160, 0xfe }, \ + { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, { ZYD_CR163, 0xfa }, \ + { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, { ZYD_CR166, 0xbe }, \ + { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, { ZYD_CR169, 0xba }, \ + { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, { ZYD_CR204, 0x7d }, \ + { ZYD_CR203, 0x30 }, { 0, 0} \ } #define ZYD_DEF_PHYB \ @@ -590,8 +590,6 @@ { 0x181a60, 0x1c0000 } \ } - - #define ZYD_AL2230_PHY \ { \ { ZYD_CR15, 0x20 }, { ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, \ @@ -617,34 +615,73 @@ #define ZYD_AL2230_PHY_B \ { \ - { ZYD_CR10, 0x89 }, { ZYD_CR15, 0x20 }, { ZYD_CR17, 0x2b }, \ + { ZYD_CR10, 0x89 }, { ZYD_CR15, 0x20 }, { ZYD_CR17, 0x2B }, \ { ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, { ZYD_CR26, 0x93 }, \ { ZYD_CR28, 0x3e }, { ZYD_CR29, 0x00 }, { ZYD_CR33, 0x28 }, \ { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x3e }, { ZYD_CR41, 0x24 }, \ { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x99 }, { ZYD_CR47, 0x1e }, \ - { ZYD_CR48, 0x00 }, { ZYD_CR49, 0x00 }, { ZYD_CR51, 0x01 }, \ + { ZYD_CR48, 0x06 }, { ZYD_CR49, 0xf9 }, { ZYD_CR51, 0x01 }, \ { ZYD_CR52, 0x80 }, { ZYD_CR53, 0x7e }, { ZYD_CR65, 0x00 }, \ { ZYD_CR66, 0x00 }, { ZYD_CR67, 0x00 }, { ZYD_CR68, 0x00 }, \ { ZYD_CR69, 0x28 }, { ZYD_CR79, 0x58 }, { ZYD_CR80, 0x30 }, \ { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, { ZYD_CR89, 0x04 }, \ { ZYD_CR91, 0x00 }, { ZYD_CR92, 0x0a }, { ZYD_CR98, 0x8d }, \ - { ZYD_CR99, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR106, 0x24 }, \ - { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x13 }, { ZYD_CR110, 0x1f }, \ - { ZYD_CR111, 0x1f }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, \ + { ZYD_CR99, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \ + { ZYD_CR106, 0x24 }, { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x13 }, \ + { ZYD_CR110, 0x1f }, { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, \ + { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, \ { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xfa }, { ZYD_CR118, 0xfa }, \ { ZYD_CR119, 0x10 }, { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x6c }, \ { ZYD_CR122, 0xfc }, { ZYD_CR123, 0x57 }, { ZYD_CR125, 0xad }, \ { ZYD_CR126, 0x6c }, { ZYD_CR127, 0x03 }, { ZYD_CR137, 0x50 }, \ { ZYD_CR138, 0xa8 }, { ZYD_CR144, 0xac }, { ZYD_CR150, 0x0d }, \ - { ZYD_CR252, 0x00 }, { ZYD_CR253, 0x00 } \ + { ZYD_CR252, 0x34 }, { ZYD_CR253, 0x34 } \ } -#define ZYD_AL2230_RF \ +#define ZYD_AL2230_PHY_PART1 \ +{ \ + { ZYD_CR240, 0x57 }, { ZYD_CR9, 0xe0 } \ +} + +#define ZYD_AL2230_PHY_PART2 \ +{ \ + { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x7f }, \ +} + +#define ZYD_AL2230_PHY_PART3 \ +{ \ + { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \ +} + +#define ZYD_AL2230S_PHY_INIT \ +{ \ + { ZYD_CR47, 0x1e }, { ZYD_CR106, 0x22 }, { ZYD_CR107, 0x2a }, \ + { ZYD_CR109, 0x13 }, { ZYD_CR118, 0xf8 }, { ZYD_CR119, 0x12 }, \ + { ZYD_CR122, 0xe0 }, { ZYD_CR128, 0x10 }, { ZYD_CR129, 0x0e }, \ + { ZYD_CR130, 0x10 } \ +} + +#define ZYD_AL2230_PHY_FINI_PART1 \ +{ \ + { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR79, 0x58 }, \ + { ZYD_CR12, 0xf0 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x58 }, \ + { ZYD_CR203, 0x06 }, { ZYD_CR240, 0x80 }, \ +} + +#define ZYD_AL2230_RF_PART1 \ +{ \ + 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3 \ +} + +#define ZYD_AL2230_RF_PART2 \ { \ - 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3, \ 0x000da4, 0x0f4dc5, 0x0805b6, 0x011687, 0x000688, 0x0403b9, \ - 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00500f, 0x00d00f, \ - 0x004c0f, 0x00540f, 0x00700f, 0x00500f \ + 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00500f \ +} + +#define ZYD_AL2230_RF_PART3 \ +{ \ + 0x00d00f, 0x004c0f, 0x00540f, 0x00700f, 0x00500f \ } #define ZYD_AL2230_RF_B \ @@ -654,6 +691,22 @@ 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00580f \ } +#define ZYD_AL2230_RF_B_PART1 \ +{ \ + 0x8cccd0, 0x481dc0, 0xcfff00, 0x25a000 \ +} + +#define ZYD_AL2230_RF_B_PART2 \ +{ \ + 0x25a000, 0xa3b2f0, 0x6da010, 0xe36280, 0x116000, 0x9dc020, \ + 0x5ddb00, 0xd99000, 0x3ffbd0, 0xb00000, 0xf01a00 \ +} + +#define ZYD_AL2230_RF_B_PART3 \ +{ \ + 0xf01b00, 0xf01e00, 0xf01a00 \ +} + #define ZYD_AL2230_CHANTABLE \ { \ { 0x03f790, 0x033331, 0x00000d }, \ @@ -672,7 +725,23 @@ { 0x03e7c0, 0x066661, 0x00000d } \ } - +#define ZYD_AL2230_CHANTABLE_B \ +{ \ + { 0x09efc0, 0x8cccc0, 0xb00000 }, \ + { 0x09efc0, 0x8cccd0, 0xb00000 }, \ + { 0x09e7c0, 0x8cccc0, 0xb00000 }, \ + { 0x09e7c0, 0x8cccd0, 0xb00000 }, \ + { 0x05efc0, 0x8cccc0, 0xb00000 }, \ + { 0x05efc0, 0x8cccd0, 0xb00000 }, \ + { 0x05e7c0, 0x8cccc0, 0xb00000 }, \ + { 0x05e7c0, 0x8cccd0, 0xb00000 }, \ + { 0x0defc0, 0x8cccc0, 0xb00000 }, \ + { 0x0defc0, 0x8cccd0, 0xb00000 }, \ + { 0x0de7c0, 0x8cccc0, 0xb00000 }, \ + { 0x0de7c0, 0x8cccd0, 0xb00000 }, \ + { 0x03efc0, 0x8cccc0, 0xb00000 }, \ + { 0x03e7c0, 0x866660, 0xb00000 } \ +} #define ZYD_AL7230B_PHY_1 \ { \ @@ -744,8 +813,6 @@ { 0x03ec00, 0x866660 } \ } - - #define ZYD_AL2210_PHY \ { \ { ZYD_CR9, 0xe0 }, { ZYD_CR10, 0x91 }, { ZYD_CR12, 0x90 }, \ @@ -771,8 +838,6 @@ 0x019a80, 0x019b40 \ } - - #define ZYD_GCT_PHY \ { \ { ZYD_CR47, 0x1e }, { ZYD_CR15, 0xdc }, { ZYD_CR113, 0xc0 }, \ @@ -801,8 +866,6 @@ 0x1a3000, 0x1ab000 \ } - - #define ZYD_MAXIM_PHY \ { \ { ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \ @@ -855,8 +918,6 @@ { 0x199a4, 0x20a53 } \ } - - #define ZYD_MAXIM2_PHY \ { \ { ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \ @@ -917,17 +978,18 @@ /* * Control pipe requests. */ -#define ZYD_DOWNLOADREQ 0x30 -#define ZYD_DOWNLOADSTS 0x31 +#define ZYD_DOWNLOADREQ 0x30 +#define ZYD_DOWNLOADSTS 0x31 +#define ZYD_READFWDATAREQ 0x32 /* possible values for register ZYD_CR_INTERRUPT */ -#define ZYD_HWINT_MASK 0x004f0000 +#define ZYD_HWINT_MASK 0x004f0000 /* possible values for register ZYD_MAC_MISC */ #define ZYD_UNLOCK_PHY_REGS 0x80 /* possible values for register ZYD_MAC_ENCRYPTION_TYPE */ -#define ZYD_ENC_SNIFFER 8 +#define ZYD_ENC_SNIFFER 8 /* flags for register ZYD_MAC_RXFILTER */ #define ZYD_FILTER_ASS_REQ (1 << 0) @@ -951,23 +1013,27 @@ /* helpers for register ZYD_MAC_RXFILTER */ #define ZYD_FILTER_MONITOR 0xffffffff #define ZYD_FILTER_BSS \ - (ZYD_FILTER_ASS_RSP | ZYD_FILTER_REASS_RSP | \ - ZYD_FILTER_PRB_RSP | ZYD_FILTER_BCN | ZYD_FILTER_DEASS | \ - ZYD_FILTER_AUTH | ZYD_FILTER_DEAUTH) + (ZYD_FILTER_ASS_REQ | ZYD_FILTER_ASS_RSP | \ + ZYD_FILTER_REASS_REQ | ZYD_FILTER_REASS_RSP | \ + ZYD_FILTER_PRB_REQ | ZYD_FILTER_PRB_RSP | \ + (0x3 << 6) | \ + ZYD_FILTER_BCN | ZYD_FILTER_ATIM | ZYD_FILTER_DEASS | \ + ZYD_FILTER_AUTH | ZYD_FILTER_DEAUTH | \ + (0x7 << 13) | \ + ZYD_FILTER_PS_POLL | ZYD_FILTER_ACK) #define ZYD_FILTER_HOSTAP \ (ZYD_FILTER_ASS_REQ | ZYD_FILTER_REASS_REQ | \ ZYD_FILTER_PRB_REQ | ZYD_FILTER_DEASS | ZYD_FILTER_AUTH | \ ZYD_FILTER_DEAUTH | ZYD_FILTER_PS_POLL) struct zyd_tx_desc { - uint8_t phy; + uint8_t phy; #define ZYD_TX_PHY_SIGNAL(x) ((x) & 0xf) #define ZYD_TX_PHY_OFDM (1 << 4) #define ZYD_TX_PHY_SHPREAMBLE (1 << 5) /* CCK */ #define ZYD_TX_PHY_5GHZ (1 << 5) /* OFDM */ - - uint16_t len; - uint8_t flags; + uint16_t len; + uint8_t flags; #define ZYD_TX_FLAG_BACKOFF (1 << 0) #define ZYD_TX_FLAG_MULTICAST (1 << 1) #define ZYD_TX_FLAG_TYPE(x) (((x) & 0x3) << 2) @@ -979,26 +1045,24 @@ struct zyd_tx_desc { #define ZYD_TX_FLAG_RTS (1 << 5) #define ZYD_TX_FLAG_ENCRYPT (1 << 6) #define ZYD_TX_FLAG_CTS_TO_SELF (1 << 7) - - uint16_t pktlen; - uint16_t plcp_length; - uint8_t plcp_service; + uint16_t pktlen; + uint16_t plcp_length; + uint8_t plcp_service; #define ZYD_PLCP_LENGEXT 0x80 - - uint16_t nextlen; + uint16_t nextlen; } __packed; struct zyd_plcphdr { - uint8_t signal; - uint8_t reserved[2]; - uint16_t service; /* unaligned! */ + uint8_t signal; + uint8_t reserved[2]; + uint16_t service; /* unaligned! */ } __packed; struct zyd_rx_stat { - uint8_t signal_cck; - uint8_t rssi; - uint8_t signal_ofdm; - uint8_t cipher; + uint8_t signal_cck; + uint8_t rssi; + uint8_t signal_ofdm; + uint8_t cipher; #define ZYD_RX_CIPHER_WEP64 1 #define ZYD_RX_CIPHER_TKIP 2 #define ZYD_RX_CIPHER_AES 4 @@ -1006,8 +1070,7 @@ struct zyd_rx_stat { #define ZYD_RX_CIPHER_WEP256 6 #define ZYD_RX_CIPHER_WEP \ (ZYD_RX_CIPHER_WEP64 | ZYD_RX_CIPHER_WEP128 | ZYD_RX_CIPHER_WEP256) - - uint8_t flags; + uint8_t flags; #define ZYD_RX_OFDM (1 << 0) #define ZYD_RX_TIMEOUT (1 << 1) #define ZYD_RX_OVERRUN (1 << 2) @@ -1021,55 +1084,49 @@ struct zyd_rx_stat { /* this structure may be unaligned */ struct zyd_rx_desc { #define ZYD_MAX_RXFRAMECNT 3 - uWord len[ZYD_MAX_RXFRAMECNT]; - uWord tag; + uWord len[ZYD_MAX_RXFRAMECNT]; + uWord tag; #define ZYD_TAG_MULTIFRAME 0x697e } __packed; /* I2C bus alike */ -struct zyd_rfwrite { - uint16_t code; - uint16_t width; - uint16_t bit[32]; -#define ZYD_RF_IF_LE (1 << 1) -#define ZYD_RF_CLK (1 << 2) -#define ZYD_RF_DATA (1 << 3) +struct zyd_rfwrite_cmd { + uint16_t code; + uint16_t width; + uint16_t bit[32]; +#define ZYD_RF_IF_LE (1 << 1) +#define ZYD_RF_CLK (1 << 2) +#define ZYD_RF_DATA (1 << 3) } __packed; struct zyd_cmd { - uint16_t code; + uint16_t code; #define ZYD_CMD_IOWR 0x0021 /* write HMAC or PHY register */ #define ZYD_CMD_IORD 0x0022 /* read HMAC or PHY register */ #define ZYD_CMD_RFCFG 0x0023 /* write RF register */ #define ZYD_NOTIF_IORD 0x9001 /* response for ZYD_CMD_IORD */ #define ZYD_NOTIF_MACINTR 0x9001 /* interrupt notification */ #define ZYD_NOTIF_RETRYSTATUS 0xa001 /* Tx retry notification */ - - uint8_t data[64]; + uint8_t data[64]; } __packed; /* structure for command ZYD_CMD_IOWR */ struct zyd_pair { - uint16_t reg; + uint16_t reg; /* helpers macros to read/write 32-bit registers */ #define ZYD_REG32_LO(reg) (reg) #define ZYD_REG32_HI(reg) \ ((reg) + ((((reg) & 0xf000) == 0x9000) ? 2 : 1)) - - uint16_t val; + uint16_t val; } __packed; /* structure for notification ZYD_NOTIF_RETRYSTATUS */ struct zyd_notif_retry { - uint16_t rate; - uint8_t macaddr[IEEE80211_ADDR_LEN]; - uint16_t count; + uint16_t rate; + uint8_t macaddr[IEEE80211_ADDR_LEN]; + uint16_t count; } __packed; - -#define ZYD_RX_LIST_CNT 1 -#define ZYD_TX_LIST_CNT 1 - #define ZYD_CONFIG_NO 1 #define ZYD_IFACE_INDEX 0 @@ -1078,7 +1135,6 @@ struct zyd_notif_retry { #define ZYD_MAX_TXBUFSZ \ (sizeof(struct zyd_tx_desc) + MCLBYTES) - #define ZYD_MIN_FRAGSZ \ (sizeof(struct zyd_plcphdr) + IEEE80211_MIN_LEN + \ sizeof(struct zyd_rx_stat)) @@ -1087,21 +1143,22 @@ struct zyd_notif_retry { ((sizeof (struct zyd_plcphdr) + IEEE80211_MAX_LEN + \ sizeof (struct zyd_rx_stat)) * ZYD_MAX_RXFRAMECNT + \ sizeof (struct zyd_rx_desc)) - +#define ZYD_RX_LIST_CNT 1 +#define ZYD_TX_LIST_CNT 5 #define ZYD_CMD_FLAG_READ (1 << 0) /* quickly determine if a given rate is CCK or OFDM */ #define ZYD_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) struct zyd_phy_pair { - uint16_t reg; - uint8_t val; + uint16_t reg; + uint8_t val; }; struct zyd_mac_pair { - uint16_t reg; - uint32_t val; + uint16_t reg; + uint32_t val; }; struct zyd_tx_data { @@ -1119,19 +1176,19 @@ struct zyd_rx_data { }; struct zyd_node { - struct ieee80211_node ni; /* must be the first */ + struct ieee80211_node ni; /* must be the first */ struct ieee80211_amrr_node amn; }; #define ZYD_NODE(ni) ((struct zyd_node *)(ni)) struct zyd_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; - uint8_t wr_flags; - uint8_t wr_rate; - uint16_t wr_chan_freq; - uint16_t wr_chan_flags; - int8_t wr_antsignal; - int8_t wr_antnoise; + uint8_t wr_flags; + uint8_t wr_rate; + uint16_t wr_chan_freq; + uint16_t wr_chan_flags; + int8_t wr_antsignal; + int8_t wr_antnoise; } __packed; #define ZYD_RX_RADIOTAP_PRESENT \ @@ -1143,10 +1200,10 @@ struct zyd_rx_radiotap_header { struct zyd_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; - uint8_t wt_flags; - uint8_t wt_rate; - uint16_t wt_chan_freq; - uint16_t wt_chan_flags; + uint8_t wt_flags; + uint8_t wt_rate; + uint16_t wt_chan_freq; + uint16_t wt_chan_flags; } __packed; #define ZYD_TX_RADIOTAP_PRESENT \ @@ -1158,20 +1215,21 @@ struct zyd_softc; /* forward declaration */ struct zyd_rf { /* RF methods */ - int (*init)(struct zyd_rf *); - int (*switch_radio)(struct zyd_rf *, int); - int (*set_channel)(struct zyd_rf *, uint8_t); - + int (*init)(struct zyd_rf *); + int (*switch_radio)(struct zyd_rf *, int); + int (*set_channel)(struct zyd_rf *, uint8_t); + int (*bandedge6)(struct zyd_rf *, + struct ieee80211_channel *); /* RF attributes */ - struct zyd_softc *rf_sc; /* back-pointer */ - int width; + struct zyd_softc *rf_sc; /* back-pointer */ + int width; }; -struct rq { - const uint16_t *idata; - struct zyd_pair *odata; - int len; - STAILQ_ENTRY(rq) rq; +struct zyd_rq { + const uint16_t *idata; + struct zyd_pair *odata; + int len; + STAILQ_ENTRY(zyd_rq) rq; }; struct zyd_vap { @@ -1184,73 +1242,81 @@ struct zyd_vap { #define ZYD_VAP(vap) ((struct zyd_vap *)(vap)) struct zyd_softc { - device_t sc_dev; - struct ifnet *sc_ifp; - struct zyd_rf sc_rf; + device_t sc_dev; + usbd_device_handle sc_udev; + usbd_interface_handle sc_iface; + struct ifnet *sc_ifp; - struct usb_task sc_task; - struct usb_task sc_scantask; - int sc_scan_action; -#define ZYD_SCAN_START 0 -#define ZYD_SCAN_END 1 -#define ZYD_SET_CHANNEL 2 - struct usb_task sc_mcasttask; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; - int sc_flags; -#define ZYD_FLAG_FWLOADED (1 << 0) -#define ZYD_FLAG_DETACHING (1 << 1) - int sc_if_flags; - uint8_t sc_bssid[IEEE80211_ADDR_LEN]; + enum ieee80211_state sc_state; + int sc_arg; + int sc_flags; +#define ZYD_FLAG_FWLOADED (1 << 0) +#define ZYD_FLAG_DETACHING (1 << 1) +#define ZYD_FLAG_INITONCE (1 << 2) +#define ZYD_FLAG_INITDONE (1 << 3) + int sc_if_flags; + uint32_t sc_debug; - enum ieee80211_state sc_state; - int sc_arg; + struct usb_task sc_mcasttask; + struct usb_task sc_scantask; + int sc_scan_action; +#define ZYD_SCAN_START 0 +#define ZYD_SCAN_END 1 +#define ZYD_SET_CHANNEL 2 + struct usb_task sc_task; + struct callout sc_watchdog_ch; - struct mtx sc_mtx; - struct callout sc_watchdog_ch; + struct zyd_rf sc_rf; - STAILQ_HEAD(rqh, rq) sc_rqh; + STAILQ_HEAD(, zyd_rq) sc_rqh; - uint16_t fwbase; - uint8_t regdomain; - uint8_t mac_rev; - uint16_t fw_rev; - uint8_t rf_rev; - uint8_t pa_rev; - uint8_t fix_cr47; - uint8_t fix_cr157; - uint8_t pwr_cal[14]; - uint8_t pwr_int[14]; - uint8_t ofdm36_cal[14]; - uint8_t ofdm48_cal[14]; - uint8_t ofdm54_cal[14]; + uint8_t sc_bssid[IEEE80211_ADDR_LEN]; + uint16_t sc_fwbase; + uint8_t sc_regdomain; + uint8_t sc_macrev; + uint16_t sc_fwrev; + uint8_t sc_rfrev; + uint8_t sc_parev; + uint8_t sc_al2230s; + uint8_t sc_bandedge6; + uint8_t sc_newphy; + uint8_t sc_cckgain; + uint8_t sc_fix_cr157; + uint8_t sc_ledtype; + uint8_t sc_txled; -#define ZYD_ENDPT_BOUT 0 -#define ZYD_ENDPT_BIN 1 -#define ZYD_ENDPT_IIN 2 -#define ZYD_ENDPT_IOUT 3 -#define ZYD_ENDPT_CNT 4 - usbd_pipe_handle zyd_ep[ZYD_ENDPT_CNT]; - uint8_t *ibuf; + uint32_t sc_atim_wnd; + uint32_t sc_pre_tbtt; + uint32_t sc_bcn_int; - struct zyd_rx_data rx_data[ZYD_RX_LIST_CNT]; - struct zyd_tx_data tx_data[ZYD_TX_LIST_CNT]; - int tx_queued; + uint8_t sc_pwrcal[14]; + uint8_t sc_pwrint[14]; + uint8_t sc_ofdm36_cal[14]; + uint8_t sc_ofdm48_cal[14]; + uint8_t sc_ofdm54_cal[14]; +#define ZYD_ENDPT_BOUT 0 +#define ZYD_ENDPT_BIN 1 +#define ZYD_ENDPT_IIN 2 +#define ZYD_ENDPT_IOUT 3 +#define ZYD_ENDPT_CNT 4 + usbd_pipe_handle sc_ep[ZYD_ENDPT_CNT]; + uint8_t *sc_ibuf; - int tx_timer; + struct mtx sc_txmtx; + struct zyd_rx_data sc_rxdata[ZYD_RX_LIST_CNT]; + struct zyd_tx_data sc_txdata[ZYD_TX_LIST_CNT]; + int sc_txidx; + int sc_txqueued; + int sc_txtimer; struct zyd_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; - + int sc_rxtap_len; struct zyd_tx_radiotap_header sc_txtap; - int sc_txtap_len; + int sc_txtap_len; }; -#if 0 -#define ZYD_LOCK(sc) mtx_lock(&(sc)->sc_mtx) -#define ZYD_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) -#else -#define ZYD_LOCK(sc) do { ((sc) = (sc)); mtx_lock(&Giant); } while (0) -#define ZYD_UNLOCK(sc) mtx_unlock(&Giant) -#endif +#define ZYD_LOCK(sc) do { ((sc) = (sc)); mtx_lock(&Giant); } while (0) +#define ZYD_UNLOCK(sc) mtx_unlock(&Giant) +#define ZYD_TX_LOCK(sc) mtx_lock(&(sc)->sc_txmtx) +#define ZYD_TX_UNLOCK(sc) mtx_unlock(&(sc)->sc_txmtx)