if_zyd.c revision 1.6.2.4 1 1.6.2.2 itohy /* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */
2 1.6.2.4 itohy /* $NetBSD: if_zyd.c,v 1.6.2.4 2007/06/25 09:27:39 itohy Exp $ */
3 1.6.2.2 itohy
4 1.6.2.2 itohy /*-
5 1.6.2.2 itohy * Copyright (c) 2006 by Damien Bergamini <damien.bergamini (at) free.fr>
6 1.6.2.2 itohy * Copyright (c) 2006 by Florian Stoehr <ich (at) florian-stoehr.de>
7 1.6.2.2 itohy *
8 1.6.2.2 itohy * Permission to use, copy, modify, and distribute this software for any
9 1.6.2.2 itohy * purpose with or without fee is hereby granted, provided that the above
10 1.6.2.2 itohy * copyright notice and this permission notice appear in all copies.
11 1.6.2.2 itohy *
12 1.6.2.2 itohy * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 1.6.2.2 itohy * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 1.6.2.2 itohy * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 1.6.2.2 itohy * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 1.6.2.2 itohy * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 1.6.2.2 itohy * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 1.6.2.2 itohy * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 1.6.2.2 itohy */
20 1.6.2.2 itohy
21 1.6.2.2 itohy /*
22 1.6.2.2 itohy * ZyDAS ZD1211/ZD1211B USB WLAN driver.
23 1.6.2.2 itohy */
24 1.6.2.2 itohy #include <sys/cdefs.h>
25 1.6.2.4 itohy __KERNEL_RCSID(0, "$NetBSD: if_zyd.c,v 1.6.2.4 2007/06/25 09:27:39 itohy Exp $");
26 1.6.2.2 itohy
27 1.6.2.2 itohy #include "bpfilter.h"
28 1.6.2.2 itohy
29 1.6.2.2 itohy #include <sys/param.h>
30 1.6.2.2 itohy #include <sys/sockio.h>
31 1.6.2.2 itohy #include <sys/proc.h>
32 1.6.2.2 itohy #include <sys/mbuf.h>
33 1.6.2.2 itohy #include <sys/kernel.h>
34 1.6.2.2 itohy #include <sys/socket.h>
35 1.6.2.2 itohy #include <sys/systm.h>
36 1.6.2.2 itohy #include <sys/malloc.h>
37 1.6.2.2 itohy #include <sys/conf.h>
38 1.6.2.2 itohy #include <sys/device.h>
39 1.6.2.2 itohy
40 1.6.2.2 itohy #include <machine/bus.h>
41 1.6.2.2 itohy #include <machine/endian.h>
42 1.6.2.2 itohy
43 1.6.2.2 itohy #if NBPFILTER > 0
44 1.6.2.2 itohy #include <net/bpf.h>
45 1.6.2.2 itohy #endif
46 1.6.2.2 itohy #include <net/if.h>
47 1.6.2.2 itohy #include <net/if_arp.h>
48 1.6.2.2 itohy #include <net/if_dl.h>
49 1.6.2.2 itohy #include <net/if_ether.h>
50 1.6.2.2 itohy #include <net/if_media.h>
51 1.6.2.2 itohy #include <net/if_types.h>
52 1.6.2.2 itohy
53 1.6.2.2 itohy #include <netinet/in.h>
54 1.6.2.2 itohy #include <netinet/in_systm.h>
55 1.6.2.2 itohy #include <netinet/in_var.h>
56 1.6.2.2 itohy #include <netinet/ip.h>
57 1.6.2.2 itohy
58 1.6.2.2 itohy #include <net80211/ieee80211_netbsd.h>
59 1.6.2.2 itohy #include <net80211/ieee80211_var.h>
60 1.6.2.2 itohy #include <net80211/ieee80211_amrr.h>
61 1.6.2.2 itohy #include <net80211/ieee80211_radiotap.h>
62 1.6.2.2 itohy
63 1.6.2.2 itohy #include <dev/firmload.h>
64 1.6.2.2 itohy
65 1.6.2.2 itohy #include <dev/usb/usb.h>
66 1.6.2.2 itohy #include <dev/usb/usbdi.h>
67 1.6.2.2 itohy #include <dev/usb/usbdi_util.h>
68 1.6.2.2 itohy #include <dev/usb/usbdevs.h>
69 1.6.2.2 itohy #include <dev/usb/usb_ethersubr.h>
70 1.6.2.2 itohy
71 1.6.2.2 itohy #include <dev/usb/if_zydreg.h>
72 1.6.2.2 itohy
73 1.6.2.2 itohy #ifdef USB_DEBUG
74 1.6.2.2 itohy #define ZYD_DEBUG
75 1.6.2.2 itohy #endif
76 1.6.2.2 itohy
77 1.6.2.2 itohy #ifdef ZYD_DEBUG
78 1.6.2.2 itohy #define DPRINTF(x) do { if (zyddebug > 0) printf x; } while (0)
79 1.6.2.2 itohy #define DPRINTFN(n, x) do { if (zyddebug > (n)) printf x; } while (0)
80 1.6.2.2 itohy int zyddebug = 0;
81 1.6.2.2 itohy #else
82 1.6.2.2 itohy #define DPRINTF(x)
83 1.6.2.2 itohy #define DPRINTFN(n, x)
84 1.6.2.2 itohy #endif
85 1.6.2.2 itohy
86 1.6.2.2 itohy static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY;
87 1.6.2.2 itohy static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB;
88 1.6.2.2 itohy
89 1.6.2.2 itohy /* various supported device vendors/products */
90 1.6.2.2 itohy #define ZYD_ZD1211_DEV(v, p) \
91 1.6.2.2 itohy { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211 }
92 1.6.2.2 itohy #define ZYD_ZD1211B_DEV(v, p) \
93 1.6.2.2 itohy { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211B }
94 1.6.2.2 itohy static const struct zyd_type {
95 1.6.2.2 itohy struct usb_devno dev;
96 1.6.2.2 itohy uint8_t rev;
97 1.6.2.2 itohy #define ZYD_ZD1211 0
98 1.6.2.2 itohy #define ZYD_ZD1211B 1
99 1.6.2.2 itohy } zyd_devs[] = {
100 1.6.2.2 itohy ZYD_ZD1211_DEV(3COM2, 3CRUSB10075),
101 1.6.2.2 itohy ZYD_ZD1211_DEV(ABOCOM, WL54),
102 1.6.2.2 itohy ZYD_ZD1211_DEV(ASUSTEK, WL159G),
103 1.6.2.2 itohy ZYD_ZD1211_DEV(CYBERTAN, TG54USB),
104 1.6.2.2 itohy ZYD_ZD1211_DEV(DRAYTEK, VIGOR550),
105 1.6.2.2 itohy ZYD_ZD1211_DEV(PLANEX2, GWUS54GZL),
106 1.6.2.2 itohy ZYD_ZD1211_DEV(PLANEX3, GWUS54GZ),
107 1.6.2.2 itohy ZYD_ZD1211_DEV(PLANEX3, GWUS54MINI),
108 1.6.2.2 itohy ZYD_ZD1211_DEV(SAGEM, XG760A),
109 1.6.2.2 itohy ZYD_ZD1211_DEV(SENAO, NUB8301),
110 1.6.2.2 itohy ZYD_ZD1211_DEV(SITECOMEU, WL113),
111 1.6.2.2 itohy ZYD_ZD1211_DEV(SWEEX, ZD1211),
112 1.6.2.2 itohy ZYD_ZD1211_DEV(TEKRAM, QUICKWLAN),
113 1.6.2.2 itohy ZYD_ZD1211_DEV(TEKRAM, ZD1211_1),
114 1.6.2.2 itohy ZYD_ZD1211_DEV(TEKRAM, ZD1211_2),
115 1.6.2.2 itohy ZYD_ZD1211_DEV(TWINMOS, G240),
116 1.6.2.2 itohy ZYD_ZD1211_DEV(UMEDIA, ALL0298V2),
117 1.6.2.2 itohy ZYD_ZD1211_DEV(UMEDIA, TEW429UB_A),
118 1.6.2.2 itohy ZYD_ZD1211_DEV(UMEDIA, TEW429UB),
119 1.6.2.2 itohy ZYD_ZD1211_DEV(WISTRONNEWEB, UR055G),
120 1.6.2.2 itohy ZYD_ZD1211_DEV(ZCOM, ZD1211),
121 1.6.2.2 itohy ZYD_ZD1211_DEV(ZYDAS, ZD1211),
122 1.6.2.2 itohy ZYD_ZD1211_DEV(ZYXEL, AG225H),
123 1.6.2.2 itohy ZYD_ZD1211_DEV(ZYXEL, ZYAIRG220),
124 1.6.2.2 itohy
125 1.6.2.2 itohy ZYD_ZD1211B_DEV(ACCTON, SMCWUSBG),
126 1.6.2.2 itohy ZYD_ZD1211B_DEV(ACCTON, ZD1211B),
127 1.6.2.2 itohy ZYD_ZD1211B_DEV(ASUSTEK, A9T_WIFI),
128 1.6.2.2 itohy ZYD_ZD1211B_DEV(BELKIN, F5D7050C),
129 1.6.2.2 itohy ZYD_ZD1211B_DEV(BELKIN, ZD1211B),
130 1.6.2.2 itohy ZYD_ZD1211B_DEV(CISCOLINKSYS, WUSBF54G),
131 1.6.2.2 itohy ZYD_ZD1211B_DEV(FIBERLINE, WL430U),
132 1.6.2.2 itohy ZYD_ZD1211B_DEV(MELCO, KG54L),
133 1.6.2.2 itohy ZYD_ZD1211B_DEV(PHILIPS, SNU5600),
134 1.6.2.2 itohy ZYD_ZD1211B_DEV(SAGEM, XG76NA),
135 1.6.2.2 itohy ZYD_ZD1211B_DEV(SITECOMEU, ZD1211B),
136 1.6.2.2 itohy ZYD_ZD1211B_DEV(UMEDIA, TEW429UBC1),
137 1.6.2.2 itohy #if 0 /* Shall we needs? */
138 1.6.2.2 itohy ZYD_ZD1211B_DEV(UNKNOWN1, ZD1211B_1),
139 1.6.2.2 itohy ZYD_ZD1211B_DEV(UNKNOWN1, ZD1211B_2),
140 1.6.2.2 itohy ZYD_ZD1211B_DEV(UNKNOWN2, ZD1211B),
141 1.6.2.2 itohy ZYD_ZD1211B_DEV(UNKNOWN3, ZD1211B),
142 1.6.2.2 itohy #endif
143 1.6.2.2 itohy ZYD_ZD1211B_DEV(USR, USR5423),
144 1.6.2.2 itohy ZYD_ZD1211B_DEV(VTECH, ZD1211B),
145 1.6.2.2 itohy ZYD_ZD1211B_DEV(ZCOM, ZD1211B),
146 1.6.2.2 itohy ZYD_ZD1211B_DEV(ZYDAS, ZD1211B),
147 1.6.2.2 itohy ZYD_ZD1211B_DEV(ZYXEL, M202),
148 1.6.2.2 itohy ZYD_ZD1211B_DEV(ZYXEL, G220V2),
149 1.6.2.2 itohy };
150 1.6.2.2 itohy #define zyd_lookup(v, p) \
151 1.6.2.2 itohy ((const struct zyd_type *)usb_lookup(zyd_devs, v, p))
152 1.6.2.2 itohy
153 1.6.2.2 itohy USB_DECLARE_DRIVER(zyd);
154 1.6.2.2 itohy
155 1.6.2.2 itohy Static int zyd_attachhook(void *);
156 1.6.2.2 itohy Static int zyd_complete_attach(struct zyd_softc *);
157 1.6.2.2 itohy Static int zyd_open_pipes(struct zyd_softc *);
158 1.6.2.2 itohy Static void zyd_abort_pipes(struct zyd_softc *);
159 1.6.2.2 itohy Static void zyd_close_pipes(struct zyd_softc *);
160 1.6.2.2 itohy Static void zyd_free_tx_list(struct zyd_softc *);
161 1.6.2.2 itohy Static void zyd_free_rx_list(struct zyd_softc *);
162 1.6.2.2 itohy Static struct ieee80211_node *zyd_node_alloc(struct ieee80211_node_table *);
163 1.6.2.2 itohy Static int zyd_media_change(struct ifnet *);
164 1.6.2.2 itohy Static void zyd_next_scan(void *);
165 1.6.2.2 itohy Static void zyd_task(void *);
166 1.6.2.2 itohy Static int zyd_newstate(struct ieee80211com *, enum ieee80211_state, int);
167 1.6.2.2 itohy Static int zyd_cmd(struct zyd_softc *, uint16_t, const void *, int,
168 1.6.2.2 itohy void *, int, u_int);
169 1.6.2.2 itohy Static int zyd_read16(struct zyd_softc *, uint16_t, uint16_t *);
170 1.6.2.2 itohy Static int zyd_read32(struct zyd_softc *, uint16_t, uint32_t *);
171 1.6.2.2 itohy Static int zyd_write16(struct zyd_softc *, uint16_t, uint16_t);
172 1.6.2.2 itohy Static int zyd_write32(struct zyd_softc *, uint16_t, uint32_t);
173 1.6.2.2 itohy Static int zyd_rfwrite(struct zyd_softc *, uint32_t);
174 1.6.2.2 itohy Static void zyd_lock_phy(struct zyd_softc *);
175 1.6.2.2 itohy Static void zyd_unlock_phy(struct zyd_softc *);
176 1.6.2.2 itohy Static int zyd_rfmd_init(struct zyd_rf *);
177 1.6.2.2 itohy Static int zyd_rfmd_switch_radio(struct zyd_rf *, int);
178 1.6.2.2 itohy Static int zyd_rfmd_set_channel(struct zyd_rf *, uint8_t);
179 1.6.2.2 itohy Static int zyd_al2230_init(struct zyd_rf *);
180 1.6.2.2 itohy Static int zyd_al2230_switch_radio(struct zyd_rf *, int);
181 1.6.2.2 itohy Static int zyd_al2230_set_channel(struct zyd_rf *, uint8_t);
182 1.6.2.2 itohy Static int zyd_al2230_init_b(struct zyd_rf *);
183 1.6.2.2 itohy Static int zyd_al7230B_init(struct zyd_rf *);
184 1.6.2.2 itohy Static int zyd_al7230B_switch_radio(struct zyd_rf *, int);
185 1.6.2.2 itohy Static int zyd_al7230B_set_channel(struct zyd_rf *, uint8_t);
186 1.6.2.2 itohy Static int zyd_al2210_init(struct zyd_rf *);
187 1.6.2.2 itohy Static int zyd_al2210_switch_radio(struct zyd_rf *, int);
188 1.6.2.2 itohy Static int zyd_al2210_set_channel(struct zyd_rf *, uint8_t);
189 1.6.2.2 itohy Static int zyd_gct_init(struct zyd_rf *);
190 1.6.2.2 itohy Static int zyd_gct_switch_radio(struct zyd_rf *, int);
191 1.6.2.2 itohy Static int zyd_gct_set_channel(struct zyd_rf *, uint8_t);
192 1.6.2.2 itohy Static int zyd_maxim_init(struct zyd_rf *);
193 1.6.2.2 itohy Static int zyd_maxim_switch_radio(struct zyd_rf *, int);
194 1.6.2.2 itohy Static int zyd_maxim_set_channel(struct zyd_rf *, uint8_t);
195 1.6.2.2 itohy Static int zyd_maxim2_init(struct zyd_rf *);
196 1.6.2.2 itohy Static int zyd_maxim2_switch_radio(struct zyd_rf *, int);
197 1.6.2.2 itohy Static int zyd_maxim2_set_channel(struct zyd_rf *, uint8_t);
198 1.6.2.2 itohy Static int zyd_rf_attach(struct zyd_softc *, uint8_t);
199 1.6.2.2 itohy Static const char *zyd_rf_name(uint8_t);
200 1.6.2.2 itohy Static int zyd_hw_init(struct zyd_softc *);
201 1.6.2.2 itohy Static int zyd_read_eeprom(struct zyd_softc *);
202 1.6.2.2 itohy Static int zyd_set_macaddr(struct zyd_softc *, const uint8_t *);
203 1.6.2.2 itohy Static int zyd_set_bssid(struct zyd_softc *, const uint8_t *);
204 1.6.2.2 itohy Static int zyd_switch_radio(struct zyd_softc *, int);
205 1.6.2.2 itohy Static void zyd_set_led(struct zyd_softc *, int, int);
206 1.6.2.2 itohy Static int zyd_set_rxfilter(struct zyd_softc *);
207 1.6.2.2 itohy Static void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
208 1.6.2.2 itohy Static int zyd_set_beacon_interval(struct zyd_softc *, int);
209 1.6.2.2 itohy Static uint8_t zyd_plcp_signal(int);
210 1.6.2.2 itohy Static void zyd_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
211 1.6.2.2 itohy Static void zyd_rx_data(struct zyd_softc *, struct mbuf *, uint16_t);
212 1.6.2.2 itohy Static void zyd_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
213 1.6.2.2 itohy Static void zyd_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
214 1.6.2.2 itohy Static int zyd_tx_mgt(struct zyd_softc *, struct mbuf *,
215 1.6.2.2 itohy struct ieee80211_node *);
216 1.6.2.2 itohy Static int zyd_tx_data(struct zyd_softc *, struct mbuf *,
217 1.6.2.2 itohy struct ieee80211_node *);
218 1.6.2.2 itohy Static void zyd_start(struct ifnet *);
219 1.6.2.2 itohy Static void zyd_watchdog(struct ifnet *);
220 1.6.2.2 itohy Static int zyd_ioctl(struct ifnet *, u_long, usb_ioctlarg_t);
221 1.6.2.2 itohy Static int zyd_init(struct ifnet *);
222 1.6.2.2 itohy Static void zyd_stop(struct ifnet *, int);
223 1.6.2.2 itohy Static int zyd_loadfirmware(struct zyd_softc *, u_char *, size_t);
224 1.6.2.2 itohy Static void zyd_iter_func(void *, struct ieee80211_node *);
225 1.6.2.2 itohy Static void zyd_amrr_timeout(void *);
226 1.6.2.2 itohy Static void zyd_newassoc(struct ieee80211_node *, int);
227 1.6.2.2 itohy
228 1.6.2.2 itohy static const struct ieee80211_rateset zyd_rateset_11b =
229 1.6.2.2 itohy { 4, { 2, 4, 11, 22 } };
230 1.6.2.2 itohy
231 1.6.2.2 itohy static const struct ieee80211_rateset zyd_rateset_11g =
232 1.6.2.2 itohy { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
233 1.6.2.2 itohy
234 1.6.2.2 itohy USB_MATCH(zyd)
235 1.6.2.2 itohy {
236 1.6.2.2 itohy USB_MATCH_START(zyd, uaa);
237 1.6.2.2 itohy
238 1.6.2.2 itohy #ifndef USB_USE_IFATTACH
239 1.6.2.2 itohy if (uaa->iface != NULL)
240 1.6.2.2 itohy return UMATCH_NONE;
241 1.6.2.2 itohy #endif /* USB_USE_IFATTACH */
242 1.6.2.2 itohy
243 1.6.2.2 itohy return (zyd_lookup(uaa->vendor, uaa->product) != NULL) ?
244 1.6.2.2 itohy UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
245 1.6.2.2 itohy }
246 1.6.2.2 itohy
247 1.6.2.2 itohy Static int
248 1.6.2.2 itohy zyd_attachhook(void *xsc)
249 1.6.2.2 itohy {
250 1.6.2.2 itohy struct zyd_softc *sc = xsc;
251 1.6.2.2 itohy firmware_handle_t fwh;
252 1.6.2.2 itohy const char *fwname;
253 1.6.2.2 itohy u_char *fw;
254 1.6.2.2 itohy size_t size;
255 1.6.2.2 itohy int error;
256 1.6.2.2 itohy
257 1.6.2.2 itohy fwname = (sc->mac_rev == ZYD_ZD1211) ? "zyd-zd1211" : "zyd-zd1211b";
258 1.6.2.2 itohy if ((error = firmware_open("zyd", fwname, &fwh)) != 0) {
259 1.6.2.2 itohy printf("%s: failed to open firmware %s (error=%d)\n",
260 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), fwname, error);
261 1.6.2.2 itohy return error;
262 1.6.2.2 itohy }
263 1.6.2.2 itohy size = firmware_get_size(fwh);
264 1.6.2.2 itohy fw = firmware_malloc(size);
265 1.6.2.2 itohy if (fw == NULL) {
266 1.6.2.2 itohy printf("%s: failed to allocate firmware memory\n",
267 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
268 1.6.2.2 itohy firmware_close(fwh);
269 1.6.2.2 itohy return ENOMEM;;
270 1.6.2.2 itohy }
271 1.6.2.2 itohy error = firmware_read(fwh, 0, fw, size);
272 1.6.2.2 itohy firmware_close(fwh);
273 1.6.2.2 itohy if (error != 0) {
274 1.6.2.2 itohy printf("%s: failed to read firmware (error %d)\n",
275 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), error);
276 1.6.2.2 itohy firmware_free(fw, 0);
277 1.6.2.2 itohy return error;
278 1.6.2.2 itohy }
279 1.6.2.2 itohy
280 1.6.2.2 itohy error = zyd_loadfirmware(sc, fw, size);
281 1.6.2.2 itohy if (error != 0) {
282 1.6.2.2 itohy printf("%s: could not load firmware (error=%d)\n",
283 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), error);
284 1.6.2.2 itohy firmware_free(fw, 0);
285 1.6.2.2 itohy return ENXIO;
286 1.6.2.2 itohy }
287 1.6.2.2 itohy
288 1.6.2.2 itohy firmware_free(fw, 0);
289 1.6.2.2 itohy sc->sc_flags |= ZD1211_FWLOADED;
290 1.6.2.2 itohy
291 1.6.2.2 itohy /* complete the attach process */
292 1.6.2.2 itohy if ((error = zyd_complete_attach(sc)) == 0)
293 1.6.2.2 itohy sc->attached = 1;
294 1.6.2.2 itohy return error;
295 1.6.2.2 itohy }
296 1.6.2.2 itohy
297 1.6.2.2 itohy USB_ATTACH(zyd)
298 1.6.2.2 itohy {
299 1.6.2.2 itohy USB_ATTACH_START(zyd, sc, uaa);
300 1.6.2.2 itohy char *devinfop;
301 1.6.2.2 itohy usb_device_descriptor_t* ddesc;
302 1.6.2.2 itohy struct ifnet *ifp = &sc->sc_if;
303 1.6.2.2 itohy
304 1.6.2.2 itohy sc->sc_udev = uaa->device;
305 1.6.2.2 itohy sc->sc_flags = 0;
306 1.6.2.2 itohy
307 1.6.2.2 itohy devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
308 1.6.2.2 itohy USB_ATTACH_SETUP;
309 1.6.2.2 itohy printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfop);
310 1.6.2.2 itohy usbd_devinfo_free(devinfop);
311 1.6.2.2 itohy
312 1.6.2.2 itohy sc->mac_rev = zyd_lookup(uaa->vendor, uaa->product)->rev;
313 1.6.2.2 itohy
314 1.6.2.2 itohy ddesc = usbd_get_device_descriptor(sc->sc_udev);
315 1.6.2.2 itohy if (UGETW(ddesc->bcdDevice) < 0x4330) {
316 1.6.2.2 itohy printf("%s: device version mismatch: 0x%x "
317 1.6.2.2 itohy "(only >= 43.30 supported)\n", USBDEVNAME(sc->sc_dev),
318 1.6.2.2 itohy UGETW(ddesc->bcdDevice));
319 1.6.2.2 itohy USB_ATTACH_ERROR_RETURN;
320 1.6.2.2 itohy }
321 1.6.2.2 itohy
322 1.6.2.2 itohy ifp->if_softc = sc;
323 1.6.2.2 itohy ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
324 1.6.2.2 itohy ifp->if_init = zyd_init;
325 1.6.2.2 itohy ifp->if_ioctl = zyd_ioctl;
326 1.6.2.2 itohy ifp->if_start = zyd_start;
327 1.6.2.2 itohy ifp->if_watchdog = zyd_watchdog;
328 1.6.2.2 itohy IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
329 1.6.2.2 itohy IFQ_SET_READY(&ifp->if_snd);
330 1.6.2.2 itohy memcpy(ifp->if_xname, USBDEVNAME(sc->sc_dev), IFNAMSIZ);
331 1.6.2.2 itohy
332 1.6.2.2 itohy if_attach(ifp);
333 1.6.2.2 itohy /* XXXX: alloc temporarily until the layer2 can be configured. */
334 1.6.2.2 itohy if_alloc_sadl(ifp);
335 1.6.2.2 itohy
336 1.6.2.2 itohy SIMPLEQ_INIT(&sc->sc_rqh);
337 1.6.2.2 itohy
338 1.6.2.2 itohy USB_ATTACH_SUCCESS_RETURN;
339 1.6.2.2 itohy }
340 1.6.2.2 itohy
341 1.6.2.2 itohy Static int
342 1.6.2.2 itohy zyd_complete_attach(struct zyd_softc *sc)
343 1.6.2.2 itohy {
344 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
345 1.6.2.2 itohy struct ifnet *ifp = &sc->sc_if;
346 1.6.2.2 itohy usbd_status error;
347 1.6.2.2 itohy int i;
348 1.6.2.2 itohy
349 1.6.2.2 itohy usb_init_task(&sc->sc_task, zyd_task, sc);
350 1.6.2.2 itohy usb_callout_init(sc->sc_scan_ch);
351 1.6.2.2 itohy
352 1.6.2.2 itohy sc->amrr.amrr_min_success_threshold = 1;
353 1.6.2.2 itohy sc->amrr.amrr_max_success_threshold = 10;
354 1.6.2.2 itohy usb_callout_init(sc->sc_amrr_ch);
355 1.6.2.2 itohy
356 1.6.2.2 itohy error = usbd_set_config_no(sc->sc_udev, ZYD_CONFIG_NO, 1);
357 1.6.2.2 itohy if (error != 0) {
358 1.6.2.2 itohy printf("%s: setting config no failed\n",
359 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
360 1.6.2.2 itohy goto fail;
361 1.6.2.2 itohy }
362 1.6.2.2 itohy
363 1.6.2.2 itohy error = usbd_device2interface_handle(sc->sc_udev, ZYD_IFACE_INDEX,
364 1.6.2.2 itohy &sc->sc_iface);
365 1.6.2.2 itohy if (error != 0) {
366 1.6.2.2 itohy printf("%s: getting interface handle failed\n",
367 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
368 1.6.2.2 itohy goto fail;
369 1.6.2.2 itohy }
370 1.6.2.2 itohy
371 1.6.2.2 itohy if ((error = zyd_open_pipes(sc)) != 0) {
372 1.6.2.2 itohy printf("%s: could not open pipes\n", USBDEVNAME(sc->sc_dev));
373 1.6.2.2 itohy goto fail;
374 1.6.2.2 itohy }
375 1.6.2.2 itohy
376 1.6.2.2 itohy if ((error = zyd_read_eeprom(sc)) != 0) {
377 1.6.2.2 itohy printf("%s: could not read EEPROM\n", USBDEVNAME(sc->sc_dev));
378 1.6.2.2 itohy goto fail;
379 1.6.2.2 itohy }
380 1.6.2.2 itohy
381 1.6.2.2 itohy if ((error = zyd_rf_attach(sc, sc->rf_rev)) != 0) {
382 1.6.2.2 itohy printf("%s: could not attach RF\n", USBDEVNAME(sc->sc_dev));
383 1.6.2.2 itohy goto fail;
384 1.6.2.2 itohy }
385 1.6.2.2 itohy
386 1.6.2.2 itohy if ((error = zyd_hw_init(sc)) != 0) {
387 1.6.2.2 itohy printf("%s: hardware initialization failed\n",
388 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
389 1.6.2.2 itohy goto fail;
390 1.6.2.2 itohy }
391 1.6.2.2 itohy
392 1.6.2.2 itohy printf("%s: HMAC ZD1211%s, FW %02x.%02x, RF %s, PA %x, address %s\n",
393 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), (sc->mac_rev == ZYD_ZD1211) ? "": "B",
394 1.6.2.2 itohy sc->fw_rev >> 8, sc->fw_rev & 0xff, zyd_rf_name(sc->rf_rev),
395 1.6.2.2 itohy sc->pa_rev, ether_sprintf(ic->ic_myaddr));
396 1.6.2.2 itohy
397 1.6.2.2 itohy ic->ic_ifp = ifp;
398 1.6.2.2 itohy ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
399 1.6.2.2 itohy ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
400 1.6.2.2 itohy ic->ic_state = IEEE80211_S_INIT;
401 1.6.2.2 itohy
402 1.6.2.2 itohy /* set device capabilities */
403 1.6.2.2 itohy ic->ic_caps =
404 1.6.2.2 itohy IEEE80211_C_MONITOR | /* monitor mode supported */
405 1.6.2.2 itohy IEEE80211_C_TXPMGT | /* tx power management */
406 1.6.2.2 itohy IEEE80211_C_SHPREAMBLE | /* short preamble supported */
407 1.6.2.2 itohy IEEE80211_C_WEP; /* s/w WEP */
408 1.6.2.2 itohy
409 1.6.2.2 itohy /* set supported .11b and .11g rates */
410 1.6.2.2 itohy ic->ic_sup_rates[IEEE80211_MODE_11B] = zyd_rateset_11b;
411 1.6.2.2 itohy ic->ic_sup_rates[IEEE80211_MODE_11G] = zyd_rateset_11g;
412 1.6.2.2 itohy
413 1.6.2.2 itohy /* set supported .11b and .11g channels (1 through 14) */
414 1.6.2.2 itohy for (i = 1; i <= 14; i++) {
415 1.6.2.2 itohy ic->ic_channels[i].ic_freq =
416 1.6.2.2 itohy ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
417 1.6.2.2 itohy ic->ic_channels[i].ic_flags =
418 1.6.2.2 itohy IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
419 1.6.2.2 itohy IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
420 1.6.2.2 itohy }
421 1.6.2.2 itohy
422 1.6.2.2 itohy if_free_sadl(ifp);
423 1.6.2.2 itohy ieee80211_ifattach(ic);
424 1.6.2.2 itohy ic->ic_node_alloc = zyd_node_alloc;
425 1.6.2.2 itohy ic->ic_newassoc = zyd_newassoc;
426 1.6.2.2 itohy
427 1.6.2.2 itohy /* override state transition machine */
428 1.6.2.2 itohy sc->sc_newstate = ic->ic_newstate;
429 1.6.2.2 itohy ic->ic_newstate = zyd_newstate;
430 1.6.2.2 itohy ieee80211_media_init(ic, zyd_media_change, ieee80211_media_status);
431 1.6.2.2 itohy
432 1.6.2.2 itohy #if NBPFILTER > 0
433 1.6.2.2 itohy bpfattach2(ifp, DLT_IEEE802_11_RADIO,
434 1.6.2.2 itohy sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
435 1.6.2.2 itohy &sc->sc_drvbpf);
436 1.6.2.2 itohy
437 1.6.2.2 itohy sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
438 1.6.2.2 itohy sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
439 1.6.2.2 itohy sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT);
440 1.6.2.2 itohy
441 1.6.2.2 itohy sc->sc_txtap_len = sizeof sc->sc_txtapu;
442 1.6.2.2 itohy sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
443 1.6.2.2 itohy sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT);
444 1.6.2.2 itohy #endif
445 1.6.2.2 itohy
446 1.6.2.2 itohy ieee80211_announce(ic);
447 1.6.2.2 itohy
448 1.6.2.2 itohy usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
449 1.6.2.2 itohy USBDEV(sc->sc_dev));
450 1.6.2.2 itohy
451 1.6.2.2 itohy fail: return error;
452 1.6.2.2 itohy }
453 1.6.2.2 itohy
454 1.6.2.2 itohy USB_DETACH(zyd)
455 1.6.2.2 itohy {
456 1.6.2.2 itohy USB_DETACH_START(zyd, sc);
457 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
458 1.6.2.2 itohy struct ifnet *ifp = &sc->sc_if;
459 1.6.2.2 itohy int s;
460 1.6.2.2 itohy
461 1.6.2.2 itohy if (!sc->attached) {
462 1.6.2.2 itohy if_free_sadl(ifp);
463 1.6.2.2 itohy if_detach(ifp);
464 1.6.2.2 itohy return 0;
465 1.6.2.2 itohy }
466 1.6.2.2 itohy
467 1.6.2.2 itohy s = splusb();
468 1.6.2.2 itohy
469 1.6.2.2 itohy zyd_stop(ifp, 1);
470 1.6.2.2 itohy usb_rem_task(sc->sc_udev, &sc->sc_task);
471 1.6.2.2 itohy usb_uncallout(sc->sc_scan_ch, zyd_next_scan, sc);
472 1.6.2.2 itohy usb_uncallout(sc->sc_amrr_ch, zyd_amrr_timeout, sc);
473 1.6.2.2 itohy
474 1.6.2.2 itohy zyd_abort_pipes(sc);
475 1.6.2.2 itohy
476 1.6.2.2 itohy zyd_free_rx_list(sc);
477 1.6.2.2 itohy zyd_free_tx_list(sc);
478 1.6.2.2 itohy
479 1.6.2.2 itohy zyd_close_pipes(sc);
480 1.6.2.2 itohy
481 1.6.2.2 itohy sc->attached = 0;
482 1.6.2.2 itohy
483 1.6.2.2 itohy #if NBPFILTER > 0
484 1.6.2.2 itohy bpfdetach(ifp);
485 1.6.2.2 itohy #endif
486 1.6.2.2 itohy ieee80211_ifdetach(ic);
487 1.6.2.2 itohy if_detach(ifp);
488 1.6.2.2 itohy
489 1.6.2.2 itohy splx(s);
490 1.6.2.2 itohy
491 1.6.2.2 itohy usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
492 1.6.2.2 itohy USBDEV(sc->sc_dev));
493 1.6.2.2 itohy
494 1.6.2.2 itohy return 0;
495 1.6.2.2 itohy }
496 1.6.2.2 itohy
497 1.6.2.2 itohy Static int
498 1.6.2.2 itohy zyd_open_pipes(struct zyd_softc *sc)
499 1.6.2.2 itohy {
500 1.6.2.2 itohy usb_endpoint_descriptor_t *edesc;
501 1.6.2.2 itohy int isize;
502 1.6.2.2 itohy usbd_status error;
503 1.6.2.2 itohy
504 1.6.2.2 itohy /* interrupt in */
505 1.6.2.2 itohy edesc = usbd_get_endpoint_descriptor(sc->sc_iface, 0x83);
506 1.6.2.2 itohy if (edesc == NULL)
507 1.6.2.2 itohy return EINVAL;
508 1.6.2.2 itohy
509 1.6.2.2 itohy isize = UGETW(edesc->wMaxPacketSize);
510 1.6.2.2 itohy if (isize == 0) /* should not happen */
511 1.6.2.2 itohy return EINVAL;
512 1.6.2.2 itohy
513 1.6.2.2 itohy sc->ibuf = malloc(isize, M_USBDEV, M_NOWAIT);
514 1.6.2.2 itohy if (sc->ibuf == NULL)
515 1.6.2.2 itohy return ENOMEM;
516 1.6.2.2 itohy
517 1.6.2.2 itohy error = usbd_open_pipe_intr(sc->sc_iface, 0x83, USBD_SHORT_XFER_OK,
518 1.6.2.2 itohy &sc->zyd_ep[ZYD_ENDPT_IIN], sc, sc->ibuf, isize, zyd_intr,
519 1.6.2.2 itohy USBD_DEFAULT_INTERVAL);
520 1.6.2.2 itohy if (error != 0) {
521 1.6.2.2 itohy printf("%s: open rx intr pipe failed: %s\n",
522 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), usbd_errstr(error));
523 1.6.2.2 itohy goto fail;
524 1.6.2.2 itohy }
525 1.6.2.2 itohy
526 1.6.2.2 itohy /* interrupt out (not necessarily an interrupt pipe) */
527 1.6.2.2 itohy error = usbd_open_pipe(sc->sc_iface, 0x04, USBD_EXCLUSIVE_USE,
528 1.6.2.2 itohy &sc->zyd_ep[ZYD_ENDPT_IOUT]);
529 1.6.2.2 itohy if (error != 0) {
530 1.6.2.2 itohy printf("%s: open tx intr pipe failed: %s\n",
531 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), usbd_errstr(error));
532 1.6.2.2 itohy goto fail;
533 1.6.2.2 itohy }
534 1.6.2.2 itohy
535 1.6.2.2 itohy /* bulk in */
536 1.6.2.2 itohy error = usbd_open_pipe(sc->sc_iface, 0x82, USBD_EXCLUSIVE_USE,
537 1.6.2.2 itohy &sc->zyd_ep[ZYD_ENDPT_BIN]);
538 1.6.2.2 itohy if (error != 0) {
539 1.6.2.2 itohy printf("%s: open rx pipe failed: %s\n",
540 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), usbd_errstr(error));
541 1.6.2.2 itohy goto fail;
542 1.6.2.2 itohy }
543 1.6.2.2 itohy
544 1.6.2.2 itohy /* bulk out */
545 1.6.2.2 itohy error = usbd_open_pipe(sc->sc_iface, 0x01, USBD_EXCLUSIVE_USE,
546 1.6.2.2 itohy &sc->zyd_ep[ZYD_ENDPT_BOUT]);
547 1.6.2.2 itohy if (error != 0) {
548 1.6.2.2 itohy printf("%s: open tx pipe failed: %s\n",
549 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), usbd_errstr(error));
550 1.6.2.2 itohy goto fail;
551 1.6.2.2 itohy }
552 1.6.2.2 itohy
553 1.6.2.2 itohy return 0;
554 1.6.2.2 itohy
555 1.6.2.2 itohy fail: zyd_close_pipes(sc);
556 1.6.2.2 itohy return error;
557 1.6.2.2 itohy }
558 1.6.2.2 itohy
559 1.6.2.2 itohy Static void
560 1.6.2.2 itohy zyd_abort_pipes(struct zyd_softc *sc)
561 1.6.2.2 itohy {
562 1.6.2.2 itohy int i;
563 1.6.2.2 itohy
564 1.6.2.2 itohy for (i = 0; i < ZYD_ENDPT_CNT; i++) {
565 1.6.2.2 itohy if (sc->zyd_ep[i] != NULL) {
566 1.6.2.2 itohy usbd_abort_pipe(sc->zyd_ep[i]);
567 1.6.2.2 itohy }
568 1.6.2.2 itohy }
569 1.6.2.2 itohy }
570 1.6.2.2 itohy
571 1.6.2.2 itohy Static void
572 1.6.2.2 itohy zyd_close_pipes(struct zyd_softc *sc)
573 1.6.2.2 itohy {
574 1.6.2.2 itohy int i;
575 1.6.2.2 itohy
576 1.6.2.2 itohy for (i = 0; i < ZYD_ENDPT_CNT; i++) {
577 1.6.2.2 itohy if (sc->zyd_ep[i] != NULL) {
578 1.6.2.2 itohy usbd_close_pipe(sc->zyd_ep[i]);
579 1.6.2.2 itohy sc->zyd_ep[i] = NULL;
580 1.6.2.2 itohy }
581 1.6.2.2 itohy }
582 1.6.2.2 itohy if (sc->ibuf != NULL) {
583 1.6.2.2 itohy free(sc->ibuf, M_USBDEV);
584 1.6.2.2 itohy sc->ibuf = NULL;
585 1.6.2.2 itohy }
586 1.6.2.2 itohy }
587 1.6.2.2 itohy
588 1.6.2.2 itohy Static void
589 1.6.2.2 itohy zyd_free_tx_list(struct zyd_softc *sc)
590 1.6.2.2 itohy {
591 1.6.2.2 itohy int i;
592 1.6.2.2 itohy
593 1.6.2.2 itohy usb_ether_tx_list_free(sc->tx_data, ZYD_TX_LIST_CNT);
594 1.6.2.2 itohy
595 1.6.2.2 itohy for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
596 1.6.2.2 itohy if (sc->tx_ni[i] != NULL) {
597 1.6.2.2 itohy ieee80211_free_node(sc->tx_ni[i]);
598 1.6.2.2 itohy sc->tx_ni[i] = NULL;
599 1.6.2.2 itohy }
600 1.6.2.2 itohy }
601 1.6.2.2 itohy }
602 1.6.2.2 itohy
603 1.6.2.2 itohy Static void
604 1.6.2.2 itohy zyd_free_rx_list(struct zyd_softc *sc)
605 1.6.2.2 itohy {
606 1.6.2.2 itohy
607 1.6.2.2 itohy usb_ether_rx_list_free(sc->rx_data, ZYD_RX_LIST_CNT);
608 1.6.2.2 itohy }
609 1.6.2.2 itohy
610 1.6.2.2 itohy /* ARGUSED */
611 1.6.2.2 itohy Static struct ieee80211_node *
612 1.6.2.2 itohy zyd_node_alloc(struct ieee80211_node_table *nt __unused)
613 1.6.2.2 itohy {
614 1.6.2.2 itohy struct zyd_node *zn;
615 1.6.2.2 itohy
616 1.6.2.2 itohy zn = malloc(sizeof (struct zyd_node), M_DEVBUF, M_NOWAIT);
617 1.6.2.2 itohy if (zn != NULL)
618 1.6.2.2 itohy bzero(zn, sizeof (struct zyd_node));
619 1.6.2.2 itohy return (struct ieee80211_node *)zn;
620 1.6.2.2 itohy }
621 1.6.2.2 itohy
622 1.6.2.2 itohy Static int
623 1.6.2.2 itohy zyd_media_change(struct ifnet *ifp)
624 1.6.2.2 itohy {
625 1.6.2.2 itohy int error;
626 1.6.2.2 itohy
627 1.6.2.2 itohy error = ieee80211_media_change(ifp);
628 1.6.2.2 itohy if (error != ENETRESET)
629 1.6.2.2 itohy return error;
630 1.6.2.2 itohy
631 1.6.2.2 itohy if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
632 1.6.2.2 itohy zyd_init(ifp);
633 1.6.2.2 itohy
634 1.6.2.2 itohy return 0;
635 1.6.2.2 itohy }
636 1.6.2.2 itohy
637 1.6.2.2 itohy /*
638 1.6.2.2 itohy * This function is called periodically (every 200ms) during scanning to
639 1.6.2.2 itohy * switch from one channel to another.
640 1.6.2.2 itohy */
641 1.6.2.2 itohy Static void
642 1.6.2.2 itohy zyd_next_scan(void *arg)
643 1.6.2.2 itohy {
644 1.6.2.2 itohy struct zyd_softc *sc = arg;
645 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
646 1.6.2.2 itohy
647 1.6.2.2 itohy if (ic->ic_state == IEEE80211_S_SCAN)
648 1.6.2.2 itohy ieee80211_next_scan(ic);
649 1.6.2.2 itohy }
650 1.6.2.2 itohy
651 1.6.2.2 itohy Static void
652 1.6.2.2 itohy zyd_task(void *arg)
653 1.6.2.2 itohy {
654 1.6.2.2 itohy struct zyd_softc *sc = arg;
655 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
656 1.6.2.2 itohy enum ieee80211_state ostate;
657 1.6.2.2 itohy
658 1.6.2.2 itohy ostate = ic->ic_state;
659 1.6.2.2 itohy
660 1.6.2.2 itohy switch (sc->sc_state) {
661 1.6.2.2 itohy case IEEE80211_S_INIT:
662 1.6.2.2 itohy if (ostate == IEEE80211_S_RUN) {
663 1.6.2.2 itohy /* turn link LED off */
664 1.6.2.2 itohy zyd_set_led(sc, ZYD_LED1, 0);
665 1.6.2.2 itohy
666 1.6.2.2 itohy /* stop data LED from blinking */
667 1.6.2.2 itohy zyd_write32(sc, sc->fwbase + ZYD_FW_LINK_STATUS, 0);
668 1.6.2.2 itohy }
669 1.6.2.2 itohy break;
670 1.6.2.2 itohy
671 1.6.2.2 itohy case IEEE80211_S_SCAN:
672 1.6.2.2 itohy zyd_set_chan(sc, ic->ic_curchan);
673 1.6.2.2 itohy usb_callout(sc->sc_scan_ch, hz / 5, zyd_next_scan, sc);
674 1.6.2.2 itohy break;
675 1.6.2.2 itohy
676 1.6.2.2 itohy case IEEE80211_S_AUTH:
677 1.6.2.2 itohy case IEEE80211_S_ASSOC:
678 1.6.2.2 itohy zyd_set_chan(sc, ic->ic_curchan);
679 1.6.2.2 itohy break;
680 1.6.2.2 itohy
681 1.6.2.2 itohy case IEEE80211_S_RUN:
682 1.6.2.2 itohy {
683 1.6.2.2 itohy struct ieee80211_node *ni = ic->ic_bss;
684 1.6.2.2 itohy
685 1.6.2.2 itohy zyd_set_chan(sc, ic->ic_curchan);
686 1.6.2.2 itohy
687 1.6.2.2 itohy if (ic->ic_opmode != IEEE80211_M_MONITOR) {
688 1.6.2.2 itohy /* turn link LED on */
689 1.6.2.2 itohy zyd_set_led(sc, ZYD_LED1, 1);
690 1.6.2.2 itohy
691 1.6.2.2 itohy /* make data LED blink upon Tx */
692 1.6.2.2 itohy zyd_write32(sc, sc->fwbase + ZYD_FW_LINK_STATUS, 1);
693 1.6.2.2 itohy
694 1.6.2.2 itohy zyd_set_bssid(sc, ni->ni_bssid);
695 1.6.2.2 itohy }
696 1.6.2.2 itohy
697 1.6.2.2 itohy if (ic->ic_opmode == IEEE80211_M_STA) {
698 1.6.2.2 itohy /* fake a join to init the tx rate */
699 1.6.2.2 itohy zyd_newassoc(ni, 1);
700 1.6.2.2 itohy }
701 1.6.2.2 itohy
702 1.6.2.2 itohy /* start automatic rate control timer */
703 1.6.2.2 itohy if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)
704 1.6.2.2 itohy usb_callout(sc->sc_amrr_ch, hz, zyd_amrr_timeout, sc);
705 1.6.2.2 itohy
706 1.6.2.2 itohy break;
707 1.6.2.2 itohy }
708 1.6.2.2 itohy }
709 1.6.2.2 itohy
710 1.6.2.2 itohy sc->sc_newstate(ic, sc->sc_state, -1);
711 1.6.2.2 itohy }
712 1.6.2.2 itohy
713 1.6.2.2 itohy Static int
714 1.6.2.2 itohy zyd_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
715 1.6.2.2 itohy {
716 1.6.2.2 itohy struct zyd_softc *sc = ic->ic_ifp->if_softc;
717 1.6.2.2 itohy
718 1.6.2.2 itohy usb_rem_task(sc->sc_udev, &sc->sc_task);
719 1.6.2.2 itohy usb_uncallout(sc->sc_scan_ch, zyd_next_scan, sc);
720 1.6.2.2 itohy usb_uncallout(sc->sc_amrr_ch, zyd_amrr_timeout, sc);
721 1.6.2.2 itohy
722 1.6.2.2 itohy /* do it in a process context */
723 1.6.2.2 itohy sc->sc_state = nstate;
724 1.6.2.2 itohy usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
725 1.6.2.2 itohy
726 1.6.2.2 itohy return 0;
727 1.6.2.2 itohy }
728 1.6.2.2 itohy
729 1.6.2.2 itohy Static int
730 1.6.2.2 itohy zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen,
731 1.6.2.2 itohy void *odata, int olen, u_int flags)
732 1.6.2.2 itohy {
733 1.6.2.2 itohy usbd_xfer_handle xfer;
734 1.6.2.2 itohy struct zyd_cmd cmd;
735 1.6.2.2 itohy struct rq rq;
736 1.6.2.2 itohy uint16_t xferflags;
737 1.6.2.2 itohy usbd_status error;
738 1.6.2.2 itohy int s = 0;
739 1.6.2.2 itohy
740 1.6.2.2 itohy if ((xfer = usbd_alloc_xfer(sc->sc_udev, sc->zyd_ep[ZYD_ENDPT_IOUT]))
741 1.6.2.2 itohy == NULL)
742 1.6.2.2 itohy return ENOMEM;
743 1.6.2.2 itohy
744 1.6.2.2 itohy cmd.code = htole16(code);
745 1.6.2.2 itohy bcopy(idata, cmd.data, ilen);
746 1.6.2.2 itohy
747 1.6.2.2 itohy xferflags = USBD_FORCE_SHORT_XFER;
748 1.6.2.2 itohy if (!(flags & ZYD_CMD_FLAG_READ))
749 1.6.2.2 itohy xferflags |= USBD_SYNCHRONOUS;
750 1.6.2.2 itohy else {
751 1.6.2.2 itohy s = splusb();
752 1.6.2.2 itohy rq.idata = idata;
753 1.6.2.2 itohy rq.odata = odata;
754 1.6.2.2 itohy rq.len = olen / sizeof (struct zyd_pair);
755 1.6.2.2 itohy SIMPLEQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq);
756 1.6.2.2 itohy }
757 1.6.2.2 itohy
758 1.6.2.2 itohy usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_IOUT], 0, &cmd,
759 1.6.2.2 itohy sizeof (uint16_t) + ilen, xferflags, ZYD_INTR_TIMEOUT, NULL);
760 1.6.2.2 itohy error = usbd_transfer(xfer);
761 1.6.2.2 itohy if (error != USBD_IN_PROGRESS && error != 0) {
762 1.6.2.2 itohy if (flags & ZYD_CMD_FLAG_READ)
763 1.6.2.2 itohy splx(s);
764 1.6.2.2 itohy printf("%s: could not send command (error=%s)\n",
765 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), usbd_errstr(error));
766 1.6.2.2 itohy (void)usbd_free_xfer(xfer);
767 1.6.2.2 itohy return EIO;
768 1.6.2.2 itohy }
769 1.6.2.2 itohy if (!(flags & ZYD_CMD_FLAG_READ)) {
770 1.6.2.2 itohy (void)usbd_free_xfer(xfer);
771 1.6.2.2 itohy return 0; /* write: don't wait for reply */
772 1.6.2.2 itohy }
773 1.6.2.2 itohy /* wait at most one second for command reply */
774 1.6.2.2 itohy error = tsleep(odata, PCATCH, "zydcmd", hz);
775 1.6.2.2 itohy if (error == EWOULDBLOCK)
776 1.6.2.2 itohy printf("%s: zyd_read sleep timeout\n", USBDEVNAME(sc->sc_dev));
777 1.6.2.2 itohy SIMPLEQ_REMOVE(&sc->sc_rqh, &rq, rq, rq);
778 1.6.2.2 itohy splx(s);
779 1.6.2.2 itohy
780 1.6.2.2 itohy (void)usbd_free_xfer(xfer);
781 1.6.2.2 itohy return error;
782 1.6.2.2 itohy }
783 1.6.2.2 itohy
784 1.6.2.2 itohy Static int
785 1.6.2.2 itohy zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val)
786 1.6.2.2 itohy {
787 1.6.2.2 itohy struct zyd_pair tmp;
788 1.6.2.2 itohy int error;
789 1.6.2.2 itohy
790 1.6.2.2 itohy reg = htole16(reg);
791 1.6.2.2 itohy error = zyd_cmd(sc, ZYD_CMD_IORD, ®, sizeof reg, &tmp, sizeof tmp,
792 1.6.2.2 itohy ZYD_CMD_FLAG_READ);
793 1.6.2.2 itohy if (error == 0)
794 1.6.2.2 itohy *val = le16toh(tmp.val);
795 1.6.2.2 itohy return error;
796 1.6.2.2 itohy }
797 1.6.2.2 itohy
798 1.6.2.2 itohy Static int
799 1.6.2.2 itohy zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val)
800 1.6.2.2 itohy {
801 1.6.2.2 itohy struct zyd_pair tmp[2];
802 1.6.2.2 itohy uint16_t regs[2];
803 1.6.2.2 itohy int error;
804 1.6.2.2 itohy
805 1.6.2.2 itohy regs[0] = htole16(ZYD_REG32_HI(reg));
806 1.6.2.2 itohy regs[1] = htole16(ZYD_REG32_LO(reg));
807 1.6.2.2 itohy error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof regs, tmp, sizeof tmp,
808 1.6.2.2 itohy ZYD_CMD_FLAG_READ);
809 1.6.2.2 itohy if (error == 0)
810 1.6.2.2 itohy *val = le16toh(tmp[0].val) << 16 | le16toh(tmp[1].val);
811 1.6.2.2 itohy return error;
812 1.6.2.2 itohy }
813 1.6.2.2 itohy
814 1.6.2.2 itohy Static int
815 1.6.2.2 itohy zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val)
816 1.6.2.2 itohy {
817 1.6.2.2 itohy struct zyd_pair pair;
818 1.6.2.2 itohy
819 1.6.2.2 itohy pair.reg = htole16(reg);
820 1.6.2.2 itohy pair.val = htole16(val);
821 1.6.2.2 itohy
822 1.6.2.2 itohy return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof pair, NULL, 0, 0);
823 1.6.2.2 itohy }
824 1.6.2.2 itohy
825 1.6.2.2 itohy Static int
826 1.6.2.2 itohy zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val)
827 1.6.2.2 itohy {
828 1.6.2.2 itohy struct zyd_pair pair[2];
829 1.6.2.2 itohy
830 1.6.2.2 itohy pair[0].reg = htole16(ZYD_REG32_HI(reg));
831 1.6.2.2 itohy pair[0].val = htole16(val >> 16);
832 1.6.2.2 itohy pair[1].reg = htole16(ZYD_REG32_LO(reg));
833 1.6.2.2 itohy pair[1].val = htole16(val & 0xffff);
834 1.6.2.2 itohy
835 1.6.2.2 itohy return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof pair, NULL, 0, 0);
836 1.6.2.2 itohy }
837 1.6.2.2 itohy
838 1.6.2.2 itohy Static int
839 1.6.2.2 itohy zyd_rfwrite(struct zyd_softc *sc, uint32_t val)
840 1.6.2.2 itohy {
841 1.6.2.2 itohy struct zyd_rf *rf = &sc->sc_rf;
842 1.6.2.2 itohy struct zyd_rfwrite req;
843 1.6.2.2 itohy uint16_t cr203;
844 1.6.2.2 itohy int i;
845 1.6.2.2 itohy
846 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_CR203, &cr203);
847 1.6.2.2 itohy cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA);
848 1.6.2.2 itohy
849 1.6.2.2 itohy req.code = htole16(2);
850 1.6.2.2 itohy req.width = htole16(rf->width);
851 1.6.2.2 itohy for (i = 0; i < rf->width; i++) {
852 1.6.2.2 itohy req.bit[i] = htole16(cr203);
853 1.6.2.2 itohy if (val & (1 << (rf->width - 1 - i)))
854 1.6.2.2 itohy req.bit[i] |= htole16(ZYD_RF_DATA);
855 1.6.2.2 itohy }
856 1.6.2.2 itohy return zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0);
857 1.6.2.2 itohy }
858 1.6.2.2 itohy
859 1.6.2.2 itohy Static void
860 1.6.2.2 itohy zyd_lock_phy(struct zyd_softc *sc)
861 1.6.2.2 itohy {
862 1.6.2.2 itohy uint32_t tmp;
863 1.6.2.2 itohy
864 1.6.2.2 itohy (void)zyd_read32(sc, ZYD_MAC_MISC, &tmp);
865 1.6.2.2 itohy tmp &= ~ZYD_UNLOCK_PHY_REGS;
866 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_MISC, tmp);
867 1.6.2.2 itohy }
868 1.6.2.2 itohy
869 1.6.2.2 itohy Static void
870 1.6.2.2 itohy zyd_unlock_phy(struct zyd_softc *sc)
871 1.6.2.2 itohy {
872 1.6.2.2 itohy uint32_t tmp;
873 1.6.2.2 itohy
874 1.6.2.2 itohy (void)zyd_read32(sc, ZYD_MAC_MISC, &tmp);
875 1.6.2.2 itohy tmp |= ZYD_UNLOCK_PHY_REGS;
876 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_MISC, tmp);
877 1.6.2.2 itohy }
878 1.6.2.2 itohy
879 1.6.2.2 itohy /*
880 1.6.2.2 itohy * RFMD RF methods.
881 1.6.2.2 itohy */
882 1.6.2.2 itohy Static int
883 1.6.2.2 itohy zyd_rfmd_init(struct zyd_rf *rf)
884 1.6.2.2 itohy {
885 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
886 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
887 1.6.2.2 itohy static const struct zyd_phy_pair phyini[] = ZYD_RFMD_PHY;
888 1.6.2.2 itohy static const uint32_t rfini[] = ZYD_RFMD_RF;
889 1.6.2.2 itohy int i, error;
890 1.6.2.2 itohy
891 1.6.2.2 itohy /* init RF-dependent PHY registers */
892 1.6.2.2 itohy for (i = 0; i < N(phyini); i++) {
893 1.6.2.2 itohy error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
894 1.6.2.2 itohy if (error != 0)
895 1.6.2.2 itohy return error;
896 1.6.2.2 itohy }
897 1.6.2.2 itohy
898 1.6.2.2 itohy /* init RFMD radio */
899 1.6.2.2 itohy for (i = 0; i < N(rfini); i++) {
900 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
901 1.6.2.2 itohy return error;
902 1.6.2.2 itohy }
903 1.6.2.2 itohy return 0;
904 1.6.2.2 itohy #undef N
905 1.6.2.2 itohy }
906 1.6.2.2 itohy
907 1.6.2.2 itohy Static int
908 1.6.2.2 itohy zyd_rfmd_switch_radio(struct zyd_rf *rf, int on)
909 1.6.2.2 itohy {
910 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
911 1.6.2.2 itohy
912 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR10, on ? 0x89 : 0x15);
913 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR11, on ? 0x00 : 0x81);
914 1.6.2.2 itohy
915 1.6.2.2 itohy return 0;
916 1.6.2.2 itohy }
917 1.6.2.2 itohy
918 1.6.2.2 itohy Static int
919 1.6.2.2 itohy zyd_rfmd_set_channel(struct zyd_rf *rf, uint8_t chan)
920 1.6.2.2 itohy {
921 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
922 1.6.2.2 itohy static const struct {
923 1.6.2.2 itohy uint32_t r1, r2;
924 1.6.2.2 itohy } rfprog[] = ZYD_RFMD_CHANTABLE;
925 1.6.2.2 itohy
926 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
927 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
928 1.6.2.2 itohy
929 1.6.2.2 itohy return 0;
930 1.6.2.2 itohy }
931 1.6.2.2 itohy
932 1.6.2.2 itohy /*
933 1.6.2.2 itohy * AL2230 RF methods.
934 1.6.2.2 itohy */
935 1.6.2.2 itohy Static int
936 1.6.2.2 itohy zyd_al2230_init(struct zyd_rf *rf)
937 1.6.2.2 itohy {
938 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
939 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
940 1.6.2.2 itohy static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY;
941 1.6.2.2 itohy static const uint32_t rfini[] = ZYD_AL2230_RF;
942 1.6.2.2 itohy int i, error;
943 1.6.2.2 itohy
944 1.6.2.2 itohy /* init RF-dependent PHY registers */
945 1.6.2.2 itohy for (i = 0; i < N(phyini); i++) {
946 1.6.2.2 itohy error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
947 1.6.2.2 itohy if (error != 0)
948 1.6.2.2 itohy return error;
949 1.6.2.2 itohy }
950 1.6.2.2 itohy
951 1.6.2.2 itohy /* init AL2230 radio */
952 1.6.2.2 itohy for (i = 0; i < N(rfini); i++) {
953 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
954 1.6.2.2 itohy return error;
955 1.6.2.2 itohy }
956 1.6.2.2 itohy return 0;
957 1.6.2.2 itohy #undef N
958 1.6.2.2 itohy }
959 1.6.2.2 itohy
960 1.6.2.2 itohy Static int
961 1.6.2.2 itohy zyd_al2230_init_b(struct zyd_rf *rf)
962 1.6.2.2 itohy {
963 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
964 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
965 1.6.2.2 itohy static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B;
966 1.6.2.2 itohy static const uint32_t rfini[] = ZYD_AL2230_RF_B;
967 1.6.2.2 itohy int i, error;
968 1.6.2.2 itohy
969 1.6.2.2 itohy /* init RF-dependent PHY registers */
970 1.6.2.2 itohy for (i = 0; i < N(phyini); i++) {
971 1.6.2.2 itohy error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
972 1.6.2.2 itohy if (error != 0)
973 1.6.2.2 itohy return error;
974 1.6.2.2 itohy }
975 1.6.2.2 itohy
976 1.6.2.2 itohy /* init AL2230 radio */
977 1.6.2.2 itohy for (i = 0; i < N(rfini); i++) {
978 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
979 1.6.2.2 itohy return error;
980 1.6.2.2 itohy }
981 1.6.2.2 itohy return 0;
982 1.6.2.2 itohy #undef N
983 1.6.2.2 itohy }
984 1.6.2.2 itohy
985 1.6.2.2 itohy Static int
986 1.6.2.2 itohy zyd_al2230_switch_radio(struct zyd_rf *rf, int on)
987 1.6.2.2 itohy {
988 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
989 1.6.2.2 itohy int on251 = (sc->mac_rev == ZYD_ZD1211) ? 0x3f : 0x7f;
990 1.6.2.2 itohy
991 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR11, on ? 0x00 : 0x04);
992 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR251, on ? on251 : 0x2f);
993 1.6.2.2 itohy
994 1.6.2.2 itohy return 0;
995 1.6.2.2 itohy }
996 1.6.2.2 itohy
997 1.6.2.2 itohy Static int
998 1.6.2.2 itohy zyd_al2230_set_channel(struct zyd_rf *rf, uint8_t chan)
999 1.6.2.2 itohy {
1000 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1001 1.6.2.2 itohy static const struct {
1002 1.6.2.2 itohy uint32_t r1, r2, r3;
1003 1.6.2.2 itohy } rfprog[] = ZYD_AL2230_CHANTABLE;
1004 1.6.2.2 itohy
1005 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
1006 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
1007 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r3);
1008 1.6.2.2 itohy
1009 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR138, 0x28);
1010 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, 0x06);
1011 1.6.2.2 itohy
1012 1.6.2.2 itohy return 0;
1013 1.6.2.2 itohy }
1014 1.6.2.2 itohy
1015 1.6.2.2 itohy /*
1016 1.6.2.2 itohy * AL7230B RF methods.
1017 1.6.2.2 itohy */
1018 1.6.2.2 itohy Static int
1019 1.6.2.2 itohy zyd_al7230B_init(struct zyd_rf *rf)
1020 1.6.2.2 itohy {
1021 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
1022 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1023 1.6.2.2 itohy static const struct zyd_phy_pair phyini_1[] = ZYD_AL7230B_PHY_1;
1024 1.6.2.2 itohy static const struct zyd_phy_pair phyini_2[] = ZYD_AL7230B_PHY_2;
1025 1.6.2.2 itohy static const struct zyd_phy_pair phyini_3[] = ZYD_AL7230B_PHY_3;
1026 1.6.2.2 itohy static const uint32_t rfini_1[] = ZYD_AL7230B_RF_1;
1027 1.6.2.2 itohy static const uint32_t rfini_2[] = ZYD_AL7230B_RF_2;
1028 1.6.2.2 itohy int i, error;
1029 1.6.2.2 itohy
1030 1.6.2.2 itohy /* for AL7230B, PHY and RF need to be initialized in "phases" */
1031 1.6.2.2 itohy
1032 1.6.2.2 itohy /* init RF-dependent PHY registers, part one */
1033 1.6.2.2 itohy for (i = 0; i < N(phyini_1); i++) {
1034 1.6.2.2 itohy error = zyd_write16(sc, phyini_1[i].reg, phyini_1[i].val);
1035 1.6.2.2 itohy if (error != 0)
1036 1.6.2.2 itohy return error;
1037 1.6.2.2 itohy }
1038 1.6.2.2 itohy /* init AL7230B radio, part one */
1039 1.6.2.2 itohy for (i = 0; i < N(rfini_1); i++) {
1040 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini_1[i])) != 0)
1041 1.6.2.2 itohy return error;
1042 1.6.2.2 itohy }
1043 1.6.2.2 itohy /* init RF-dependent PHY registers, part two */
1044 1.6.2.2 itohy for (i = 0; i < N(phyini_2); i++) {
1045 1.6.2.2 itohy error = zyd_write16(sc, phyini_2[i].reg, phyini_2[i].val);
1046 1.6.2.2 itohy if (error != 0)
1047 1.6.2.2 itohy return error;
1048 1.6.2.2 itohy }
1049 1.6.2.2 itohy /* init AL7230B radio, part two */
1050 1.6.2.2 itohy for (i = 0; i < N(rfini_2); i++) {
1051 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini_2[i])) != 0)
1052 1.6.2.2 itohy return error;
1053 1.6.2.2 itohy }
1054 1.6.2.2 itohy /* init RF-dependent PHY registers, part three */
1055 1.6.2.2 itohy for (i = 0; i < N(phyini_3); i++) {
1056 1.6.2.2 itohy error = zyd_write16(sc, phyini_3[i].reg, phyini_3[i].val);
1057 1.6.2.2 itohy if (error != 0)
1058 1.6.2.2 itohy return error;
1059 1.6.2.2 itohy }
1060 1.6.2.2 itohy
1061 1.6.2.2 itohy return 0;
1062 1.6.2.2 itohy #undef N
1063 1.6.2.2 itohy }
1064 1.6.2.2 itohy
1065 1.6.2.2 itohy Static int
1066 1.6.2.2 itohy zyd_al7230B_switch_radio(struct zyd_rf *rf, int on)
1067 1.6.2.2 itohy {
1068 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1069 1.6.2.2 itohy
1070 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR11, on ? 0x00 : 0x04);
1071 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR251, on ? 0x3f : 0x2f);
1072 1.6.2.2 itohy
1073 1.6.2.2 itohy return 0;
1074 1.6.2.2 itohy }
1075 1.6.2.2 itohy
1076 1.6.2.2 itohy Static int
1077 1.6.2.2 itohy zyd_al7230B_set_channel(struct zyd_rf *rf, uint8_t chan)
1078 1.6.2.2 itohy {
1079 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
1080 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1081 1.6.2.2 itohy static const struct {
1082 1.6.2.2 itohy uint32_t r1, r2;
1083 1.6.2.2 itohy } rfprog[] = ZYD_AL7230B_CHANTABLE;
1084 1.6.2.2 itohy static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL;
1085 1.6.2.2 itohy int i, error;
1086 1.6.2.2 itohy
1087 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR240, 0x57);
1088 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR251, 0x2f);
1089 1.6.2.2 itohy
1090 1.6.2.2 itohy for (i = 0; i < N(rfsc); i++) {
1091 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfsc[i])) != 0)
1092 1.6.2.2 itohy return error;
1093 1.6.2.2 itohy }
1094 1.6.2.2 itohy
1095 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR128, 0x14);
1096 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR129, 0x12);
1097 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR130, 0x10);
1098 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR38, 0x38);
1099 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR136, 0xdf);
1100 1.6.2.2 itohy
1101 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
1102 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
1103 1.6.2.2 itohy (void)zyd_rfwrite(sc, 0x3c9000);
1104 1.6.2.2 itohy
1105 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR251, 0x3f);
1106 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, 0x06);
1107 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR240, 0x08);
1108 1.6.2.2 itohy
1109 1.6.2.2 itohy return 0;
1110 1.6.2.2 itohy #undef N
1111 1.6.2.2 itohy }
1112 1.6.2.2 itohy
1113 1.6.2.2 itohy /*
1114 1.6.2.2 itohy * AL2210 RF methods.
1115 1.6.2.2 itohy */
1116 1.6.2.2 itohy Static int
1117 1.6.2.2 itohy zyd_al2210_init(struct zyd_rf *rf)
1118 1.6.2.2 itohy {
1119 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
1120 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1121 1.6.2.2 itohy static const struct zyd_phy_pair phyini[] = ZYD_AL2210_PHY;
1122 1.6.2.2 itohy static const uint32_t rfini[] = ZYD_AL2210_RF;
1123 1.6.2.2 itohy uint32_t tmp;
1124 1.6.2.2 itohy int i, error;
1125 1.6.2.2 itohy
1126 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR18, 2);
1127 1.6.2.2 itohy
1128 1.6.2.2 itohy /* init RF-dependent PHY registers */
1129 1.6.2.2 itohy for (i = 0; i < N(phyini); i++) {
1130 1.6.2.2 itohy error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1131 1.6.2.2 itohy if (error != 0)
1132 1.6.2.2 itohy return error;
1133 1.6.2.2 itohy }
1134 1.6.2.2 itohy /* init AL2210 radio */
1135 1.6.2.2 itohy for (i = 0; i < N(rfini); i++) {
1136 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1137 1.6.2.2 itohy return error;
1138 1.6.2.2 itohy }
1139 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR47, 0x1e);
1140 1.6.2.2 itohy (void)zyd_read32(sc, ZYD_CR_RADIO_PD, &tmp);
1141 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1);
1142 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp | 1);
1143 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x05);
1144 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x00);
1145 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR47, 0x1e);
1146 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR18, 3);
1147 1.6.2.2 itohy
1148 1.6.2.2 itohy return 0;
1149 1.6.2.2 itohy #undef N
1150 1.6.2.2 itohy }
1151 1.6.2.2 itohy
1152 1.6.2.2 itohy Static int
1153 1.6.2.2 itohy zyd_al2210_switch_radio(struct zyd_rf *rf, int on)
1154 1.6.2.2 itohy {
1155 1.6.2.2 itohy /* vendor driver does nothing for this RF chip */
1156 1.6.2.2 itohy
1157 1.6.2.2 itohy return 0;
1158 1.6.2.2 itohy }
1159 1.6.2.2 itohy
1160 1.6.2.2 itohy Static int
1161 1.6.2.2 itohy zyd_al2210_set_channel(struct zyd_rf *rf, uint8_t chan)
1162 1.6.2.2 itohy {
1163 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1164 1.6.2.2 itohy static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE;
1165 1.6.2.2 itohy uint32_t tmp;
1166 1.6.2.2 itohy
1167 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR18, 2);
1168 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR47, 0x1e);
1169 1.6.2.2 itohy (void)zyd_read32(sc, ZYD_CR_RADIO_PD, &tmp);
1170 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1);
1171 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp | 1);
1172 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x05);
1173 1.6.2.2 itohy
1174 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_RFCFG, 0x00);
1175 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR47, 0x1e);
1176 1.6.2.2 itohy
1177 1.6.2.2 itohy /* actually set the channel */
1178 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1]);
1179 1.6.2.2 itohy
1180 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR18, 3);
1181 1.6.2.2 itohy
1182 1.6.2.2 itohy return 0;
1183 1.6.2.2 itohy }
1184 1.6.2.2 itohy
1185 1.6.2.2 itohy /*
1186 1.6.2.2 itohy * GCT RF methods.
1187 1.6.2.2 itohy */
1188 1.6.2.2 itohy Static int
1189 1.6.2.2 itohy zyd_gct_init(struct zyd_rf *rf)
1190 1.6.2.2 itohy {
1191 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
1192 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1193 1.6.2.2 itohy static const struct zyd_phy_pair phyini[] = ZYD_GCT_PHY;
1194 1.6.2.2 itohy static const uint32_t rfini[] = ZYD_GCT_RF;
1195 1.6.2.2 itohy int i, error;
1196 1.6.2.2 itohy
1197 1.6.2.2 itohy /* init RF-dependent PHY registers */
1198 1.6.2.2 itohy for (i = 0; i < N(phyini); i++) {
1199 1.6.2.2 itohy error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1200 1.6.2.2 itohy if (error != 0)
1201 1.6.2.2 itohy return error;
1202 1.6.2.2 itohy }
1203 1.6.2.2 itohy /* init cgt radio */
1204 1.6.2.2 itohy for (i = 0; i < N(rfini); i++) {
1205 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1206 1.6.2.2 itohy return error;
1207 1.6.2.2 itohy }
1208 1.6.2.2 itohy return 0;
1209 1.6.2.2 itohy #undef N
1210 1.6.2.2 itohy }
1211 1.6.2.2 itohy
1212 1.6.2.2 itohy Static int
1213 1.6.2.2 itohy zyd_gct_switch_radio(struct zyd_rf *rf, int on)
1214 1.6.2.2 itohy {
1215 1.6.2.2 itohy /* vendor driver does nothing for this RF chip */
1216 1.6.2.2 itohy
1217 1.6.2.2 itohy return 0;
1218 1.6.2.2 itohy }
1219 1.6.2.2 itohy
1220 1.6.2.2 itohy Static int
1221 1.6.2.2 itohy zyd_gct_set_channel(struct zyd_rf *rf, uint8_t chan)
1222 1.6.2.2 itohy {
1223 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1224 1.6.2.2 itohy static const uint32_t rfprog[] = ZYD_GCT_CHANTABLE;
1225 1.6.2.2 itohy
1226 1.6.2.2 itohy (void)zyd_rfwrite(sc, 0x1c0000);
1227 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1]);
1228 1.6.2.2 itohy (void)zyd_rfwrite(sc, 0x1c0008);
1229 1.6.2.2 itohy
1230 1.6.2.2 itohy return 0;
1231 1.6.2.2 itohy }
1232 1.6.2.2 itohy
1233 1.6.2.2 itohy /*
1234 1.6.2.2 itohy * Maxim RF methods.
1235 1.6.2.2 itohy */
1236 1.6.2.2 itohy Static int
1237 1.6.2.2 itohy zyd_maxim_init(struct zyd_rf *rf)
1238 1.6.2.2 itohy {
1239 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
1240 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1241 1.6.2.2 itohy static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
1242 1.6.2.2 itohy static const uint32_t rfini[] = ZYD_MAXIM_RF;
1243 1.6.2.2 itohy uint16_t tmp;
1244 1.6.2.2 itohy int i, error;
1245 1.6.2.2 itohy
1246 1.6.2.2 itohy /* init RF-dependent PHY registers */
1247 1.6.2.2 itohy for (i = 0; i < N(phyini); i++) {
1248 1.6.2.2 itohy error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1249 1.6.2.2 itohy if (error != 0)
1250 1.6.2.2 itohy return error;
1251 1.6.2.2 itohy }
1252 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_CR203, &tmp);
1253 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
1254 1.6.2.2 itohy
1255 1.6.2.2 itohy /* init maxim radio */
1256 1.6.2.2 itohy for (i = 0; i < N(rfini); i++) {
1257 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1258 1.6.2.2 itohy return error;
1259 1.6.2.2 itohy }
1260 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_CR203, &tmp);
1261 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
1262 1.6.2.2 itohy
1263 1.6.2.2 itohy return 0;
1264 1.6.2.2 itohy #undef N
1265 1.6.2.2 itohy }
1266 1.6.2.2 itohy
1267 1.6.2.2 itohy Static int
1268 1.6.2.2 itohy zyd_maxim_switch_radio(struct zyd_rf *rf, int on)
1269 1.6.2.2 itohy {
1270 1.6.2.2 itohy /* vendor driver does nothing for this RF chip */
1271 1.6.2.2 itohy
1272 1.6.2.2 itohy return 0;
1273 1.6.2.2 itohy }
1274 1.6.2.2 itohy
1275 1.6.2.2 itohy Static int
1276 1.6.2.2 itohy zyd_maxim_set_channel(struct zyd_rf *rf, uint8_t chan)
1277 1.6.2.2 itohy {
1278 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
1279 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1280 1.6.2.2 itohy static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
1281 1.6.2.2 itohy static const uint32_t rfini[] = ZYD_MAXIM_RF;
1282 1.6.2.2 itohy static const struct {
1283 1.6.2.2 itohy uint32_t r1, r2;
1284 1.6.2.2 itohy } rfprog[] = ZYD_MAXIM_CHANTABLE;
1285 1.6.2.2 itohy uint16_t tmp;
1286 1.6.2.2 itohy int i, error;
1287 1.6.2.2 itohy
1288 1.6.2.2 itohy /*
1289 1.6.2.2 itohy * Do the same as we do when initializing it, except for the channel
1290 1.6.2.2 itohy * values coming from the two channel tables.
1291 1.6.2.2 itohy */
1292 1.6.2.2 itohy
1293 1.6.2.2 itohy /* init RF-dependent PHY registers */
1294 1.6.2.2 itohy for (i = 0; i < N(phyini); i++) {
1295 1.6.2.2 itohy error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1296 1.6.2.2 itohy if (error != 0)
1297 1.6.2.2 itohy return error;
1298 1.6.2.2 itohy }
1299 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_CR203, &tmp);
1300 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
1301 1.6.2.2 itohy
1302 1.6.2.2 itohy /* first two values taken from the chantables */
1303 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
1304 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
1305 1.6.2.2 itohy
1306 1.6.2.2 itohy /* init maxim radio - skipping the two first values */
1307 1.6.2.2 itohy for (i = 2; i < N(rfini); i++) {
1308 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1309 1.6.2.2 itohy return error;
1310 1.6.2.2 itohy }
1311 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_CR203, &tmp);
1312 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
1313 1.6.2.2 itohy
1314 1.6.2.2 itohy return 0;
1315 1.6.2.2 itohy #undef N
1316 1.6.2.2 itohy }
1317 1.6.2.2 itohy
1318 1.6.2.2 itohy /*
1319 1.6.2.2 itohy * Maxim2 RF methods.
1320 1.6.2.2 itohy */
1321 1.6.2.2 itohy Static int
1322 1.6.2.2 itohy zyd_maxim2_init(struct zyd_rf *rf)
1323 1.6.2.2 itohy {
1324 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
1325 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1326 1.6.2.2 itohy static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
1327 1.6.2.2 itohy static const uint32_t rfini[] = ZYD_MAXIM2_RF;
1328 1.6.2.2 itohy uint16_t tmp;
1329 1.6.2.2 itohy int i, error;
1330 1.6.2.2 itohy
1331 1.6.2.2 itohy /* init RF-dependent PHY registers */
1332 1.6.2.2 itohy for (i = 0; i < N(phyini); i++) {
1333 1.6.2.2 itohy error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1334 1.6.2.2 itohy if (error != 0)
1335 1.6.2.2 itohy return error;
1336 1.6.2.2 itohy }
1337 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_CR203, &tmp);
1338 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
1339 1.6.2.2 itohy
1340 1.6.2.2 itohy /* init maxim2 radio */
1341 1.6.2.2 itohy for (i = 0; i < N(rfini); i++) {
1342 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1343 1.6.2.2 itohy return error;
1344 1.6.2.2 itohy }
1345 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_CR203, &tmp);
1346 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
1347 1.6.2.2 itohy
1348 1.6.2.2 itohy return 0;
1349 1.6.2.2 itohy #undef N
1350 1.6.2.2 itohy }
1351 1.6.2.2 itohy
1352 1.6.2.2 itohy Static int
1353 1.6.2.2 itohy zyd_maxim2_switch_radio(struct zyd_rf *rf, int on)
1354 1.6.2.2 itohy {
1355 1.6.2.2 itohy /* vendor driver does nothing for this RF chip */
1356 1.6.2.2 itohy
1357 1.6.2.2 itohy return 0;
1358 1.6.2.2 itohy }
1359 1.6.2.2 itohy
1360 1.6.2.2 itohy Static int
1361 1.6.2.2 itohy zyd_maxim2_set_channel(struct zyd_rf *rf, uint8_t chan)
1362 1.6.2.2 itohy {
1363 1.6.2.2 itohy #define N(a) (sizeof (a) / sizeof ((a)[0]))
1364 1.6.2.2 itohy struct zyd_softc *sc = rf->rf_sc;
1365 1.6.2.2 itohy static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
1366 1.6.2.2 itohy static const uint32_t rfini[] = ZYD_MAXIM2_RF;
1367 1.6.2.2 itohy static const struct {
1368 1.6.2.2 itohy uint32_t r1, r2;
1369 1.6.2.2 itohy } rfprog[] = ZYD_MAXIM2_CHANTABLE;
1370 1.6.2.2 itohy uint16_t tmp;
1371 1.6.2.2 itohy int i, error;
1372 1.6.2.2 itohy
1373 1.6.2.2 itohy /*
1374 1.6.2.2 itohy * Do the same as we do when initializing it, except for the channel
1375 1.6.2.2 itohy * values coming from the two channel tables.
1376 1.6.2.2 itohy */
1377 1.6.2.2 itohy
1378 1.6.2.2 itohy /* init RF-dependent PHY registers */
1379 1.6.2.2 itohy for (i = 0; i < N(phyini); i++) {
1380 1.6.2.2 itohy error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1381 1.6.2.2 itohy if (error != 0)
1382 1.6.2.2 itohy return error;
1383 1.6.2.2 itohy }
1384 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_CR203, &tmp);
1385 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
1386 1.6.2.2 itohy
1387 1.6.2.2 itohy /* first two values taken from the chantables */
1388 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
1389 1.6.2.2 itohy (void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
1390 1.6.2.2 itohy
1391 1.6.2.2 itohy /* init maxim2 radio - skipping the two first values */
1392 1.6.2.2 itohy for (i = 2; i < N(rfini); i++) {
1393 1.6.2.2 itohy if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1394 1.6.2.2 itohy return error;
1395 1.6.2.2 itohy }
1396 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_CR203, &tmp);
1397 1.6.2.2 itohy (void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
1398 1.6.2.2 itohy
1399 1.6.2.2 itohy return 0;
1400 1.6.2.2 itohy #undef N
1401 1.6.2.2 itohy }
1402 1.6.2.2 itohy
1403 1.6.2.2 itohy Static int
1404 1.6.2.2 itohy zyd_rf_attach(struct zyd_softc *sc, uint8_t type)
1405 1.6.2.2 itohy {
1406 1.6.2.2 itohy struct zyd_rf *rf = &sc->sc_rf;
1407 1.6.2.2 itohy
1408 1.6.2.2 itohy rf->rf_sc = sc;
1409 1.6.2.2 itohy
1410 1.6.2.2 itohy switch (type) {
1411 1.6.2.2 itohy case ZYD_RF_RFMD:
1412 1.6.2.2 itohy rf->init = zyd_rfmd_init;
1413 1.6.2.2 itohy rf->switch_radio = zyd_rfmd_switch_radio;
1414 1.6.2.2 itohy rf->set_channel = zyd_rfmd_set_channel;
1415 1.6.2.2 itohy rf->width = 24; /* 24-bit RF values */
1416 1.6.2.2 itohy break;
1417 1.6.2.2 itohy case ZYD_RF_AL2230:
1418 1.6.2.2 itohy if (sc->mac_rev == ZYD_ZD1211B)
1419 1.6.2.2 itohy rf->init = zyd_al2230_init_b;
1420 1.6.2.2 itohy else
1421 1.6.2.2 itohy rf->init = zyd_al2230_init;
1422 1.6.2.2 itohy rf->switch_radio = zyd_al2230_switch_radio;
1423 1.6.2.2 itohy rf->set_channel = zyd_al2230_set_channel;
1424 1.6.2.2 itohy rf->width = 24; /* 24-bit RF values */
1425 1.6.2.2 itohy break;
1426 1.6.2.2 itohy case ZYD_RF_AL7230B:
1427 1.6.2.2 itohy rf->init = zyd_al7230B_init;
1428 1.6.2.2 itohy rf->switch_radio = zyd_al7230B_switch_radio;
1429 1.6.2.2 itohy rf->set_channel = zyd_al7230B_set_channel;
1430 1.6.2.2 itohy rf->width = 24; /* 24-bit RF values */
1431 1.6.2.2 itohy break;
1432 1.6.2.2 itohy case ZYD_RF_AL2210:
1433 1.6.2.2 itohy rf->init = zyd_al2210_init;
1434 1.6.2.2 itohy rf->switch_radio = zyd_al2210_switch_radio;
1435 1.6.2.2 itohy rf->set_channel = zyd_al2210_set_channel;
1436 1.6.2.2 itohy rf->width = 24; /* 24-bit RF values */
1437 1.6.2.2 itohy break;
1438 1.6.2.2 itohy case ZYD_RF_GCT:
1439 1.6.2.2 itohy rf->init = zyd_gct_init;
1440 1.6.2.2 itohy rf->switch_radio = zyd_gct_switch_radio;
1441 1.6.2.2 itohy rf->set_channel = zyd_gct_set_channel;
1442 1.6.2.2 itohy rf->width = 21; /* 21-bit RF values */
1443 1.6.2.2 itohy break;
1444 1.6.2.2 itohy case ZYD_RF_MAXIM_NEW:
1445 1.6.2.2 itohy rf->init = zyd_maxim_init;
1446 1.6.2.2 itohy rf->switch_radio = zyd_maxim_switch_radio;
1447 1.6.2.2 itohy rf->set_channel = zyd_maxim_set_channel;
1448 1.6.2.2 itohy rf->width = 18; /* 18-bit RF values */
1449 1.6.2.2 itohy break;
1450 1.6.2.2 itohy case ZYD_RF_MAXIM_NEW2:
1451 1.6.2.2 itohy rf->init = zyd_maxim2_init;
1452 1.6.2.2 itohy rf->switch_radio = zyd_maxim2_switch_radio;
1453 1.6.2.2 itohy rf->set_channel = zyd_maxim2_set_channel;
1454 1.6.2.2 itohy rf->width = 18; /* 18-bit RF values */
1455 1.6.2.2 itohy break;
1456 1.6.2.2 itohy default:
1457 1.6.2.2 itohy printf("%s: sorry, radio \"%s\" is not supported yet\n",
1458 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), zyd_rf_name(type));
1459 1.6.2.2 itohy return EINVAL;
1460 1.6.2.2 itohy }
1461 1.6.2.2 itohy return 0;
1462 1.6.2.2 itohy }
1463 1.6.2.2 itohy
1464 1.6.2.2 itohy Static const char *
1465 1.6.2.2 itohy zyd_rf_name(uint8_t type)
1466 1.6.2.2 itohy {
1467 1.6.2.2 itohy static const char * const zyd_rfs[] = {
1468 1.6.2.2 itohy "unknown", "unknown", "UW2451", "UCHIP", "AL2230",
1469 1.6.2.2 itohy "AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT",
1470 1.6.2.2 itohy "PV2000", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2",
1471 1.6.2.2 itohy "PHILIPS"
1472 1.6.2.2 itohy };
1473 1.6.2.2 itohy
1474 1.6.2.2 itohy return zyd_rfs[(type > 15) ? 0 : type];
1475 1.6.2.2 itohy }
1476 1.6.2.2 itohy
1477 1.6.2.2 itohy Static int
1478 1.6.2.2 itohy zyd_hw_init(struct zyd_softc *sc)
1479 1.6.2.2 itohy {
1480 1.6.2.2 itohy struct zyd_rf *rf = &sc->sc_rf;
1481 1.6.2.2 itohy const struct zyd_phy_pair *phyp;
1482 1.6.2.2 itohy int error;
1483 1.6.2.2 itohy
1484 1.6.2.2 itohy /* specify that the plug and play is finished */
1485 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_AFTER_PNP, 1);
1486 1.6.2.2 itohy
1487 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->fwbase);
1488 1.6.2.2 itohy DPRINTF(("firmware base address=0x%04x\n", sc->fwbase));
1489 1.6.2.2 itohy
1490 1.6.2.2 itohy /* retrieve firmware revision number */
1491 1.6.2.2 itohy (void)zyd_read16(sc, sc->fwbase + ZYD_FW_FIRMWARE_REV, &sc->fw_rev);
1492 1.6.2.2 itohy
1493 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_GPI_EN, 0);
1494 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f);
1495 1.6.2.2 itohy
1496 1.6.2.2 itohy /* disable interrupts */
1497 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_INTERRUPT, 0);
1498 1.6.2.2 itohy
1499 1.6.2.2 itohy /* PHY init */
1500 1.6.2.2 itohy zyd_lock_phy(sc);
1501 1.6.2.2 itohy phyp = (sc->mac_rev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy;
1502 1.6.2.2 itohy for (; phyp->reg != 0; phyp++) {
1503 1.6.2.2 itohy if ((error = zyd_write16(sc, phyp->reg, phyp->val)) != 0)
1504 1.6.2.2 itohy goto fail;
1505 1.6.2.2 itohy }
1506 1.6.2.2 itohy zyd_unlock_phy(sc);
1507 1.6.2.2 itohy
1508 1.6.2.2 itohy /* HMAC init */
1509 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000020);
1510 1.6.2.2 itohy zyd_write32(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808);
1511 1.6.2.2 itohy
1512 1.6.2.2 itohy if (sc->mac_rev == ZYD_ZD1211) {
1513 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_RETRY, 0x00000002);
1514 1.6.2.2 itohy } else {
1515 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_RETRY, 0x02020202);
1516 1.6.2.2 itohy zyd_write32(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f);
1517 1.6.2.2 itohy zyd_write32(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f);
1518 1.6.2.2 itohy zyd_write32(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f);
1519 1.6.2.2 itohy zyd_write32(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f);
1520 1.6.2.2 itohy zyd_write32(sc, ZYD_MACB_AIFS_CTL1, 0x00280028);
1521 1.6.2.2 itohy zyd_write32(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C);
1522 1.6.2.2 itohy zyd_write32(sc, ZYD_MACB_TXOP, 0x01800824);
1523 1.6.2.2 itohy }
1524 1.6.2.2 itohy
1525 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_SNIFFER, 0x00000000);
1526 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_RXFILTER, 0x00000000);
1527 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_GHTBL, 0x00000000);
1528 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_GHTBH, 0x80000000);
1529 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_MISC, 0x000000a4);
1530 1.6.2.2 itohy zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f);
1531 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_BCNCFG, 0x00f00401);
1532 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_PHY_DELAY2, 0x00000000);
1533 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000080);
1534 1.6.2.2 itohy zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000);
1535 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100);
1536 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0547c032);
1537 1.6.2.2 itohy zyd_write32(sc, ZYD_CR_RX_PE_DELAY, 0x00000070);
1538 1.6.2.2 itohy zyd_write32(sc, ZYD_CR_PS_CTRL, 0x10000000);
1539 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_RTSCTSRATE, 0x02030203);
1540 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
1541 1.6.2.2 itohy zyd_write32(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114);
1542 1.6.2.2 itohy
1543 1.6.2.2 itohy /* RF chip init */
1544 1.6.2.2 itohy zyd_lock_phy(sc);
1545 1.6.2.2 itohy error = (*rf->init)(rf);
1546 1.6.2.2 itohy zyd_unlock_phy(sc);
1547 1.6.2.2 itohy if (error != 0) {
1548 1.6.2.2 itohy printf("%s: radio initialization failed\n",
1549 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
1550 1.6.2.2 itohy goto fail;
1551 1.6.2.2 itohy }
1552 1.6.2.2 itohy
1553 1.6.2.2 itohy /* init beacon interval to 100ms */
1554 1.6.2.2 itohy if ((error = zyd_set_beacon_interval(sc, 100)) != 0)
1555 1.6.2.2 itohy goto fail;
1556 1.6.2.2 itohy
1557 1.6.2.2 itohy fail: return error;
1558 1.6.2.2 itohy }
1559 1.6.2.2 itohy
1560 1.6.2.2 itohy Static int
1561 1.6.2.2 itohy zyd_read_eeprom(struct zyd_softc *sc)
1562 1.6.2.2 itohy {
1563 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
1564 1.6.2.2 itohy uint32_t tmp;
1565 1.6.2.2 itohy uint16_t val;
1566 1.6.2.2 itohy int i;
1567 1.6.2.2 itohy
1568 1.6.2.2 itohy /* read MAC address */
1569 1.6.2.2 itohy (void)zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P1, &tmp);
1570 1.6.2.2 itohy ic->ic_myaddr[0] = tmp & 0xff;
1571 1.6.2.2 itohy ic->ic_myaddr[1] = tmp >> 8;
1572 1.6.2.2 itohy ic->ic_myaddr[2] = tmp >> 16;
1573 1.6.2.2 itohy ic->ic_myaddr[3] = tmp >> 24;
1574 1.6.2.2 itohy (void)zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P2, &tmp);
1575 1.6.2.2 itohy ic->ic_myaddr[4] = tmp & 0xff;
1576 1.6.2.2 itohy ic->ic_myaddr[5] = tmp >> 8;
1577 1.6.2.2 itohy
1578 1.6.2.2 itohy (void)zyd_read32(sc, ZYD_EEPROM_POD, &tmp);
1579 1.6.2.2 itohy sc->rf_rev = tmp & 0x0f;
1580 1.6.2.2 itohy sc->pa_rev = (tmp >> 16) & 0x0f;
1581 1.6.2.2 itohy
1582 1.6.2.2 itohy /* read regulatory domain (currently unused) */
1583 1.6.2.2 itohy (void)zyd_read32(sc, ZYD_EEPROM_SUBID, &tmp);
1584 1.6.2.2 itohy sc->regdomain = tmp >> 16;
1585 1.6.2.2 itohy DPRINTF(("regulatory domain %x\n", sc->regdomain));
1586 1.6.2.2 itohy
1587 1.6.2.2 itohy /* read Tx power calibration tables */
1588 1.6.2.2 itohy for (i = 0; i < 7; i++) {
1589 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_EEPROM_PWR_CAL + i, &val);
1590 1.6.2.2 itohy sc->pwr_cal[i * 2] = val >> 8;
1591 1.6.2.2 itohy sc->pwr_cal[i * 2 + 1] = val & 0xff;
1592 1.6.2.2 itohy
1593 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_EEPROM_PWR_INT + i, &val);
1594 1.6.2.2 itohy sc->pwr_int[i * 2] = val >> 8;
1595 1.6.2.2 itohy sc->pwr_int[i * 2 + 1] = val & 0xff;
1596 1.6.2.2 itohy
1597 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_EEPROM_36M_CAL + i, &val);
1598 1.6.2.2 itohy sc->ofdm36_cal[i * 2] = val >> 8;
1599 1.6.2.2 itohy sc->ofdm36_cal[i * 2 + 1] = val & 0xff;
1600 1.6.2.2 itohy
1601 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_EEPROM_48M_CAL + i, &val);
1602 1.6.2.2 itohy sc->ofdm48_cal[i * 2] = val >> 8;
1603 1.6.2.2 itohy sc->ofdm48_cal[i * 2 + 1] = val & 0xff;
1604 1.6.2.2 itohy
1605 1.6.2.2 itohy (void)zyd_read16(sc, ZYD_EEPROM_54M_CAL + i, &val);
1606 1.6.2.2 itohy sc->ofdm54_cal[i * 2] = val >> 8;
1607 1.6.2.2 itohy sc->ofdm54_cal[i * 2 + 1] = val & 0xff;
1608 1.6.2.2 itohy }
1609 1.6.2.2 itohy return 0;
1610 1.6.2.2 itohy }
1611 1.6.2.2 itohy
1612 1.6.2.2 itohy Static int
1613 1.6.2.2 itohy zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr)
1614 1.6.2.2 itohy {
1615 1.6.2.2 itohy uint32_t tmp;
1616 1.6.2.2 itohy
1617 1.6.2.2 itohy tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
1618 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_MACADRL, tmp);
1619 1.6.2.2 itohy
1620 1.6.2.2 itohy tmp = addr[5] << 8 | addr[4];
1621 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_MACADRH, tmp);
1622 1.6.2.2 itohy
1623 1.6.2.2 itohy return 0;
1624 1.6.2.2 itohy }
1625 1.6.2.2 itohy
1626 1.6.2.2 itohy Static int
1627 1.6.2.2 itohy zyd_set_bssid(struct zyd_softc *sc, const uint8_t *addr)
1628 1.6.2.2 itohy {
1629 1.6.2.2 itohy uint32_t tmp;
1630 1.6.2.2 itohy
1631 1.6.2.2 itohy tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
1632 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_BSSADRL, tmp);
1633 1.6.2.2 itohy
1634 1.6.2.2 itohy tmp = addr[5] << 8 | addr[4];
1635 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_BSSADRH, tmp);
1636 1.6.2.2 itohy
1637 1.6.2.2 itohy return 0;
1638 1.6.2.2 itohy }
1639 1.6.2.2 itohy
1640 1.6.2.2 itohy Static int
1641 1.6.2.2 itohy zyd_switch_radio(struct zyd_softc *sc, int on)
1642 1.6.2.2 itohy {
1643 1.6.2.2 itohy struct zyd_rf *rf = &sc->sc_rf;
1644 1.6.2.2 itohy int error;
1645 1.6.2.2 itohy
1646 1.6.2.2 itohy zyd_lock_phy(sc);
1647 1.6.2.2 itohy error = (*rf->switch_radio)(rf, on);
1648 1.6.2.2 itohy zyd_unlock_phy(sc);
1649 1.6.2.2 itohy
1650 1.6.2.2 itohy return error;
1651 1.6.2.2 itohy }
1652 1.6.2.2 itohy
1653 1.6.2.2 itohy Static void
1654 1.6.2.2 itohy zyd_set_led(struct zyd_softc *sc, int which, int on)
1655 1.6.2.2 itohy {
1656 1.6.2.2 itohy uint32_t tmp;
1657 1.6.2.2 itohy
1658 1.6.2.2 itohy (void)zyd_read32(sc, ZYD_MAC_TX_PE_CONTROL, &tmp);
1659 1.6.2.2 itohy tmp &= ~which;
1660 1.6.2.2 itohy if (on)
1661 1.6.2.2 itohy tmp |= which;
1662 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_TX_PE_CONTROL, tmp);
1663 1.6.2.2 itohy }
1664 1.6.2.2 itohy
1665 1.6.2.2 itohy Static int
1666 1.6.2.2 itohy zyd_set_rxfilter(struct zyd_softc *sc)
1667 1.6.2.2 itohy {
1668 1.6.2.2 itohy uint32_t rxfilter;
1669 1.6.2.2 itohy
1670 1.6.2.2 itohy switch (sc->sc_ic.ic_opmode) {
1671 1.6.2.2 itohy case IEEE80211_M_STA:
1672 1.6.2.2 itohy rxfilter = ZYD_FILTER_BSS;
1673 1.6.2.2 itohy break;
1674 1.6.2.2 itohy case IEEE80211_M_IBSS:
1675 1.6.2.2 itohy case IEEE80211_M_HOSTAP:
1676 1.6.2.2 itohy rxfilter = ZYD_FILTER_HOSTAP;
1677 1.6.2.2 itohy break;
1678 1.6.2.2 itohy case IEEE80211_M_MONITOR:
1679 1.6.2.2 itohy rxfilter = ZYD_FILTER_MONITOR;
1680 1.6.2.2 itohy break;
1681 1.6.2.2 itohy default:
1682 1.6.2.2 itohy /* should not get there */
1683 1.6.2.2 itohy return EINVAL;
1684 1.6.2.2 itohy }
1685 1.6.2.2 itohy return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter);
1686 1.6.2.2 itohy }
1687 1.6.2.2 itohy
1688 1.6.2.2 itohy Static void
1689 1.6.2.2 itohy zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c)
1690 1.6.2.2 itohy {
1691 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
1692 1.6.2.2 itohy struct zyd_rf *rf = &sc->sc_rf;
1693 1.6.2.2 itohy u_int chan;
1694 1.6.2.2 itohy
1695 1.6.2.2 itohy chan = ieee80211_chan2ieee(ic, c);
1696 1.6.2.2 itohy if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1697 1.6.2.2 itohy return;
1698 1.6.2.2 itohy
1699 1.6.2.2 itohy zyd_lock_phy(sc);
1700 1.6.2.2 itohy
1701 1.6.2.2 itohy (*rf->set_channel)(rf, chan);
1702 1.6.2.2 itohy
1703 1.6.2.2 itohy /* update Tx power */
1704 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR31, sc->pwr_int[chan - 1]);
1705 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR68, sc->pwr_cal[chan - 1]);
1706 1.6.2.2 itohy
1707 1.6.2.2 itohy if (sc->mac_rev == ZYD_ZD1211B) {
1708 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR67, sc->ofdm36_cal[chan - 1]);
1709 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR66, sc->ofdm48_cal[chan - 1]);
1710 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR65, sc->ofdm54_cal[chan - 1]);
1711 1.6.2.2 itohy
1712 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR69, 0x28);
1713 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR69, 0x2a);
1714 1.6.2.2 itohy }
1715 1.6.2.2 itohy
1716 1.6.2.2 itohy zyd_unlock_phy(sc);
1717 1.6.2.2 itohy }
1718 1.6.2.2 itohy
1719 1.6.2.2 itohy Static int
1720 1.6.2.2 itohy zyd_set_beacon_interval(struct zyd_softc *sc, int bintval)
1721 1.6.2.2 itohy {
1722 1.6.2.2 itohy /* XXX this is probably broken.. */
1723 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_ATIM_WND_PERIOD, bintval - 2);
1724 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_PRE_TBTT, bintval - 1);
1725 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_BCN_INTERVAL, bintval);
1726 1.6.2.2 itohy
1727 1.6.2.2 itohy return 0;
1728 1.6.2.2 itohy }
1729 1.6.2.2 itohy
1730 1.6.2.2 itohy Static uint8_t
1731 1.6.2.2 itohy zyd_plcp_signal(int rate)
1732 1.6.2.2 itohy {
1733 1.6.2.2 itohy switch (rate) {
1734 1.6.2.2 itohy /* CCK rates (returned values are device-dependent) */
1735 1.6.2.2 itohy case 2: return 0x0;
1736 1.6.2.2 itohy case 4: return 0x1;
1737 1.6.2.2 itohy case 11: return 0x2;
1738 1.6.2.2 itohy case 22: return 0x3;
1739 1.6.2.2 itohy
1740 1.6.2.2 itohy /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
1741 1.6.2.2 itohy case 12: return 0xb;
1742 1.6.2.2 itohy case 18: return 0xf;
1743 1.6.2.2 itohy case 24: return 0xa;
1744 1.6.2.2 itohy case 36: return 0xe;
1745 1.6.2.2 itohy case 48: return 0x9;
1746 1.6.2.2 itohy case 72: return 0xd;
1747 1.6.2.2 itohy case 96: return 0x8;
1748 1.6.2.2 itohy case 108: return 0xc;
1749 1.6.2.2 itohy
1750 1.6.2.2 itohy /* unsupported rates (should not get there) */
1751 1.6.2.2 itohy default: return 0xff;
1752 1.6.2.2 itohy }
1753 1.6.2.2 itohy }
1754 1.6.2.2 itohy
1755 1.6.2.2 itohy Static void
1756 1.6.2.2 itohy zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1757 1.6.2.2 itohy {
1758 1.6.2.2 itohy struct zyd_softc *sc = (struct zyd_softc *)priv;
1759 1.6.2.2 itohy struct zyd_cmd *cmd;
1760 1.6.2.2 itohy uint32_t datalen;
1761 1.6.2.2 itohy
1762 1.6.2.2 itohy if (status != USBD_NORMAL_COMPLETION) {
1763 1.6.2.2 itohy if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1764 1.6.2.2 itohy return;
1765 1.6.2.2 itohy
1766 1.6.2.2 itohy if (status == USBD_STALLED) {
1767 1.6.2.2 itohy usbd_clear_endpoint_stall_async(
1768 1.6.2.2 itohy sc->zyd_ep[ZYD_ENDPT_IIN]);
1769 1.6.2.2 itohy }
1770 1.6.2.2 itohy return;
1771 1.6.2.2 itohy }
1772 1.6.2.2 itohy
1773 1.6.2.2 itohy cmd = (struct zyd_cmd *)sc->ibuf;
1774 1.6.2.2 itohy
1775 1.6.2.2 itohy if (le16toh(cmd->code) == ZYD_NOTIF_RETRYSTATUS) {
1776 1.6.2.2 itohy struct zyd_notif_retry *retry =
1777 1.6.2.2 itohy (struct zyd_notif_retry *)cmd->data;
1778 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
1779 1.6.2.2 itohy struct ifnet *ifp = &sc->sc_if;
1780 1.6.2.2 itohy struct ieee80211_node *ni;
1781 1.6.2.2 itohy
1782 1.6.2.2 itohy DPRINTF(("retry intr: rate=0x%x addr=%s count=%d (0x%x)\n",
1783 1.6.2.2 itohy le16toh(retry->rate), ether_sprintf(retry->macaddr),
1784 1.6.2.2 itohy le16toh(retry->count) & 0xff, le16toh(retry->count)));
1785 1.6.2.2 itohy
1786 1.6.2.2 itohy /*
1787 1.6.2.2 itohy * Find the node to which the packet was sent and update its
1788 1.6.2.2 itohy * retry statistics. In BSS mode, this node is the AP we're
1789 1.6.2.2 itohy * associated to so no lookup is actually needed.
1790 1.6.2.2 itohy */
1791 1.6.2.2 itohy if (ic->ic_opmode != IEEE80211_M_STA) {
1792 1.6.2.2 itohy ni = ieee80211_find_node(&ic->ic_scan, retry->macaddr);
1793 1.6.2.2 itohy if (ni == NULL)
1794 1.6.2.2 itohy return; /* just ignore */
1795 1.6.2.2 itohy } else
1796 1.6.2.2 itohy ni = ic->ic_bss;
1797 1.6.2.2 itohy
1798 1.6.2.2 itohy ((struct zyd_node *)ni)->amn.amn_retrycnt++;
1799 1.6.2.2 itohy
1800 1.6.2.2 itohy if (le16toh(retry->count) & 0x100)
1801 1.6.2.2 itohy ifp->if_oerrors++; /* too many retries */
1802 1.6.2.2 itohy
1803 1.6.2.2 itohy } else if (le16toh(cmd->code) == ZYD_NOTIF_IORD) {
1804 1.6.2.2 itohy struct rq *rqp;
1805 1.6.2.2 itohy
1806 1.6.2.2 itohy if (le16toh(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT)
1807 1.6.2.2 itohy return; /* HMAC interrupt */
1808 1.6.2.2 itohy
1809 1.6.2.2 itohy usbd_get_xfer_status(xfer, NULL, NULL, &datalen, NULL);
1810 1.6.2.2 itohy datalen -= sizeof(cmd->code);
1811 1.6.2.2 itohy datalen -= 2; /* XXX: padding? */
1812 1.6.2.2 itohy
1813 1.6.2.2 itohy SIMPLEQ_FOREACH(rqp, &sc->sc_rqh, rq) {
1814 1.6.2.2 itohy int i;
1815 1.6.2.2 itohy
1816 1.6.2.3 itohy if (sizeof(struct zyd_pair) * rqp->len != datalen)
1817 1.6.2.2 itohy continue;
1818 1.6.2.2 itohy for (i = 0; i < rqp->len; i++) {
1819 1.6.2.2 itohy if (*(((const uint16_t *)rqp->idata) + i) !=
1820 1.6.2.2 itohy (((struct zyd_pair *)cmd->data) + i)->reg)
1821 1.6.2.2 itohy break;
1822 1.6.2.2 itohy }
1823 1.6.2.2 itohy if (i != rqp->len)
1824 1.6.2.2 itohy continue;
1825 1.6.2.2 itohy
1826 1.6.2.2 itohy /* copy answer into caller-supplied buffer */
1827 1.6.2.2 itohy bcopy(cmd->data, rqp->odata,
1828 1.6.2.2 itohy sizeof(struct zyd_pair) * rqp->len);
1829 1.6.2.2 itohy wakeup(rqp->odata); /* wakeup caller */
1830 1.6.2.2 itohy
1831 1.6.2.2 itohy return;
1832 1.6.2.2 itohy }
1833 1.6.2.2 itohy return; /* unexpected IORD notification */
1834 1.6.2.2 itohy } else {
1835 1.6.2.2 itohy printf("%s: unknown notification %x\n", USBDEVNAME(sc->sc_dev),
1836 1.6.2.2 itohy le16toh(cmd->code));
1837 1.6.2.2 itohy }
1838 1.6.2.2 itohy }
1839 1.6.2.2 itohy
1840 1.6.2.2 itohy Static void
1841 1.6.2.2 itohy zyd_rx_data(struct zyd_softc *sc, struct mbuf *m, uint16_t len)
1842 1.6.2.2 itohy {
1843 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
1844 1.6.2.2 itohy struct ifnet *ifp = &sc->sc_if;
1845 1.6.2.2 itohy struct ieee80211_node *ni;
1846 1.6.2.2 itohy struct ieee80211_frame *wh;
1847 1.6.2.2 itohy const struct zyd_plcphdr *plcp;
1848 1.6.2.2 itohy const struct zyd_rx_stat *stat;
1849 1.6.2.2 itohy int rlen, s;
1850 1.6.2.2 itohy
1851 1.6.2.2 itohy if (len < ZYD_MIN_FRAGSZ) {
1852 1.6.2.2 itohy m_freem(m);
1853 1.6.2.2 itohy printf("%s: frame too short (length=%d)\n",
1854 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), len);
1855 1.6.2.2 itohy ifp->if_ierrors++;
1856 1.6.2.2 itohy return;
1857 1.6.2.2 itohy }
1858 1.6.2.2 itohy
1859 1.6.2.2 itohy plcp = mtod(m, const struct zyd_plcphdr *);
1860 1.6.2.2 itohy stat = (const struct zyd_rx_stat *)
1861 1.6.2.2 itohy (mtod(m, char *) + len - sizeof (struct zyd_rx_stat));
1862 1.6.2.2 itohy
1863 1.6.2.2 itohy if (stat->flags & ZYD_RX_ERROR) {
1864 1.6.2.2 itohy m_freem(m);
1865 1.6.2.2 itohy DPRINTF(("%s: RX status indicated error (%x)\n",
1866 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), stat->flags));
1867 1.6.2.2 itohy ifp->if_ierrors++;
1868 1.6.2.2 itohy return;
1869 1.6.2.2 itohy }
1870 1.6.2.2 itohy
1871 1.6.2.2 itohy /* compute actual frame length */
1872 1.6.2.2 itohy rlen = len - sizeof (struct zyd_plcphdr) -
1873 1.6.2.2 itohy sizeof (struct zyd_rx_stat) - IEEE80211_CRC_LEN;
1874 1.6.2.2 itohy
1875 1.6.2.2 itohy m->m_pkthdr.rcvif = ifp;
1876 1.6.2.2 itohy m_adj(m, sizeof(struct zyd_plcphdr));
1877 1.6.2.2 itohy m->m_pkthdr.len = m->m_len = rlen;
1878 1.6.2.2 itohy
1879 1.6.2.2 itohy s = splnet();
1880 1.6.2.2 itohy
1881 1.6.2.2 itohy #if NBPFILTER > 0
1882 1.6.2.2 itohy if (sc->sc_drvbpf != NULL) {
1883 1.6.2.2 itohy struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
1884 1.6.2.2 itohy static const uint8_t rates[] = {
1885 1.6.2.2 itohy /* reverse function of zyd_plcp_signal() */
1886 1.6.2.2 itohy 2, 4, 11, 22, 0, 0, 0, 0,
1887 1.6.2.2 itohy 96, 48, 24, 12, 108, 72, 36, 18
1888 1.6.2.2 itohy };
1889 1.6.2.2 itohy
1890 1.6.2.2 itohy tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
1891 1.6.2.2 itohy tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
1892 1.6.2.2 itohy tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
1893 1.6.2.2 itohy tap->wr_rssi = stat->rssi;
1894 1.6.2.2 itohy tap->wr_rate = rates[plcp->signal & 0xf];
1895 1.6.2.2 itohy
1896 1.6.2.2 itohy bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
1897 1.6.2.2 itohy }
1898 1.6.2.2 itohy #endif
1899 1.6.2.2 itohy
1900 1.6.2.2 itohy wh = mtod(m, struct ieee80211_frame *);
1901 1.6.2.2 itohy ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
1902 1.6.2.2 itohy ieee80211_input(ic, m, ni, stat->rssi, 0);
1903 1.6.2.2 itohy
1904 1.6.2.2 itohy /* node is no longer needed */
1905 1.6.2.2 itohy ieee80211_free_node(ni);
1906 1.6.2.2 itohy
1907 1.6.2.2 itohy splx(s);
1908 1.6.2.2 itohy }
1909 1.6.2.2 itohy
1910 1.6.2.2 itohy Static void
1911 1.6.2.2 itohy zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1912 1.6.2.2 itohy {
1913 1.6.2.2 itohy struct ue_chain *data = priv;
1914 1.6.2.2 itohy struct zyd_softc *sc = (void *)data->ue_dev;
1915 1.6.2.2 itohy struct ifnet *ifp = &sc->sc_if;
1916 1.6.2.2 itohy const struct zyd_rx_desc *desc;
1917 1.6.2.2 itohy int len;
1918 1.6.2.2 itohy struct mbuf *m;
1919 1.6.2.2 itohy
1920 1.6.2.2 itohy usbd_unmap_buffer(xfer);
1921 1.6.2.2 itohy
1922 1.6.2.2 itohy if (status != USBD_NORMAL_COMPLETION) {
1923 1.6.2.2 itohy if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1924 1.6.2.2 itohy return;
1925 1.6.2.2 itohy
1926 1.6.2.2 itohy if (status == USBD_STALLED)
1927 1.6.2.2 itohy usbd_clear_endpoint_stall(sc->zyd_ep[ZYD_ENDPT_BIN]);
1928 1.6.2.2 itohy
1929 1.6.2.2 itohy goto skip;
1930 1.6.2.2 itohy }
1931 1.6.2.2 itohy usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1932 1.6.2.2 itohy
1933 1.6.2.2 itohy if (len < ZYD_MIN_RXBUFSZ) {
1934 1.6.2.2 itohy printf("%s: xfer too short (length=%d)\n",
1935 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), len);
1936 1.6.2.2 itohy ifp->if_ierrors++;
1937 1.6.2.2 itohy goto skip;
1938 1.6.2.2 itohy }
1939 1.6.2.2 itohy
1940 1.6.2.2 itohy m = data->ue_mbuf;
1941 1.6.2.2 itohy
1942 1.6.2.2 itohy /*
1943 1.6.2.2 itohy * Allocate new mbuf cluster for the next transfer.
1944 1.6.2.2 itohy * If that failed, discard current packet and recycle the mbuf.
1945 1.6.2.2 itohy */
1946 1.6.2.2 itohy if ((data->ue_mbuf = usb_ether_newbuf(NULL)) == NULL) {
1947 1.6.2.2 itohy printf("%s: no memory for rx list -- packet dropped!\n",
1948 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
1949 1.6.2.2 itohy ifp->if_ierrors++;
1950 1.6.2.2 itohy data->ue_mbuf = usb_ether_newbuf(m);
1951 1.6.2.2 itohy goto skip;
1952 1.6.2.2 itohy }
1953 1.6.2.2 itohy
1954 1.6.2.2 itohy desc = (const struct zyd_rx_desc *)
1955 1.6.2.2 itohy (mtod(m, char *) + len - sizeof (struct zyd_rx_desc));
1956 1.6.2.2 itohy
1957 1.6.2.2 itohy if (UGETW(desc->tag) == ZYD_TAG_MULTIFRAME) {
1958 1.6.2.2 itohy int pktoff[ZYD_MAX_RXFRAMECNT];
1959 1.6.2.2 itohy uint16_t pktlen[ZYD_MAX_RXFRAMECNT];
1960 1.6.2.2 itohy struct mbuf *pktmbuf[ZYD_MAX_RXFRAMECNT];
1961 1.6.2.2 itohy int npkt, i, off;
1962 1.6.2.2 itohy
1963 1.6.2.2 itohy DPRINTFN(3, ("received multi-frame transfer\n"));
1964 1.6.2.2 itohy
1965 1.6.2.2 itohy m->m_pkthdr.len = m->m_len = len;
1966 1.6.2.2 itohy off = 0;
1967 1.6.2.2 itohy for (npkt = 0; npkt < ZYD_MAX_RXFRAMECNT; npkt++) {
1968 1.6.2.2 itohy const uint16_t len16 = UGETW(desc->len[npkt]);
1969 1.6.2.2 itohy
1970 1.6.2.2 itohy if (len16 == 0 || off + len16 > len)
1971 1.6.2.2 itohy break;
1972 1.6.2.2 itohy pktoff[npkt] = off;
1973 1.6.2.2 itohy pktlen[npkt] = len16;
1974 1.6.2.2 itohy /* next frame is aligned on a 32-bit boundary */
1975 1.6.2.2 itohy off += (len16 + 3) & ~3;
1976 1.6.2.2 itohy }
1977 1.6.2.2 itohy
1978 1.6.2.2 itohy /*
1979 1.6.2.4 itohy * Split an mbuf into packets. This is done in reverse order
1980 1.6.2.4 itohy * to reduce amount of data to be copied.
1981 1.6.2.2 itohy */
1982 1.6.2.2 itohy for (i = npkt - 1; i > 0; i--)
1983 1.6.2.2 itohy pktmbuf[i] = m_split(m, pktoff[i], M_DONTWAIT);
1984 1.6.2.2 itohy pktmbuf[0] = m;
1985 1.6.2.2 itohy
1986 1.6.2.2 itohy /* input packets in order */
1987 1.6.2.2 itohy for (i = 0; i < npkt; i++) {
1988 1.6.2.2 itohy if (pktmbuf[i] == NULL) {
1989 1.6.2.2 itohy printf("%s: could not allocate rx mbuf\n",
1990 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
1991 1.6.2.2 itohy ifp->if_ierrors++;
1992 1.6.2.2 itohy continue;
1993 1.6.2.2 itohy }
1994 1.6.2.2 itohy zyd_rx_data(sc, pktmbuf[i], pktlen[i]);
1995 1.6.2.2 itohy }
1996 1.6.2.2 itohy } else {
1997 1.6.2.2 itohy DPRINTFN(3, ("received single-frame transfer\n"));
1998 1.6.2.2 itohy
1999 1.6.2.2 itohy zyd_rx_data(sc, m, len);
2000 1.6.2.2 itohy }
2001 1.6.2.2 itohy
2002 1.6.2.2 itohy skip: /* setup a new transfer */
2003 1.6.2.2 itohy (void)usbd_map_buffer_mbuf(xfer, data->ue_mbuf);
2004 1.6.2.2 itohy usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data, NULL,
2005 1.6.2.2 itohy ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK,
2006 1.6.2.2 itohy USBD_NO_TIMEOUT, zyd_rxeof);
2007 1.6.2.2 itohy (void)usbd_transfer(xfer);
2008 1.6.2.2 itohy }
2009 1.6.2.2 itohy
2010 1.6.2.2 itohy Static int
2011 1.6.2.2 itohy zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
2012 1.6.2.2 itohy {
2013 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
2014 1.6.2.2 itohy struct ifnet *ifp = &sc->sc_if;
2015 1.6.2.2 itohy struct zyd_tx_desc *desc;
2016 1.6.2.2 itohy struct ue_chain *data;
2017 1.6.2.2 itohy struct ieee80211_frame *wh;
2018 1.6.2.2 itohy uint8_t i_addr1[IEEE80211_ADDR_LEN];
2019 1.6.2.2 itohy uint8_t i_fc_0;
2020 1.6.2.2 itohy int xferlen, totlen, rate;
2021 1.6.2.2 itohy uint16_t pktlen;
2022 1.6.2.2 itohy usbd_status error;
2023 1.6.2.2 itohy int ret;
2024 1.6.2.2 itohy
2025 1.6.2.2 itohy data = &sc->tx_data[0];
2026 1.6.2.2 itohy
2027 1.6.2.2 itohy rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
2028 1.6.2.2 itohy
2029 1.6.2.2 itohy sc->tx_ni[data->ue_idx] = ni;
2030 1.6.2.2 itohy
2031 1.6.2.2 itohy wh = mtod(m0, struct ieee80211_frame *);
2032 1.6.2.2 itohy
2033 1.6.2.2 itohy /* save local copy against possible mbuf move */
2034 1.6.2.2 itohy USB_KASSERT(sizeof i_addr1 == sizeof wh->i_addr1);
2035 1.6.2.2 itohy memcpy(i_addr1, wh->i_addr1, sizeof i_addr1);
2036 1.6.2.2 itohy i_fc_0 = wh->i_fc[0];
2037 1.6.2.2 itohy
2038 1.6.2.2 itohy xferlen = sizeof (struct zyd_tx_desc) + m0->m_pkthdr.len;
2039 1.6.2.2 itohy totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
2040 1.6.2.2 itohy
2041 1.6.2.2 itohy /* Prepend Tx descriptor */
2042 1.6.2.2 itohy M_PREPEND(m0, sizeof(struct zyd_tx_desc), M_DONTWAIT);
2043 1.6.2.2 itohy if (m0 != NULL)
2044 1.6.2.2 itohy m0 = m_pullup(m0, sizeof(struct zyd_tx_desc));/* just in case */
2045 1.6.2.2 itohy if (m0 == NULL) {
2046 1.6.2.2 itohy return ENOBUFS;
2047 1.6.2.2 itohy }
2048 1.6.2.2 itohy desc = mtod(m0, struct zyd_tx_desc *);
2049 1.6.2.2 itohy
2050 1.6.2.2 itohy /* fill Tx descriptor */
2051 1.6.2.2 itohy USETW((uint8_t *)&desc->len, totlen);
2052 1.6.2.2 itohy
2053 1.6.2.2 itohy desc->flags = ZYD_TX_FLAG_BACKOFF;
2054 1.6.2.2 itohy if (!IEEE80211_IS_MULTICAST(i_addr1)) {
2055 1.6.2.2 itohy /* multicast frames are not sent at OFDM rates in 802.11b/g */
2056 1.6.2.2 itohy if (totlen > ic->ic_rtsthreshold) {
2057 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_RTS;
2058 1.6.2.2 itohy } else if (ZYD_RATE_IS_OFDM(rate) &&
2059 1.6.2.2 itohy (ic->ic_flags & IEEE80211_F_USEPROT)) {
2060 1.6.2.2 itohy if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2061 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
2062 1.6.2.2 itohy else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2063 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_RTS;
2064 1.6.2.2 itohy }
2065 1.6.2.2 itohy } else
2066 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_MULTICAST;
2067 1.6.2.2 itohy
2068 1.6.2.2 itohy if ((i_fc_0 &
2069 1.6.2.2 itohy (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
2070 1.6.2.2 itohy (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
2071 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
2072 1.6.2.2 itohy
2073 1.6.2.2 itohy desc->phy = zyd_plcp_signal(rate);
2074 1.6.2.2 itohy if (ZYD_RATE_IS_OFDM(rate)) {
2075 1.6.2.2 itohy desc->phy |= ZYD_TX_PHY_OFDM;
2076 1.6.2.2 itohy if (ic->ic_curmode == IEEE80211_MODE_11A)
2077 1.6.2.2 itohy desc->phy |= ZYD_TX_PHY_5GHZ;
2078 1.6.2.2 itohy } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
2079 1.6.2.2 itohy desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
2080 1.6.2.2 itohy
2081 1.6.2.2 itohy /* actual transmit length (XXX why +10?) */
2082 1.6.2.2 itohy pktlen = sizeof (struct zyd_tx_desc) + 10;
2083 1.6.2.2 itohy if (sc->mac_rev == ZYD_ZD1211)
2084 1.6.2.2 itohy pktlen += totlen;
2085 1.6.2.2 itohy USETW((uint8_t *)&desc->pktlen, pktlen);
2086 1.6.2.2 itohy
2087 1.6.2.2 itohy USETW((uint8_t *)&desc->plcp_length, (16 * totlen + rate - 1) / rate);
2088 1.6.2.2 itohy desc->plcp_service = 0;
2089 1.6.2.2 itohy if (rate == 22) {
2090 1.6.2.2 itohy const int remainder = (16 * totlen) % 22;
2091 1.6.2.2 itohy if (remainder != 0 && remainder < 7)
2092 1.6.2.2 itohy desc->plcp_service |= ZYD_PLCP_LENGEXT;
2093 1.6.2.2 itohy }
2094 1.6.2.2 itohy
2095 1.6.2.2 itohy #if NBPFILTER > 0
2096 1.6.2.2 itohy if (sc->sc_drvbpf != NULL) {
2097 1.6.2.2 itohy struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
2098 1.6.2.2 itohy
2099 1.6.2.2 itohy tap->wt_flags = 0;
2100 1.6.2.2 itohy tap->wt_rate = rate;
2101 1.6.2.2 itohy tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
2102 1.6.2.2 itohy tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
2103 1.6.2.2 itohy
2104 1.6.2.2 itohy bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
2105 1.6.2.2 itohy }
2106 1.6.2.2 itohy #endif
2107 1.6.2.2 itohy
2108 1.6.2.2 itohy DPRINTFN(10, ("%s: sending mgt frame len=%zu rate=%u xferlen=%u\n",
2109 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), (size_t)m0->m_pkthdr.len, rate, xferlen));
2110 1.6.2.2 itohy
2111 1.6.2.2 itohy ret = usb_ether_map_tx_buffer_mbuf(data, m0);
2112 1.6.2.2 itohy if (ret) {
2113 1.6.2.2 itohy m_freem(m0);
2114 1.6.2.2 itohy return ret;
2115 1.6.2.2 itohy }
2116 1.6.2.2 itohy
2117 1.6.2.2 itohy usbd_setup_xfer(data->ue_xfer, sc->zyd_ep[ZYD_ENDPT_BOUT], data,
2118 1.6.2.2 itohy NULL /* XXX buf */, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
2119 1.6.2.2 itohy ZYD_TX_TIMEOUT, zyd_txeof);
2120 1.6.2.2 itohy error = usbd_transfer(data->ue_xfer);
2121 1.6.2.2 itohy if (error != USBD_IN_PROGRESS && error != 0) {
2122 1.6.2.2 itohy data->ue_mbuf = NULL;
2123 1.6.2.2 itohy m_freem(m0);
2124 1.6.2.2 itohy ifp->if_oerrors++;
2125 1.6.2.2 itohy return EIO;
2126 1.6.2.2 itohy }
2127 1.6.2.2 itohy sc->tx_queued++;
2128 1.6.2.2 itohy
2129 1.6.2.2 itohy return 0;
2130 1.6.2.2 itohy }
2131 1.6.2.2 itohy
2132 1.6.2.2 itohy Static void
2133 1.6.2.2 itohy zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
2134 1.6.2.2 itohy {
2135 1.6.2.2 itohy struct ue_chain *data = priv;
2136 1.6.2.2 itohy struct zyd_softc *sc = (void *)data->ue_dev;
2137 1.6.2.2 itohy struct ifnet *ifp = &sc->sc_if;
2138 1.6.2.2 itohy int s;
2139 1.6.2.2 itohy
2140 1.6.2.2 itohy usbd_unmap_buffer(xfer);
2141 1.6.2.2 itohy
2142 1.6.2.2 itohy if (status != USBD_NORMAL_COMPLETION) {
2143 1.6.2.2 itohy if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
2144 1.6.2.2 itohy return;
2145 1.6.2.2 itohy
2146 1.6.2.2 itohy printf("%s: could not transmit buffer: %s\n",
2147 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), usbd_errstr(status));
2148 1.6.2.2 itohy
2149 1.6.2.2 itohy if (status == USBD_STALLED) {
2150 1.6.2.2 itohy usbd_clear_endpoint_stall_async(
2151 1.6.2.2 itohy sc->zyd_ep[ZYD_ENDPT_BOUT]);
2152 1.6.2.2 itohy }
2153 1.6.2.2 itohy ifp->if_oerrors++;
2154 1.6.2.2 itohy return;
2155 1.6.2.2 itohy }
2156 1.6.2.2 itohy
2157 1.6.2.2 itohy s = splnet();
2158 1.6.2.2 itohy
2159 1.6.2.2 itohy m_freem(data->ue_mbuf);
2160 1.6.2.2 itohy data->ue_mbuf = NULL;
2161 1.6.2.2 itohy
2162 1.6.2.2 itohy /* update rate control statistics */
2163 1.6.2.2 itohy ((struct zyd_node *)sc->tx_ni[data->ue_idx])->amn.amn_txcnt++;
2164 1.6.2.2 itohy
2165 1.6.2.2 itohy ieee80211_free_node(sc->tx_ni[data->ue_idx]);
2166 1.6.2.2 itohy sc->tx_ni[data->ue_idx] = NULL;
2167 1.6.2.2 itohy
2168 1.6.2.2 itohy sc->tx_queued--;
2169 1.6.2.2 itohy ifp->if_opackets++;
2170 1.6.2.2 itohy
2171 1.6.2.2 itohy sc->tx_timer = 0;
2172 1.6.2.2 itohy ifp->if_flags &= ~IFF_OACTIVE;
2173 1.6.2.2 itohy zyd_start(ifp);
2174 1.6.2.2 itohy
2175 1.6.2.2 itohy splx(s);
2176 1.6.2.2 itohy }
2177 1.6.2.2 itohy
2178 1.6.2.2 itohy Static int
2179 1.6.2.2 itohy zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
2180 1.6.2.2 itohy {
2181 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
2182 1.6.2.2 itohy struct ifnet *ifp = &sc->sc_if;
2183 1.6.2.2 itohy struct zyd_tx_desc *desc;
2184 1.6.2.2 itohy struct ue_chain *data;
2185 1.6.2.2 itohy struct ieee80211_frame *wh;
2186 1.6.2.2 itohy struct ieee80211_key *k;
2187 1.6.2.2 itohy uint8_t i_addr1[IEEE80211_ADDR_LEN];
2188 1.6.2.2 itohy uint8_t i_fc_0;
2189 1.6.2.2 itohy int xferlen, totlen, rate;
2190 1.6.2.2 itohy uint16_t pktlen;
2191 1.6.2.2 itohy usbd_status error;
2192 1.6.2.2 itohy int ret;
2193 1.6.2.2 itohy
2194 1.6.2.2 itohy wh = mtod(m0, struct ieee80211_frame *);
2195 1.6.2.2 itohy
2196 1.6.2.2 itohy if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
2197 1.6.2.2 itohy rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate];
2198 1.6.2.2 itohy else
2199 1.6.2.2 itohy rate = ni->ni_rates.rs_rates[ni->ni_txrate];
2200 1.6.2.2 itohy rate &= IEEE80211_RATE_VAL;
2201 1.6.2.2 itohy
2202 1.6.2.2 itohy /* save local copy against possible mbuf move */
2203 1.6.2.2 itohy USB_KASSERT(sizeof i_addr1 == sizeof wh->i_addr1);
2204 1.6.2.2 itohy memcpy(i_addr1, wh->i_addr1, sizeof i_addr1);
2205 1.6.2.2 itohy i_fc_0 = wh->i_fc[0];
2206 1.6.2.2 itohy
2207 1.6.2.2 itohy if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2208 1.6.2.2 itohy k = ieee80211_crypto_encap(ic, ni, m0);
2209 1.6.2.2 itohy if (k == NULL) {
2210 1.6.2.2 itohy m_freem(m0);
2211 1.6.2.2 itohy return ENOBUFS;
2212 1.6.2.2 itohy }
2213 1.6.2.2 itohy }
2214 1.6.2.2 itohy
2215 1.6.2.2 itohy data = &sc->tx_data[0];
2216 1.6.2.2 itohy
2217 1.6.2.2 itohy sc->tx_ni[data->ue_idx] = ni;
2218 1.6.2.2 itohy
2219 1.6.2.2 itohy xferlen = sizeof (struct zyd_tx_desc) + m0->m_pkthdr.len;
2220 1.6.2.2 itohy totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
2221 1.6.2.2 itohy
2222 1.6.2.2 itohy /* Prepend Tx descriptor */
2223 1.6.2.2 itohy M_PREPEND(m0, sizeof(struct zyd_tx_desc), M_DONTWAIT);
2224 1.6.2.2 itohy if (m0 != NULL)
2225 1.6.2.2 itohy m0 = m_pullup(m0, sizeof(struct zyd_tx_desc));/* just in case */
2226 1.6.2.2 itohy if (m0 == NULL) {
2227 1.6.2.2 itohy return ENOBUFS;
2228 1.6.2.2 itohy }
2229 1.6.2.2 itohy desc = mtod(m0, struct zyd_tx_desc *);
2230 1.6.2.2 itohy
2231 1.6.2.2 itohy /* fill Tx descriptor */
2232 1.6.2.2 itohy USETW((uint8_t *)&desc->len, totlen);
2233 1.6.2.2 itohy
2234 1.6.2.2 itohy desc->flags = ZYD_TX_FLAG_BACKOFF;
2235 1.6.2.2 itohy if (!IEEE80211_IS_MULTICAST(i_addr1)) {
2236 1.6.2.2 itohy /* multicast frames are not sent at OFDM rates in 802.11b/g */
2237 1.6.2.2 itohy if (totlen > ic->ic_rtsthreshold) {
2238 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_RTS;
2239 1.6.2.2 itohy } else if (ZYD_RATE_IS_OFDM(rate) &&
2240 1.6.2.2 itohy (ic->ic_flags & IEEE80211_F_USEPROT)) {
2241 1.6.2.2 itohy if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2242 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
2243 1.6.2.2 itohy else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2244 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_RTS;
2245 1.6.2.2 itohy }
2246 1.6.2.2 itohy } else
2247 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_MULTICAST;
2248 1.6.2.2 itohy
2249 1.6.2.2 itohy if ((i_fc_0 &
2250 1.6.2.2 itohy (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
2251 1.6.2.2 itohy (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
2252 1.6.2.2 itohy desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
2253 1.6.2.2 itohy
2254 1.6.2.2 itohy desc->phy = zyd_plcp_signal(rate);
2255 1.6.2.2 itohy if (ZYD_RATE_IS_OFDM(rate)) {
2256 1.6.2.2 itohy desc->phy |= ZYD_TX_PHY_OFDM;
2257 1.6.2.2 itohy if (ic->ic_curmode == IEEE80211_MODE_11A)
2258 1.6.2.2 itohy desc->phy |= ZYD_TX_PHY_5GHZ;
2259 1.6.2.2 itohy } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
2260 1.6.2.2 itohy desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
2261 1.6.2.2 itohy
2262 1.6.2.2 itohy /* actual transmit length (XXX why +10?) */
2263 1.6.2.2 itohy pktlen = sizeof (struct zyd_tx_desc) + 10;
2264 1.6.2.2 itohy if (sc->mac_rev == ZYD_ZD1211)
2265 1.6.2.2 itohy pktlen += totlen;
2266 1.6.2.2 itohy USETW((uint8_t *)&desc->pktlen, pktlen);
2267 1.6.2.2 itohy
2268 1.6.2.2 itohy USETW((uint8_t *)&desc->plcp_length, (16 * totlen + rate - 1) / rate);
2269 1.6.2.2 itohy desc->plcp_service = 0;
2270 1.6.2.2 itohy if (rate == 22) {
2271 1.6.2.2 itohy const int remainder = (16 * totlen) % 22;
2272 1.6.2.2 itohy if (remainder != 0 && remainder < 7)
2273 1.6.2.2 itohy desc->plcp_service |= ZYD_PLCP_LENGEXT;
2274 1.6.2.2 itohy }
2275 1.6.2.2 itohy
2276 1.6.2.2 itohy #if NBPFILTER > 0
2277 1.6.2.2 itohy if (sc->sc_drvbpf != NULL) {
2278 1.6.2.2 itohy struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
2279 1.6.2.2 itohy
2280 1.6.2.2 itohy tap->wt_flags = 0;
2281 1.6.2.2 itohy tap->wt_rate = rate;
2282 1.6.2.2 itohy tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
2283 1.6.2.2 itohy tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
2284 1.6.2.2 itohy
2285 1.6.2.2 itohy bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
2286 1.6.2.2 itohy }
2287 1.6.2.2 itohy #endif
2288 1.6.2.2 itohy
2289 1.6.2.2 itohy DPRINTFN(10, ("%s: sending data frame len=%zu rate=%u xferlen=%u\n",
2290 1.6.2.2 itohy USBDEVNAME(sc->sc_dev), (size_t)m0->m_pkthdr.len, rate, xferlen));
2291 1.6.2.2 itohy
2292 1.6.2.2 itohy ret = usb_ether_map_tx_buffer_mbuf(data, m0);
2293 1.6.2.2 itohy if (ret) {
2294 1.6.2.2 itohy m_freem(m0);
2295 1.6.2.2 itohy return ret;
2296 1.6.2.2 itohy }
2297 1.6.2.2 itohy
2298 1.6.2.2 itohy usbd_setup_xfer(data->ue_xfer, sc->zyd_ep[ZYD_ENDPT_BOUT], data,
2299 1.6.2.2 itohy NULL /* XXX buf */, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
2300 1.6.2.2 itohy ZYD_TX_TIMEOUT, zyd_txeof);
2301 1.6.2.2 itohy error = usbd_transfer(data->ue_xfer);
2302 1.6.2.2 itohy if (error != USBD_IN_PROGRESS && error != 0) {
2303 1.6.2.2 itohy data->ue_mbuf = NULL;
2304 1.6.2.2 itohy m_freem(m0);
2305 1.6.2.2 itohy ifp->if_oerrors++;
2306 1.6.2.2 itohy return EIO;
2307 1.6.2.2 itohy }
2308 1.6.2.2 itohy sc->tx_queued++;
2309 1.6.2.2 itohy
2310 1.6.2.2 itohy return 0;
2311 1.6.2.2 itohy }
2312 1.6.2.2 itohy
2313 1.6.2.2 itohy Static void
2314 1.6.2.2 itohy zyd_start(struct ifnet *ifp)
2315 1.6.2.2 itohy {
2316 1.6.2.2 itohy struct zyd_softc *sc = ifp->if_softc;
2317 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
2318 1.6.2.2 itohy struct ether_header *eh;
2319 1.6.2.2 itohy struct ieee80211_node *ni;
2320 1.6.2.2 itohy struct mbuf *m0;
2321 1.6.2.2 itohy
2322 1.6.2.2 itohy for (;;) {
2323 1.6.2.2 itohy IF_POLL(&ic->ic_mgtq, m0);
2324 1.6.2.2 itohy if (m0 != NULL) {
2325 1.6.2.2 itohy if (sc->tx_queued >= ZYD_TX_LIST_CNT) {
2326 1.6.2.2 itohy ifp->if_flags |= IFF_OACTIVE;
2327 1.6.2.2 itohy break;
2328 1.6.2.2 itohy }
2329 1.6.2.2 itohy IF_DEQUEUE(&ic->ic_mgtq, m0);
2330 1.6.2.2 itohy
2331 1.6.2.2 itohy ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
2332 1.6.2.2 itohy m0->m_pkthdr.rcvif = NULL;
2333 1.6.2.2 itohy #if NBPFILTER > 0
2334 1.6.2.2 itohy if (ic->ic_rawbpf != NULL)
2335 1.6.2.2 itohy bpf_mtap(ic->ic_rawbpf, m0);
2336 1.6.2.2 itohy #endif
2337 1.6.2.2 itohy if (zyd_tx_mgt(sc, m0, ni) != 0)
2338 1.6.2.2 itohy break;
2339 1.6.2.2 itohy } else {
2340 1.6.2.2 itohy if (ic->ic_state != IEEE80211_S_RUN)
2341 1.6.2.2 itohy break;
2342 1.6.2.2 itohy IFQ_POLL(&ifp->if_snd, m0);
2343 1.6.2.2 itohy if (m0 == NULL)
2344 1.6.2.2 itohy break;
2345 1.6.2.2 itohy if (sc->tx_queued >= ZYD_TX_LIST_CNT) {
2346 1.6.2.2 itohy ifp->if_flags |= IFF_OACTIVE;
2347 1.6.2.2 itohy break;
2348 1.6.2.2 itohy }
2349 1.6.2.2 itohy IFQ_DEQUEUE(&ifp->if_snd, m0);
2350 1.6.2.2 itohy
2351 1.6.2.2 itohy if (m0->m_len < sizeof(struct ether_header) &&
2352 1.6.2.2 itohy !(m0 = m_pullup(m0, sizeof(struct ether_header))))
2353 1.6.2.2 itohy continue;
2354 1.6.2.2 itohy
2355 1.6.2.2 itohy eh = mtod(m0, struct ether_header *);
2356 1.6.2.2 itohy ni = ieee80211_find_txnode(ic, eh->ether_dhost);
2357 1.6.2.2 itohy if (ni == NULL) {
2358 1.6.2.2 itohy m_freem(m0);
2359 1.6.2.2 itohy continue;
2360 1.6.2.2 itohy }
2361 1.6.2.2 itohy #if NBPFILTER > 0
2362 1.6.2.2 itohy if (ifp->if_bpf != NULL)
2363 1.6.2.2 itohy bpf_mtap(ifp->if_bpf, m0);
2364 1.6.2.2 itohy #endif
2365 1.6.2.2 itohy if ((m0 = ieee80211_encap(ic, m0, ni)) == NULL) {
2366 1.6.2.2 itohy ieee80211_free_node(ni);
2367 1.6.2.2 itohy ifp->if_oerrors++;
2368 1.6.2.2 itohy continue;
2369 1.6.2.2 itohy }
2370 1.6.2.2 itohy #if NBPFILTER > 0
2371 1.6.2.2 itohy if (ic->ic_rawbpf != NULL)
2372 1.6.2.2 itohy bpf_mtap(ic->ic_rawbpf, m0);
2373 1.6.2.2 itohy #endif
2374 1.6.2.2 itohy if (zyd_tx_data(sc, m0, ni) != 0) {
2375 1.6.2.2 itohy ieee80211_free_node(ni);
2376 1.6.2.2 itohy ifp->if_oerrors++;
2377 1.6.2.2 itohy break;
2378 1.6.2.2 itohy }
2379 1.6.2.2 itohy }
2380 1.6.2.2 itohy
2381 1.6.2.2 itohy sc->tx_timer = 5;
2382 1.6.2.2 itohy ifp->if_timer = 1;
2383 1.6.2.2 itohy }
2384 1.6.2.2 itohy }
2385 1.6.2.2 itohy
2386 1.6.2.2 itohy Static void
2387 1.6.2.2 itohy zyd_watchdog(struct ifnet *ifp)
2388 1.6.2.2 itohy {
2389 1.6.2.2 itohy struct zyd_softc *sc = ifp->if_softc;
2390 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
2391 1.6.2.2 itohy
2392 1.6.2.2 itohy ifp->if_timer = 0;
2393 1.6.2.2 itohy
2394 1.6.2.2 itohy if (sc->tx_timer > 0) {
2395 1.6.2.2 itohy if (--sc->tx_timer == 0) {
2396 1.6.2.2 itohy printf("%s: device timeout\n", USBDEVNAME(sc->sc_dev));
2397 1.6.2.2 itohy /* zyd_init(ifp); XXX needs a process context ? */
2398 1.6.2.2 itohy ifp->if_oerrors++;
2399 1.6.2.2 itohy return;
2400 1.6.2.2 itohy }
2401 1.6.2.2 itohy ifp->if_timer = 1;
2402 1.6.2.2 itohy }
2403 1.6.2.2 itohy
2404 1.6.2.2 itohy ieee80211_watchdog(ic);
2405 1.6.2.2 itohy }
2406 1.6.2.2 itohy
2407 1.6.2.2 itohy Static int
2408 1.6.2.2 itohy zyd_ioctl(struct ifnet *ifp, u_long cmd, usb_ioctlarg_t data)
2409 1.6.2.2 itohy {
2410 1.6.2.2 itohy struct zyd_softc *sc = ifp->if_softc;
2411 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
2412 1.6.2.2 itohy int s, error = 0;
2413 1.6.2.2 itohy
2414 1.6.2.2 itohy s = splnet();
2415 1.6.2.2 itohy
2416 1.6.2.2 itohy switch (cmd) {
2417 1.6.2.2 itohy case SIOCSIFFLAGS:
2418 1.6.2.2 itohy if (ifp->if_flags & IFF_UP) {
2419 1.6.2.2 itohy if (!(ifp->if_flags & IFF_RUNNING))
2420 1.6.2.2 itohy zyd_init(ifp);
2421 1.6.2.2 itohy } else {
2422 1.6.2.2 itohy if (ifp->if_flags & IFF_RUNNING)
2423 1.6.2.2 itohy zyd_stop(ifp, 1);
2424 1.6.2.2 itohy }
2425 1.6.2.2 itohy break;
2426 1.6.2.2 itohy
2427 1.6.2.2 itohy default:
2428 1.6.2.2 itohy if (!sc->attached)
2429 1.6.2.2 itohy error = ENOTTY;
2430 1.6.2.2 itohy else
2431 1.6.2.2 itohy error = ieee80211_ioctl(ic, cmd, data);
2432 1.6.2.2 itohy }
2433 1.6.2.2 itohy
2434 1.6.2.2 itohy if (error == ENETRESET) {
2435 1.6.2.2 itohy if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) ==
2436 1.6.2.2 itohy (IFF_RUNNING | IFF_UP))
2437 1.6.2.2 itohy zyd_init(ifp);
2438 1.6.2.2 itohy error = 0;
2439 1.6.2.2 itohy }
2440 1.6.2.2 itohy
2441 1.6.2.2 itohy splx(s);
2442 1.6.2.2 itohy
2443 1.6.2.2 itohy return error;
2444 1.6.2.2 itohy }
2445 1.6.2.2 itohy
2446 1.6.2.2 itohy Static int
2447 1.6.2.2 itohy zyd_init(struct ifnet *ifp)
2448 1.6.2.2 itohy {
2449 1.6.2.2 itohy struct zyd_softc *sc = ifp->if_softc;
2450 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
2451 1.6.2.2 itohy int i, error;
2452 1.6.2.2 itohy
2453 1.6.2.2 itohy if ((sc->sc_flags & ZD1211_FWLOADED) == 0)
2454 1.6.2.2 itohy if ((error = zyd_attachhook(sc)) != 0)
2455 1.6.2.2 itohy return error;
2456 1.6.2.2 itohy
2457 1.6.2.2 itohy zyd_stop(ifp, 0);
2458 1.6.2.2 itohy
2459 1.6.2.2 itohy IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
2460 1.6.2.2 itohy DPRINTF(("setting MAC address to %s\n", ether_sprintf(ic->ic_myaddr)));
2461 1.6.2.2 itohy error = zyd_set_macaddr(sc, ic->ic_myaddr);
2462 1.6.2.2 itohy if (error != 0)
2463 1.6.2.2 itohy return error;
2464 1.6.2.2 itohy
2465 1.6.2.2 itohy /* we'll do software WEP decryption for now */
2466 1.6.2.2 itohy DPRINTF(("setting encryption type\n"));
2467 1.6.2.2 itohy error = zyd_write32(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER);
2468 1.6.2.2 itohy if (error != 0)
2469 1.6.2.2 itohy return error;
2470 1.6.2.2 itohy
2471 1.6.2.2 itohy /* promiscuous mode */
2472 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_SNIFFER,
2473 1.6.2.2 itohy (ic->ic_opmode == IEEE80211_M_MONITOR) ? 1 : 0);
2474 1.6.2.2 itohy
2475 1.6.2.2 itohy (void)zyd_set_rxfilter(sc);
2476 1.6.2.2 itohy
2477 1.6.2.2 itohy /* switch radio transmitter ON */
2478 1.6.2.2 itohy (void)zyd_switch_radio(sc, 1);
2479 1.6.2.2 itohy
2480 1.6.2.2 itohy /* set basic rates */
2481 1.6.2.2 itohy if (ic->ic_curmode == IEEE80211_MODE_11B)
2482 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x0003);
2483 1.6.2.2 itohy else if (ic->ic_curmode == IEEE80211_MODE_11A)
2484 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x1500);
2485 1.6.2.2 itohy else /* assumes 802.11b/g */
2486 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x000f);
2487 1.6.2.2 itohy
2488 1.6.2.2 itohy /* set mandatory rates */
2489 1.6.2.2 itohy if (ic->ic_curmode == IEEE80211_MODE_11B)
2490 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x000f);
2491 1.6.2.2 itohy else if (ic->ic_curmode == IEEE80211_MODE_11A)
2492 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x1500);
2493 1.6.2.2 itohy else /* assumes 802.11b/g */
2494 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x150f);
2495 1.6.2.2 itohy
2496 1.6.2.2 itohy /* set default BSS channel */
2497 1.6.2.2 itohy ic->ic_bss->ni_chan = ic->ic_ibss_chan;
2498 1.6.2.2 itohy zyd_set_chan(sc, ic->ic_bss->ni_chan);
2499 1.6.2.2 itohy
2500 1.6.2.2 itohy /* enable interrupts */
2501 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
2502 1.6.2.2 itohy
2503 1.6.2.2 itohy /*
2504 1.6.2.2 itohy * Allocate Tx and Rx xfer queues.
2505 1.6.2.2 itohy */
2506 1.6.2.2 itohy sc->tx_queued = 0;
2507 1.6.2.2 itohy if ((error = usb_ether_tx_list_init(USBDEV(sc->sc_dev),
2508 1.6.2.2 itohy sc->tx_data, ZYD_TX_LIST_CNT,
2509 1.6.2.2 itohy sc->sc_udev, sc->zyd_ep[ZYD_ENDPT_BOUT], NULL)) != 0) {
2510 1.6.2.2 itohy printf("%s: could not allocate Tx list\n",
2511 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
2512 1.6.2.2 itohy goto fail;
2513 1.6.2.2 itohy }
2514 1.6.2.2 itohy if ((error = usb_ether_rx_list_init(USBDEV(sc->sc_dev),
2515 1.6.2.2 itohy sc->rx_data, ZYD_RX_LIST_CNT,
2516 1.6.2.2 itohy sc->sc_udev, sc->zyd_ep[ZYD_ENDPT_BIN])) != 0) {
2517 1.6.2.2 itohy printf("%s: could not allocate Rx list\n",
2518 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
2519 1.6.2.2 itohy goto fail;
2520 1.6.2.2 itohy }
2521 1.6.2.2 itohy
2522 1.6.2.2 itohy /*
2523 1.6.2.2 itohy * Start up the receive pipe.
2524 1.6.2.2 itohy */
2525 1.6.2.2 itohy for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
2526 1.6.2.2 itohy struct ue_chain *data = &sc->rx_data[i];
2527 1.6.2.2 itohy
2528 1.6.2.2 itohy (void)usbd_map_buffer_mbuf(data->ue_xfer, data->ue_mbuf);
2529 1.6.2.2 itohy usbd_setup_xfer(data->ue_xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data,
2530 1.6.2.2 itohy NULL, ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK,
2531 1.6.2.2 itohy USBD_NO_TIMEOUT, zyd_rxeof);
2532 1.6.2.2 itohy error = usbd_transfer(data->ue_xfer);
2533 1.6.2.2 itohy if (error != USBD_IN_PROGRESS && error != 0) {
2534 1.6.2.2 itohy printf("%s: could not queue Rx transfer\n",
2535 1.6.2.2 itohy USBDEVNAME(sc->sc_dev));
2536 1.6.2.2 itohy goto fail;
2537 1.6.2.2 itohy }
2538 1.6.2.2 itohy }
2539 1.6.2.2 itohy
2540 1.6.2.2 itohy ifp->if_flags &= ~IFF_OACTIVE;
2541 1.6.2.2 itohy ifp->if_flags |= IFF_RUNNING;
2542 1.6.2.2 itohy
2543 1.6.2.2 itohy if (ic->ic_opmode == IEEE80211_M_MONITOR)
2544 1.6.2.2 itohy ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2545 1.6.2.2 itohy else
2546 1.6.2.2 itohy ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2547 1.6.2.2 itohy
2548 1.6.2.2 itohy return 0;
2549 1.6.2.2 itohy
2550 1.6.2.2 itohy fail: zyd_stop(ifp, 1);
2551 1.6.2.2 itohy return error;
2552 1.6.2.2 itohy }
2553 1.6.2.2 itohy
2554 1.6.2.2 itohy Static void
2555 1.6.2.2 itohy zyd_stop(struct ifnet *ifp, int disable)
2556 1.6.2.2 itohy {
2557 1.6.2.2 itohy struct zyd_softc *sc = ifp->if_softc;
2558 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
2559 1.6.2.2 itohy
2560 1.6.2.2 itohy ieee80211_new_state(ic, IEEE80211_S_INIT, -1); /* free all nodes */
2561 1.6.2.2 itohy
2562 1.6.2.2 itohy sc->tx_timer = 0;
2563 1.6.2.2 itohy ifp->if_timer = 0;
2564 1.6.2.2 itohy ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2565 1.6.2.2 itohy
2566 1.6.2.2 itohy /* switch radio transmitter OFF */
2567 1.6.2.2 itohy (void)zyd_switch_radio(sc, 0);
2568 1.6.2.2 itohy
2569 1.6.2.2 itohy /* disable Rx */
2570 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_MAC_RXFILTER, 0);
2571 1.6.2.2 itohy
2572 1.6.2.2 itohy /* disable interrupts */
2573 1.6.2.2 itohy (void)zyd_write32(sc, ZYD_CR_INTERRUPT, 0);
2574 1.6.2.2 itohy
2575 1.6.2.2 itohy usbd_abort_pipe(sc->zyd_ep[ZYD_ENDPT_BIN]);
2576 1.6.2.2 itohy usbd_abort_pipe(sc->zyd_ep[ZYD_ENDPT_BOUT]);
2577 1.6.2.2 itohy
2578 1.6.2.2 itohy zyd_free_rx_list(sc);
2579 1.6.2.2 itohy zyd_free_tx_list(sc);
2580 1.6.2.2 itohy }
2581 1.6.2.2 itohy
2582 1.6.2.2 itohy Static int
2583 1.6.2.2 itohy zyd_loadfirmware(struct zyd_softc *sc, u_char *fw, size_t size)
2584 1.6.2.2 itohy {
2585 1.6.2.2 itohy usb_device_request_t req;
2586 1.6.2.2 itohy uint16_t addr;
2587 1.6.2.2 itohy uint8_t stat;
2588 1.6.2.2 itohy
2589 1.6.2.2 itohy DPRINTF(("firmware size=%zu\n", size));
2590 1.6.2.2 itohy
2591 1.6.2.2 itohy req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2592 1.6.2.2 itohy req.bRequest = ZYD_DOWNLOADREQ;
2593 1.6.2.2 itohy USETW(req.wIndex, 0);
2594 1.6.2.2 itohy
2595 1.6.2.2 itohy addr = ZYD_FIRMWARE_START_ADDR;
2596 1.6.2.2 itohy while (size > 0) {
2597 1.6.2.2 itohy #if 0
2598 1.6.2.2 itohy const int mlen = min(size, 4096);
2599 1.6.2.2 itohy #else
2600 1.6.2.2 itohy /*
2601 1.6.2.2 itohy * XXXX: When the transfer size is 4096 bytes, it is not
2602 1.6.2.2 itohy * likely to be able to transfer it.
2603 1.6.2.2 itohy * The cause is port or machine or chip?
2604 1.6.2.2 itohy */
2605 1.6.2.2 itohy const int mlen = min(size, 64);
2606 1.6.2.2 itohy #endif
2607 1.6.2.2 itohy
2608 1.6.2.2 itohy DPRINTF(("loading firmware block: len=%d, addr=0x%x\n", mlen,
2609 1.6.2.2 itohy addr));
2610 1.6.2.2 itohy
2611 1.6.2.2 itohy USETW(req.wValue, addr);
2612 1.6.2.2 itohy USETW(req.wLength, mlen);
2613 1.6.2.2 itohy if (usbd_do_request(sc->sc_udev, &req, fw) != 0)
2614 1.6.2.2 itohy return EIO;
2615 1.6.2.2 itohy
2616 1.6.2.2 itohy addr += mlen / 2;
2617 1.6.2.2 itohy fw += mlen;
2618 1.6.2.2 itohy size -= mlen;
2619 1.6.2.2 itohy }
2620 1.6.2.2 itohy
2621 1.6.2.2 itohy /* check whether the upload succeeded */
2622 1.6.2.2 itohy req.bmRequestType = UT_READ_VENDOR_DEVICE;
2623 1.6.2.2 itohy req.bRequest = ZYD_DOWNLOADSTS;
2624 1.6.2.2 itohy USETW(req.wValue, 0);
2625 1.6.2.2 itohy USETW(req.wIndex, 0);
2626 1.6.2.2 itohy USETW(req.wLength, sizeof stat);
2627 1.6.2.2 itohy if (usbd_do_request(sc->sc_udev, &req, &stat) != 0)
2628 1.6.2.2 itohy return EIO;
2629 1.6.2.2 itohy
2630 1.6.2.2 itohy return (stat & 0x80) ? EIO : 0;
2631 1.6.2.2 itohy }
2632 1.6.2.2 itohy
2633 1.6.2.2 itohy Static void
2634 1.6.2.2 itohy zyd_iter_func(void *arg, struct ieee80211_node *ni)
2635 1.6.2.2 itohy {
2636 1.6.2.2 itohy struct zyd_softc *sc = arg;
2637 1.6.2.2 itohy struct zyd_node *zn = (struct zyd_node *)ni;
2638 1.6.2.2 itohy
2639 1.6.2.2 itohy ieee80211_amrr_choose(&sc->amrr, ni, &zn->amn);
2640 1.6.2.2 itohy }
2641 1.6.2.2 itohy
2642 1.6.2.2 itohy Static void
2643 1.6.2.2 itohy zyd_amrr_timeout(void *arg)
2644 1.6.2.2 itohy {
2645 1.6.2.2 itohy struct zyd_softc *sc = arg;
2646 1.6.2.2 itohy struct ieee80211com *ic = &sc->sc_ic;
2647 1.6.2.2 itohy int s;
2648 1.6.2.2 itohy
2649 1.6.2.2 itohy s = splnet();
2650 1.6.2.2 itohy if (ic->ic_opmode == IEEE80211_M_STA)
2651 1.6.2.2 itohy zyd_iter_func(sc, ic->ic_bss);
2652 1.6.2.2 itohy else
2653 1.6.2.2 itohy ieee80211_iterate_nodes(&ic->ic_sta, zyd_iter_func, sc);
2654 1.6.2.2 itohy splx(s);
2655 1.6.2.2 itohy
2656 1.6.2.2 itohy usb_callout(sc->sc_amrr_ch, hz, zyd_amrr_timeout, sc);
2657 1.6.2.2 itohy }
2658 1.6.2.2 itohy
2659 1.6.2.2 itohy Static void
2660 1.6.2.2 itohy zyd_newassoc(struct ieee80211_node *ni, int isnew)
2661 1.6.2.2 itohy {
2662 1.6.2.2 itohy struct zyd_softc *sc = ni->ni_ic->ic_ifp->if_softc;
2663 1.6.2.2 itohy int i;
2664 1.6.2.2 itohy
2665 1.6.2.2 itohy ieee80211_amrr_node_init(&sc->amrr, &((struct zyd_node *)ni)->amn);
2666 1.6.2.2 itohy
2667 1.6.2.2 itohy /* set rate to some reasonable initial value */
2668 1.6.2.2 itohy for (i = ni->ni_rates.rs_nrates - 1;
2669 1.6.2.2 itohy i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
2670 1.6.2.2 itohy i--);
2671 1.6.2.2 itohy ni->ni_txrate = i;
2672 1.6.2.2 itohy }
2673 1.6.2.2 itohy
2674 1.6.2.2 itohy int
2675 1.6.2.2 itohy zyd_activate(device_ptr_t self, enum devact act)
2676 1.6.2.2 itohy {
2677 1.6.2.2 itohy struct zyd_softc *sc = (struct zyd_softc *)self;
2678 1.6.2.2 itohy
2679 1.6.2.2 itohy switch (act) {
2680 1.6.2.2 itohy case DVACT_ACTIVATE:
2681 1.6.2.2 itohy break;
2682 1.6.2.2 itohy
2683 1.6.2.2 itohy case DVACT_DEACTIVATE:
2684 1.6.2.2 itohy if_deactivate(&sc->sc_if);
2685 1.6.2.2 itohy break;
2686 1.6.2.2 itohy }
2687 1.6.2.2 itohy return 0;
2688 1.6.2.2 itohy }
2689