1 /* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */
2 /* $NetBSD: if_zyd.c,v 1.22 2009/09/23 19:07:19 plunky Exp $ */
5 * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
6 * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de>
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * ZyDAS ZD1211/ZD1211B USB WLAN driver.
24 #include <sys/cdefs.h>
25 __KERNEL_RCSID(0, "$NetBSD: if_zyd.c,v 1.22 2009/09/23 19:07:19 plunky Exp $");
29 #include <sys/param.h>
30 #include <sys/sockio.h>
33 #include <sys/kernel.h>
34 #include <sys/socket.h>
35 #include <sys/systm.h>
36 #include <sys/malloc.h>
38 #include <sys/device.h>
41 #include <machine/endian.h>
47 #include <net/if_arp.h>
48 #include <net/if_dl.h>
49 #include <net/if_ether.h>
50 #include <net/if_media.h>
51 #include <net/if_types.h>
53 #include <netinet/in.h>
54 #include <netinet/in_systm.h>
55 #include <netinet/in_var.h>
56 #include <netinet/ip.h>
58 #include <net80211/ieee80211_netbsd.h>
59 #include <net80211/ieee80211_var.h>
60 #include <net80211/ieee80211_amrr.h>
61 #include <net80211/ieee80211_radiotap.h>
63 #include <dev/firmload.h>
65 #include <dev/usb/usb.h>
66 #include <dev/usb/usbdi.h>
67 #include <dev/usb/usbdi_util.h>
68 #include <dev/usb/usbdevs.h>
70 #include <dev/usb/if_zydreg.h>
77 #define DPRINTF(x) do { if (zyddebug > 0) printf x; } while (0)
78 #define DPRINTFN(n, x) do { if (zyddebug > (n)) printf x; } while (0)
82 #define DPRINTFN(n, x)
85 static const struct zyd_phy_pair zyd_def_phy
[] = ZYD_DEF_PHY
;
86 static const struct zyd_phy_pair zyd_def_phyB
[] = ZYD_DEF_PHYB
;
88 /* various supported device vendors/products */
89 #define ZYD_ZD1211_DEV(v, p) \
90 { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211 }
91 #define ZYD_ZD1211B_DEV(v, p) \
92 { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211B }
93 static const struct zyd_type
{
99 ZYD_ZD1211_DEV(3COM2
, 3CRUSB10075
),
100 ZYD_ZD1211_DEV(ABOCOM
, WL54
),
101 ZYD_ZD1211_DEV(ASUSTEK
, WL159G
),
102 ZYD_ZD1211_DEV(CYBERTAN
, TG54USB
),
103 ZYD_ZD1211_DEV(DRAYTEK
, VIGOR550
),
104 ZYD_ZD1211_DEV(PLANEX2
, GWUS54GZL
),
105 ZYD_ZD1211_DEV(PLANEX3
, GWUS54GZ
),
106 ZYD_ZD1211_DEV(PLANEX3
, GWUS54MINI
),
107 ZYD_ZD1211_DEV(SAGEM
, XG760A
),
108 ZYD_ZD1211_DEV(SENAO
, NUB8301
),
109 ZYD_ZD1211_DEV(SITECOMEU
, WL113
),
110 ZYD_ZD1211_DEV(SWEEX
, ZD1211
),
111 ZYD_ZD1211_DEV(TEKRAM
, QUICKWLAN
),
112 ZYD_ZD1211_DEV(TEKRAM
, ZD1211_1
),
113 ZYD_ZD1211_DEV(TEKRAM
, ZD1211_2
),
114 ZYD_ZD1211_DEV(TWINMOS
, G240
),
115 ZYD_ZD1211_DEV(UMEDIA
, ALL0298V2
),
116 ZYD_ZD1211_DEV(UMEDIA
, TEW429UB_A
),
117 ZYD_ZD1211_DEV(UMEDIA
, TEW429UB
),
118 ZYD_ZD1211_DEV(WISTRONNEWEB
, UR055G
),
119 ZYD_ZD1211_DEV(ZCOM
, ZD1211
),
120 ZYD_ZD1211_DEV(ZYDAS
, ZD1211
),
121 ZYD_ZD1211_DEV(ZYXEL
, AG225H
),
122 ZYD_ZD1211_DEV(ZYXEL
, ZYAIRG220
),
124 ZYD_ZD1211B_DEV(ACCTON
, SMCWUSBG
),
125 ZYD_ZD1211B_DEV(ACCTON
, ZD1211B
),
126 ZYD_ZD1211B_DEV(ASUSTEK
, A9T_WIFI
),
127 ZYD_ZD1211B_DEV(BELKIN
, F5D7050C
),
128 ZYD_ZD1211B_DEV(BELKIN
, ZD1211B
),
129 ZYD_ZD1211B_DEV(CISCOLINKSYS
, WUSBF54G
),
130 ZYD_ZD1211B_DEV(FIBERLINE
, WL430U
),
131 ZYD_ZD1211B_DEV(MELCO
, KG54L
),
132 ZYD_ZD1211B_DEV(PHILIPS
, SNU5600
),
133 ZYD_ZD1211B_DEV(SAGEM
, XG76NA
),
134 ZYD_ZD1211B_DEV(SITECOMEU
, ZD1211B
),
135 ZYD_ZD1211B_DEV(UMEDIA
, TEW429UBC1
),
136 #if 0 /* Shall we needs? */
137 ZYD_ZD1211B_DEV(UNKNOWN1
, ZD1211B_1
),
138 ZYD_ZD1211B_DEV(UNKNOWN1
, ZD1211B_2
),
139 ZYD_ZD1211B_DEV(UNKNOWN2
, ZD1211B
),
140 ZYD_ZD1211B_DEV(UNKNOWN3
, ZD1211B
),
142 ZYD_ZD1211B_DEV(USR
, USR5423
),
143 ZYD_ZD1211B_DEV(VTECH
, ZD1211B
),
144 ZYD_ZD1211B_DEV(ZCOM
, ZD1211B
),
145 ZYD_ZD1211B_DEV(ZYDAS
, ZD1211B
),
146 ZYD_ZD1211B_DEV(ZYXEL
, M202
),
147 ZYD_ZD1211B_DEV(ZYXEL
, G220V2
),
148 ZYD_ZD1211B_DEV(PLANEX2
, GWUS54GXS
),
150 #define zyd_lookup(v, p) \
151 ((const struct zyd_type *)usb_lookup(zyd_devs, v, p))
153 int zyd_match(device_t
, cfdata_t
, void *);
154 void zyd_attach(device_t
, device_t
, void *);
155 int zyd_detach(device_t
, int);
156 int zyd_activate(device_t
, enum devact
);
157 extern struct cfdriver zyd_cd
;
159 CFATTACH_DECL_NEW(zyd
, sizeof(struct zyd_softc
), zyd_match
,
160 zyd_attach
, zyd_detach
, zyd_activate
);
162 Static
int zyd_attachhook(void *);
163 Static
int zyd_complete_attach(struct zyd_softc
*);
164 Static
int zyd_open_pipes(struct zyd_softc
*);
165 Static
void zyd_close_pipes(struct zyd_softc
*);
166 Static
int zyd_alloc_tx_list(struct zyd_softc
*);
167 Static
void zyd_free_tx_list(struct zyd_softc
*);
168 Static
int zyd_alloc_rx_list(struct zyd_softc
*);
169 Static
void zyd_free_rx_list(struct zyd_softc
*);
170 Static
struct ieee80211_node
*zyd_node_alloc(struct ieee80211_node_table
*);
171 Static
int zyd_media_change(struct ifnet
*);
172 Static
void zyd_next_scan(void *);
173 Static
void zyd_task(void *);
174 Static
int zyd_newstate(struct ieee80211com
*, enum ieee80211_state
, int);
175 Static
int zyd_cmd(struct zyd_softc
*, uint16_t, const void *, int,
177 Static
int zyd_read16(struct zyd_softc
*, uint16_t, uint16_t *);
178 Static
int zyd_read32(struct zyd_softc
*, uint16_t, uint32_t *);
179 Static
int zyd_write16(struct zyd_softc
*, uint16_t, uint16_t);
180 Static
int zyd_write32(struct zyd_softc
*, uint16_t, uint32_t);
181 Static
int zyd_rfwrite(struct zyd_softc
*, uint32_t);
182 Static
void zyd_lock_phy(struct zyd_softc
*);
183 Static
void zyd_unlock_phy(struct zyd_softc
*);
184 Static
int zyd_rfmd_init(struct zyd_rf
*);
185 Static
int zyd_rfmd_switch_radio(struct zyd_rf
*, int);
186 Static
int zyd_rfmd_set_channel(struct zyd_rf
*, uint8_t);
187 Static
int zyd_al2230_init(struct zyd_rf
*);
188 Static
int zyd_al2230_switch_radio(struct zyd_rf
*, int);
189 Static
int zyd_al2230_set_channel(struct zyd_rf
*, uint8_t);
190 Static
int zyd_al2230_init_b(struct zyd_rf
*);
191 Static
int zyd_al7230B_init(struct zyd_rf
*);
192 Static
int zyd_al7230B_switch_radio(struct zyd_rf
*, int);
193 Static
int zyd_al7230B_set_channel(struct zyd_rf
*, uint8_t);
194 Static
int zyd_al2210_init(struct zyd_rf
*);
195 Static
int zyd_al2210_switch_radio(struct zyd_rf
*, int);
196 Static
int zyd_al2210_set_channel(struct zyd_rf
*, uint8_t);
197 Static
int zyd_gct_init(struct zyd_rf
*);
198 Static
int zyd_gct_switch_radio(struct zyd_rf
*, int);
199 Static
int zyd_gct_set_channel(struct zyd_rf
*, uint8_t);
200 Static
int zyd_maxim_init(struct zyd_rf
*);
201 Static
int zyd_maxim_switch_radio(struct zyd_rf
*, int);
202 Static
int zyd_maxim_set_channel(struct zyd_rf
*, uint8_t);
203 Static
int zyd_maxim2_init(struct zyd_rf
*);
204 Static
int zyd_maxim2_switch_radio(struct zyd_rf
*, int);
205 Static
int zyd_maxim2_set_channel(struct zyd_rf
*, uint8_t);
206 Static
int zyd_rf_attach(struct zyd_softc
*, uint8_t);
207 Static
const char *zyd_rf_name(uint8_t);
208 Static
int zyd_hw_init(struct zyd_softc
*);
209 Static
int zyd_read_eeprom(struct zyd_softc
*);
210 Static
int zyd_set_macaddr(struct zyd_softc
*, const uint8_t *);
211 Static
int zyd_set_bssid(struct zyd_softc
*, const uint8_t *);
212 Static
int zyd_switch_radio(struct zyd_softc
*, int);
213 Static
void zyd_set_led(struct zyd_softc
*, int, int);
214 Static
int zyd_set_rxfilter(struct zyd_softc
*);
215 Static
void zyd_set_chan(struct zyd_softc
*, struct ieee80211_channel
*);
216 Static
int zyd_set_beacon_interval(struct zyd_softc
*, int);
217 Static
uint8_t zyd_plcp_signal(int);
218 Static
void zyd_intr(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
219 Static
void zyd_rx_data(struct zyd_softc
*, const uint8_t *, uint16_t);
220 Static
void zyd_rxeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
221 Static
void zyd_txeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
222 Static
int zyd_tx_mgt(struct zyd_softc
*, struct mbuf
*,
223 struct ieee80211_node
*);
224 Static
int zyd_tx_data(struct zyd_softc
*, struct mbuf
*,
225 struct ieee80211_node
*);
226 Static
void zyd_start(struct ifnet
*);
227 Static
void zyd_watchdog(struct ifnet
*);
228 Static
int zyd_ioctl(struct ifnet
*, u_long
, void *);
229 Static
int zyd_init(struct ifnet
*);
230 Static
void zyd_stop(struct ifnet
*, int);
231 Static
int zyd_loadfirmware(struct zyd_softc
*, u_char
*, size_t);
232 Static
void zyd_iter_func(void *, struct ieee80211_node
*);
233 Static
void zyd_amrr_timeout(void *);
234 Static
void zyd_newassoc(struct ieee80211_node
*, int);
236 static const struct ieee80211_rateset zyd_rateset_11b
=
237 { 4, { 2, 4, 11, 22 } };
239 static const struct ieee80211_rateset zyd_rateset_11g
=
240 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
243 zyd_match(device_t parent
, cfdata_t match
, void *aux
)
245 struct usb_attach_arg
*uaa
= aux
;
247 return (zyd_lookup(uaa
->vendor
, uaa
->product
) != NULL
) ?
248 UMATCH_VENDOR_PRODUCT
: UMATCH_NONE
;
252 zyd_attachhook(void *xsc
)
254 struct zyd_softc
*sc
= xsc
;
255 firmware_handle_t fwh
;
261 fwname
= (sc
->mac_rev
== ZYD_ZD1211
) ? "zyd-zd1211" : "zyd-zd1211b";
262 if ((error
= firmware_open("zyd", fwname
, &fwh
)) != 0) {
263 aprint_error_dev(sc
->sc_dev
,
264 "failed to open firmware %s (error=%d)\n", fwname
, error
);
267 size
= firmware_get_size(fwh
);
268 fw
= firmware_malloc(size
);
270 aprint_error_dev(sc
->sc_dev
,
271 "failed to allocate firmware memory\n");
275 error
= firmware_read(fwh
, 0, fw
, size
);
278 aprint_error_dev(sc
->sc_dev
,
279 "failed to read firmware (error %d)\n", error
);
280 firmware_free(fw
, 0);
284 error
= zyd_loadfirmware(sc
, fw
, size
);
286 aprint_error_dev(sc
->sc_dev
,
287 "could not load firmware (error=%d)\n", error
);
288 firmware_free(fw
, 0);
292 firmware_free(fw
, 0);
293 sc
->sc_flags
|= ZD1211_FWLOADED
;
295 /* complete the attach process */
296 if ((error
= zyd_complete_attach(sc
)) == 0)
302 zyd_attach(device_t parent
, device_t self
, void *aux
)
304 struct zyd_softc
*sc
= device_private(self
);
305 struct usb_attach_arg
*uaa
= aux
;
307 usb_device_descriptor_t
* ddesc
;
308 struct ifnet
*ifp
= &sc
->sc_if
;
311 sc
->sc_udev
= uaa
->device
;
317 devinfop
= usbd_devinfo_alloc(uaa
->device
, 0);
318 aprint_normal_dev(self
, "%s\n", devinfop
);
319 usbd_devinfo_free(devinfop
);
321 sc
->mac_rev
= zyd_lookup(uaa
->vendor
, uaa
->product
)->rev
;
323 ddesc
= usbd_get_device_descriptor(sc
->sc_udev
);
324 if (UGETW(ddesc
->bcdDevice
) < 0x4330) {
325 aprint_error_dev(self
, "device version mismatch: 0x%x "
326 "(only >= 43.30 supported)\n", UGETW(ddesc
->bcdDevice
));
331 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
332 ifp
->if_init
= zyd_init
;
333 ifp
->if_ioctl
= zyd_ioctl
;
334 ifp
->if_start
= zyd_start
;
335 ifp
->if_watchdog
= zyd_watchdog
;
336 IFQ_SET_MAXLEN(&ifp
->if_snd
, IFQ_MAXLEN
);
337 IFQ_SET_READY(&ifp
->if_snd
);
338 memcpy(ifp
->if_xname
, device_xname(sc
->sc_dev
), IFNAMSIZ
);
341 /* XXXX: alloc temporarily until the layer2 can be configured. */
344 SIMPLEQ_INIT(&sc
->sc_rqh
);
350 zyd_complete_attach(struct zyd_softc
*sc
)
352 struct ieee80211com
*ic
= &sc
->sc_ic
;
353 struct ifnet
*ifp
= &sc
->sc_if
;
357 usb_init_task(&sc
->sc_task
, zyd_task
, sc
);
358 callout_init(&(sc
->sc_scan_ch
), 0);
360 sc
->amrr
.amrr_min_success_threshold
= 1;
361 sc
->amrr
.amrr_max_success_threshold
= 10;
362 callout_init(&sc
->sc_amrr_ch
, 0);
364 error
= usbd_set_config_no(sc
->sc_udev
, ZYD_CONFIG_NO
, 1);
366 aprint_error_dev(sc
->sc_dev
, "setting config no failed\n");
370 error
= usbd_device2interface_handle(sc
->sc_udev
, ZYD_IFACE_INDEX
,
373 aprint_error_dev(sc
->sc_dev
,
374 "getting interface handle failed\n");
378 if ((error
= zyd_open_pipes(sc
)) != 0) {
379 aprint_error_dev(sc
->sc_dev
, "could not open pipes\n");
383 if ((error
= zyd_read_eeprom(sc
)) != 0) {
384 aprint_error_dev(sc
->sc_dev
, "could not read EEPROM\n");
388 if ((error
= zyd_rf_attach(sc
, sc
->rf_rev
)) != 0) {
389 aprint_error_dev(sc
->sc_dev
, "could not attach RF\n");
393 if ((error
= zyd_hw_init(sc
)) != 0) {
394 aprint_error_dev(sc
->sc_dev
,
395 "hardware initialization failed\n");
399 aprint_normal_dev(sc
->sc_dev
,
400 "HMAC ZD1211%s, FW %02x.%02x, RF %s, PA %x, address %s\n",
401 (sc
->mac_rev
== ZYD_ZD1211
) ? "": "B",
402 sc
->fw_rev
>> 8, sc
->fw_rev
& 0xff, zyd_rf_name(sc
->rf_rev
),
403 sc
->pa_rev
, ether_sprintf(ic
->ic_myaddr
));
406 ic
->ic_phytype
= IEEE80211_T_OFDM
; /* not only, but not used */
407 ic
->ic_opmode
= IEEE80211_M_STA
; /* default to BSS mode */
408 ic
->ic_state
= IEEE80211_S_INIT
;
410 /* set device capabilities */
412 IEEE80211_C_MONITOR
| /* monitor mode supported */
413 IEEE80211_C_TXPMGT
| /* tx power management */
414 IEEE80211_C_SHPREAMBLE
| /* short preamble supported */
415 IEEE80211_C_WEP
; /* s/w WEP */
417 /* set supported .11b and .11g rates */
418 ic
->ic_sup_rates
[IEEE80211_MODE_11B
] = zyd_rateset_11b
;
419 ic
->ic_sup_rates
[IEEE80211_MODE_11G
] = zyd_rateset_11g
;
421 /* set supported .11b and .11g channels (1 through 14) */
422 for (i
= 1; i
<= 14; i
++) {
423 ic
->ic_channels
[i
].ic_freq
=
424 ieee80211_ieee2mhz(i
, IEEE80211_CHAN_2GHZ
);
425 ic
->ic_channels
[i
].ic_flags
=
426 IEEE80211_CHAN_CCK
| IEEE80211_CHAN_OFDM
|
427 IEEE80211_CHAN_DYN
| IEEE80211_CHAN_2GHZ
;
431 ieee80211_ifattach(ic
);
432 ic
->ic_node_alloc
= zyd_node_alloc
;
433 ic
->ic_newassoc
= zyd_newassoc
;
435 /* override state transition machine */
436 sc
->sc_newstate
= ic
->ic_newstate
;
437 ic
->ic_newstate
= zyd_newstate
;
438 ieee80211_media_init(ic
, zyd_media_change
, ieee80211_media_status
);
441 bpfattach2(ifp
, DLT_IEEE802_11_RADIO
,
442 sizeof (struct ieee80211_frame
) + IEEE80211_RADIOTAP_HDRLEN
,
445 sc
->sc_rxtap_len
= sizeof sc
->sc_rxtapu
;
446 sc
->sc_rxtap
.wr_ihdr
.it_len
= htole16(sc
->sc_rxtap_len
);
447 sc
->sc_rxtap
.wr_ihdr
.it_present
= htole32(ZYD_RX_RADIOTAP_PRESENT
);
449 sc
->sc_txtap_len
= sizeof sc
->sc_txtapu
;
450 sc
->sc_txtap
.wt_ihdr
.it_len
= htole16(sc
->sc_txtap_len
);
451 sc
->sc_txtap
.wt_ihdr
.it_present
= htole32(ZYD_TX_RADIOTAP_PRESENT
);
454 ieee80211_announce(ic
);
456 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH
, sc
->sc_udev
, sc
->sc_dev
);
462 zyd_detach(device_t self
, int flags
)
464 struct zyd_softc
*sc
= device_private(self
);
465 struct ieee80211com
*ic
= &sc
->sc_ic
;
466 struct ifnet
*ifp
= &sc
->sc_if
;
478 usb_rem_task(sc
->sc_udev
, &sc
->sc_task
);
479 callout_stop(&sc
->sc_scan_ch
);
480 callout_stop(&sc
->sc_amrr_ch
);
489 ieee80211_ifdetach(ic
);
494 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH
, sc
->sc_udev
,
501 zyd_open_pipes(struct zyd_softc
*sc
)
503 usb_endpoint_descriptor_t
*edesc
;
508 edesc
= usbd_get_endpoint_descriptor(sc
->sc_iface
, 0x83);
512 isize
= UGETW(edesc
->wMaxPacketSize
);
513 if (isize
== 0) /* should not happen */
516 sc
->ibuf
= malloc(isize
, M_USBDEV
, M_NOWAIT
);
517 if (sc
->ibuf
== NULL
)
520 error
= usbd_open_pipe_intr(sc
->sc_iface
, 0x83, USBD_SHORT_XFER_OK
,
521 &sc
->zyd_ep
[ZYD_ENDPT_IIN
], sc
, sc
->ibuf
, isize
, zyd_intr
,
522 USBD_DEFAULT_INTERVAL
);
524 printf("%s: open rx intr pipe failed: %s\n",
525 device_xname(sc
->sc_dev
), usbd_errstr(error
));
529 /* interrupt out (not necessarily an interrupt pipe) */
530 error
= usbd_open_pipe(sc
->sc_iface
, 0x04, USBD_EXCLUSIVE_USE
,
531 &sc
->zyd_ep
[ZYD_ENDPT_IOUT
]);
533 printf("%s: open tx intr pipe failed: %s\n",
534 device_xname(sc
->sc_dev
), usbd_errstr(error
));
539 error
= usbd_open_pipe(sc
->sc_iface
, 0x82, USBD_EXCLUSIVE_USE
,
540 &sc
->zyd_ep
[ZYD_ENDPT_BIN
]);
542 printf("%s: open rx pipe failed: %s\n",
543 device_xname(sc
->sc_dev
), usbd_errstr(error
));
548 error
= usbd_open_pipe(sc
->sc_iface
, 0x01, USBD_EXCLUSIVE_USE
,
549 &sc
->zyd_ep
[ZYD_ENDPT_BOUT
]);
551 printf("%s: open tx pipe failed: %s\n",
552 device_xname(sc
->sc_dev
), usbd_errstr(error
));
558 fail
: zyd_close_pipes(sc
);
563 zyd_close_pipes(struct zyd_softc
*sc
)
567 for (i
= 0; i
< ZYD_ENDPT_CNT
; i
++) {
568 if (sc
->zyd_ep
[i
] != NULL
) {
569 usbd_abort_pipe(sc
->zyd_ep
[i
]);
570 usbd_close_pipe(sc
->zyd_ep
[i
]);
571 sc
->zyd_ep
[i
] = NULL
;
574 if (sc
->ibuf
!= NULL
) {
575 free(sc
->ibuf
, M_USBDEV
);
581 zyd_alloc_tx_list(struct zyd_softc
*sc
)
587 for (i
= 0; i
< ZYD_TX_LIST_CNT
; i
++) {
588 struct zyd_tx_data
*data
= &sc
->tx_data
[i
];
590 data
->sc
= sc
; /* backpointer for callbacks */
592 data
->xfer
= usbd_alloc_xfer(sc
->sc_udev
);
593 if (data
->xfer
== NULL
) {
594 printf("%s: could not allocate tx xfer\n",
595 device_xname(sc
->sc_dev
));
599 data
->buf
= usbd_alloc_buffer(data
->xfer
, ZYD_MAX_TXBUFSZ
);
600 if (data
->buf
== NULL
) {
601 printf("%s: could not allocate tx buffer\n",
602 device_xname(sc
->sc_dev
));
607 /* clear Tx descriptor */
608 memset(data
->buf
, 0, sizeof (struct zyd_tx_desc
));
612 fail
: zyd_free_tx_list(sc
);
617 zyd_free_tx_list(struct zyd_softc
*sc
)
621 for (i
= 0; i
< ZYD_TX_LIST_CNT
; i
++) {
622 struct zyd_tx_data
*data
= &sc
->tx_data
[i
];
624 if (data
->xfer
!= NULL
) {
625 usbd_free_xfer(data
->xfer
);
628 if (data
->ni
!= NULL
) {
629 ieee80211_free_node(data
->ni
);
636 zyd_alloc_rx_list(struct zyd_softc
*sc
)
640 for (i
= 0; i
< ZYD_RX_LIST_CNT
; i
++) {
641 struct zyd_rx_data
*data
= &sc
->rx_data
[i
];
643 data
->sc
= sc
; /* backpointer for callbacks */
645 data
->xfer
= usbd_alloc_xfer(sc
->sc_udev
);
646 if (data
->xfer
== NULL
) {
647 printf("%s: could not allocate rx xfer\n",
648 device_xname(sc
->sc_dev
));
652 data
->buf
= usbd_alloc_buffer(data
->xfer
, ZYX_MAX_RXBUFSZ
);
653 if (data
->buf
== NULL
) {
654 printf("%s: could not allocate rx buffer\n",
655 device_xname(sc
->sc_dev
));
662 fail
: zyd_free_rx_list(sc
);
667 zyd_free_rx_list(struct zyd_softc
*sc
)
671 for (i
= 0; i
< ZYD_RX_LIST_CNT
; i
++) {
672 struct zyd_rx_data
*data
= &sc
->rx_data
[i
];
674 if (data
->xfer
!= NULL
) {
675 usbd_free_xfer(data
->xfer
);
682 Static
struct ieee80211_node
*
683 zyd_node_alloc(struct ieee80211_node_table
*nt __unused
)
687 zn
= malloc(sizeof (struct zyd_node
), M_80211_NODE
, M_NOWAIT
| M_ZERO
);
693 zyd_media_change(struct ifnet
*ifp
)
697 error
= ieee80211_media_change(ifp
);
698 if (error
!= ENETRESET
)
701 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) == (IFF_UP
| IFF_RUNNING
))
708 * This function is called periodically (every 200ms) during scanning to
709 * switch from one channel to another.
712 zyd_next_scan(void *arg
)
714 struct zyd_softc
*sc
= arg
;
715 struct ieee80211com
*ic
= &sc
->sc_ic
;
717 if (ic
->ic_state
== IEEE80211_S_SCAN
)
718 ieee80211_next_scan(ic
);
724 struct zyd_softc
*sc
= arg
;
725 struct ieee80211com
*ic
= &sc
->sc_ic
;
726 enum ieee80211_state ostate
;
728 ostate
= ic
->ic_state
;
730 switch (sc
->sc_state
) {
731 case IEEE80211_S_INIT
:
732 if (ostate
== IEEE80211_S_RUN
) {
733 /* turn link LED off */
734 zyd_set_led(sc
, ZYD_LED1
, 0);
736 /* stop data LED from blinking */
737 zyd_write32(sc
, sc
->fwbase
+ ZYD_FW_LINK_STATUS
, 0);
741 case IEEE80211_S_SCAN
:
742 zyd_set_chan(sc
, ic
->ic_curchan
);
743 callout_reset(&sc
->sc_scan_ch
, hz
/ 5, zyd_next_scan
, sc
);
746 case IEEE80211_S_AUTH
:
747 case IEEE80211_S_ASSOC
:
748 zyd_set_chan(sc
, ic
->ic_curchan
);
751 case IEEE80211_S_RUN
:
753 struct ieee80211_node
*ni
= ic
->ic_bss
;
755 zyd_set_chan(sc
, ic
->ic_curchan
);
757 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
758 /* turn link LED on */
759 zyd_set_led(sc
, ZYD_LED1
, 1);
761 /* make data LED blink upon Tx */
762 zyd_write32(sc
, sc
->fwbase
+ ZYD_FW_LINK_STATUS
, 1);
764 zyd_set_bssid(sc
, ni
->ni_bssid
);
767 if (ic
->ic_opmode
== IEEE80211_M_STA
) {
768 /* fake a join to init the tx rate */
772 /* start automatic rate control timer */
773 if (ic
->ic_fixed_rate
== IEEE80211_FIXED_RATE_NONE
)
774 callout_reset(&sc
->sc_amrr_ch
, hz
, zyd_amrr_timeout
, sc
);
780 sc
->sc_newstate(ic
, sc
->sc_state
, -1);
784 zyd_newstate(struct ieee80211com
*ic
, enum ieee80211_state nstate
, int arg
)
786 struct zyd_softc
*sc
= ic
->ic_ifp
->if_softc
;
791 usb_rem_task(sc
->sc_udev
, &sc
->sc_task
);
792 callout_stop(&sc
->sc_scan_ch
);
793 callout_stop(&sc
->sc_amrr_ch
);
795 /* do it in a process context */
796 sc
->sc_state
= nstate
;
797 usb_add_task(sc
->sc_udev
, &sc
->sc_task
, USB_TASKQ_DRIVER
);
803 zyd_cmd(struct zyd_softc
*sc
, uint16_t code
, const void *idata
, int ilen
,
804 void *odata
, int olen
, u_int flags
)
806 usbd_xfer_handle xfer
;
813 if ((xfer
= usbd_alloc_xfer(sc
->sc_udev
)) == NULL
)
816 cmd
.code
= htole16(code
);
817 bcopy(idata
, cmd
.data
, ilen
);
819 xferflags
= USBD_FORCE_SHORT_XFER
;
820 if (!(flags
& ZYD_CMD_FLAG_READ
))
821 xferflags
|= USBD_SYNCHRONOUS
;
826 rq
.len
= olen
/ sizeof (struct zyd_pair
);
827 SIMPLEQ_INSERT_TAIL(&sc
->sc_rqh
, &rq
, rq
);
830 usbd_setup_xfer(xfer
, sc
->zyd_ep
[ZYD_ENDPT_IOUT
], 0, &cmd
,
831 sizeof (uint16_t) + ilen
, xferflags
, ZYD_INTR_TIMEOUT
, NULL
);
832 error
= usbd_transfer(xfer
);
833 if (error
!= USBD_IN_PROGRESS
&& error
!= 0) {
834 if (flags
& ZYD_CMD_FLAG_READ
)
836 printf("%s: could not send command (error=%s)\n",
837 device_xname(sc
->sc_dev
), usbd_errstr(error
));
838 (void)usbd_free_xfer(xfer
);
841 if (!(flags
& ZYD_CMD_FLAG_READ
)) {
842 (void)usbd_free_xfer(xfer
);
843 return 0; /* write: don't wait for reply */
845 /* wait at most one second for command reply */
846 error
= tsleep(odata
, PCATCH
, "zydcmd", hz
);
847 if (error
== EWOULDBLOCK
)
848 printf("%s: zyd_read sleep timeout\n", device_xname(sc
->sc_dev
));
849 SIMPLEQ_REMOVE(&sc
->sc_rqh
, &rq
, rq
, rq
);
852 (void)usbd_free_xfer(xfer
);
857 zyd_read16(struct zyd_softc
*sc
, uint16_t reg
, uint16_t *val
)
863 error
= zyd_cmd(sc
, ZYD_CMD_IORD
, ®
, sizeof reg
, &tmp
, sizeof tmp
,
866 *val
= le16toh(tmp
.val
);
871 zyd_read32(struct zyd_softc
*sc
, uint16_t reg
, uint32_t *val
)
873 struct zyd_pair tmp
[2];
877 regs
[0] = htole16(ZYD_REG32_HI(reg
));
878 regs
[1] = htole16(ZYD_REG32_LO(reg
));
879 error
= zyd_cmd(sc
, ZYD_CMD_IORD
, regs
, sizeof regs
, tmp
, sizeof tmp
,
882 *val
= le16toh(tmp
[0].val
) << 16 | le16toh(tmp
[1].val
);
887 zyd_write16(struct zyd_softc
*sc
, uint16_t reg
, uint16_t val
)
889 struct zyd_pair pair
;
891 pair
.reg
= htole16(reg
);
892 pair
.val
= htole16(val
);
894 return zyd_cmd(sc
, ZYD_CMD_IOWR
, &pair
, sizeof pair
, NULL
, 0, 0);
898 zyd_write32(struct zyd_softc
*sc
, uint16_t reg
, uint32_t val
)
900 struct zyd_pair pair
[2];
902 pair
[0].reg
= htole16(ZYD_REG32_HI(reg
));
903 pair
[0].val
= htole16(val
>> 16);
904 pair
[1].reg
= htole16(ZYD_REG32_LO(reg
));
905 pair
[1].val
= htole16(val
& 0xffff);
907 return zyd_cmd(sc
, ZYD_CMD_IOWR
, pair
, sizeof pair
, NULL
, 0, 0);
911 zyd_rfwrite(struct zyd_softc
*sc
, uint32_t val
)
913 struct zyd_rf
*rf
= &sc
->sc_rf
;
914 struct zyd_rfwrite req
;
918 (void)zyd_read16(sc
, ZYD_CR203
, &cr203
);
919 cr203
&= ~(ZYD_RF_IF_LE
| ZYD_RF_CLK
| ZYD_RF_DATA
);
921 req
.code
= htole16(2);
922 req
.width
= htole16(rf
->width
);
923 for (i
= 0; i
< rf
->width
; i
++) {
924 req
.bit
[i
] = htole16(cr203
);
925 if (val
& (1 << (rf
->width
- 1 - i
)))
926 req
.bit
[i
] |= htole16(ZYD_RF_DATA
);
928 return zyd_cmd(sc
, ZYD_CMD_RFCFG
, &req
, 4 + 2 * rf
->width
, NULL
, 0, 0);
932 zyd_lock_phy(struct zyd_softc
*sc
)
936 (void)zyd_read32(sc
, ZYD_MAC_MISC
, &tmp
);
937 tmp
&= ~ZYD_UNLOCK_PHY_REGS
;
938 (void)zyd_write32(sc
, ZYD_MAC_MISC
, tmp
);
942 zyd_unlock_phy(struct zyd_softc
*sc
)
946 (void)zyd_read32(sc
, ZYD_MAC_MISC
, &tmp
);
947 tmp
|= ZYD_UNLOCK_PHY_REGS
;
948 (void)zyd_write32(sc
, ZYD_MAC_MISC
, tmp
);
955 zyd_rfmd_init(struct zyd_rf
*rf
)
957 #define N(a) (sizeof (a) / sizeof ((a)[0]))
958 struct zyd_softc
*sc
= rf
->rf_sc
;
959 static const struct zyd_phy_pair phyini
[] = ZYD_RFMD_PHY
;
960 static const uint32_t rfini
[] = ZYD_RFMD_RF
;
963 /* init RF-dependent PHY registers */
964 for (i
= 0; i
< N(phyini
); i
++) {
965 error
= zyd_write16(sc
, phyini
[i
].reg
, phyini
[i
].val
);
970 /* init RFMD radio */
971 for (i
= 0; i
< N(rfini
); i
++) {
972 if ((error
= zyd_rfwrite(sc
, rfini
[i
])) != 0)
980 zyd_rfmd_switch_radio(struct zyd_rf
*rf
, int on
)
982 struct zyd_softc
*sc
= rf
->rf_sc
;
984 (void)zyd_write16(sc
, ZYD_CR10
, on
? 0x89 : 0x15);
985 (void)zyd_write16(sc
, ZYD_CR11
, on
? 0x00 : 0x81);
991 zyd_rfmd_set_channel(struct zyd_rf
*rf
, uint8_t chan
)
993 struct zyd_softc
*sc
= rf
->rf_sc
;
994 static const struct {
996 } rfprog
[] = ZYD_RFMD_CHANTABLE
;
998 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r1
);
999 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r2
);
1005 * AL2230 RF methods.
1008 zyd_al2230_init(struct zyd_rf
*rf
)
1010 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1011 struct zyd_softc
*sc
= rf
->rf_sc
;
1012 static const struct zyd_phy_pair phyini
[] = ZYD_AL2230_PHY
;
1013 static const uint32_t rfini
[] = ZYD_AL2230_RF
;
1016 /* init RF-dependent PHY registers */
1017 for (i
= 0; i
< N(phyini
); i
++) {
1018 error
= zyd_write16(sc
, phyini
[i
].reg
, phyini
[i
].val
);
1023 /* init AL2230 radio */
1024 for (i
= 0; i
< N(rfini
); i
++) {
1025 if ((error
= zyd_rfwrite(sc
, rfini
[i
])) != 0)
1033 zyd_al2230_init_b(struct zyd_rf
*rf
)
1035 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1036 struct zyd_softc
*sc
= rf
->rf_sc
;
1037 static const struct zyd_phy_pair phyini
[] = ZYD_AL2230_PHY_B
;
1038 static const uint32_t rfini
[] = ZYD_AL2230_RF_B
;
1041 /* init RF-dependent PHY registers */
1042 for (i
= 0; i
< N(phyini
); i
++) {
1043 error
= zyd_write16(sc
, phyini
[i
].reg
, phyini
[i
].val
);
1048 /* init AL2230 radio */
1049 for (i
= 0; i
< N(rfini
); i
++) {
1050 if ((error
= zyd_rfwrite(sc
, rfini
[i
])) != 0)
1058 zyd_al2230_switch_radio(struct zyd_rf
*rf
, int on
)
1060 struct zyd_softc
*sc
= rf
->rf_sc
;
1061 int on251
= (sc
->mac_rev
== ZYD_ZD1211
) ? 0x3f : 0x7f;
1063 (void)zyd_write16(sc
, ZYD_CR11
, on
? 0x00 : 0x04);
1064 (void)zyd_write16(sc
, ZYD_CR251
, on
? on251
: 0x2f);
1070 zyd_al2230_set_channel(struct zyd_rf
*rf
, uint8_t chan
)
1072 struct zyd_softc
*sc
= rf
->rf_sc
;
1073 static const struct {
1074 uint32_t r1
, r2
, r3
;
1075 } rfprog
[] = ZYD_AL2230_CHANTABLE
;
1077 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r1
);
1078 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r2
);
1079 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r3
);
1081 (void)zyd_write16(sc
, ZYD_CR138
, 0x28);
1082 (void)zyd_write16(sc
, ZYD_CR203
, 0x06);
1088 * AL7230B RF methods.
1091 zyd_al7230B_init(struct zyd_rf
*rf
)
1093 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1094 struct zyd_softc
*sc
= rf
->rf_sc
;
1095 static const struct zyd_phy_pair phyini_1
[] = ZYD_AL7230B_PHY_1
;
1096 static const struct zyd_phy_pair phyini_2
[] = ZYD_AL7230B_PHY_2
;
1097 static const struct zyd_phy_pair phyini_3
[] = ZYD_AL7230B_PHY_3
;
1098 static const uint32_t rfini_1
[] = ZYD_AL7230B_RF_1
;
1099 static const uint32_t rfini_2
[] = ZYD_AL7230B_RF_2
;
1102 /* for AL7230B, PHY and RF need to be initialized in "phases" */
1104 /* init RF-dependent PHY registers, part one */
1105 for (i
= 0; i
< N(phyini_1
); i
++) {
1106 error
= zyd_write16(sc
, phyini_1
[i
].reg
, phyini_1
[i
].val
);
1110 /* init AL7230B radio, part one */
1111 for (i
= 0; i
< N(rfini_1
); i
++) {
1112 if ((error
= zyd_rfwrite(sc
, rfini_1
[i
])) != 0)
1115 /* init RF-dependent PHY registers, part two */
1116 for (i
= 0; i
< N(phyini_2
); i
++) {
1117 error
= zyd_write16(sc
, phyini_2
[i
].reg
, phyini_2
[i
].val
);
1121 /* init AL7230B radio, part two */
1122 for (i
= 0; i
< N(rfini_2
); i
++) {
1123 if ((error
= zyd_rfwrite(sc
, rfini_2
[i
])) != 0)
1126 /* init RF-dependent PHY registers, part three */
1127 for (i
= 0; i
< N(phyini_3
); i
++) {
1128 error
= zyd_write16(sc
, phyini_3
[i
].reg
, phyini_3
[i
].val
);
1138 zyd_al7230B_switch_radio(struct zyd_rf
*rf
, int on
)
1140 struct zyd_softc
*sc
= rf
->rf_sc
;
1142 (void)zyd_write16(sc
, ZYD_CR11
, on
? 0x00 : 0x04);
1143 (void)zyd_write16(sc
, ZYD_CR251
, on
? 0x3f : 0x2f);
1149 zyd_al7230B_set_channel(struct zyd_rf
*rf
, uint8_t chan
)
1151 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1152 struct zyd_softc
*sc
= rf
->rf_sc
;
1153 static const struct {
1155 } rfprog
[] = ZYD_AL7230B_CHANTABLE
;
1156 static const uint32_t rfsc
[] = ZYD_AL7230B_RF_SETCHANNEL
;
1159 (void)zyd_write16(sc
, ZYD_CR240
, 0x57);
1160 (void)zyd_write16(sc
, ZYD_CR251
, 0x2f);
1162 for (i
= 0; i
< N(rfsc
); i
++) {
1163 if ((error
= zyd_rfwrite(sc
, rfsc
[i
])) != 0)
1167 (void)zyd_write16(sc
, ZYD_CR128
, 0x14);
1168 (void)zyd_write16(sc
, ZYD_CR129
, 0x12);
1169 (void)zyd_write16(sc
, ZYD_CR130
, 0x10);
1170 (void)zyd_write16(sc
, ZYD_CR38
, 0x38);
1171 (void)zyd_write16(sc
, ZYD_CR136
, 0xdf);
1173 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r1
);
1174 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r2
);
1175 (void)zyd_rfwrite(sc
, 0x3c9000);
1177 (void)zyd_write16(sc
, ZYD_CR251
, 0x3f);
1178 (void)zyd_write16(sc
, ZYD_CR203
, 0x06);
1179 (void)zyd_write16(sc
, ZYD_CR240
, 0x08);
1186 * AL2210 RF methods.
1189 zyd_al2210_init(struct zyd_rf
*rf
)
1191 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1192 struct zyd_softc
*sc
= rf
->rf_sc
;
1193 static const struct zyd_phy_pair phyini
[] = ZYD_AL2210_PHY
;
1194 static const uint32_t rfini
[] = ZYD_AL2210_RF
;
1198 (void)zyd_write32(sc
, ZYD_CR18
, 2);
1200 /* init RF-dependent PHY registers */
1201 for (i
= 0; i
< N(phyini
); i
++) {
1202 error
= zyd_write16(sc
, phyini
[i
].reg
, phyini
[i
].val
);
1206 /* init AL2210 radio */
1207 for (i
= 0; i
< N(rfini
); i
++) {
1208 if ((error
= zyd_rfwrite(sc
, rfini
[i
])) != 0)
1211 (void)zyd_write16(sc
, ZYD_CR47
, 0x1e);
1212 (void)zyd_read32(sc
, ZYD_CR_RADIO_PD
, &tmp
);
1213 (void)zyd_write32(sc
, ZYD_CR_RADIO_PD
, tmp
& ~1);
1214 (void)zyd_write32(sc
, ZYD_CR_RADIO_PD
, tmp
| 1);
1215 (void)zyd_write32(sc
, ZYD_CR_RFCFG
, 0x05);
1216 (void)zyd_write32(sc
, ZYD_CR_RFCFG
, 0x00);
1217 (void)zyd_write16(sc
, ZYD_CR47
, 0x1e);
1218 (void)zyd_write32(sc
, ZYD_CR18
, 3);
1225 zyd_al2210_switch_radio(struct zyd_rf
*rf
, int on
)
1227 /* vendor driver does nothing for this RF chip */
1233 zyd_al2210_set_channel(struct zyd_rf
*rf
, uint8_t chan
)
1235 struct zyd_softc
*sc
= rf
->rf_sc
;
1236 static const uint32_t rfprog
[] = ZYD_AL2210_CHANTABLE
;
1239 (void)zyd_write32(sc
, ZYD_CR18
, 2);
1240 (void)zyd_write16(sc
, ZYD_CR47
, 0x1e);
1241 (void)zyd_read32(sc
, ZYD_CR_RADIO_PD
, &tmp
);
1242 (void)zyd_write32(sc
, ZYD_CR_RADIO_PD
, tmp
& ~1);
1243 (void)zyd_write32(sc
, ZYD_CR_RADIO_PD
, tmp
| 1);
1244 (void)zyd_write32(sc
, ZYD_CR_RFCFG
, 0x05);
1246 (void)zyd_write32(sc
, ZYD_CR_RFCFG
, 0x00);
1247 (void)zyd_write16(sc
, ZYD_CR47
, 0x1e);
1249 /* actually set the channel */
1250 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1]);
1252 (void)zyd_write32(sc
, ZYD_CR18
, 3);
1261 zyd_gct_init(struct zyd_rf
*rf
)
1263 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1264 struct zyd_softc
*sc
= rf
->rf_sc
;
1265 static const struct zyd_phy_pair phyini
[] = ZYD_GCT_PHY
;
1266 static const uint32_t rfini
[] = ZYD_GCT_RF
;
1269 /* init RF-dependent PHY registers */
1270 for (i
= 0; i
< N(phyini
); i
++) {
1271 error
= zyd_write16(sc
, phyini
[i
].reg
, phyini
[i
].val
);
1275 /* init cgt radio */
1276 for (i
= 0; i
< N(rfini
); i
++) {
1277 if ((error
= zyd_rfwrite(sc
, rfini
[i
])) != 0)
1285 zyd_gct_switch_radio(struct zyd_rf
*rf
, int on
)
1287 /* vendor driver does nothing for this RF chip */
1293 zyd_gct_set_channel(struct zyd_rf
*rf
, uint8_t chan
)
1295 struct zyd_softc
*sc
= rf
->rf_sc
;
1296 static const uint32_t rfprog
[] = ZYD_GCT_CHANTABLE
;
1298 (void)zyd_rfwrite(sc
, 0x1c0000);
1299 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1]);
1300 (void)zyd_rfwrite(sc
, 0x1c0008);
1309 zyd_maxim_init(struct zyd_rf
*rf
)
1311 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1312 struct zyd_softc
*sc
= rf
->rf_sc
;
1313 static const struct zyd_phy_pair phyini
[] = ZYD_MAXIM_PHY
;
1314 static const uint32_t rfini
[] = ZYD_MAXIM_RF
;
1318 /* init RF-dependent PHY registers */
1319 for (i
= 0; i
< N(phyini
); i
++) {
1320 error
= zyd_write16(sc
, phyini
[i
].reg
, phyini
[i
].val
);
1324 (void)zyd_read16(sc
, ZYD_CR203
, &tmp
);
1325 (void)zyd_write16(sc
, ZYD_CR203
, tmp
& ~(1 << 4));
1327 /* init maxim radio */
1328 for (i
= 0; i
< N(rfini
); i
++) {
1329 if ((error
= zyd_rfwrite(sc
, rfini
[i
])) != 0)
1332 (void)zyd_read16(sc
, ZYD_CR203
, &tmp
);
1333 (void)zyd_write16(sc
, ZYD_CR203
, tmp
| (1 << 4));
1340 zyd_maxim_switch_radio(struct zyd_rf
*rf
, int on
)
1342 /* vendor driver does nothing for this RF chip */
1348 zyd_maxim_set_channel(struct zyd_rf
*rf
, uint8_t chan
)
1350 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1351 struct zyd_softc
*sc
= rf
->rf_sc
;
1352 static const struct zyd_phy_pair phyini
[] = ZYD_MAXIM_PHY
;
1353 static const uint32_t rfini
[] = ZYD_MAXIM_RF
;
1354 static const struct {
1356 } rfprog
[] = ZYD_MAXIM_CHANTABLE
;
1361 * Do the same as we do when initializing it, except for the channel
1362 * values coming from the two channel tables.
1365 /* init RF-dependent PHY registers */
1366 for (i
= 0; i
< N(phyini
); i
++) {
1367 error
= zyd_write16(sc
, phyini
[i
].reg
, phyini
[i
].val
);
1371 (void)zyd_read16(sc
, ZYD_CR203
, &tmp
);
1372 (void)zyd_write16(sc
, ZYD_CR203
, tmp
& ~(1 << 4));
1374 /* first two values taken from the chantables */
1375 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r1
);
1376 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r2
);
1378 /* init maxim radio - skipping the two first values */
1379 for (i
= 2; i
< N(rfini
); i
++) {
1380 if ((error
= zyd_rfwrite(sc
, rfini
[i
])) != 0)
1383 (void)zyd_read16(sc
, ZYD_CR203
, &tmp
);
1384 (void)zyd_write16(sc
, ZYD_CR203
, tmp
| (1 << 4));
1391 * Maxim2 RF methods.
1394 zyd_maxim2_init(struct zyd_rf
*rf
)
1396 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1397 struct zyd_softc
*sc
= rf
->rf_sc
;
1398 static const struct zyd_phy_pair phyini
[] = ZYD_MAXIM2_PHY
;
1399 static const uint32_t rfini
[] = ZYD_MAXIM2_RF
;
1403 /* init RF-dependent PHY registers */
1404 for (i
= 0; i
< N(phyini
); i
++) {
1405 error
= zyd_write16(sc
, phyini
[i
].reg
, phyini
[i
].val
);
1409 (void)zyd_read16(sc
, ZYD_CR203
, &tmp
);
1410 (void)zyd_write16(sc
, ZYD_CR203
, tmp
& ~(1 << 4));
1412 /* init maxim2 radio */
1413 for (i
= 0; i
< N(rfini
); i
++) {
1414 if ((error
= zyd_rfwrite(sc
, rfini
[i
])) != 0)
1417 (void)zyd_read16(sc
, ZYD_CR203
, &tmp
);
1418 (void)zyd_write16(sc
, ZYD_CR203
, tmp
| (1 << 4));
1425 zyd_maxim2_switch_radio(struct zyd_rf
*rf
, int on
)
1427 /* vendor driver does nothing for this RF chip */
1433 zyd_maxim2_set_channel(struct zyd_rf
*rf
, uint8_t chan
)
1435 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1436 struct zyd_softc
*sc
= rf
->rf_sc
;
1437 static const struct zyd_phy_pair phyini
[] = ZYD_MAXIM2_PHY
;
1438 static const uint32_t rfini
[] = ZYD_MAXIM2_RF
;
1439 static const struct {
1441 } rfprog
[] = ZYD_MAXIM2_CHANTABLE
;
1446 * Do the same as we do when initializing it, except for the channel
1447 * values coming from the two channel tables.
1450 /* init RF-dependent PHY registers */
1451 for (i
= 0; i
< N(phyini
); i
++) {
1452 error
= zyd_write16(sc
, phyini
[i
].reg
, phyini
[i
].val
);
1456 (void)zyd_read16(sc
, ZYD_CR203
, &tmp
);
1457 (void)zyd_write16(sc
, ZYD_CR203
, tmp
& ~(1 << 4));
1459 /* first two values taken from the chantables */
1460 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r1
);
1461 (void)zyd_rfwrite(sc
, rfprog
[chan
- 1].r2
);
1463 /* init maxim2 radio - skipping the two first values */
1464 for (i
= 2; i
< N(rfini
); i
++) {
1465 if ((error
= zyd_rfwrite(sc
, rfini
[i
])) != 0)
1468 (void)zyd_read16(sc
, ZYD_CR203
, &tmp
);
1469 (void)zyd_write16(sc
, ZYD_CR203
, tmp
| (1 << 4));
1476 zyd_rf_attach(struct zyd_softc
*sc
, uint8_t type
)
1478 struct zyd_rf
*rf
= &sc
->sc_rf
;
1484 rf
->init
= zyd_rfmd_init
;
1485 rf
->switch_radio
= zyd_rfmd_switch_radio
;
1486 rf
->set_channel
= zyd_rfmd_set_channel
;
1487 rf
->width
= 24; /* 24-bit RF values */
1490 if (sc
->mac_rev
== ZYD_ZD1211B
)
1491 rf
->init
= zyd_al2230_init_b
;
1493 rf
->init
= zyd_al2230_init
;
1494 rf
->switch_radio
= zyd_al2230_switch_radio
;
1495 rf
->set_channel
= zyd_al2230_set_channel
;
1496 rf
->width
= 24; /* 24-bit RF values */
1498 case ZYD_RF_AL7230B
:
1499 rf
->init
= zyd_al7230B_init
;
1500 rf
->switch_radio
= zyd_al7230B_switch_radio
;
1501 rf
->set_channel
= zyd_al7230B_set_channel
;
1502 rf
->width
= 24; /* 24-bit RF values */
1505 rf
->init
= zyd_al2210_init
;
1506 rf
->switch_radio
= zyd_al2210_switch_radio
;
1507 rf
->set_channel
= zyd_al2210_set_channel
;
1508 rf
->width
= 24; /* 24-bit RF values */
1511 rf
->init
= zyd_gct_init
;
1512 rf
->switch_radio
= zyd_gct_switch_radio
;
1513 rf
->set_channel
= zyd_gct_set_channel
;
1514 rf
->width
= 21; /* 21-bit RF values */
1516 case ZYD_RF_MAXIM_NEW
:
1517 rf
->init
= zyd_maxim_init
;
1518 rf
->switch_radio
= zyd_maxim_switch_radio
;
1519 rf
->set_channel
= zyd_maxim_set_channel
;
1520 rf
->width
= 18; /* 18-bit RF values */
1522 case ZYD_RF_MAXIM_NEW2
:
1523 rf
->init
= zyd_maxim2_init
;
1524 rf
->switch_radio
= zyd_maxim2_switch_radio
;
1525 rf
->set_channel
= zyd_maxim2_set_channel
;
1526 rf
->width
= 18; /* 18-bit RF values */
1529 printf("%s: sorry, radio \"%s\" is not supported yet\n",
1530 device_xname(sc
->sc_dev
), zyd_rf_name(type
));
1537 zyd_rf_name(uint8_t type
)
1539 static const char * const zyd_rfs
[] = {
1540 "unknown", "unknown", "UW2451", "UCHIP", "AL2230",
1541 "AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT",
1542 "PV2000", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2",
1546 return zyd_rfs
[(type
> 15) ? 0 : type
];
1550 zyd_hw_init(struct zyd_softc
*sc
)
1552 struct zyd_rf
*rf
= &sc
->sc_rf
;
1553 const struct zyd_phy_pair
*phyp
;
1556 /* specify that the plug and play is finished */
1557 (void)zyd_write32(sc
, ZYD_MAC_AFTER_PNP
, 1);
1559 (void)zyd_read16(sc
, ZYD_FIRMWARE_BASE_ADDR
, &sc
->fwbase
);
1560 DPRINTF(("firmware base address=0x%04x\n", sc
->fwbase
));
1562 /* retrieve firmware revision number */
1563 (void)zyd_read16(sc
, sc
->fwbase
+ ZYD_FW_FIRMWARE_REV
, &sc
->fw_rev
);
1565 (void)zyd_write32(sc
, ZYD_CR_GPI_EN
, 0);
1566 (void)zyd_write32(sc
, ZYD_MAC_CONT_WIN_LIMIT
, 0x7f043f);
1568 /* disable interrupts */
1569 (void)zyd_write32(sc
, ZYD_CR_INTERRUPT
, 0);
1573 phyp
= (sc
->mac_rev
== ZYD_ZD1211B
) ? zyd_def_phyB
: zyd_def_phy
;
1574 for (; phyp
->reg
!= 0; phyp
++) {
1575 if ((error
= zyd_write16(sc
, phyp
->reg
, phyp
->val
)) != 0)
1581 zyd_write32(sc
, ZYD_MAC_ACK_EXT
, 0x00000020);
1582 zyd_write32(sc
, ZYD_CR_ADDA_MBIAS_WT
, 0x30000808);
1584 if (sc
->mac_rev
== ZYD_ZD1211
) {
1585 zyd_write32(sc
, ZYD_MAC_RETRY
, 0x00000002);
1587 zyd_write32(sc
, ZYD_MAC_RETRY
, 0x02020202);
1588 zyd_write32(sc
, ZYD_MACB_TXPWR_CTL4
, 0x007f003f);
1589 zyd_write32(sc
, ZYD_MACB_TXPWR_CTL3
, 0x007f003f);
1590 zyd_write32(sc
, ZYD_MACB_TXPWR_CTL2
, 0x003f001f);
1591 zyd_write32(sc
, ZYD_MACB_TXPWR_CTL1
, 0x001f000f);
1592 zyd_write32(sc
, ZYD_MACB_AIFS_CTL1
, 0x00280028);
1593 zyd_write32(sc
, ZYD_MACB_AIFS_CTL2
, 0x008C003C);
1594 zyd_write32(sc
, ZYD_MACB_TXOP
, 0x01800824);
1597 zyd_write32(sc
, ZYD_MAC_SNIFFER
, 0x00000000);
1598 zyd_write32(sc
, ZYD_MAC_RXFILTER
, 0x00000000);
1599 zyd_write32(sc
, ZYD_MAC_GHTBL
, 0x00000000);
1600 zyd_write32(sc
, ZYD_MAC_GHTBH
, 0x80000000);
1601 zyd_write32(sc
, ZYD_MAC_MISC
, 0x000000a4);
1602 zyd_write32(sc
, ZYD_CR_ADDA_PWR_DWN
, 0x0000007f);
1603 zyd_write32(sc
, ZYD_MAC_BCNCFG
, 0x00f00401);
1604 zyd_write32(sc
, ZYD_MAC_PHY_DELAY2
, 0x00000000);
1605 zyd_write32(sc
, ZYD_MAC_ACK_EXT
, 0x00000080);
1606 zyd_write32(sc
, ZYD_CR_ADDA_PWR_DWN
, 0x00000000);
1607 zyd_write32(sc
, ZYD_MAC_SIFS_ACK_TIME
, 0x00000100);
1608 zyd_write32(sc
, ZYD_MAC_DIFS_EIFS_SIFS
, 0x0547c032);
1609 zyd_write32(sc
, ZYD_CR_RX_PE_DELAY
, 0x00000070);
1610 zyd_write32(sc
, ZYD_CR_PS_CTRL
, 0x10000000);
1611 zyd_write32(sc
, ZYD_MAC_RTSCTSRATE
, 0x02030203);
1612 zyd_write32(sc
, ZYD_MAC_RX_THRESHOLD
, 0x000c0640);
1613 zyd_write32(sc
, ZYD_MAC_BACKOFF_PROTECT
, 0x00000114);
1617 error
= (*rf
->init
)(rf
);
1620 printf("%s: radio initialization failed\n",
1621 device_xname(sc
->sc_dev
));
1625 /* init beacon interval to 100ms */
1626 if ((error
= zyd_set_beacon_interval(sc
, 100)) != 0)
1633 zyd_read_eeprom(struct zyd_softc
*sc
)
1635 struct ieee80211com
*ic
= &sc
->sc_ic
;
1640 /* read MAC address */
1641 (void)zyd_read32(sc
, ZYD_EEPROM_MAC_ADDR_P1
, &tmp
);
1642 ic
->ic_myaddr
[0] = tmp
& 0xff;
1643 ic
->ic_myaddr
[1] = tmp
>> 8;
1644 ic
->ic_myaddr
[2] = tmp
>> 16;
1645 ic
->ic_myaddr
[3] = tmp
>> 24;
1646 (void)zyd_read32(sc
, ZYD_EEPROM_MAC_ADDR_P2
, &tmp
);
1647 ic
->ic_myaddr
[4] = tmp
& 0xff;
1648 ic
->ic_myaddr
[5] = tmp
>> 8;
1650 (void)zyd_read32(sc
, ZYD_EEPROM_POD
, &tmp
);
1651 sc
->rf_rev
= tmp
& 0x0f;
1652 sc
->pa_rev
= (tmp
>> 16) & 0x0f;
1654 /* read regulatory domain (currently unused) */
1655 (void)zyd_read32(sc
, ZYD_EEPROM_SUBID
, &tmp
);
1656 sc
->regdomain
= tmp
>> 16;
1657 DPRINTF(("regulatory domain %x\n", sc
->regdomain
));
1659 /* read Tx power calibration tables */
1660 for (i
= 0; i
< 7; i
++) {
1661 (void)zyd_read16(sc
, ZYD_EEPROM_PWR_CAL
+ i
, &val
);
1662 sc
->pwr_cal
[i
* 2] = val
>> 8;
1663 sc
->pwr_cal
[i
* 2 + 1] = val
& 0xff;
1665 (void)zyd_read16(sc
, ZYD_EEPROM_PWR_INT
+ i
, &val
);
1666 sc
->pwr_int
[i
* 2] = val
>> 8;
1667 sc
->pwr_int
[i
* 2 + 1] = val
& 0xff;
1669 (void)zyd_read16(sc
, ZYD_EEPROM_36M_CAL
+ i
, &val
);
1670 sc
->ofdm36_cal
[i
* 2] = val
>> 8;
1671 sc
->ofdm36_cal
[i
* 2 + 1] = val
& 0xff;
1673 (void)zyd_read16(sc
, ZYD_EEPROM_48M_CAL
+ i
, &val
);
1674 sc
->ofdm48_cal
[i
* 2] = val
>> 8;
1675 sc
->ofdm48_cal
[i
* 2 + 1] = val
& 0xff;
1677 (void)zyd_read16(sc
, ZYD_EEPROM_54M_CAL
+ i
, &val
);
1678 sc
->ofdm54_cal
[i
* 2] = val
>> 8;
1679 sc
->ofdm54_cal
[i
* 2 + 1] = val
& 0xff;
1685 zyd_set_macaddr(struct zyd_softc
*sc
, const uint8_t *addr
)
1689 tmp
= addr
[3] << 24 | addr
[2] << 16 | addr
[1] << 8 | addr
[0];
1690 (void)zyd_write32(sc
, ZYD_MAC_MACADRL
, tmp
);
1692 tmp
= addr
[5] << 8 | addr
[4];
1693 (void)zyd_write32(sc
, ZYD_MAC_MACADRH
, tmp
);
1699 zyd_set_bssid(struct zyd_softc
*sc
, const uint8_t *addr
)
1703 tmp
= addr
[3] << 24 | addr
[2] << 16 | addr
[1] << 8 | addr
[0];
1704 (void)zyd_write32(sc
, ZYD_MAC_BSSADRL
, tmp
);
1706 tmp
= addr
[5] << 8 | addr
[4];
1707 (void)zyd_write32(sc
, ZYD_MAC_BSSADRH
, tmp
);
1713 zyd_switch_radio(struct zyd_softc
*sc
, int on
)
1715 struct zyd_rf
*rf
= &sc
->sc_rf
;
1719 error
= (*rf
->switch_radio
)(rf
, on
);
1726 zyd_set_led(struct zyd_softc
*sc
, int which
, int on
)
1730 (void)zyd_read32(sc
, ZYD_MAC_TX_PE_CONTROL
, &tmp
);
1734 (void)zyd_write32(sc
, ZYD_MAC_TX_PE_CONTROL
, tmp
);
1738 zyd_set_rxfilter(struct zyd_softc
*sc
)
1742 switch (sc
->sc_ic
.ic_opmode
) {
1743 case IEEE80211_M_STA
:
1744 rxfilter
= ZYD_FILTER_BSS
;
1746 case IEEE80211_M_IBSS
:
1747 case IEEE80211_M_HOSTAP
:
1748 rxfilter
= ZYD_FILTER_HOSTAP
;
1750 case IEEE80211_M_MONITOR
:
1751 rxfilter
= ZYD_FILTER_MONITOR
;
1754 /* should not get there */
1757 return zyd_write32(sc
, ZYD_MAC_RXFILTER
, rxfilter
);
1761 zyd_set_chan(struct zyd_softc
*sc
, struct ieee80211_channel
*c
)
1763 struct ieee80211com
*ic
= &sc
->sc_ic
;
1764 struct zyd_rf
*rf
= &sc
->sc_rf
;
1767 chan
= ieee80211_chan2ieee(ic
, c
);
1768 if (chan
== 0 || chan
== IEEE80211_CHAN_ANY
)
1773 (*rf
->set_channel
)(rf
, chan
);
1775 /* update Tx power */
1776 (void)zyd_write32(sc
, ZYD_CR31
, sc
->pwr_int
[chan
- 1]);
1777 (void)zyd_write32(sc
, ZYD_CR68
, sc
->pwr_cal
[chan
- 1]);
1779 if (sc
->mac_rev
== ZYD_ZD1211B
) {
1780 (void)zyd_write32(sc
, ZYD_CR67
, sc
->ofdm36_cal
[chan
- 1]);
1781 (void)zyd_write32(sc
, ZYD_CR66
, sc
->ofdm48_cal
[chan
- 1]);
1782 (void)zyd_write32(sc
, ZYD_CR65
, sc
->ofdm54_cal
[chan
- 1]);
1784 (void)zyd_write32(sc
, ZYD_CR69
, 0x28);
1785 (void)zyd_write32(sc
, ZYD_CR69
, 0x2a);
1792 zyd_set_beacon_interval(struct zyd_softc
*sc
, int bintval
)
1794 /* XXX this is probably broken.. */
1795 (void)zyd_write32(sc
, ZYD_CR_ATIM_WND_PERIOD
, bintval
- 2);
1796 (void)zyd_write32(sc
, ZYD_CR_PRE_TBTT
, bintval
- 1);
1797 (void)zyd_write32(sc
, ZYD_CR_BCN_INTERVAL
, bintval
);
1803 zyd_plcp_signal(int rate
)
1806 /* CCK rates (returned values are device-dependent) */
1809 case 11: return 0x2;
1810 case 22: return 0x3;
1812 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
1813 case 12: return 0xb;
1814 case 18: return 0xf;
1815 case 24: return 0xa;
1816 case 36: return 0xe;
1817 case 48: return 0x9;
1818 case 72: return 0xd;
1819 case 96: return 0x8;
1820 case 108: return 0xc;
1822 /* unsupported rates (should not get there) */
1823 default: return 0xff;
1828 zyd_intr(usbd_xfer_handle xfer
, usbd_private_handle priv
, usbd_status status
)
1830 struct zyd_softc
*sc
= (struct zyd_softc
*)priv
;
1831 struct zyd_cmd
*cmd
;
1834 if (status
!= USBD_NORMAL_COMPLETION
) {
1835 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
)
1838 if (status
== USBD_STALLED
) {
1839 usbd_clear_endpoint_stall_async(
1840 sc
->zyd_ep
[ZYD_ENDPT_IIN
]);
1845 cmd
= (struct zyd_cmd
*)sc
->ibuf
;
1847 if (le16toh(cmd
->code
) == ZYD_NOTIF_RETRYSTATUS
) {
1848 struct zyd_notif_retry
*retry
=
1849 (struct zyd_notif_retry
*)cmd
->data
;
1850 struct ieee80211com
*ic
= &sc
->sc_ic
;
1851 struct ifnet
*ifp
= &sc
->sc_if
;
1852 struct ieee80211_node
*ni
;
1854 DPRINTF(("retry intr: rate=0x%x addr=%s count=%d (0x%x)\n",
1855 le16toh(retry
->rate
), ether_sprintf(retry
->macaddr
),
1856 le16toh(retry
->count
) & 0xff, le16toh(retry
->count
)));
1859 * Find the node to which the packet was sent and update its
1860 * retry statistics. In BSS mode, this node is the AP we're
1861 * associated to so no lookup is actually needed.
1863 if (ic
->ic_opmode
!= IEEE80211_M_STA
) {
1864 ni
= ieee80211_find_node(&ic
->ic_scan
, retry
->macaddr
);
1866 return; /* just ignore */
1870 ((struct zyd_node
*)ni
)->amn
.amn_retrycnt
++;
1872 if (le16toh(retry
->count
) & 0x100)
1873 ifp
->if_oerrors
++; /* too many retries */
1875 } else if (le16toh(cmd
->code
) == ZYD_NOTIF_IORD
) {
1878 if (le16toh(*(uint16_t *)cmd
->data
) == ZYD_CR_INTERRUPT
)
1879 return; /* HMAC interrupt */
1881 usbd_get_xfer_status(xfer
, NULL
, NULL
, &datalen
, NULL
);
1882 datalen
-= sizeof(cmd
->code
);
1883 datalen
-= 2; /* XXX: padding? */
1885 SIMPLEQ_FOREACH(rqp
, &sc
->sc_rqh
, rq
) {
1888 if (sizeof(struct zyd_pair
) * rqp
->len
!= datalen
)
1890 for (i
= 0; i
< rqp
->len
; i
++) {
1891 if (*(((const uint16_t *)rqp
->idata
) + i
) !=
1892 (((struct zyd_pair
*)cmd
->data
) + i
)->reg
)
1898 /* copy answer into caller-supplied buffer */
1899 bcopy(cmd
->data
, rqp
->odata
,
1900 sizeof(struct zyd_pair
) * rqp
->len
);
1901 wakeup(rqp
->odata
); /* wakeup caller */
1905 return; /* unexpected IORD notification */
1907 printf("%s: unknown notification %x\n", device_xname(sc
->sc_dev
),
1908 le16toh(cmd
->code
));
1913 zyd_rx_data(struct zyd_softc
*sc
, const uint8_t *buf
, uint16_t len
)
1915 struct ieee80211com
*ic
= &sc
->sc_ic
;
1916 struct ifnet
*ifp
= &sc
->sc_if
;
1917 struct ieee80211_node
*ni
;
1918 struct ieee80211_frame
*wh
;
1919 const struct zyd_plcphdr
*plcp
;
1920 const struct zyd_rx_stat
*stat
;
1924 if (len
< ZYD_MIN_FRAGSZ
) {
1925 printf("%s: frame too short (length=%d)\n",
1926 device_xname(sc
->sc_dev
), len
);
1931 plcp
= (const struct zyd_plcphdr
*)buf
;
1932 stat
= (const struct zyd_rx_stat
*)
1933 (buf
+ len
- sizeof (struct zyd_rx_stat
));
1935 if (stat
->flags
& ZYD_RX_ERROR
) {
1936 DPRINTF(("%s: RX status indicated error (%x)\n",
1937 device_xname(sc
->sc_dev
), stat
->flags
));
1942 /* compute actual frame length */
1943 rlen
= len
- sizeof (struct zyd_plcphdr
) -
1944 sizeof (struct zyd_rx_stat
) - IEEE80211_CRC_LEN
;
1946 /* allocate a mbuf to store the frame */
1947 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
1949 printf("%s: could not allocate rx mbuf\n",
1950 device_xname(sc
->sc_dev
));
1955 MCLGET(m
, M_DONTWAIT
);
1956 if (!(m
->m_flags
& M_EXT
)) {
1957 printf("%s: could not allocate rx mbuf cluster\n",
1958 device_xname(sc
->sc_dev
));
1964 m
->m_pkthdr
.rcvif
= ifp
;
1965 m
->m_pkthdr
.len
= m
->m_len
= rlen
;
1966 bcopy((const uint8_t *)(plcp
+ 1), mtod(m
, uint8_t *), rlen
);
1971 if (sc
->sc_drvbpf
!= NULL
) {
1972 struct zyd_rx_radiotap_header
*tap
= &sc
->sc_rxtap
;
1973 static const uint8_t rates
[] = {
1974 /* reverse function of zyd_plcp_signal() */
1975 2, 4, 11, 22, 0, 0, 0, 0,
1976 96, 48, 24, 12, 108, 72, 36, 18
1979 tap
->wr_flags
= IEEE80211_RADIOTAP_F_FCS
;
1980 tap
->wr_chan_freq
= htole16(ic
->ic_curchan
->ic_freq
);
1981 tap
->wr_chan_flags
= htole16(ic
->ic_curchan
->ic_flags
);
1982 tap
->wr_rssi
= stat
->rssi
;
1983 tap
->wr_rate
= rates
[plcp
->signal
& 0xf];
1985 bpf_mtap2(sc
->sc_drvbpf
, tap
, sc
->sc_rxtap_len
, m
);
1989 wh
= mtod(m
, struct ieee80211_frame
*);
1990 ni
= ieee80211_find_rxnode(ic
, (struct ieee80211_frame_min
*)wh
);
1991 ieee80211_input(ic
, m
, ni
, stat
->rssi
, 0);
1993 /* node is no longer needed */
1994 ieee80211_free_node(ni
);
2000 zyd_rxeof(usbd_xfer_handle xfer
, usbd_private_handle priv
, usbd_status status
)
2002 struct zyd_rx_data
*data
= priv
;
2003 struct zyd_softc
*sc
= data
->sc
;
2004 struct ifnet
*ifp
= &sc
->sc_if
;
2005 const struct zyd_rx_desc
*desc
;
2008 if (status
!= USBD_NORMAL_COMPLETION
) {
2009 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
)
2012 if (status
== USBD_STALLED
)
2013 usbd_clear_endpoint_stall(sc
->zyd_ep
[ZYD_ENDPT_BIN
]);
2017 usbd_get_xfer_status(xfer
, NULL
, NULL
, &len
, NULL
);
2019 if (len
< ZYD_MIN_RXBUFSZ
) {
2020 printf("%s: xfer too short (length=%d)\n",
2021 device_xname(sc
->sc_dev
), len
);
2026 desc
= (const struct zyd_rx_desc
*)
2027 (data
->buf
+ len
- sizeof (struct zyd_rx_desc
));
2029 if (UGETW(desc
->tag
) == ZYD_TAG_MULTIFRAME
) {
2030 const uint8_t *p
= data
->buf
, *end
= p
+ len
;
2033 DPRINTFN(3, ("received multi-frame transfer\n"));
2035 for (i
= 0; i
< ZYD_MAX_RXFRAMECNT
; i
++) {
2036 const uint16_t len16
= UGETW(desc
->len
[i
]);
2038 if (len16
== 0 || p
+ len16
> end
)
2041 zyd_rx_data(sc
, p
, len16
);
2042 /* next frame is aligned on a 32-bit boundary */
2043 p
+= (len16
+ 3) & ~3;
2046 DPRINTFN(3, ("received single-frame transfer\n"));
2048 zyd_rx_data(sc
, data
->buf
, len
);
2051 skip
: /* setup a new transfer */
2052 usbd_setup_xfer(xfer
, sc
->zyd_ep
[ZYD_ENDPT_BIN
], data
, NULL
,
2053 ZYX_MAX_RXBUFSZ
, USBD_NO_COPY
| USBD_SHORT_XFER_OK
,
2054 USBD_NO_TIMEOUT
, zyd_rxeof
);
2055 (void)usbd_transfer(xfer
);
2059 zyd_tx_mgt(struct zyd_softc
*sc
, struct mbuf
*m0
, struct ieee80211_node
*ni
)
2061 struct ieee80211com
*ic
= &sc
->sc_ic
;
2062 struct ifnet
*ifp
= &sc
->sc_if
;
2063 struct zyd_tx_desc
*desc
;
2064 struct zyd_tx_data
*data
;
2065 struct ieee80211_frame
*wh
;
2066 struct ieee80211_key
*k
;
2067 int xferlen
, totlen
, rate
;
2071 data
= &sc
->tx_data
[0];
2072 desc
= (struct zyd_tx_desc
*)data
->buf
;
2074 rate
= IEEE80211_IS_CHAN_5GHZ(ic
->ic_curchan
) ? 12 : 2;
2076 wh
= mtod(m0
, struct ieee80211_frame
*);
2078 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
) {
2079 k
= ieee80211_crypto_encap(ic
, ni
, m0
);
2088 wh
= mtod(m0
, struct ieee80211_frame
*);
2090 xferlen
= sizeof (struct zyd_tx_desc
) + m0
->m_pkthdr
.len
;
2091 totlen
= m0
->m_pkthdr
.len
+ IEEE80211_CRC_LEN
;
2093 /* fill Tx descriptor */
2094 desc
->len
= htole16(totlen
);
2096 desc
->flags
= ZYD_TX_FLAG_BACKOFF
;
2097 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
)) {
2098 /* multicast frames are not sent at OFDM rates in 802.11b/g */
2099 if (totlen
> ic
->ic_rtsthreshold
) {
2100 desc
->flags
|= ZYD_TX_FLAG_RTS
;
2101 } else if (ZYD_RATE_IS_OFDM(rate
) &&
2102 (ic
->ic_flags
& IEEE80211_F_USEPROT
)) {
2103 if (ic
->ic_protmode
== IEEE80211_PROT_CTSONLY
)
2104 desc
->flags
|= ZYD_TX_FLAG_CTS_TO_SELF
;
2105 else if (ic
->ic_protmode
== IEEE80211_PROT_RTSCTS
)
2106 desc
->flags
|= ZYD_TX_FLAG_RTS
;
2109 desc
->flags
|= ZYD_TX_FLAG_MULTICAST
;
2112 (IEEE80211_FC0_TYPE_MASK
| IEEE80211_FC0_SUBTYPE_MASK
)) ==
2113 (IEEE80211_FC0_TYPE_CTL
| IEEE80211_FC0_SUBTYPE_PS_POLL
))
2114 desc
->flags
|= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL
);
2116 desc
->phy
= zyd_plcp_signal(rate
);
2117 if (ZYD_RATE_IS_OFDM(rate
)) {
2118 desc
->phy
|= ZYD_TX_PHY_OFDM
;
2119 if (ic
->ic_curmode
== IEEE80211_MODE_11A
)
2120 desc
->phy
|= ZYD_TX_PHY_5GHZ
;
2121 } else if (rate
!= 2 && (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
))
2122 desc
->phy
|= ZYD_TX_PHY_SHPREAMBLE
;
2124 /* actual transmit length (XXX why +10?) */
2125 pktlen
= sizeof (struct zyd_tx_desc
) + 10;
2126 if (sc
->mac_rev
== ZYD_ZD1211
)
2128 desc
->pktlen
= htole16(pktlen
);
2130 desc
->plcp_length
= (16 * totlen
+ rate
- 1) / rate
;
2131 desc
->plcp_service
= 0;
2133 const int remainder
= (16 * totlen
) % 22;
2134 if (remainder
!= 0 && remainder
< 7)
2135 desc
->plcp_service
|= ZYD_PLCP_LENGEXT
;
2139 if (sc
->sc_drvbpf
!= NULL
) {
2140 struct zyd_tx_radiotap_header
*tap
= &sc
->sc_txtap
;
2143 tap
->wt_rate
= rate
;
2144 tap
->wt_chan_freq
= htole16(ic
->ic_curchan
->ic_freq
);
2145 tap
->wt_chan_flags
= htole16(ic
->ic_curchan
->ic_flags
);
2147 bpf_mtap2(sc
->sc_drvbpf
, tap
, sc
->sc_txtap_len
, m0
);
2151 m_copydata(m0
, 0, m0
->m_pkthdr
.len
,
2152 data
->buf
+ sizeof (struct zyd_tx_desc
));
2154 DPRINTFN(10, ("%s: sending mgt frame len=%zu rate=%u xferlen=%u\n",
2155 device_xname(sc
->sc_dev
), (size_t)m0
->m_pkthdr
.len
, rate
, xferlen
));
2157 m_freem(m0
); /* mbuf no longer needed */
2159 usbd_setup_xfer(data
->xfer
, sc
->zyd_ep
[ZYD_ENDPT_BOUT
], data
,
2160 data
->buf
, xferlen
, USBD_FORCE_SHORT_XFER
| USBD_NO_COPY
,
2161 ZYD_TX_TIMEOUT
, zyd_txeof
);
2162 error
= usbd_transfer(data
->xfer
);
2163 if (error
!= USBD_IN_PROGRESS
&& error
!= 0) {
2173 zyd_txeof(usbd_xfer_handle xfer
, usbd_private_handle priv
, usbd_status status
)
2175 struct zyd_tx_data
*data
= priv
;
2176 struct zyd_softc
*sc
= data
->sc
;
2177 struct ifnet
*ifp
= &sc
->sc_if
;
2180 if (status
!= USBD_NORMAL_COMPLETION
) {
2181 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
)
2184 printf("%s: could not transmit buffer: %s\n",
2185 device_xname(sc
->sc_dev
), usbd_errstr(status
));
2187 if (status
== USBD_STALLED
) {
2188 usbd_clear_endpoint_stall_async(
2189 sc
->zyd_ep
[ZYD_ENDPT_BOUT
]);
2197 /* update rate control statistics */
2198 ((struct zyd_node
*)data
->ni
)->amn
.amn_txcnt
++;
2200 ieee80211_free_node(data
->ni
);
2207 ifp
->if_flags
&= ~IFF_OACTIVE
;
2214 zyd_tx_data(struct zyd_softc
*sc
, struct mbuf
*m0
, struct ieee80211_node
*ni
)
2216 struct ieee80211com
*ic
= &sc
->sc_ic
;
2217 struct ifnet
*ifp
= &sc
->sc_if
;
2218 struct zyd_tx_desc
*desc
;
2219 struct zyd_tx_data
*data
;
2220 struct ieee80211_frame
*wh
;
2221 struct ieee80211_key
*k
;
2222 int xferlen
, totlen
, rate
;
2226 wh
= mtod(m0
, struct ieee80211_frame
*);
2228 if (ic
->ic_fixed_rate
!= IEEE80211_FIXED_RATE_NONE
)
2229 rate
= ic
->ic_bss
->ni_rates
.rs_rates
[ic
->ic_fixed_rate
];
2231 rate
= ni
->ni_rates
.rs_rates
[ni
->ni_txrate
];
2232 rate
&= IEEE80211_RATE_VAL
;
2234 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
) {
2235 k
= ieee80211_crypto_encap(ic
, ni
, m0
);
2241 /* packet header may have moved, reset our local pointer */
2242 wh
= mtod(m0
, struct ieee80211_frame
*);
2245 data
= &sc
->tx_data
[0];
2246 desc
= (struct zyd_tx_desc
*)data
->buf
;
2250 xferlen
= sizeof (struct zyd_tx_desc
) + m0
->m_pkthdr
.len
;
2251 totlen
= m0
->m_pkthdr
.len
+ IEEE80211_CRC_LEN
;
2253 /* fill Tx descriptor */
2254 desc
->len
= htole16(totlen
);
2256 desc
->flags
= ZYD_TX_FLAG_BACKOFF
;
2257 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
)) {
2258 /* multicast frames are not sent at OFDM rates in 802.11b/g */
2259 if (totlen
> ic
->ic_rtsthreshold
) {
2260 desc
->flags
|= ZYD_TX_FLAG_RTS
;
2261 } else if (ZYD_RATE_IS_OFDM(rate
) &&
2262 (ic
->ic_flags
& IEEE80211_F_USEPROT
)) {
2263 if (ic
->ic_protmode
== IEEE80211_PROT_CTSONLY
)
2264 desc
->flags
|= ZYD_TX_FLAG_CTS_TO_SELF
;
2265 else if (ic
->ic_protmode
== IEEE80211_PROT_RTSCTS
)
2266 desc
->flags
|= ZYD_TX_FLAG_RTS
;
2269 desc
->flags
|= ZYD_TX_FLAG_MULTICAST
;
2272 (IEEE80211_FC0_TYPE_MASK
| IEEE80211_FC0_SUBTYPE_MASK
)) ==
2273 (IEEE80211_FC0_TYPE_CTL
| IEEE80211_FC0_SUBTYPE_PS_POLL
))
2274 desc
->flags
|= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL
);
2276 desc
->phy
= zyd_plcp_signal(rate
);
2277 if (ZYD_RATE_IS_OFDM(rate
)) {
2278 desc
->phy
|= ZYD_TX_PHY_OFDM
;
2279 if (ic
->ic_curmode
== IEEE80211_MODE_11A
)
2280 desc
->phy
|= ZYD_TX_PHY_5GHZ
;
2281 } else if (rate
!= 2 && (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
))
2282 desc
->phy
|= ZYD_TX_PHY_SHPREAMBLE
;
2284 /* actual transmit length (XXX why +10?) */
2285 pktlen
= sizeof (struct zyd_tx_desc
) + 10;
2286 if (sc
->mac_rev
== ZYD_ZD1211
)
2288 desc
->pktlen
= htole16(pktlen
);
2290 desc
->plcp_length
= (16 * totlen
+ rate
- 1) / rate
;
2291 desc
->plcp_service
= 0;
2293 const int remainder
= (16 * totlen
) % 22;
2294 if (remainder
!= 0 && remainder
< 7)
2295 desc
->plcp_service
|= ZYD_PLCP_LENGEXT
;
2299 if (sc
->sc_drvbpf
!= NULL
) {
2300 struct zyd_tx_radiotap_header
*tap
= &sc
->sc_txtap
;
2303 tap
->wt_rate
= rate
;
2304 tap
->wt_chan_freq
= htole16(ic
->ic_curchan
->ic_freq
);
2305 tap
->wt_chan_flags
= htole16(ic
->ic_curchan
->ic_flags
);
2307 bpf_mtap2(sc
->sc_drvbpf
, tap
, sc
->sc_txtap_len
, m0
);
2311 m_copydata(m0
, 0, m0
->m_pkthdr
.len
,
2312 data
->buf
+ sizeof (struct zyd_tx_desc
));
2314 DPRINTFN(10, ("%s: sending data frame len=%zu rate=%u xferlen=%u\n",
2315 device_xname(sc
->sc_dev
), (size_t)m0
->m_pkthdr
.len
, rate
, xferlen
));
2317 m_freem(m0
); /* mbuf no longer needed */
2319 usbd_setup_xfer(data
->xfer
, sc
->zyd_ep
[ZYD_ENDPT_BOUT
], data
,
2320 data
->buf
, xferlen
, USBD_FORCE_SHORT_XFER
| USBD_NO_COPY
,
2321 ZYD_TX_TIMEOUT
, zyd_txeof
);
2322 error
= usbd_transfer(data
->xfer
);
2323 if (error
!= USBD_IN_PROGRESS
&& error
!= 0) {
2333 zyd_start(struct ifnet
*ifp
)
2335 struct zyd_softc
*sc
= ifp
->if_softc
;
2336 struct ieee80211com
*ic
= &sc
->sc_ic
;
2337 struct ether_header
*eh
;
2338 struct ieee80211_node
*ni
;
2342 IF_POLL(&ic
->ic_mgtq
, m0
);
2344 if (sc
->tx_queued
>= ZYD_TX_LIST_CNT
) {
2345 ifp
->if_flags
|= IFF_OACTIVE
;
2348 IF_DEQUEUE(&ic
->ic_mgtq
, m0
);
2350 ni
= (struct ieee80211_node
*)m0
->m_pkthdr
.rcvif
;
2351 m0
->m_pkthdr
.rcvif
= NULL
;
2353 if (ic
->ic_rawbpf
!= NULL
)
2354 bpf_mtap(ic
->ic_rawbpf
, m0
);
2356 if (zyd_tx_mgt(sc
, m0
, ni
) != 0)
2359 if (ic
->ic_state
!= IEEE80211_S_RUN
)
2361 IFQ_POLL(&ifp
->if_snd
, m0
);
2364 if (sc
->tx_queued
>= ZYD_TX_LIST_CNT
) {
2365 ifp
->if_flags
|= IFF_OACTIVE
;
2368 IFQ_DEQUEUE(&ifp
->if_snd
, m0
);
2370 if (m0
->m_len
< sizeof(struct ether_header
) &&
2371 !(m0
= m_pullup(m0
, sizeof(struct ether_header
))))
2374 eh
= mtod(m0
, struct ether_header
*);
2375 ni
= ieee80211_find_txnode(ic
, eh
->ether_dhost
);
2381 if (ifp
->if_bpf
!= NULL
)
2382 bpf_mtap(ifp
->if_bpf
, m0
);
2384 if ((m0
= ieee80211_encap(ic
, m0
, ni
)) == NULL
) {
2385 ieee80211_free_node(ni
);
2390 if (ic
->ic_rawbpf
!= NULL
)
2391 bpf_mtap(ic
->ic_rawbpf
, m0
);
2393 if (zyd_tx_data(sc
, m0
, ni
) != 0) {
2394 ieee80211_free_node(ni
);
2406 zyd_watchdog(struct ifnet
*ifp
)
2408 struct zyd_softc
*sc
= ifp
->if_softc
;
2409 struct ieee80211com
*ic
= &sc
->sc_ic
;
2413 if (sc
->tx_timer
> 0) {
2414 if (--sc
->tx_timer
== 0) {
2415 printf("%s: device timeout\n", device_xname(sc
->sc_dev
));
2416 /* zyd_init(ifp); XXX needs a process context ? */
2423 ieee80211_watchdog(ic
);
2427 zyd_ioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
2429 struct zyd_softc
*sc
= ifp
->if_softc
;
2430 struct ieee80211com
*ic
= &sc
->sc_ic
;
2437 if ((error
= ifioctl_common(ifp
, cmd
, data
)) != 0)
2439 /* XXX re-use ether_ioctl() */
2440 switch (ifp
->if_flags
& (IFF_UP
|IFF_RUNNING
)) {
2453 error
= ieee80211_ioctl(ic
, cmd
, data
);
2456 if (error
== ENETRESET
) {
2457 if ((ifp
->if_flags
& (IFF_RUNNING
| IFF_UP
)) ==
2458 (IFF_RUNNING
| IFF_UP
))
2469 zyd_init(struct ifnet
*ifp
)
2471 struct zyd_softc
*sc
= ifp
->if_softc
;
2472 struct ieee80211com
*ic
= &sc
->sc_ic
;
2475 if ((sc
->sc_flags
& ZD1211_FWLOADED
) == 0)
2476 if ((error
= zyd_attachhook(sc
)) != 0)
2481 IEEE80211_ADDR_COPY(ic
->ic_myaddr
, CLLADDR(ifp
->if_sadl
));
2482 DPRINTF(("setting MAC address to %s\n", ether_sprintf(ic
->ic_myaddr
)));
2483 error
= zyd_set_macaddr(sc
, ic
->ic_myaddr
);
2487 /* we'll do software WEP decryption for now */
2488 DPRINTF(("setting encryption type\n"));
2489 error
= zyd_write32(sc
, ZYD_MAC_ENCRYPTION_TYPE
, ZYD_ENC_SNIFFER
);
2493 /* promiscuous mode */
2494 (void)zyd_write32(sc
, ZYD_MAC_SNIFFER
,
2495 (ic
->ic_opmode
== IEEE80211_M_MONITOR
) ? 1 : 0);
2497 (void)zyd_set_rxfilter(sc
);
2499 /* switch radio transmitter ON */
2500 (void)zyd_switch_radio(sc
, 1);
2502 /* set basic rates */
2503 if (ic
->ic_curmode
== IEEE80211_MODE_11B
)
2504 (void)zyd_write32(sc
, ZYD_MAC_BAS_RATE
, 0x0003);
2505 else if (ic
->ic_curmode
== IEEE80211_MODE_11A
)
2506 (void)zyd_write32(sc
, ZYD_MAC_BAS_RATE
, 0x1500);
2507 else /* assumes 802.11b/g */
2508 (void)zyd_write32(sc
, ZYD_MAC_BAS_RATE
, 0x000f);
2510 /* set mandatory rates */
2511 if (ic
->ic_curmode
== IEEE80211_MODE_11B
)
2512 (void)zyd_write32(sc
, ZYD_MAC_MAN_RATE
, 0x000f);
2513 else if (ic
->ic_curmode
== IEEE80211_MODE_11A
)
2514 (void)zyd_write32(sc
, ZYD_MAC_MAN_RATE
, 0x1500);
2515 else /* assumes 802.11b/g */
2516 (void)zyd_write32(sc
, ZYD_MAC_MAN_RATE
, 0x150f);
2518 /* set default BSS channel */
2519 ic
->ic_bss
->ni_chan
= ic
->ic_ibss_chan
;
2520 zyd_set_chan(sc
, ic
->ic_bss
->ni_chan
);
2522 /* enable interrupts */
2523 (void)zyd_write32(sc
, ZYD_CR_INTERRUPT
, ZYD_HWINT_MASK
);
2526 * Allocate Tx and Rx xfer queues.
2528 if ((error
= zyd_alloc_tx_list(sc
)) != 0) {
2529 printf("%s: could not allocate Tx list\n",
2530 device_xname(sc
->sc_dev
));
2533 if ((error
= zyd_alloc_rx_list(sc
)) != 0) {
2534 printf("%s: could not allocate Rx list\n",
2535 device_xname(sc
->sc_dev
));
2540 * Start up the receive pipe.
2542 for (i
= 0; i
< ZYD_RX_LIST_CNT
; i
++) {
2543 struct zyd_rx_data
*data
= &sc
->rx_data
[i
];
2545 usbd_setup_xfer(data
->xfer
, sc
->zyd_ep
[ZYD_ENDPT_BIN
], data
,
2546 NULL
, ZYX_MAX_RXBUFSZ
, USBD_NO_COPY
| USBD_SHORT_XFER_OK
,
2547 USBD_NO_TIMEOUT
, zyd_rxeof
);
2548 error
= usbd_transfer(data
->xfer
);
2549 if (error
!= USBD_IN_PROGRESS
&& error
!= 0) {
2550 printf("%s: could not queue Rx transfer\n",
2551 device_xname(sc
->sc_dev
));
2556 ifp
->if_flags
&= ~IFF_OACTIVE
;
2557 ifp
->if_flags
|= IFF_RUNNING
;
2559 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
)
2560 ieee80211_new_state(ic
, IEEE80211_S_RUN
, -1);
2562 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, -1);
2566 fail
: zyd_stop(ifp
, 1);
2571 zyd_stop(struct ifnet
*ifp
, int disable
)
2573 struct zyd_softc
*sc
= ifp
->if_softc
;
2574 struct ieee80211com
*ic
= &sc
->sc_ic
;
2576 ieee80211_new_state(ic
, IEEE80211_S_INIT
, -1); /* free all nodes */
2580 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
2582 /* switch radio transmitter OFF */
2583 (void)zyd_switch_radio(sc
, 0);
2586 (void)zyd_write32(sc
, ZYD_MAC_RXFILTER
, 0);
2588 /* disable interrupts */
2589 (void)zyd_write32(sc
, ZYD_CR_INTERRUPT
, 0);
2591 usbd_abort_pipe(sc
->zyd_ep
[ZYD_ENDPT_BIN
]);
2592 usbd_abort_pipe(sc
->zyd_ep
[ZYD_ENDPT_BOUT
]);
2594 zyd_free_rx_list(sc
);
2595 zyd_free_tx_list(sc
);
2599 zyd_loadfirmware(struct zyd_softc
*sc
, u_char
*fw
, size_t size
)
2601 usb_device_request_t req
;
2605 DPRINTF(("firmware size=%zu\n", size
));
2607 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
2608 req
.bRequest
= ZYD_DOWNLOADREQ
;
2609 USETW(req
.wIndex
, 0);
2611 addr
= ZYD_FIRMWARE_START_ADDR
;
2614 const int mlen
= min(size
, 4096);
2617 * XXXX: When the transfer size is 4096 bytes, it is not
2618 * likely to be able to transfer it.
2619 * The cause is port or machine or chip?
2621 const int mlen
= min(size
, 64);
2624 DPRINTF(("loading firmware block: len=%d, addr=0x%x\n", mlen
,
2627 USETW(req
.wValue
, addr
);
2628 USETW(req
.wLength
, mlen
);
2629 if (usbd_do_request(sc
->sc_udev
, &req
, fw
) != 0)
2637 /* check whether the upload succeeded */
2638 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
2639 req
.bRequest
= ZYD_DOWNLOADSTS
;
2640 USETW(req
.wValue
, 0);
2641 USETW(req
.wIndex
, 0);
2642 USETW(req
.wLength
, sizeof stat
);
2643 if (usbd_do_request(sc
->sc_udev
, &req
, &stat
) != 0)
2646 return (stat
& 0x80) ? EIO
: 0;
2650 zyd_iter_func(void *arg
, struct ieee80211_node
*ni
)
2652 struct zyd_softc
*sc
= arg
;
2653 struct zyd_node
*zn
= (struct zyd_node
*)ni
;
2655 ieee80211_amrr_choose(&sc
->amrr
, ni
, &zn
->amn
);
2659 zyd_amrr_timeout(void *arg
)
2661 struct zyd_softc
*sc
= arg
;
2662 struct ieee80211com
*ic
= &sc
->sc_ic
;
2666 if (ic
->ic_opmode
== IEEE80211_M_STA
)
2667 zyd_iter_func(sc
, ic
->ic_bss
);
2669 ieee80211_iterate_nodes(&ic
->ic_sta
, zyd_iter_func
, sc
);
2672 callout_reset(&sc
->sc_amrr_ch
, hz
, zyd_amrr_timeout
, sc
);
2676 zyd_newassoc(struct ieee80211_node
*ni
, int isnew
)
2678 struct zyd_softc
*sc
= ni
->ni_ic
->ic_ifp
->if_softc
;
2681 ieee80211_amrr_node_init(&sc
->amrr
, &((struct zyd_node
*)ni
)->amn
);
2683 /* set rate to some reasonable initial value */
2684 for (i
= ni
->ni_rates
.rs_nrates
- 1;
2685 i
> 0 && (ni
->ni_rates
.rs_rates
[i
] & IEEE80211_RATE_VAL
) > 72;
2691 zyd_activate(device_ptr_t self
, enum devact act
)
2693 struct zyd_softc
*sc
= device_private(self
);
2696 case DVACT_DEACTIVATE
:
2697 if_deactivate(&sc
->sc_if
);