Date: Tue, 25 Nov 2008 02:19:02 +0000 (UTC) From: Weongyo Jeong <weongyo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r185278 - head/sys/dev/usb Message-ID: <200811250219.mAP2J26I005125@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: weongyo Date: Tue Nov 25 02:19:02 2008 New Revision: 185278 URL: http://svn.freebsd.org/changeset/base/185278 Log: - improve AL2230 RF handling when the device type is zd1211. After this patch the RX/TX performance becomes about 17~18 Mbps comparing with the previous whose values were RX 7~8Mbps and TX 13~14Mbps. - improve AL2230 RF handling in zd1211b - support AL2230S RF that PV2000 is renamed to AL2230S - use register ZYD_CR244, ZYD_CR243, ZYD_CR242 when the driver writes values on RF. This routine is more faster than the original one - use private TX lock to avoid LOR at zyd_raw_xmit() - increase TX slots from 1 to 5 - needs to set the channel at IEEE80211_S_AUTH not IEEE80211_S_RUN - detailed error handling. In previous the next command was sent to the device even if there was errors - setting ZYD_MAC_RX_THRESHOLD value should be different between 1211 and 1211b - only try to stop the device at zyd_init_locked() if the device is UPed - do not use MTX_RECURSE - do not try to grap Giant lock when the channel is changing - move the device initialization routines from zyd_attach to zyd_init to give a device full-reset chance to the driver. - code cleanup at zyd_raw_xmit() - simplify zyd_attach() routines - resort functions and clean up variables - DPRINTF style change. - style(9) Reviewed by: sam Modified: head/sys/dev/usb/if_zyd.c head/sys/dev/usb/if_zydreg.h Modified: head/sys/dev/usb/if_zyd.c ============================================================================== --- head/sys/dev/usb/if_zyd.c Tue Nov 25 02:15:09 2008 (r185277) +++ head/sys/dev/usb/if_zyd.c Tue Nov 25 02:19:02 2008 (r185278) @@ -66,14 +66,32 @@ #include <dev/usb/if_zydreg.h> #include <dev/usb/if_zydfw.h> -#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_crea 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 * 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_l 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 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; - struct ifnet *ifp; + 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 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); + break; + case IEEE80211_S_RUN: + if (vap->iv_opmode == IEEE80211_M_MONITOR) + break; - 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); - } + /* 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, e 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, e 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 c { 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 c 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_ 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_ 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 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; + } + + 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; } - return 0; +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++) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811250219.mAP2J26I005125>