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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to