PERFORCE change 152959 for review
Weongyo Jeong
weongyo at FreeBSD.org
Thu Nov 13 18:41:06 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=152959
Change 152959 by weongyo at weongyo_ws on 2008/11/14 02:40:54
- improve AL2230 RF handling
- 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()
- increate 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)
Affected files ...
.. //depot/projects/vap/sys/dev/usb/if_zyd.c#31 edit
.. //depot/projects/vap/sys/dev/usb/if_zydreg.h#11 edit
Differences ...
==== //depot/projects/vap/sys/dev/usb/if_zyd.c#31 (text+ko) ====
@@ -1,6 +1,6 @@
/* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */
/* $NetBSD: if_zyd.c,v 1.7 2007/06/21 04:04:29 kiyohara Exp $ */
-/* $FreeBSD: src/sys/dev/usb/if_zyd.c,v 1.23 2008/10/27 16:46:50 sam Exp $ */
+/* $FreeBSD: if_zyd.c 10 2008-11-12 05:15:17Z weongyo $ */
/*-
* Copyright (c) 2006 by Damien Bergamini <damien.bergamini at free.fr>
@@ -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 @@
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 @@
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_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,35 @@
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_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 +280,57 @@
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 ieee80211com *ic;
+ struct ifnet *ifp;
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
struct zyd_softc *sc = device_get_softc(dev);
- struct usb_attach_arg *uaa = device_get_ivars(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 +341,18 @@
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 +376,9 @@
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 +388,10 @@
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 +402,24 @@
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 +432,11 @@
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 +452,10 @@
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 +478,18 @@
/* 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 +499,7 @@
/* 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 +508,7 @@
/* 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 +517,17 @@
/* 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 +536,15 @@
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 +553,10 @@
{
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 +578,10 @@
/* 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 +590,7 @@
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 +609,7 @@
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 +628,10 @@
goto fail;
}
}
- return 0;
+ return (0);
fail: zyd_free_rx_list(sc);
- return error;
+ return (error);
}
static void
@@ -694,7 +640,7 @@
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 +657,44 @@
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_AUTH:
+ zyd_set_chan(sc, ic->ic_curchan);
+ break;
case IEEE80211_S_RUN:
- {
- struct ieee80211_node *ni = vap->iv_bss;
+ if (vap->iv_opmode == IEEE80211_M_MONITOR)
+ break;
- 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);
- }
+ /* 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 +709,10 @@
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 +723,10 @@
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 +736,15 @@
{
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 +759,27 @@
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 +793,7 @@
ZYD_CMD_FLAG_READ);
if (error == 0)
*val = le16toh(tmp.val);
- return error;
+ return (error);
}
static int
@@ -856,7 +809,7 @@
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 +840,11 @@
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 +854,47 @@
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 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 void
+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 +911,49 @@
/* 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);
}
/*
@@ -990,18 +969,36 @@
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 AL2230 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_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 +1007,67 @@
{
#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)
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list