1/* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */ 2/* $NetBSD: if_zyd.c,v 1.7 2007/06/21 04:04:29 kiyohara Exp $ */
| 1/* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */ 2/* $NetBSD: if_zyd.c,v 1.7 2007/06/21 04:04:29 kiyohara Exp $ */
|
3/* $FreeBSD: head/sys/dev/usb2/wlan/if_zyd2.c 187970 2009-02-01 00:51:25Z thompsa $ */
| 3/* $FreeBSD: head/sys/dev/usb2/wlan/if_zyd2.c 188417 2009-02-09 22:12:47Z thompsa $ */
|
4 5/*- 6 * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr> 7 * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22#include <sys/cdefs.h>
| 4 5/*- 6 * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr> 7 * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22#include <sys/cdefs.h>
|
23__FBSDID("$FreeBSD: head/sys/dev/usb2/wlan/if_zyd2.c 187970 2009-02-01 00:51:25Z thompsa $");
| 23__FBSDID("$FreeBSD: head/sys/dev/usb2/wlan/if_zyd2.c 188417 2009-02-09 22:12:47Z thompsa $");
|
24 25/*
| 24 25/*
|
26 * ZyDAS ZD1211/ZD1211B USB WLAN driver 27 * 28 * NOTE: all function names beginning like "zyd_cfg_" can only 29 * be called from within the config thread function !
| 26 * ZyDAS ZD1211/ZD1211B USB WLAN driver.
|
30 */ 31 32#include <dev/usb2/include/usb2_devid.h> 33#include <dev/usb2/include/usb2_standard.h> 34#include <dev/usb2/include/usb2_mfunc.h> 35#include <dev/usb2/include/usb2_error.h> 36
| 27 */ 28 29#include <dev/usb2/include/usb2_devid.h> 30#include <dev/usb2/include/usb2_standard.h> 31#include <dev/usb2/include/usb2_mfunc.h> 32#include <dev/usb2/include/usb2_error.h> 33
|
37#define usb2_config_td_cc zyd_config_copy 38#define usb2_config_td_softc zyd_softc 39 40#define USB_DEBUG_VAR zyd_debug 41
| |
42#include <dev/usb2/core/usb2_core.h> 43#include <dev/usb2/core/usb2_lookup.h> 44#include <dev/usb2/core/usb2_process.h>
| 34#include <dev/usb2/core/usb2_core.h> 35#include <dev/usb2/core/usb2_lookup.h> 36#include <dev/usb2/core/usb2_process.h>
|
45#include <dev/usb2/core/usb2_config_td.h>
| |
46#include <dev/usb2/core/usb2_debug.h> 47#include <dev/usb2/core/usb2_request.h> 48#include <dev/usb2/core/usb2_busdma.h> 49#include <dev/usb2/core/usb2_util.h> 50 51#include <dev/usb2/wlan/usb2_wlan.h> 52#include <dev/usb2/wlan/if_zydreg.h> 53#include <dev/usb2/wlan/if_zydfw.h> 54 55#if USB_DEBUG 56static int zyd_debug = 0; 57 58SYSCTL_NODE(_hw_usb2, OID_AUTO, zyd, CTLFLAG_RW, 0, "USB zyd"); 59SYSCTL_INT(_hw_usb2_zyd, OID_AUTO, debug, CTLFLAG_RW, &zyd_debug, 0, 60 "zyd debug level");
| 37#include <dev/usb2/core/usb2_debug.h> 38#include <dev/usb2/core/usb2_request.h> 39#include <dev/usb2/core/usb2_busdma.h> 40#include <dev/usb2/core/usb2_util.h> 41 42#include <dev/usb2/wlan/usb2_wlan.h> 43#include <dev/usb2/wlan/if_zydreg.h> 44#include <dev/usb2/wlan/if_zydfw.h> 45 46#if USB_DEBUG 47static int zyd_debug = 0; 48 49SYSCTL_NODE(_hw_usb2, OID_AUTO, zyd, CTLFLAG_RW, 0, "USB zyd"); 50SYSCTL_INT(_hw_usb2_zyd, OID_AUTO, debug, CTLFLAG_RW, &zyd_debug, 0, 51 "zyd debug level");
|
| 52 53enum { 54 ZYD_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 55 ZYD_DEBUG_RECV = 0x00000002, /* basic recv operation */ 56 ZYD_DEBUG_RESET = 0x00000004, /* reset processing */ 57 ZYD_DEBUG_INIT = 0x00000008, /* device init */ 58 ZYD_DEBUG_TX_PROC = 0x00000010, /* tx ISR proc */ 59 ZYD_DEBUG_RX_PROC = 0x00000020, /* rx ISR proc */ 60 ZYD_DEBUG_STATE = 0x00000040, /* 802.11 state transitions */ 61 ZYD_DEBUG_STAT = 0x00000080, /* statistic */ 62 ZYD_DEBUG_FW = 0x00000100, /* firmware */ 63 ZYD_DEBUG_CMD = 0x00000200, /* fw commands */ 64 ZYD_DEBUG_ANY = 0xffffffff 65}; 66#define DPRINTF(sc, m, fmt, ...) do { \ 67 if (zyd_debug & (m)) \ 68 printf("%s: " fmt, __func__, ## __VA_ARGS__); \ 69} while (0) 70#else 71#define DPRINTF(sc, m, fmt, ...) do { \ 72 (void) sc; \ 73} while (0)
|
61#endif 62
| 74#endif 75
|
63#undef INDEXES 64#define INDEXES(a) (sizeof(a) / sizeof((a)[0]))
| 76#define zyd_do_request(sc,req,data) \ 77 usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000)
|
65
| 78
|
66static device_probe_t zyd_probe;
| 79static device_probe_t zyd_match;
|
67static device_attach_t zyd_attach; 68static device_detach_t zyd_detach; 69
| 80static device_attach_t zyd_attach; 81static device_detach_t zyd_detach; 82
|
70static usb2_callback_t zyd_intr_read_clear_stall_callback;
| |
71static usb2_callback_t zyd_intr_read_callback;
| 83static usb2_callback_t zyd_intr_read_callback;
|
72static usb2_callback_t zyd_intr_write_clear_stall_callback;
| |
73static usb2_callback_t zyd_intr_write_callback;
| 84static usb2_callback_t zyd_intr_write_callback;
|
74static usb2_callback_t zyd_bulk_read_clear_stall_callback;
| |
75static usb2_callback_t zyd_bulk_read_callback;
| 85static usb2_callback_t zyd_bulk_read_callback;
|
76static usb2_callback_t zyd_bulk_write_clear_stall_callback;
| |
77static usb2_callback_t zyd_bulk_write_callback; 78
| 86static usb2_callback_t zyd_bulk_write_callback; 87
|
79static usb2_config_td_command_t zyd_cfg_first_time_setup; 80static usb2_config_td_command_t zyd_cfg_update_promisc; 81static usb2_config_td_command_t zyd_cfg_set_chan; 82static usb2_config_td_command_t zyd_cfg_pre_init; 83static usb2_config_td_command_t zyd_cfg_init; 84static usb2_config_td_command_t zyd_cfg_pre_stop; 85static usb2_config_td_command_t zyd_cfg_stop; 86static usb2_config_td_command_t zyd_config_copy; 87static usb2_config_td_command_t zyd_cfg_scan_start; 88static usb2_config_td_command_t zyd_cfg_scan_end; 89static usb2_config_td_command_t zyd_cfg_set_rxfilter; 90static usb2_config_td_command_t zyd_cfg_amrr_timeout;
| 88static usb2_proc_callback_t zyd_attach_post; 89static usb2_proc_callback_t zyd_task; 90static usb2_proc_callback_t zyd_scantask; 91static usb2_proc_callback_t zyd_multitask; 92static usb2_proc_callback_t zyd_init_task; 93static usb2_proc_callback_t zyd_stop_task;
|
91
| 94
|
92static uint8_t zyd_plcp2ieee(uint8_t, uint8_t); 93static void zyd_cfg_usbrequest(struct zyd_softc *, 94 struct usb2_device_request *, uint8_t *); 95static void zyd_cfg_usb2_intr_read(struct zyd_softc *, void *, uint32_t); 96static void zyd_cfg_usb2_intr_write(struct zyd_softc *, const void *, 97 uint16_t, uint32_t); 98static void zyd_cfg_read16(struct zyd_softc *, uint16_t, uint16_t *); 99static void zyd_cfg_read32(struct zyd_softc *, uint16_t, uint32_t *); 100static void zyd_cfg_write16(struct zyd_softc *, uint16_t, uint16_t); 101static void zyd_cfg_write32(struct zyd_softc *, uint16_t, uint32_t); 102static void zyd_cfg_rfwrite(struct zyd_softc *, uint32_t); 103static uint8_t zyd_cfg_uploadfirmware(struct zyd_softc *, const uint8_t *, 104 uint32_t); 105static void zyd_cfg_lock_phy(struct zyd_softc *); 106static void zyd_cfg_unlock_phy(struct zyd_softc *); 107static void zyd_cfg_set_beacon_interval(struct zyd_softc *, uint32_t); 108static const char *zyd_rf_name(uint8_t); 109static void zyd_cfg_rf_rfmd_init(struct zyd_softc *, struct zyd_rf *); 110static void zyd_cfg_rf_rfmd_switch_radio(struct zyd_softc *, uint8_t); 111static void zyd_cfg_rf_rfmd_set_channel(struct zyd_softc *, 112 struct zyd_rf *, uint8_t); 113static void zyd_cfg_rf_al2230_switch_radio(struct zyd_softc *, uint8_t); 114static void zyd_cfg_rf_al2230_init(struct zyd_softc *, struct zyd_rf *); 115static void zyd_cfg_rf_al2230_init_b(struct zyd_softc *, struct zyd_rf *); 116static void zyd_cfg_rf_al2230_set_channel(struct zyd_softc *, 117 struct zyd_rf *, uint8_t); 118static uint8_t zyd_cfg_rf_init_hw(struct zyd_softc *, struct zyd_rf *); 119static uint8_t zyd_cfg_hw_init(struct zyd_softc *); 120static void zyd_cfg_set_mac_addr(struct zyd_softc *, const uint8_t *); 121static void zyd_cfg_switch_radio(struct zyd_softc *, uint8_t); 122static void zyd_cfg_set_bssid(struct zyd_softc *, uint8_t *); 123static void zyd_start_cb(struct ifnet *); 124static void zyd_init_cb(void *); 125static int zyd_ioctl_cb(struct ifnet *, u_long command, caddr_t data); 126static void zyd_watchdog(void *); 127static void zyd_end_of_commands(struct zyd_softc *); 128static void zyd_newassoc_cb(struct ieee80211_node *, int isnew); 129static void zyd_scan_start_cb(struct ieee80211com *); 130static void zyd_scan_end_cb(struct ieee80211com *); 131static void zyd_set_channel_cb(struct ieee80211com *); 132static void zyd_cfg_set_led(struct zyd_softc *, uint32_t, uint8_t);
| |
133static struct ieee80211vap *zyd_vap_create(struct ieee80211com *,
| 95static struct ieee80211vap *zyd_vap_create(struct ieee80211com *,
|
134 const char name[IFNAMSIZ], int unit, int opmode, int flags, 135 const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t 136 mac[IEEE80211_ADDR_LEN]); 137static void zyd_vap_delete(struct ieee80211vap *); 138static struct ieee80211_node *zyd_node_alloc_cb(struct ieee80211vap *,
| 96 const char name[IFNAMSIZ], int unit, int opmode, 97 int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
|
139 const uint8_t mac[IEEE80211_ADDR_LEN]);
| 98 const uint8_t mac[IEEE80211_ADDR_LEN]);
|
140static void zyd_cfg_set_run(struct zyd_softc *, struct usb2_config_td_cc *); 141static void zyd_fill_write_queue(struct zyd_softc *); 142static void zyd_tx_clean_queue(struct zyd_softc *); 143static void zyd_tx_freem(struct mbuf *); 144static void zyd_tx_mgt(struct zyd_softc *, struct mbuf *,
| 99static void zyd_vap_delete(struct ieee80211vap *); 100static void zyd_tx_free(struct zyd_tx_data *, int); 101static void zyd_setup_tx_list(struct zyd_softc *); 102static void zyd_unsetup_tx_list(struct zyd_softc *); 103static struct ieee80211_node *zyd_node_alloc(struct ieee80211vap *, 104 const uint8_t mac[IEEE80211_ADDR_LEN]); 105static int zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int); 106static int zyd_cmd(struct zyd_softc *, uint16_t, const void *, int, 107 void *, int, u_int); 108static int zyd_read16(struct zyd_softc *, uint16_t, uint16_t *); 109static int zyd_read32(struct zyd_softc *, uint16_t, uint32_t *); 110static int zyd_write16(struct zyd_softc *, uint16_t, uint16_t); 111static int zyd_write32(struct zyd_softc *, uint16_t, uint32_t); 112static int zyd_rfwrite(struct zyd_softc *, uint32_t); 113static int zyd_lock_phy(struct zyd_softc *); 114static int zyd_unlock_phy(struct zyd_softc *); 115static int zyd_rf_attach(struct zyd_softc *, uint8_t); 116static const char *zyd_rf_name(uint8_t); 117static int zyd_hw_init(struct zyd_softc *); 118static int zyd_read_pod(struct zyd_softc *); 119static int zyd_read_eeprom(struct zyd_softc *); 120static int zyd_get_macaddr(struct zyd_softc *); 121static int zyd_set_macaddr(struct zyd_softc *, const uint8_t *); 122static int zyd_set_bssid(struct zyd_softc *, const uint8_t *); 123static int zyd_switch_radio(struct zyd_softc *, int); 124static int zyd_set_led(struct zyd_softc *, int, int); 125static void zyd_set_multi(struct zyd_softc *); 126static void zyd_update_mcast(struct ifnet *); 127static int zyd_set_rxfilter(struct zyd_softc *); 128static void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *); 129static int zyd_set_beacon_interval(struct zyd_softc *, int); 130static void zyd_rx_data(struct usb2_xfer *, int, uint16_t); 131static int zyd_tx_mgt(struct zyd_softc *, struct mbuf *,
|
145 struct ieee80211_node *);
| 132 struct ieee80211_node *);
|
146static struct ieee80211vap *zyd_get_vap(struct zyd_softc *); 147static void zyd_tx_data(struct zyd_softc *, struct mbuf *,
| 133static int zyd_tx_data(struct zyd_softc *, struct mbuf *,
|
148 struct ieee80211_node *);
| 134 struct ieee80211_node *);
|
149static int zyd_raw_xmit_cb(struct ieee80211_node *, struct mbuf *,
| 135static void zyd_start(struct ifnet *); 136static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *,
|
150 const struct ieee80211_bpf_params *);
| 137 const struct ieee80211_bpf_params *);
|
151static void zyd_setup_desc_and_tx(struct zyd_softc *, struct mbuf *, 152 uint16_t); 153static int zyd_newstate_cb(struct ieee80211vap *, 154 enum ieee80211_state nstate, int arg); 155static void zyd_cfg_amrr_start(struct zyd_softc *); 156static void zyd_update_mcast_cb(struct ifnet *); 157static void zyd_update_promisc_cb(struct ifnet *); 158static void zyd_cfg_get_macaddr(struct zyd_softc *sc);
| 138static int zyd_ioctl(struct ifnet *, u_long, caddr_t); 139static void zyd_init(void *); 140static int zyd_loadfirmware(struct zyd_softc *); 141static void zyd_newassoc(struct ieee80211_node *, int); 142static void zyd_scan_start(struct ieee80211com *); 143static void zyd_scan_end(struct ieee80211com *); 144static void zyd_set_channel(struct ieee80211com *); 145static int zyd_rfmd_init(struct zyd_rf *); 146static int zyd_rfmd_switch_radio(struct zyd_rf *, int); 147static int zyd_rfmd_set_channel(struct zyd_rf *, uint8_t); 148static int zyd_al2230_init(struct zyd_rf *); 149static int zyd_al2230_switch_radio(struct zyd_rf *, int); 150static int zyd_al2230_set_channel(struct zyd_rf *, uint8_t); 151static int zyd_al2230_set_channel_b(struct zyd_rf *, uint8_t); 152static int zyd_al2230_init_b(struct zyd_rf *); 153static int zyd_al7230B_init(struct zyd_rf *); 154static int zyd_al7230B_switch_radio(struct zyd_rf *, int); 155static int zyd_al7230B_set_channel(struct zyd_rf *, uint8_t); 156static int zyd_al2210_init(struct zyd_rf *); 157static int zyd_al2210_switch_radio(struct zyd_rf *, int); 158static int zyd_al2210_set_channel(struct zyd_rf *, uint8_t); 159static int zyd_gct_init(struct zyd_rf *); 160static int zyd_gct_switch_radio(struct zyd_rf *, int); 161static int zyd_gct_set_channel(struct zyd_rf *, uint8_t); 162static int zyd_maxim_init(struct zyd_rf *); 163static int zyd_maxim_switch_radio(struct zyd_rf *, int); 164static int zyd_maxim_set_channel(struct zyd_rf *, uint8_t); 165static int zyd_maxim2_init(struct zyd_rf *); 166static int zyd_maxim2_switch_radio(struct zyd_rf *, int); 167static int zyd_maxim2_set_channel(struct zyd_rf *, uint8_t); 168static void zyd_queue_command(struct zyd_softc *, usb2_proc_callback_t *, 169 struct usb2_proc_msg *, struct usb2_proc_msg *);
|
159 160static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY; 161static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB; 162 163/* various supported device vendors/products */
| 170 171static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY; 172static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB; 173 174/* various supported device vendors/products */
|
164#define ZYD_ZD1211 0 165#define ZYD_ZD1211B 1
| 175#define ZYD_ZD1211 0 176#define ZYD_ZD1211B 1
|
166 167static const struct usb2_device_id zyd_devs[] = {
| 177 178static const struct usb2_device_id zyd_devs[] = {
|
168 /* ZYD_ZD1211 */ 169 {USB_VPI(USB_VENDOR_3COM2, USB_PRODUCT_3COM2_3CRUSB10075, ZYD_ZD1211)}, 170 {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WL54, ZYD_ZD1211)}, 171 {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL159G, ZYD_ZD1211)}, 172 {USB_VPI(USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_TG54USB, ZYD_ZD1211)}, 173 {USB_VPI(USB_VENDOR_DRAYTEK, USB_PRODUCT_DRAYTEK_VIGOR550, ZYD_ZD1211)}, 174 {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GD, ZYD_ZD1211)}, 175 {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GZL, ZYD_ZD1211)}, 176 {USB_VPI(USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54GZ, ZYD_ZD1211)}, 177 {USB_VPI(USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54MINI, ZYD_ZD1211)}, 178 {USB_VPI(USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG760A, ZYD_ZD1211)}, 179 {USB_VPI(USB_VENDOR_SENAO, USB_PRODUCT_SENAO_NUB8301, ZYD_ZD1211)}, 180 {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113, ZYD_ZD1211)}, 181 {USB_VPI(USB_VENDOR_SWEEX, USB_PRODUCT_SWEEX_ZD1211, ZYD_ZD1211)}, 182 {USB_VPI(USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_QUICKWLAN, ZYD_ZD1211)}, 183 {USB_VPI(USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_1, ZYD_ZD1211)}, 184 {USB_VPI(USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_2, ZYD_ZD1211)}, 185 {USB_VPI(USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_G240, ZYD_ZD1211)}, 186 {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_ALL0298V2, ZYD_ZD1211)}, 187 {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB_A, ZYD_ZD1211)}, 188 {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB, ZYD_ZD1211)}, 189 {USB_VPI(USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR055G, ZYD_ZD1211)}, 190 {USB_VPI(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211, ZYD_ZD1211)}, 191 {USB_VPI(USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211, ZYD_ZD1211)}, 192 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_AG225H, ZYD_ZD1211)}, 193 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_ZYAIRG220, ZYD_ZD1211)}, 194 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G200V2, ZYD_ZD1211)}, 195 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G202, ZYD_ZD1211)}, 196 /* ZYD_ZD1211B */ 197 {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBG, ZYD_ZD1211B)}, 198 {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_ZD1211B, ZYD_ZD1211B)}, 199 {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_A9T_WIFI, ZYD_ZD1211B)}, 200 {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050_V4000, ZYD_ZD1211B)}, 201 {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_ZD1211B, ZYD_ZD1211B)}, 202 {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSBF54G, ZYD_ZD1211B)}, 203 {USB_VPI(USB_VENDOR_FIBERLINE, USB_PRODUCT_FIBERLINE_WL430U, ZYD_ZD1211B)}, 204 {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54L, ZYD_ZD1211B)}, 205 {USB_VPI(USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU5600, ZYD_ZD1211B)}, 206 {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US54GXS, ZYD_ZD1211B)}, 207 {USB_VPI(USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG76NA, ZYD_ZD1211B)}, 208 {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_ZD1211B, ZYD_ZD1211B)}, 209 {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UBC1, ZYD_ZD1211B)}, 210 {USB_VPI(USB_VENDOR_USR, USB_PRODUCT_USR_USR5423, ZYD_ZD1211B)}, 211 {USB_VPI(USB_VENDOR_VTECH, USB_PRODUCT_VTECH_ZD1211B, ZYD_ZD1211B)}, 212 {USB_VPI(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211B, ZYD_ZD1211B)}, 213 {USB_VPI(USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211B, ZYD_ZD1211B)}, 214 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_M202, ZYD_ZD1211B)}, 215 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G220V2, ZYD_ZD1211B)},
| 179 /* ZYD_ZD1211 */ 180 {USB_VPI(USB_VENDOR_3COM2, USB_PRODUCT_3COM2_3CRUSB10075, ZYD_ZD1211)}, 181 {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WL54, ZYD_ZD1211)}, 182 {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL159G, ZYD_ZD1211)}, 183 {USB_VPI(USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_TG54USB, ZYD_ZD1211)}, 184 {USB_VPI(USB_VENDOR_DRAYTEK, USB_PRODUCT_DRAYTEK_VIGOR550, ZYD_ZD1211)}, 185 {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GD, ZYD_ZD1211)}, 186 {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GZL, ZYD_ZD1211)}, 187 {USB_VPI(USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54GZ, ZYD_ZD1211)}, 188 {USB_VPI(USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54MINI, ZYD_ZD1211)}, 189 {USB_VPI(USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG760A, ZYD_ZD1211)}, 190 {USB_VPI(USB_VENDOR_SENAO, USB_PRODUCT_SENAO_NUB8301, ZYD_ZD1211)}, 191 {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113, ZYD_ZD1211)}, 192 {USB_VPI(USB_VENDOR_SWEEX, USB_PRODUCT_SWEEX_ZD1211, ZYD_ZD1211)}, 193 {USB_VPI(USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_QUICKWLAN, ZYD_ZD1211)}, 194 {USB_VPI(USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_1, ZYD_ZD1211)}, 195 {USB_VPI(USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_2, ZYD_ZD1211)}, 196 {USB_VPI(USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_G240, ZYD_ZD1211)}, 197 {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_ALL0298V2, ZYD_ZD1211)}, 198 {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB_A, ZYD_ZD1211)}, 199 {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB, ZYD_ZD1211)}, 200 {USB_VPI(USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR055G, ZYD_ZD1211)}, 201 {USB_VPI(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211, ZYD_ZD1211)}, 202 {USB_VPI(USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211, ZYD_ZD1211)}, 203 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_AG225H, ZYD_ZD1211)}, 204 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_ZYAIRG220, ZYD_ZD1211)}, 205 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G200V2, ZYD_ZD1211)}, 206 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G202, ZYD_ZD1211)}, 207 /* ZYD_ZD1211B */ 208 {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBG, ZYD_ZD1211B)}, 209 {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_ZD1211B, ZYD_ZD1211B)}, 210 {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_A9T_WIFI, ZYD_ZD1211B)}, 211 {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050_V4000, ZYD_ZD1211B)}, 212 {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_ZD1211B, ZYD_ZD1211B)}, 213 {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSBF54G, ZYD_ZD1211B)}, 214 {USB_VPI(USB_VENDOR_FIBERLINE, USB_PRODUCT_FIBERLINE_WL430U, ZYD_ZD1211B)}, 215 {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54L, ZYD_ZD1211B)}, 216 {USB_VPI(USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU5600, ZYD_ZD1211B)}, 217 {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US54GXS, ZYD_ZD1211B)}, 218 {USB_VPI(USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG76NA, ZYD_ZD1211B)}, 219 {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_ZD1211B, ZYD_ZD1211B)}, 220 {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UBC1, ZYD_ZD1211B)}, 221 {USB_VPI(USB_VENDOR_USR, USB_PRODUCT_USR_USR5423, ZYD_ZD1211B)}, 222 {USB_VPI(USB_VENDOR_VTECH, USB_PRODUCT_VTECH_ZD1211B, ZYD_ZD1211B)}, 223 {USB_VPI(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211B, ZYD_ZD1211B)}, 224 {USB_VPI(USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211B, ZYD_ZD1211B)}, 225 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_M202, ZYD_ZD1211B)}, 226 {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G220V2, ZYD_ZD1211B)},
|
216}; 217 218static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
| 227}; 228 229static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
|
219 [ZYD_BULK_DT_WR] = {
| 230 [ZYD_BULK_WR] = {
|
220 .type = UE_BULK, 221 .endpoint = UE_ADDR_ANY, 222 .direction = UE_DIR_OUT, 223 .mh.bufsize = ZYD_MAX_TXBUFSZ, 224 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
| 231 .type = UE_BULK, 232 .endpoint = UE_ADDR_ANY, 233 .direction = UE_DIR_OUT, 234 .mh.bufsize = ZYD_MAX_TXBUFSZ, 235 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
|
225 .mh.callback = &zyd_bulk_write_callback,
| 236 .mh.callback = zyd_bulk_write_callback,
|
226 .ep_index = 0, 227 .mh.timeout = 10000, /* 10 seconds */ 228 },
| 237 .ep_index = 0, 238 .mh.timeout = 10000, /* 10 seconds */ 239 },
|
229 230 [ZYD_BULK_DT_RD] = {
| 240 [ZYD_BULK_RD] = {
|
231 .type = UE_BULK, 232 .endpoint = UE_ADDR_ANY, 233 .direction = UE_DIR_IN, 234 .mh.bufsize = ZYX_MAX_RXBUFSZ, 235 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
| 241 .type = UE_BULK, 242 .endpoint = UE_ADDR_ANY, 243 .direction = UE_DIR_IN, 244 .mh.bufsize = ZYX_MAX_RXBUFSZ, 245 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
|
236 .mh.callback = &zyd_bulk_read_callback,
| 246 .mh.callback = zyd_bulk_read_callback,
|
237 .ep_index = 0, 238 },
| 247 .ep_index = 0, 248 },
|
239 240 [ZYD_BULK_CS_WR] = { 241 .type = UE_CONTROL, 242 .endpoint = 0x00, /* Control pipe */ 243 .direction = UE_DIR_ANY, 244 .mh.bufsize = sizeof(struct usb2_device_request), 245 .mh.flags = {}, 246 .mh.callback = &zyd_bulk_write_clear_stall_callback, 247 .mh.timeout = 1000, /* 1 second */ 248 .mh.interval = 50, /* 50ms */ 249 }, 250 251 [ZYD_BULK_CS_RD] = { 252 .type = UE_CONTROL, 253 .endpoint = 0x00, /* Control pipe */ 254 .direction = UE_DIR_ANY, 255 .mh.bufsize = sizeof(struct usb2_device_request), 256 .mh.flags = {}, 257 .mh.callback = &zyd_bulk_read_clear_stall_callback, 258 .mh.timeout = 1000, /* 1 second */ 259 .mh.interval = 50, /* 50ms */ 260 }, 261 262 [ZYD_INTR_DT_WR] = {
| 249 [ZYD_INTR_WR] = {
|
263 .type = UE_BULK_INTR, 264 .endpoint = UE_ADDR_ANY, 265 .direction = UE_DIR_OUT, 266 .mh.bufsize = sizeof(struct zyd_cmd), 267 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
| 250 .type = UE_BULK_INTR, 251 .endpoint = UE_ADDR_ANY, 252 .direction = UE_DIR_OUT, 253 .mh.bufsize = sizeof(struct zyd_cmd), 254 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
|
268 .mh.callback = &zyd_intr_write_callback,
| 255 .mh.callback = zyd_intr_write_callback,
|
269 .mh.timeout = 1000, /* 1 second */ 270 .ep_index = 1, 271 },
| 256 .mh.timeout = 1000, /* 1 second */ 257 .ep_index = 1, 258 },
|
272 273 [ZYD_INTR_DT_RD] = { 274 .type = UE_BULK_INTR,
| 259 [ZYD_INTR_RD] = { 260 .type = UE_INTERRUPT,
|
275 .endpoint = UE_ADDR_ANY, 276 .direction = UE_DIR_IN, 277 .mh.bufsize = sizeof(struct zyd_cmd), 278 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
| 261 .endpoint = UE_ADDR_ANY, 262 .direction = UE_DIR_IN, 263 .mh.bufsize = sizeof(struct zyd_cmd), 264 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
|
279 .mh.callback = &zyd_intr_read_callback, 280 .ep_index = 1,
| 265 .mh.callback = zyd_intr_read_callback,
|
281 },
| 266 },
|
282 283 [ZYD_INTR_CS_WR] = { 284 .type = UE_CONTROL, 285 .endpoint = 0x00, /* Control pipe */ 286 .direction = UE_DIR_ANY, 287 .mh.bufsize = sizeof(struct usb2_device_request), 288 .mh.flags = {}, 289 .mh.callback = &zyd_intr_write_clear_stall_callback, 290 .mh.timeout = 1000, /* 1 second */ 291 .mh.interval = 50, /* 50ms */ 292 }, 293 294 [ZYD_INTR_CS_RD] = { 295 .type = UE_CONTROL, 296 .endpoint = 0x00, /* Control pipe */ 297 .direction = UE_DIR_ANY, 298 .mh.bufsize = sizeof(struct usb2_device_request), 299 .mh.flags = {}, 300 .mh.callback = &zyd_intr_read_clear_stall_callback, 301 .mh.timeout = 1000, /* 1 second */ 302 .mh.interval = 50, /* 50ms */ 303 },
| |
304};
| 267};
|
| 268#define zyd_read16_m(sc, val, data) do { \ 269 error = zyd_read16(sc, val, data); \ 270 if (error != 0) \ 271 goto fail; \ 272} while (0) 273#define zyd_write16_m(sc, val, data) do { \ 274 error = zyd_write16(sc, val, data); \ 275 if (error != 0) \ 276 goto fail; \ 277} while (0) 278#define zyd_read32_m(sc, val, data) do { \ 279 error = zyd_read32(sc, val, data); \ 280 if (error != 0) \ 281 goto fail; \ 282} while (0) 283#define zyd_write32_m(sc, val, data) do { \ 284 error = zyd_write32(sc, val, data); \ 285 if (error != 0) \ 286 goto fail; \ 287} while (0)
|
305
| 288
|
306static devclass_t zyd_devclass; 307 308static device_method_t zyd_methods[] = { 309 DEVMETHOD(device_probe, zyd_probe), 310 DEVMETHOD(device_attach, zyd_attach), 311 DEVMETHOD(device_detach, zyd_detach), 312 {0, 0} 313}; 314 315static driver_t zyd_driver = { 316 .name = "zyd", 317 .methods = zyd_methods, 318 .size = sizeof(struct zyd_softc), 319}; 320 321DRIVER_MODULE(zyd, ushub, zyd_driver, zyd_devclass, NULL, 0); 322MODULE_DEPEND(zyd, usb2_wlan, 1, 1, 1); 323MODULE_DEPEND(zyd, usb2_core, 1, 1, 1); 324MODULE_DEPEND(zyd, wlan, 1, 1, 1); 325MODULE_DEPEND(zyd, wlan_amrr, 1, 1, 1); 326 327static uint8_t 328zyd_plcp2ieee(uint8_t signal, uint8_t isofdm)
| 289static int 290zyd_match(device_t dev)
|
329{
| 291{
|
330 if (isofdm) { 331 static const uint8_t ofdmrates[16] = 332 {0, 0, 0, 0, 0, 0, 0, 96, 48, 24, 12, 108, 72, 36, 18};
| 292 struct usb2_attach_arg *uaa = device_get_ivars(dev);
|
333
| 293
|
334 return ofdmrates[signal & 0xf]; 335 } else { 336 static const uint8_t cckrates[16] = 337 {0, 0, 0, 0, 4, 0, 0, 11, 0, 0, 2, 0, 0, 0, 22, 0};
| 294 if (uaa->usb2_mode != USB_MODE_HOST) 295 return (ENXIO); 296 if (uaa->info.bConfigIndex != ZYD_CONFIG_INDEX) 297 return (ENXIO); 298 if (uaa->info.bIfaceIndex != ZYD_IFACE_INDEX) 299 return (ENXIO);
|
338
| 300
|
339 return cckrates[signal & 0xf]; 340 }
| 301 return (usb2_lookup_id_by_uaa(zyd_devs, sizeof(zyd_devs), uaa));
|
341} 342
| 302} 303
|
343/* 344 * USB request basic wrapper 345 */ 346static void 347zyd_cfg_usbrequest(struct zyd_softc *sc, struct usb2_device_request *req, uint8_t *data)
| 304static int 305zyd_attach(device_t dev)
|
348{
| 306{
|
349 usb2_error_t err; 350 uint16_t length;
| 307 struct usb2_attach_arg *uaa = device_get_ivars(dev); 308 struct zyd_softc *sc = device_get_softc(dev); 309 int error; 310 uint8_t iface_index;
|
351
| 311
|
352 if (usb2_config_td_is_gone(&sc->sc_config_td)) { 353 goto error;
| 312 if (uaa->info.bcdDevice < 0x4330) { 313 device_printf(dev, "device version mismatch: 0x%X " 314 "(only >= 43.30 supported)\n", 315 uaa->info.bcdDevice); 316 return (EINVAL);
|
354 }
| 317 }
|
355 err = usb2_do_request_flags 356 (sc->sc_udev, &sc->sc_mtx, req, data, 0, NULL, 1000);
| |
357
| 318
|
358 if (err) {
| 319 device_set_usb2_desc(dev); 320 sc->sc_dev = dev; 321 sc->sc_udev = uaa->device; 322 sc->sc_macrev = USB_GET_DRIVER_INFO(uaa);
|
359
| 323
|
360 DPRINTFN(0, "%s: device request failed, err=%s " 361 "(ignored)\n", sc->sc_name, usb2_errstr(err));
| 324 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), 325 MTX_NETWORK_LOCK, MTX_DEF);
|
362
| 326
|
363error: 364 length = UGETW(req->wLength);
| 327 STAILQ_INIT(&sc->sc_rqh);
|
365
| 328
|
366 if ((req->bmRequestType & UT_READ) && length) { 367 bzero(data, length); 368 }
| 329 iface_index = ZYD_IFACE_INDEX; 330 error = usb2_transfer_setup(uaa->device, 331 &iface_index, sc->sc_xfer, zyd_config, 332 ZYD_N_TRANSFER, sc, &sc->sc_mtx); 333 if (error) { 334 device_printf(dev, "could not allocate USB transfers, " 335 "err=%s\n", usb2_errstr(error)); 336 goto detach;
|
369 }
| 337 }
|
370}
| 338 error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx, 339 device_get_nameunit(dev), USB_PRI_MED); 340 if (error) { 341 device_printf(dev, "could not setup config thread!\n"); 342 goto detach; 343 }
|
371
| 344
|
372static void 373zyd_intr_read_clear_stall_callback(struct usb2_xfer *xfer) 374{ 375 struct zyd_softc *sc = xfer->priv_sc; 376 struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_INTR_DT_RD];
| 345 /* fork rest of the attach code */ 346 ZYD_LOCK(sc); 347 zyd_queue_command(sc, zyd_attach_post, 348 &sc->sc_synctask[0].hdr, 349 &sc->sc_synctask[1].hdr); 350 ZYD_UNLOCK(sc); 351 return (0);
|
377
| 352
|
378 if (usb2_clear_stall_callback(xfer, xfer_other)) { 379 DPRINTF("stall cleared\n"); 380 sc->sc_flags &= ~ZYD_FLAG_INTR_READ_STALL; 381 usb2_transfer_start(xfer_other); 382 }
| 353detach: 354 zyd_detach(dev); 355 return (ENXIO); /* failure */
|
383} 384
| 356} 357
|
385/* 386 * Callback handler for interrupt transfer 387 */
| |
388static void
| 358static void
|
389zyd_intr_read_callback(struct usb2_xfer *xfer)
| 359zyd_attach_post(struct usb2_proc_msg *pm)
|
390{
| 360{
|
391 struct zyd_softc *sc = xfer->priv_sc; 392 struct zyd_cmd *cmd = &sc->sc_intr_ibuf; 393 uint32_t actlen;
| 361 struct zyd_task *task = (struct zyd_task *)pm; 362 struct zyd_softc *sc = task->sc; 363 struct ifnet *ifp; 364 struct ieee80211com *ic; 365 int error; 366 uint8_t bands;
|
394
| 367
|
395 switch (USB_GET_STATE(xfer)) { 396 case USB_ST_TRANSFERRED:
| 368 if ((error = zyd_get_macaddr(sc)) != 0) { 369 device_printf(sc->sc_dev, "could not read EEPROM\n"); 370 return; 371 }
|
397
| 372
|
398 actlen = xfer->actlen;
| 373 ZYD_UNLOCK(sc);
|
399
| 374
|
400 DPRINTFN(3, "length=%d\n", actlen); 401 402 if (actlen > sizeof(sc->sc_intr_ibuf)) { 403 actlen = sizeof(sc->sc_intr_ibuf); 404 } 405 usb2_copy_out(xfer->frbuffers, 0, 406 &sc->sc_intr_ibuf, actlen); 407 408 switch (le16toh(cmd->code)) { 409 case ZYD_NOTIF_RETRYSTATUS: 410 goto handle_notif_retrystatus; 411 case ZYD_NOTIF_IORD: 412 goto handle_notif_iord; 413 default: 414 DPRINTFN(2, "unknown indication: 0x%04x\n", 415 le16toh(cmd->code)); 416 } 417 418 /* fallthrough */ 419 420 case USB_ST_SETUP: 421tr_setup: 422 if (sc->sc_flags & ZYD_FLAG_INTR_READ_STALL) { 423 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_CS_RD]); 424 break; 425 } 426 xfer->frlengths[0] = xfer->max_data_length; 427 usb2_start_hardware(xfer); 428 break; 429 430 default: /* Error */ 431 DPRINTFN(3, "error = %s\n", 432 usb2_errstr(xfer->error)); 433 434 if (xfer->error != USB_ERR_CANCELLED) { 435 /* try to clear stall first */ 436 sc->sc_flags |= ZYD_FLAG_INTR_READ_STALL; 437 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_CS_RD]); 438 } 439 break;
| 375 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 376 if (ifp == NULL) { 377 device_printf(sc->sc_dev, "can not if_alloc()\n"); 378 ZYD_LOCK(sc); 379 return;
|
440 }
| 380 }
|
441 return;
| 381 ifp->if_softc = sc; 382 if_initname(ifp, "zyd", device_get_unit(sc->sc_dev)); 383 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 384 ifp->if_init = zyd_init; 385 ifp->if_ioctl = zyd_ioctl; 386 ifp->if_start = zyd_start; 387 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 388 IFQ_SET_READY(&ifp->if_snd);
|
442
| 389
|
443handle_notif_retrystatus:{
| 390 ic = ifp->if_l2com; 391 ic->ic_ifp = ifp; 392 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 393 ic->ic_opmode = IEEE80211_M_STA; 394 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
|
444
| 395
|
445 struct zyd_notif_retry *retry = (void *)(cmd->data); 446 struct ifnet *ifp = sc->sc_ifp; 447 struct ieee80211vap *vap; 448 struct ieee80211_node *ni;
| 396 /* set device capabilities */ 397 ic->ic_caps = 398 IEEE80211_C_STA /* station mode */ 399 | IEEE80211_C_MONITOR /* monitor mode */ 400 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 401 | IEEE80211_C_SHSLOT /* short slot time supported */ 402 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 403 | IEEE80211_C_WPA /* 802.11i */ 404 ;
|
449
| 405
|
450 DPRINTF("retry intr: rate=0x%x " 451 "addr=%02x:%02x:%02x:%02x:%02x:%02x count=%d (0x%x)\n", 452 le16toh(retry->rate), retry->macaddr[0], retry->macaddr[1], 453 retry->macaddr[2], retry->macaddr[3], retry->macaddr[4], 454 retry->macaddr[5], le16toh(retry->count) & 0xff, 455 le16toh(retry->count));
| 406 bands = 0; 407 setbit(&bands, IEEE80211_MODE_11B); 408 setbit(&bands, IEEE80211_MODE_11G); 409 ieee80211_init_channels(ic, NULL, &bands);
|
456
| 410
|
457 vap = zyd_get_vap(sc); 458 if ((vap != NULL) && (sc->sc_amrr_timer)) { 459 /* 460 * Find the node to which the packet was sent 461 * and update its retry statistics. In BSS 462 * mode, this node is the AP we're associated 463 * to so no lookup is actually needed. 464 */ 465 ni = ieee80211_find_txnode(vap, retry->macaddr); 466 if (ni != NULL) { 467 ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn, 468 IEEE80211_AMRR_FAILURE, 1); 469 ieee80211_free_node(ni); 470 } 471 } 472 if (retry->count & htole16(0x100)) { 473 ifp->if_oerrors++; /* too many retries */ 474 } 475 goto tr_setup; 476 }
| 411 ieee80211_ifattach(ic); 412 ic->ic_newassoc = zyd_newassoc; 413 ic->ic_raw_xmit = zyd_raw_xmit; 414 ic->ic_node_alloc = zyd_node_alloc; 415 ic->ic_scan_start = zyd_scan_start; 416 ic->ic_scan_end = zyd_scan_end; 417 ic->ic_set_channel = zyd_set_channel;
|
477
| 418
|
478handle_notif_iord:
| 419 ic->ic_vap_create = zyd_vap_create; 420 ic->ic_vap_delete = zyd_vap_delete; 421 ic->ic_update_mcast = zyd_update_mcast;
|
479
| 422
|
480 if (*(uint16_t *)cmd->data == htole16(ZYD_CR_INTERRUPT)) { 481 goto tr_setup; /* HMAC interrupt */ 482 } 483 if (actlen < 4) { 484 DPRINTFN(0, "too short, %u bytes\n", actlen); 485 goto tr_setup; /* too short */ 486 } 487 actlen -= 4;
| 423 bpfattach(ifp, DLT_IEEE802_11_RADIO, 424 sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap)); 425 sc->sc_rxtap_len = sizeof(sc->sc_rxtap); 426 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 427 sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT); 428 sc->sc_txtap_len = sizeof(sc->sc_txtap); 429 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 430 sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT);
|
488
| 431
|
489 sc->sc_intr_ilen = actlen;
| 432 if (bootverbose) 433 ieee80211_announce(ic);
|
490
| 434
|
491 if (sc->sc_intr_iwakeup) { 492 sc->sc_intr_iwakeup = 0; 493 usb2_cv_signal(&sc->sc_intr_cv); 494 } else { 495 sc->sc_intr_iwakeup = 1; 496 } 497 /* 498 * We pause reading data from the interrupt endpoint until the 499 * data has been picked up! 500 */
| 435 ZYD_LOCK(sc);
|
501} 502
| 436} 437
|
503/* 504 * Interrupt call reply transfer, read 505 */ 506static void 507zyd_cfg_usb2_intr_read(struct zyd_softc *sc, void *data, uint32_t size)
| 438static int 439zyd_detach(device_t dev)
|
508{
| 440{
|
509 uint16_t actlen; 510 uint16_t x;
| 441 struct zyd_softc *sc = device_get_softc(dev); 442 struct ifnet *ifp = sc->sc_ifp; 443 struct ieee80211com *ic = ifp->if_l2com;
|
511
| 444
|
512 if (size > sizeof(sc->sc_intr_ibuf.data)) { 513 DPRINTFN(0, "truncating transfer size!\n"); 514 size = sizeof(sc->sc_intr_ibuf.data); 515 } 516 if (usb2_config_td_is_gone(&sc->sc_config_td)) { 517 bzero(data, size); 518 goto done; 519 } 520 if (sc->sc_intr_iwakeup) { 521 DPRINTF("got data already!\n"); 522 sc->sc_intr_iwakeup = 0; 523 goto skip0; 524 } 525repeat: 526 sc->sc_intr_iwakeup = 1;
| 445 /* wait for any post attach or other command to complete */ 446 usb2_proc_drain(&sc->sc_tq);
|
527
| 447
|
528 while (sc->sc_intr_iwakeup) {
| 448 /* stop all USB transfers */ 449 usb2_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER); 450 usb2_proc_free(&sc->sc_tq);
|
529
| 451
|
530 /* wait for data */
| 452 /* free TX list, if any */ 453 zyd_unsetup_tx_list(sc);
|
531
| 454
|
532 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_RD]); 533 534 if (usb2_cv_timedwait(&sc->sc_intr_cv, 535 &sc->sc_mtx, hz / 2)) { 536 /* should not happen */ 537 } 538 if (usb2_config_td_is_gone(&sc->sc_config_td)) { 539 bzero(data, size); 540 goto done; 541 }
| 455 if (ifp) { 456 bpfdetach(ifp); 457 ieee80211_ifdetach(ic); 458 if_free(ifp);
|
542 }
| 459 }
|
543skip0: 544 if (size != sc->sc_intr_ilen) { 545 DPRINTFN(0, "unexpected length %u != %u\n", 546 size, sc->sc_intr_ilen); 547 goto repeat; 548 } 549 actlen = sc->sc_intr_ilen; 550 actlen /= 4;
| |
551
| 460
|
552 /* verify register values */ 553 for (x = 0; x != actlen; x++) { 554 if (sc->sc_intr_obuf.data[(2 * x)] != 555 sc->sc_intr_ibuf.data[(4 * x)]) { 556 /* invalid register */ 557 DPRINTFN(0, "Invalid register (1) at %u!\n", x); 558 goto repeat; 559 } 560 if (sc->sc_intr_obuf.data[(2 * x) + 1] != 561 sc->sc_intr_ibuf.data[(4 * x) + 1]) { 562 /* invalid register */ 563 DPRINTFN(0, "Invalid register (2) at %u!\n", x); 564 goto repeat; 565 } 566 }
| 461 mtx_destroy(&sc->sc_mtx);
|
567
| 462
|
568 bcopy(sc->sc_intr_ibuf.data, data, size); 569 570 /* 571 * We have fetched the data from the shared buffer and it is 572 * safe to restart the interrupt transfer! 573 */ 574 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_RD]); 575done: 576 return;
| 463 return (0);
|
577} 578
| 464} 465
|
579static void 580zyd_intr_write_clear_stall_callback(struct usb2_xfer *xfer)
| 466static struct ieee80211vap * 467zyd_vap_create(struct ieee80211com *ic, 468 const char name[IFNAMSIZ], int unit, int opmode, int flags, 469 const uint8_t bssid[IEEE80211_ADDR_LEN], 470 const uint8_t mac[IEEE80211_ADDR_LEN])
|
581{
| 471{
|
582 struct zyd_softc *sc = xfer->priv_sc; 583 struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_INTR_DT_WR];
| 472 struct zyd_vap *zvp; 473 struct ieee80211vap *vap;
|
584
| 474
|
585 if (usb2_clear_stall_callback(xfer, xfer_other)) { 586 DPRINTF("stall cleared\n"); 587 sc->sc_flags &= ~ZYD_FLAG_INTR_WRITE_STALL; 588 usb2_transfer_start(xfer_other); 589 } 590}
| 475 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 476 return (NULL); 477 zvp = (struct zyd_vap *) malloc(sizeof(struct zyd_vap), 478 M_80211_VAP, M_NOWAIT | M_ZERO); 479 if (zvp == NULL) 480 return (NULL); 481 vap = &zvp->vap; 482 /* enable s/w bmiss handling for sta mode */ 483 ieee80211_vap_setup(ic, vap, name, unit, opmode, 484 flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
|
591
| 485
|
592static void 593zyd_intr_write_callback(struct usb2_xfer *xfer) 594{ 595 struct zyd_softc *sc = xfer->priv_sc;
| 486 /* override state transition machine */ 487 zvp->newstate = vap->iv_newstate; 488 vap->iv_newstate = zyd_newstate;
|
596
| 489
|
597 switch (USB_GET_STATE(xfer)) { 598 case USB_ST_TRANSFERRED: 599 DPRINTFN(3, "length=%d\n", xfer->actlen); 600 goto wakeup;
| 490 ieee80211_amrr_init(&zvp->amrr, vap, 491 IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, 492 IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, 493 1000 /* 1 sec */);
|
601
| 494
|
602 case USB_ST_SETUP: 603 604 if (sc->sc_flags & ZYD_FLAG_INTR_WRITE_STALL) { 605 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_CS_WR]); 606 goto wakeup; 607 } 608 if (sc->sc_intr_owakeup) { 609 usb2_copy_in(xfer->frbuffers, 0, &sc->sc_intr_obuf, 610 sc->sc_intr_olen); 611 612 xfer->frlengths[0] = sc->sc_intr_olen; 613 usb2_start_hardware(xfer); 614 } 615 break; 616 617 default: /* Error */ 618 DPRINTFN(3, "error = %s\n", 619 usb2_errstr(xfer->error)); 620 621 if (xfer->error != USB_ERR_CANCELLED) { 622 /* try to clear stall first */ 623 sc->sc_flags |= ZYD_FLAG_INTR_WRITE_STALL; 624 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_CS_WR]); 625 } 626 goto wakeup; 627 } 628 return; 629 630wakeup: 631 if (sc->sc_intr_owakeup) { 632 sc->sc_intr_owakeup = 0; 633 usb2_cv_signal(&sc->sc_intr_cv); 634 }
| 495 /* complete setup */ 496 ieee80211_vap_attach(vap, ieee80211_media_change, 497 ieee80211_media_status); 498 ic->ic_opmode = opmode; 499 return (vap);
|
635} 636
| 500} 501
|
637/* 638 * Interrupt transfer, write. 639 * 640 * Not always an "interrupt transfer". If operating in 641 * full speed mode, EP4 is bulk out, not interrupt out. 642 */
| |
643static void
| 502static void
|
644zyd_cfg_usb2_intr_write(struct zyd_softc *sc, const void *data, 645 uint16_t code, uint32_t size)
| 503zyd_vap_delete(struct ieee80211vap *vap)
|
646{
| 504{
|
647 if (size > sizeof(sc->sc_intr_obuf.data)) { 648 DPRINTFN(0, "truncating transfer size!\n"); 649 size = sizeof(sc->sc_intr_obuf.data); 650 } 651 if (usb2_config_td_is_gone(&sc->sc_config_td)) { 652 goto done; 653 } 654 sc->sc_intr_olen = size + 2; 655 sc->sc_intr_owakeup = 1;
| 505 struct zyd_vap *zvp = ZYD_VAP(vap);
|
656
| 506
|
657 sc->sc_intr_obuf.code = htole16(code); 658 bcopy(data, sc->sc_intr_obuf.data, size); 659 660 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_WR]); 661 662 while (sc->sc_intr_owakeup) { 663 if (usb2_cv_timedwait(&sc->sc_intr_cv, 664 &sc->sc_mtx, hz / 2)) { 665 /* should not happen */ 666 } 667 if (usb2_config_td_is_gone(&sc->sc_config_td)) { 668 sc->sc_intr_owakeup = 0; 669 goto done; 670 } 671 } 672done: 673 return;
| 507 ieee80211_amrr_cleanup(&zvp->amrr); 508 ieee80211_vap_detach(vap); 509 free(zvp, M_80211_VAP);
|
674} 675 676static void
| 510} 511 512static void
|
677zyd_cfg_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, uint16_t ilen, 678 void *odata, uint16_t olen, uint16_t flags)
| 513zyd_tx_free(struct zyd_tx_data *data, int txerr)
|
679{
| 514{
|
680 zyd_cfg_usb2_intr_write(sc, idata, code, ilen);
| 515 struct zyd_softc *sc = data->sc;
|
681
| 516
|
682 if (flags & ZYD_CMD_FLAG_READ) { 683 zyd_cfg_usb2_intr_read(sc, odata, olen);
| 517 if (data->m != NULL) { 518 if (data->m->m_flags & M_TXCB) 519 ieee80211_process_callback(data->ni, data->m, 520 txerr ? ETIMEDOUT : 0); 521 m_freem(data->m); 522 data->m = NULL; 523 524 ieee80211_free_node(data->ni); 525 data->ni = NULL;
|
684 }
| 526 }
|
| 527 STAILQ_INSERT_TAIL(&sc->tx_free, data, next); 528 sc->tx_nfree++;
|
685} 686 687static void
| 529} 530 531static void
|
688zyd_cfg_read16(struct zyd_softc *sc, uint16_t addr, uint16_t *value)
| 532zyd_setup_tx_list(struct zyd_softc *sc)
|
689{
| 533{
|
690 struct zyd_pair tmp[1];
| 534 struct zyd_tx_data *data; 535 int i;
|
691
| 536
|
692 addr = htole16(addr); 693 zyd_cfg_cmd(sc, ZYD_CMD_IORD, &addr, sizeof(addr), 694 tmp, sizeof(tmp), ZYD_CMD_FLAG_READ); 695 *value = le16toh(tmp[0].val); 696}
| 537 sc->tx_nfree = 0; 538 STAILQ_INIT(&sc->tx_q); 539 STAILQ_INIT(&sc->tx_free);
|
697
| 540
|
698static void 699zyd_cfg_read32(struct zyd_softc *sc, uint16_t addr, uint32_t *value) 700{ 701 struct zyd_pair tmp[2]; 702 uint16_t regs[2];
| 541 for (i = 0; i < ZYD_TX_LIST_CNT; i++) { 542 data = &sc->tx_data[i];
|
703
| 543
|
704 regs[0] = ZYD_REG32_HI(addr); 705 regs[1] = ZYD_REG32_LO(addr); 706 regs[0] = htole16(regs[0]); 707 regs[1] = htole16(regs[1]); 708 709 zyd_cfg_cmd(sc, ZYD_CMD_IORD, regs, sizeof(regs), 710 tmp, sizeof(tmp), ZYD_CMD_FLAG_READ); 711 *value = (le16toh(tmp[0].val) << 16) | le16toh(tmp[1].val);
| 544 data->sc = sc; 545 STAILQ_INSERT_TAIL(&sc->tx_free, data, next); 546 sc->tx_nfree++; 547 }
|
712} 713 714static void
| 548} 549 550static void
|
715zyd_cfg_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val)
| 551zyd_unsetup_tx_list(struct zyd_softc *sc)
|
716{
| 552{
|
717 struct zyd_pair pair[1];
| 553 struct zyd_tx_data *data; 554 int i;
|
718
| 555
|
719 pair[0].reg = htole16(reg); 720 pair[0].val = htole16(val);
| 556 /* make sure any subsequent use of the queues will fail */ 557 sc->tx_nfree = 0; 558 STAILQ_INIT(&sc->tx_q); 559 STAILQ_INIT(&sc->tx_free);
|
721
| 560
|
722 zyd_cfg_cmd(sc, ZYD_CMD_IOWR, pair, sizeof(pair), NULL, 0, 0); 723}
| 561 /* free up all node references and mbufs */ 562 for (i = 0; i < ZYD_TX_LIST_CNT; i++) { 563 data = &sc->tx_data[i];
|
724
| 564
|
725static void 726zyd_cfg_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val) 727{ 728 struct zyd_pair pair[2]; 729 730 pair[0].reg = htole16(ZYD_REG32_HI(reg)); 731 pair[0].val = htole16(val >> 16); 732 pair[1].reg = htole16(ZYD_REG32_LO(reg)); 733 pair[1].val = htole16(val & 0xffff); 734 735 zyd_cfg_cmd(sc, ZYD_CMD_IOWR, pair, sizeof(pair), NULL, 0, 0);
| 565 if (data->m != NULL) { 566 m_freem(data->m); 567 data->m = NULL; 568 } 569 if (data->ni != NULL) { 570 ieee80211_free_node(data->ni); 571 data->ni = NULL; 572 } 573 }
|
736} 737
| 574} 575
|
738/*------------------------------------------------------------------------* 739 * zyd_cfg_rfwrite - write RF registers 740 *------------------------------------------------------------------------*/ 741static void 742zyd_cfg_rfwrite(struct zyd_softc *sc, uint32_t value)
| 576/* ARGUSED */ 577static struct ieee80211_node * 578zyd_node_alloc(struct ieee80211vap *vap __unused, 579 const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
|
743{
| 580{
|
744 struct zyd_rf *rf = &sc->sc_rf; 745 struct zyd_rfwrite req; 746 uint16_t cr203; 747 uint16_t i;
| 581 struct zyd_node *zn;
|
748
| 582
|
749 zyd_cfg_read16(sc, ZYD_CR203, &cr203); 750 cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA); 751 752 req.code = htole16(2); 753 req.width = htole16(rf->width); 754 for (i = 0; i != rf->width; i++) { 755 req.bit[i] = htole16(cr203); 756 if (value & (1 << (rf->width - 1 - i))) 757 req.bit[i] |= htole16(ZYD_RF_DATA); 758 } 759 zyd_cfg_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + (2 * rf->width), NULL, 0, 0);
| 583 zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO); 584 return (zn != NULL) ? (&zn->ni) : (NULL);
|
760} 761
| 585} 586
|
762/*------------------------------------------------------------------------* 763 * zyd_cfg_rfwrite_cr 764 *------------------------------------------------------------------------*/
| |
765static void
| 587static void
|
766zyd_cfg_rfwrite_cr(struct zyd_softc *sc, uint32_t val)
| 588zyd_task(struct usb2_proc_msg *pm)
|
767{
| 589{
|
768 zyd_cfg_write16(sc, ZYD_CR244, (val >> 16) & 0xff); 769 zyd_cfg_write16(sc, ZYD_CR243, (val >> 8) & 0xff); 770 zyd_cfg_write16(sc, ZYD_CR242, (val >> 0) & 0xff); 771}
| 590 struct zyd_task *task = (struct zyd_task *)pm; 591 struct zyd_softc *sc = task->sc; 592 struct ifnet *ifp = sc->sc_ifp; 593 struct ieee80211com *ic = ifp->if_l2com; 594 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 595 struct ieee80211_node *ni = vap->iv_bss; 596 struct zyd_vap *zvp = ZYD_VAP(vap); 597 int error;
|
772
| 598
|
773static void 774zyd_bulk_read_clear_stall_callback(struct usb2_xfer *xfer) 775{ 776 struct zyd_softc *sc = xfer->priv_sc; 777 struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_BULK_DT_RD];
| 599 switch (sc->sc_state) { 600 case IEEE80211_S_AUTH: 601 zyd_set_chan(sc, ic->ic_curchan); 602 break; 603 case IEEE80211_S_RUN: 604 if (vap->iv_opmode == IEEE80211_M_MONITOR) 605 break;
|
778
| 606
|
779 if (usb2_clear_stall_callback(xfer, xfer_other)) { 780 DPRINTF("stall cleared\n"); 781 sc->sc_flags &= ~ZYD_FLAG_BULK_READ_STALL; 782 usb2_transfer_start(xfer_other);
| 607 /* turn link LED on */ 608 error = zyd_set_led(sc, ZYD_LED1, 1); 609 if (error != 0) 610 goto fail; 611 612 /* make data LED blink upon Tx */ 613 zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1); 614 615 IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); 616 zyd_set_bssid(sc, sc->sc_bssid); 617 break; 618 default: 619 break;
|
783 }
| 620 }
|
| 621fail: 622 ZYD_UNLOCK(sc); 623 IEEE80211_LOCK(ic); 624 zvp->newstate(vap, sc->sc_state, sc->sc_arg); 625 if (vap->iv_newstate_cb != NULL) 626 vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); 627 IEEE80211_UNLOCK(ic); 628 ZYD_LOCK(sc);
|
784} 785
| 629} 630
|
786static void 787zyd_bulk_read_callback_sub(struct usb2_xfer *xfer, struct zyd_ifq *mq, 788 uint32_t offset, uint16_t len)
| 631static int 632zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
789{
| 633{
|
790 enum { 791 ZYD_OVERHEAD = (ZYD_HW_PADDING + IEEE80211_CRC_LEN), 792 }; 793 struct zyd_softc *sc = xfer->priv_sc; 794 struct ifnet *ifp = sc->sc_ifp; 795 struct zyd_plcphdr plcp; 796 struct zyd_rx_stat stat; 797 struct mbuf *m;
| 634 struct zyd_vap *zvp = ZYD_VAP(vap); 635 struct ieee80211com *ic = vap->iv_ic; 636 struct zyd_softc *sc = ic->ic_ifp->if_softc;
|
798
| 637
|
799 if (len < ZYD_OVERHEAD) { 800 DPRINTF("frame too " 801 "short (length=%d)\n", len); 802 ifp->if_ierrors++; 803 return; 804 } 805 usb2_copy_out(xfer->frbuffers, offset, &plcp, sizeof(plcp)); 806 usb2_copy_out(xfer->frbuffers, offset + len - sizeof(stat), 807 &stat, sizeof(stat));
| 638 DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__, 639 ieee80211_state_name[vap->iv_state], 640 ieee80211_state_name[nstate]);
|
808
| 641
|
809 if (stat.flags & ZYD_RX_ERROR) { 810 DPRINTF("RX status indicated " 811 "error (0x%02x)\n", stat.flags); 812 ifp->if_ierrors++; 813 return; 814 } 815 /* compute actual frame length */ 816 len -= ZYD_OVERHEAD;
| 642 ZYD_LOCK(sc); 643 /* do it in a process context */ 644 sc->sc_state = nstate; 645 sc->sc_arg = arg; 646 ZYD_UNLOCK(sc);
|
817
| 647
|
818 /* allocate a mbuf to store the frame */ 819 if (len > MCLBYTES) { 820 DPRINTF("too large frame, " 821 "%u bytes\n", len); 822 return; 823 } else if (len > MHLEN) 824 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 825 else 826 m = m_gethdr(M_DONTWAIT, MT_DATA); 827 828 if (m == NULL) { 829 DPRINTF("could not allocate rx mbuf\n"); 830 ifp->if_ierrors++; 831 return;
| 648 if (nstate == IEEE80211_S_INIT) { 649 zvp->newstate(vap, nstate, arg); 650 return (0); 651 } else { 652 ZYD_LOCK(sc); 653 zyd_queue_command(sc, zyd_task, &sc->sc_task[0].hdr, 654 &sc->sc_task[1].hdr); 655 ZYD_UNLOCK(sc); 656 return (EINPROGRESS);
|
832 }
| 657 }
|
833 m->m_pkthdr.rcvif = ifp; 834 m->m_pkthdr.len = len; 835 m->m_len = len; 836 837 usb2_copy_out(xfer->frbuffers, offset + 838 sizeof(plcp), m->m_data, len); 839 840 if (bpf_peers_present(ifp->if_bpf)) { 841 struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap; 842 843 tap->wr_flags = 0; 844 if (stat.flags & (ZYD_RX_BADCRC16 | ZYD_RX_BADCRC32)) 845 tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; 846 /* XXX toss, no way to express errors */ 847 if (stat.flags & ZYD_RX_DECRYPTERR) 848 tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; 849 tap->wr_rate = 850 zyd_plcp2ieee(plcp.signal, stat.flags & ZYD_RX_OFDM); 851 tap->wr_antsignal = stat.rssi + -95; 852 tap->wr_antnoise = -95; /* XXX */ 853 854 bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); 855 } 856 if (sizeof(m->m_hdr.pad) > 0) { 857 m->m_hdr.pad[0] = stat.rssi; /* XXX hack */ 858 } 859 _IF_ENQUEUE(mq, m);
| |
860} 861
| 658} 659
|
| 660/* 661 * Callback handler for interrupt transfer 662 */
|
862static void
| 663static void
|
863zyd_bulk_read_callback(struct usb2_xfer *xfer)
| 664zyd_intr_read_callback(struct usb2_xfer *xfer)
|
864{ 865 struct zyd_softc *sc = xfer->priv_sc; 866 struct ifnet *ifp = sc->sc_ifp; 867 struct ieee80211com *ic = ifp->if_l2com;
| 665{ 666 struct zyd_softc *sc = xfer->priv_sc; 667 struct ifnet *ifp = sc->sc_ifp; 668 struct ieee80211com *ic = ifp->if_l2com;
|
| 669 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
868 struct ieee80211_node *ni;
| 670 struct ieee80211_node *ni;
|
869 struct zyd_rx_desc rx_desc; 870 struct zyd_ifq mq = {NULL, NULL, 0}; 871 struct mbuf *m; 872 uint32_t offset; 873 uint16_t len16; 874 uint8_t x; 875 uint8_t rssi; 876 int8_t nf;
| 671 struct zyd_cmd *cmd = &sc->sc_ibuf; 672 int datalen;
|
877 878 switch (USB_GET_STATE(xfer)) { 879 case USB_ST_TRANSFERRED:
| 673 674 switch (USB_GET_STATE(xfer)) { 675 case USB_ST_TRANSFERRED:
|
| 676 usb2_copy_out(xfer->frbuffers, 0, cmd, sizeof(*cmd));
|
880
| 677
|
881 if (xfer->actlen < MAX(sizeof(rx_desc), ZYD_MIN_FRAGSZ)) { 882 DPRINTFN(0, "xfer too short, %d bytes\n", xfer->actlen); 883 ifp->if_ierrors++; 884 goto tr_setup; 885 } 886 usb2_copy_out(xfer->frbuffers, xfer->actlen - sizeof(rx_desc), 887 &rx_desc, sizeof(rx_desc));
| 678 switch (le16toh(cmd->code)) { 679 case ZYD_NOTIF_RETRYSTATUS: 680 { 681 struct zyd_notif_retry *retry = 682 (struct zyd_notif_retry *)cmd->data;
|
888
| 683
|
889 if (UGETW(rx_desc.tag) == ZYD_TAG_MULTIFRAME) {
| 684 DPRINTF(sc, ZYD_DEBUG_TX_PROC, 685 "retry intr: rate=0x%x addr=%s count=%d (0x%x)\n", 686 le16toh(retry->rate), ether_sprintf(retry->macaddr), 687 le16toh(retry->count)&0xff, le16toh(retry->count));
|
890
| 688
|
891 offset = 0;
| 689 /* 690 * Find the node to which the packet was sent and 691 * update its retry statistics. In BSS mode, this node 692 * is the AP we're associated to so no lookup is 693 * actually needed. 694 */ 695 ni = ieee80211_find_txnode(vap, retry->macaddr); 696 if (ni != NULL) { 697 ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn, 698 IEEE80211_AMRR_FAILURE, 1); 699 ieee80211_free_node(ni); 700 } 701 if (le16toh(retry->count) & 0x100) 702 ifp->if_oerrors++; /* too many retries */ 703 break; 704 } 705 case ZYD_NOTIF_IORD: 706 { 707 struct zyd_rq *rqp;
|
892
| 708
|
893 DPRINTFN(4, "received multi-frame transfer, " 894 "%u bytes\n", xfer->actlen);
| 709 if (le16toh(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT) 710 break; /* HMAC interrupt */
|
895
| 711
|
896 for (x = 0; x < ZYD_MAX_RXFRAMECNT; x++) { 897 len16 = UGETW(rx_desc.len[x]);
| 712 datalen = xfer->actlen - sizeof(cmd->code); 713 datalen -= 2; /* XXX: padding? */
|
898
| 714
|
899 if ((len16 == 0) || (len16 > xfer->actlen)) { 900 break; 901 } 902 zyd_bulk_read_callback_sub(xfer, &mq, offset, len16);
| 715 STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) { 716 int i, cnt;
|
903
| 717
|
904 /* 905 * next frame is aligned on a 32-bit 906 * boundary 907 */ 908 len16 = (len16 + 3) & ~3; 909 offset += len16; 910 if (len16 > xfer->actlen) { 911 break;
| 718 if (rqp->olen != datalen) 719 continue; 720 cnt = rqp->olen / sizeof(struct zyd_pair); 721 for (i = 0; i < cnt; i++) { 722 if (*(((const uint16_t *)rqp->idata) + i) != 723 (((struct zyd_pair *)cmd->data) + i)->reg) 724 break;
|
912 }
| 725 }
|
913 xfer->actlen -= len16;
| 726 if (i != cnt) 727 continue; 728 /* copy answer into caller-supplied buffer */ 729 bcopy(cmd->data, rqp->odata, rqp->olen); 730 DPRINTF(sc, ZYD_DEBUG_CMD, 731 "command %p complete, data = %*D \n", 732 rqp, rqp->olen, rqp->odata, ":"); 733 wakeup(rqp); /* wakeup caller */ 734 break;
|
914 }
| 735 }
|
915 } else { 916 DPRINTFN(4, "received single-frame transfer, " 917 "%u bytes\n", xfer->actlen); 918 zyd_bulk_read_callback_sub(xfer, &mq, 0, xfer->actlen);
| 736 if (rqp == NULL) { 737 device_printf(sc->sc_dev, 738 "unexpected IORD notification %*D\n", 739 datalen, cmd->data, ":"); 740 } 741 break;
|
919 }
| 742 }
|
| 743 default: 744 device_printf(sc->sc_dev, "unknown notification %x\n", 745 le16toh(cmd->code)); 746 }
|
920
| 747
|
| 748 /* FALLTHROUGH */
|
921 case USB_ST_SETUP: 922tr_setup:
| 749 case USB_ST_SETUP: 750tr_setup:
|
923 DPRINTF("setup\n");
| 751 xfer->frlengths[0] = xfer->max_data_length; 752 usb2_start_hardware(xfer); 753 break;
|
924
| 754
|
925 if (sc->sc_flags & ZYD_FLAG_BULK_READ_STALL) { 926 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_CS_RD]); 927 } else { 928 xfer->frlengths[0] = xfer->max_data_length; 929 usb2_start_hardware(xfer);
| 755 default: /* Error */ 756 DPRINTF(sc, ZYD_DEBUG_CMD, "error = %s\n", 757 usb2_errstr(xfer->error)); 758 759 if (xfer->error != USB_ERR_CANCELLED) { 760 /* try to clear stall first */ 761 xfer->flags.stall_pipe = 1; 762 goto tr_setup;
|
930 }
| 763 }
|
| 764 break; 765 } 766}
|
931
| 767
|
932 /* 933 * At the end of a USB callback it is always safe to unlock 934 * the private mutex of a device! That is why we do the 935 * "ieee80211_input" here, and not some lines up! 936 */ 937 if (mq.ifq_head) {
| 768static void 769zyd_intr_write_callback(struct usb2_xfer *xfer) 770{ 771 struct zyd_softc *sc = xfer->priv_sc; 772 struct zyd_rq *rqp;
|
938
| 773
|
939 mtx_unlock(&sc->sc_mtx);
| 774 switch (USB_GET_STATE(xfer)) { 775 case USB_ST_TRANSFERRED: 776 rqp = xfer->priv_fifo; 777 DPRINTF(sc, ZYD_DEBUG_CMD, "command %p transferred\n", rqp); 778 if ((rqp->flags & ZYD_CMD_FLAG_READ) == 0) 779 wakeup(rqp); /* wakeup caller */
|
940
| 780
|
941 while (1) {
| 781 /* FALLTHROUGH */ 782 case USB_ST_SETUP: 783tr_setup: 784 STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) { 785 if (rqp->flags & ZYD_CMD_FLAG_SENT) 786 continue;
|
942
| 787
|
943 _IF_DEQUEUE(&mq, m);
| 788 usb2_copy_in(xfer->frbuffers, 0, rqp->cmd, rqp->ilen);
|
944
| 789
|
945 if (m == NULL) 946 break; 947 948 rssi = m->m_hdr.pad[0]; /* XXX hack */ 949 950 rssi = (rssi > 63) ? 127 : 2 * rssi; 951 nf = -95; /* XXX */ 952 953 ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); 954 if (ni != NULL) { 955 if (ieee80211_input(ni, m, rssi, nf, 0)) { 956 /* ignore */ 957 } 958 ieee80211_free_node(ni); 959 } else { 960 if (ieee80211_input_all(ic, m, rssi, nf, 0)) { 961 /* ignore */ 962 } 963 } 964 } 965 966 mtx_lock(&sc->sc_mtx);
| 790 xfer->frlengths[0] = rqp->ilen; 791 xfer->priv_fifo = rqp; 792 rqp->flags |= ZYD_CMD_FLAG_SENT; 793 usb2_start_hardware(xfer); 794 break;
|
967 } 968 break; 969 970 default: /* Error */
| 795 } 796 break; 797 798 default: /* Error */
|
971 DPRINTF("frame error: %s\n", usb2_errstr(xfer->error));
| 799 DPRINTF(sc, ZYD_DEBUG_ANY, "error = %s\n", 800 usb2_errstr(xfer->error));
|
972 973 if (xfer->error != USB_ERR_CANCELLED) { 974 /* try to clear stall first */
| 801 802 if (xfer->error != USB_ERR_CANCELLED) { 803 /* try to clear stall first */
|
975 sc->sc_flags |= ZYD_FLAG_BULK_READ_STALL; 976 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_CS_RD]);
| 804 xfer->flags.stall_pipe = 1; 805 goto tr_setup;
|
977 } 978 break; 979 } 980} 981
| 806 } 807 break; 808 } 809} 810
|
982/*------------------------------------------------------------------------* 983 * zyd_cfg_uploadfirmware 984 * Returns: 985 * 0: Success 986 * Else: Failure 987 *------------------------------------------------------------------------*/ 988static uint8_t 989zyd_cfg_uploadfirmware(struct zyd_softc *sc, const uint8_t *fw_ptr, 990 uint32_t fw_len)
| 811static int 812zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, 813 void *odata, int olen, u_int flags)
|
991{
| 814{
|
992 struct usb2_device_request req; 993 uint16_t temp; 994 uint16_t addr; 995 uint8_t stat;
| 815 struct zyd_cmd cmd; 816 struct zyd_rq rq; 817 int error;
|
996
| 818
|
997 DPRINTF("firmware %p size=%u\n", fw_ptr, fw_len);
| 819 if (ilen > sizeof(cmd.data)) 820 return (EINVAL);
|
998
| 821
|
999 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1000 req.bRequest = ZYD_DOWNLOADREQ; 1001 USETW(req.wIndex, 0);
| 822 if (usb2_proc_is_gone(&sc->sc_tq)) 823 return (ENXIO);
|
1002
| 824
|
1003 temp = 64;
| 825 cmd.code = htole16(code); 826 bcopy(idata, cmd.data, ilen); 827 DPRINTF(sc, ZYD_DEBUG_CMD, "sending cmd %p = %*D\n", 828 &rq, ilen, idata, ":");
|
1004
| 829
|
1005 addr = ZYD_FIRMWARE_START_ADDR; 1006 while (fw_len > 0) {
| 830 rq.cmd = &cmd; 831 rq.idata = idata; 832 rq.odata = odata; 833 rq.ilen = sizeof(uint16_t) + ilen; 834 rq.olen = olen; 835 rq.flags = flags; 836 STAILQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq); 837 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_RD]); 838 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_WR]);
|
1007
| 839
|
1008 if (fw_len < 64) { 1009 temp = fw_len; 1010 } 1011 DPRINTF("firmware block: fw_len=%u\n", fw_len);
| 840 /* wait at most one second for command reply */ 841 error = mtx_sleep(&rq, &sc->sc_mtx, 0 , "zydcmd", hz); 842 if (error) 843 device_printf(sc->sc_dev, "command timeout\n"); 844 STAILQ_REMOVE(&sc->sc_rqh, &rq, zyd_rq, rq); 845 DPRINTF(sc, ZYD_DEBUG_CMD, "finsihed cmd %p, error = %d \n", 846 &rq, error);
|
1012
| 847
|
1013 USETW(req.wValue, addr); 1014 USETW(req.wLength, temp); 1015 1016 zyd_cfg_usbrequest(sc, &req, 1017 USB_ADD_BYTES(fw_ptr, 0)); 1018 1019 addr += (temp / 2); 1020 fw_len -= temp; 1021 fw_ptr += temp; 1022 } 1023 1024 /* check whether the upload succeeded */ 1025 req.bmRequestType = UT_READ_VENDOR_DEVICE; 1026 req.bRequest = ZYD_DOWNLOADSTS; 1027 USETW(req.wValue, 0); 1028 USETW(req.wIndex, 0); 1029 USETW(req.wLength, sizeof(stat)); 1030 1031 zyd_cfg_usbrequest(sc, &req, &stat); 1032 1033 return ((stat & 0x80) ? 1 : 0);
| 848 return (error);
|
1034} 1035
| 849} 850
|
1036/* 1037 * Driver OS interface 1038 */ 1039 1040/* 1041 * Probe for a ZD1211-containing product 1042 */
| |
1043static int
| 851static int
|
1044zyd_probe(device_t dev)
| 852zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val)
|
1045{
| 853{
|
1046 struct usb2_attach_arg *uaa = device_get_ivars(dev);
| 854 struct zyd_pair tmp; 855 int error;
|
1047
| 856
|
1048 if (uaa->usb2_mode != USB_MODE_HOST) { 1049 return (ENXIO); 1050 } 1051 if (uaa->info.bConfigIndex != 0) { 1052 return (ENXIO); 1053 } 1054 if (uaa->info.bIfaceIndex != ZYD_IFACE_INDEX) { 1055 return (ENXIO); 1056 } 1057 return (usb2_lookup_id_by_uaa(zyd_devs, sizeof(zyd_devs), uaa));
| 857 reg = htole16(reg); 858 error = zyd_cmd(sc, ZYD_CMD_IORD, ®, sizeof(reg), &tmp, sizeof(tmp), 859 ZYD_CMD_FLAG_READ); 860 if (error == 0) 861 *val = le16toh(tmp.val); 862 return (error);
|
1058} 1059
| 863} 864
|
1060/* 1061 * Attach the interface. Allocate softc structures, do 1062 * setup and ethernet/BPF attach. 1063 */
| |
1064static int
| 865static int
|
1065zyd_attach(device_t dev)
| 866zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val)
|
1066{
| 867{
|
1067 struct usb2_attach_arg *uaa = device_get_ivars(dev); 1068 struct zyd_softc *sc = device_get_softc(dev);
| 868 struct zyd_pair tmp[2]; 869 uint16_t regs[2];
|
1069 int error;
| 870 int error;
|
1070 uint8_t iface_index;
| |
1071
| 871
|
1072 if (uaa->info.bcdDevice < 0x4330) { 1073 device_printf(dev, "device version mismatch: 0x%X " 1074 "(only >= 43.30 supported)\n", 1075 uaa->info.bcdDevice); 1076 return (EINVAL); 1077 } 1078 device_set_usb2_desc(dev);
| 872 regs[0] = htole16(ZYD_REG32_HI(reg)); 873 regs[1] = htole16(ZYD_REG32_LO(reg)); 874 error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof(regs), tmp, sizeof(tmp), 875 ZYD_CMD_FLAG_READ); 876 if (error == 0) 877 *val = le16toh(tmp[0].val) << 16 | le16toh(tmp[1].val); 878 return (error); 879}
|
1079
| 880
|
1080 snprintf(sc->sc_name, sizeof(sc->sc_name), "%s", 1081 device_get_nameunit(dev));
| 881static int 882zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val) 883{ 884 struct zyd_pair pair;
|
1082
| 885
|
1083 sc->sc_unit = device_get_unit(dev); 1084 sc->sc_udev = uaa->device; 1085 sc->sc_mac_rev = USB_GET_DRIVER_INFO(uaa);
| 886 pair.reg = htole16(reg); 887 pair.val = htole16(val);
|
1086
| 888
|
1087 mtx_init(&sc->sc_mtx, "zyd lock", MTX_NETWORK_LOCK, 1088 MTX_DEF | MTX_RECURSE);
| 889 return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof(pair), NULL, 0, 0); 890}
|
1089
| 891
|
1090 usb2_cv_init(&sc->sc_intr_cv, "IWAIT");
| 892static int 893zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val) 894{ 895 struct zyd_pair pair[2];
|
1091
| 896
|
1092 usb2_callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
| 897 pair[0].reg = htole16(ZYD_REG32_HI(reg)); 898 pair[0].val = htole16(val >> 16); 899 pair[1].reg = htole16(ZYD_REG32_LO(reg)); 900 pair[1].val = htole16(val & 0xffff);
|
1093
| 901
|
1094 /* 1095 * Endpoint 1 = Bulk out (512b @ high speed / 64b @ full speed) 1096 * Endpoint 2 = Bulk in (512b @ high speed / 64b @ full speed) 1097 * Endpoint 3 = Intr in (64b) 1098 * Endpoint 4 = Intr out @ high speed / bulk out @ full speed (64b) 1099 */ 1100 iface_index = ZYD_IFACE_INDEX; 1101 error = usb2_transfer_setup(uaa->device, &iface_index, 1102 sc->sc_xfer, zyd_config, ZYD_N_TRANSFER, sc, &sc->sc_mtx); 1103 if (error) { 1104 device_printf(dev, "could not allocate USB " 1105 "transfers: %s\n", usb2_errstr(error)); 1106 goto detach; 1107 } 1108 error = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_mtx, 1109 &zyd_end_of_commands, sizeof(struct usb2_config_td_cc), 16); 1110 if (error) { 1111 device_printf(dev, "could not setup config " 1112 "thread!\n"); 1113 goto detach; 1114 } 1115 mtx_lock(&sc->sc_mtx); 1116 1117 /* start setup */ 1118 1119 usb2_config_td_queue_command 1120 (&sc->sc_config_td, NULL, &zyd_cfg_first_time_setup, 0, 0); 1121 1122 zyd_watchdog(sc); 1123 mtx_unlock(&sc->sc_mtx); 1124 return (0); 1125 1126detach: 1127 zyd_detach(dev); 1128 return (ENXIO);
| 902 return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof(pair), NULL, 0, 0);
|
1129} 1130
| 903} 904
|
1131/* 1132 * Lock PHY registers 1133 */ 1134static void 1135zyd_cfg_lock_phy(struct zyd_softc *sc)
| 905static int 906zyd_rfwrite(struct zyd_softc *sc, uint32_t val)
|
1136{
| 907{
|
1137 uint32_t temp;
| 908 struct zyd_rf *rf = &sc->sc_rf; 909 struct zyd_rfwrite_cmd req; 910 uint16_t cr203; 911 int error, i;
|
1138
| 912
|
1139 zyd_cfg_read32(sc, ZYD_MAC_MISC, &temp); 1140 temp &= ~ZYD_UNLOCK_PHY_REGS; 1141 zyd_cfg_write32(sc, ZYD_MAC_MISC, temp);
| 913 zyd_read16_m(sc, ZYD_CR203, &cr203); 914 cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA); 915 916 req.code = htole16(2); 917 req.width = htole16(rf->width); 918 for (i = 0; i < rf->width; i++) { 919 req.bit[i] = htole16(cr203); 920 if (val & (1 << (rf->width - 1 - i))) 921 req.bit[i] |= htole16(ZYD_RF_DATA); 922 } 923 error = zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0); 924fail: 925 return (error);
|
1142} 1143
| 926} 927
|
1144/* 1145 * Unlock PHY registers 1146 */ 1147static void 1148zyd_cfg_unlock_phy(struct zyd_softc *sc)
| 928static int 929zyd_rfwrite_cr(struct zyd_softc *sc, uint32_t val)
|
1149{
| 930{
|
1150 uint32_t temp;
| 931 int error;
|
1151
| 932
|
1152 zyd_cfg_read32(sc, ZYD_MAC_MISC, &temp); 1153 temp |= ZYD_UNLOCK_PHY_REGS; 1154 zyd_cfg_write32(sc, ZYD_MAC_MISC, temp);
| 933 zyd_write16_m(sc, ZYD_CR244, (val >> 16) & 0xff); 934 zyd_write16_m(sc, ZYD_CR243, (val >> 8) & 0xff); 935 zyd_write16_m(sc, ZYD_CR242, (val >> 0) & 0xff); 936fail: 937 return (error);
|
1155} 1156
| 938} 939
|
1157static void 1158zyd_cfg_set_beacon_interval(struct zyd_softc *sc, uint32_t bintval)
| 940static int 941zyd_lock_phy(struct zyd_softc *sc)
|
1159{
| 942{
|
1160 uint32_t val;
| 943 int error; 944 uint32_t tmp;
|
1161
| 945
|
1162 zyd_cfg_read32(sc, ZYD_CR_ATIM_WND_PERIOD, &val); 1163 sc->sc_atim_wnd = val; 1164 zyd_cfg_read32(sc, ZYD_CR_PRE_TBTT, &val); 1165 sc->sc_pre_tbtt = val; 1166 sc->sc_bcn_int = bintval; 1167 1168 if (sc->sc_bcn_int <= 5) 1169 sc->sc_bcn_int = 5; 1170 if (sc->sc_pre_tbtt < 4 || sc->sc_pre_tbtt >= sc->sc_bcn_int) 1171 sc->sc_pre_tbtt = sc->sc_bcn_int - 1; 1172 if (sc->sc_atim_wnd >= sc->sc_pre_tbtt) 1173 sc->sc_atim_wnd = sc->sc_pre_tbtt - 1; 1174 1175 zyd_cfg_write32(sc, ZYD_CR_ATIM_WND_PERIOD, sc->sc_atim_wnd); 1176 zyd_cfg_write32(sc, ZYD_CR_PRE_TBTT, sc->sc_pre_tbtt); 1177 zyd_cfg_write32(sc, ZYD_CR_BCN_INTERVAL, sc->sc_bcn_int);
| 946 zyd_read32_m(sc, ZYD_MAC_MISC, &tmp); 947 tmp &= ~ZYD_UNLOCK_PHY_REGS; 948 zyd_write32_m(sc, ZYD_MAC_MISC, tmp); 949fail: 950 return (error);
|
1178} 1179
| 951} 952
|
1180/* 1181 * Get RF name 1182 */ 1183static const char * 1184zyd_rf_name(uint8_t type)
| 953static int 954zyd_unlock_phy(struct zyd_softc *sc)
|
1185{
| 955{
|
1186 static const char *const zyd_rfs[] = { 1187 "unknown", "unknown", "UW2451", "UCHIP", "AL2230", 1188 "AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT", 1189 "AL2230S", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2", 1190 "PHILIPS" 1191 };
| 956 int error; 957 uint32_t tmp;
|
1192
| 958
|
1193 return (zyd_rfs[(type > 15) ? 0 : type]);
| 959 zyd_read32_m(sc, ZYD_MAC_MISC, &tmp); 960 tmp |= ZYD_UNLOCK_PHY_REGS; 961 zyd_write32_m(sc, ZYD_MAC_MISC, tmp); 962fail: 963 return (error);
|
1194} 1195 1196/*
| 964} 965 966/*
|
1197 * RF driver: Init for RFMD chip
| 967 * RFMD RF methods.
|
1198 */
| 968 */
|
1199static void 1200zyd_cfg_rf_rfmd_init(struct zyd_softc *sc, struct zyd_rf *rf)
| 969static int 970zyd_rfmd_init(struct zyd_rf *rf)
|
1201{
| 971{
|
| 972#define N(a) (sizeof(a) / sizeof((a)[0])) 973 struct zyd_softc *sc = rf->rf_sc;
|
1202 static const struct zyd_phy_pair phyini[] = ZYD_RFMD_PHY; 1203 static const uint32_t rfini[] = ZYD_RFMD_RF;
| 974 static const struct zyd_phy_pair phyini[] = ZYD_RFMD_PHY; 975 static const uint32_t rfini[] = ZYD_RFMD_RF;
|
1204 uint32_t i;
| 976 int i, error;
|
1205 1206 /* init RF-dependent PHY registers */
| 977 978 /* init RF-dependent PHY registers */
|
1207 for (i = 0; i != INDEXES(phyini); i++) { 1208 zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val);
| 979 for (i = 0; i < N(phyini); i++) { 980 zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
|
1209 } 1210 1211 /* init RFMD radio */
| 981 } 982 983 /* init RFMD radio */
|
1212 for (i = 0; i != INDEXES(rfini); i++) { 1213 zyd_cfg_rfwrite(sc, rfini[i]);
| 984 for (i = 0; i < N(rfini); i++) { 985 if ((error = zyd_rfwrite(sc, rfini[i])) != 0) 986 return (error);
|
1214 }
| 987 }
|
| 988fail: 989 return (error); 990#undef N
|
1215} 1216
| 991} 992
|
1217/* 1218 * RF driver: Switch radio on/off for RFMD chip 1219 */ 1220static void 1221zyd_cfg_rf_rfmd_switch_radio(struct zyd_softc *sc, uint8_t on)
| 993static int 994zyd_rfmd_switch_radio(struct zyd_rf *rf, int on)
|
1222{
| 995{
|
1223 zyd_cfg_write16(sc, ZYD_CR10, on ? 0x89 : 0x15); 1224 zyd_cfg_write16(sc, ZYD_CR11, on ? 0x00 : 0x81);
| 996 int error; 997 struct zyd_softc *sc = rf->rf_sc; 998 999 zyd_write16_m(sc, ZYD_CR10, on ? 0x89 : 0x15); 1000 zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x81); 1001fail: 1002 return (error);
|
1225} 1226
| 1003} 1004
|
1227/* 1228 * RF driver: Channel setting for RFMD chip 1229 */ 1230static void 1231zyd_cfg_rf_rfmd_set_channel(struct zyd_softc *sc, struct zyd_rf *rf, 1232 uint8_t channel)
| 1005static int 1006zyd_rfmd_set_channel(struct zyd_rf *rf, uint8_t chan)
|
1233{
| 1007{
|
| 1008 int error; 1009 struct zyd_softc *sc = rf->rf_sc;
|
1234 static const struct {
| 1010 static const struct {
|
1235 uint32_t r1, r2; 1236 } rfprog[] = ZYD_RFMD_CHANTABLE;
| 1011 uint32_t r1, r2; 1012 } rfprog[] = ZYD_RFMD_CHANTABLE;
|
1237
| 1013
|
1238 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r1); 1239 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r2); 1240}
| 1014 error = zyd_rfwrite(sc, rfprog[chan - 1].r1); 1015 if (error != 0) 1016 goto fail; 1017 error = zyd_rfwrite(sc, rfprog[chan - 1].r2); 1018 if (error != 0) 1019 goto fail;
|
1241
| 1020
|
1242/* 1243 * RF driver: Switch radio on/off for AL2230 chip 1244 */ 1245static void 1246zyd_cfg_rf_al2230_switch_radio(struct zyd_softc *sc, uint8_t on) 1247{ 1248 uint8_t on251 = (sc->sc_mac_rev == ZYD_ZD1211) ? 0x3f : 0x7f; 1249 1250 zyd_cfg_write16(sc, ZYD_CR11, on ? 0x00 : 0x04); 1251 zyd_cfg_write16(sc, ZYD_CR251, on ? on251 : 0x2f);
| 1021fail: 1022 return (error);
|
1252} 1253 1254/*
| 1023} 1024 1025/*
|
1255 * RF driver: Init for AL2230 chip
| 1026 * AL2230 RF methods.
|
1256 */
| 1027 */
|
1257static void 1258zyd_cfg_rf_al2230_init(struct zyd_softc *sc, struct zyd_rf *rf)
| 1028static int 1029zyd_al2230_init(struct zyd_rf *rf)
|
1259{
| 1030{
|
| 1031#define N(a) (sizeof(a) / sizeof((a)[0])) 1032 struct zyd_softc *sc = rf->rf_sc;
|
1260 static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY; 1261 static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT; 1262 static const struct zyd_phy_pair phypll[] = {
| 1033 static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY; 1034 static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT; 1035 static const struct zyd_phy_pair phypll[] = {
|
1263 {ZYD_CR251, 0x2f}, {ZYD_CR251, 0x3f}, 1264 {ZYD_CR138, 0x28}, {ZYD_CR203, 0x06}
| 1036 { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x3f }, 1037 { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 }
|
1265 }; 1266 static const uint32_t rfini1[] = ZYD_AL2230_RF_PART1; 1267 static const uint32_t rfini2[] = ZYD_AL2230_RF_PART2; 1268 static const uint32_t rfini3[] = ZYD_AL2230_RF_PART3;
| 1038 }; 1039 static const uint32_t rfini1[] = ZYD_AL2230_RF_PART1; 1040 static const uint32_t rfini2[] = ZYD_AL2230_RF_PART2; 1041 static const uint32_t rfini3[] = ZYD_AL2230_RF_PART3;
|
1269 uint32_t i;
| 1042 int i, error;
|
1270 1271 /* init RF-dependent PHY registers */
| 1043 1044 /* init RF-dependent PHY registers */
|
1272 for (i = 0; i != INDEXES(phyini); i++) 1273 zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val);
| 1045 for (i = 0; i < N(phyini); i++) 1046 zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
|
1274
| 1047
|
1275 if ((sc->sc_rf_rev == ZYD_RF_AL2230S) || (sc->sc_al2230s != 0)) { 1276 for (i = 0; i != INDEXES(phy2230s); i++) 1277 zyd_cfg_write16(sc, phy2230s[i].reg, phy2230s[i].val);
| 1048 if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) { 1049 for (i = 0; i < N(phy2230s); i++) 1050 zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val);
|
1278 }
| 1051 }
|
| 1052
|
1279 /* init AL2230 radio */
| 1053 /* init AL2230 radio */
|
1280 for (i = 0; i != INDEXES(rfini1); i++) 1281 zyd_cfg_rfwrite(sc, rfini1[i]);
| 1054 for (i = 0; i < N(rfini1); i++) { 1055 error = zyd_rfwrite(sc, rfini1[i]); 1056 if (error != 0) 1057 goto fail; 1058 }
|
1282
| 1059
|
1283 if ((sc->sc_rf_rev == ZYD_RF_AL2230S) || (sc->sc_al2230s != 0)) 1284 zyd_cfg_rfwrite(sc, 0x000824);
| 1060 if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) 1061 error = zyd_rfwrite(sc, 0x000824);
|
1285 else
| 1062 else
|
1286 zyd_cfg_rfwrite(sc, 0x0005a4);
| 1063 error = zyd_rfwrite(sc, 0x0005a4); 1064 if (error != 0) 1065 goto fail;
|
1287
| 1066
|
1288 for (i = 0; i != INDEXES(rfini2); i++) 1289 zyd_cfg_rfwrite(sc, rfini2[i]);
| 1067 for (i = 0; i < N(rfini2); i++) { 1068 error = zyd_rfwrite(sc, rfini2[i]); 1069 if (error != 0) 1070 goto fail; 1071 }
|
1290
| 1072
|
1291 for (i = 0; i != INDEXES(phypll); i++) 1292 zyd_cfg_write16(sc, phypll[i].reg, phypll[i].val);
| 1073 for (i = 0; i < N(phypll); i++) 1074 zyd_write16_m(sc, phypll[i].reg, phypll[i].val);
|
1293
| 1075
|
1294 for (i = 0; i != INDEXES(rfini3); i++) 1295 zyd_cfg_rfwrite(sc, rfini3[i]);
| 1076 for (i = 0; i < N(rfini3); i++) { 1077 error = zyd_rfwrite(sc, rfini3[i]); 1078 if (error != 0) 1079 goto fail; 1080 } 1081fail: 1082 return (error); 1083#undef N
|
1296} 1297
| 1084} 1085
|
1298static void 1299zyd_cfg_rf_al2230_fini(struct zyd_softc *sc, struct zyd_rf *rf)
| 1086static int 1087zyd_al2230_fini(struct zyd_rf *rf)
|
1300{
| 1088{
|
| 1089#define N(a) (sizeof(a) / sizeof((a)[0])) 1090 int error, i; 1091 struct zyd_softc *sc = rf->rf_sc;
|
1301 static const struct zyd_phy_pair phy[] = ZYD_AL2230_PHY_FINI_PART1;
| 1092 static const struct zyd_phy_pair phy[] = ZYD_AL2230_PHY_FINI_PART1;
|
1302 uint32_t i;
| |
1303
| 1093
|
1304 for (i = 0; i != INDEXES(phy); i++) 1305 zyd_cfg_write16(sc, phy[i].reg, phy[i].val);
| 1094 for (i = 0; i < N(phy); i++) 1095 zyd_write16_m(sc, phy[i].reg, phy[i].val);
|
1306 1307 if (sc->sc_newphy != 0)
| 1096 1097 if (sc->sc_newphy != 0)
|
1308 zyd_cfg_write16(sc, ZYD_CR9, 0xe1); 1309 zyd_cfg_write16(sc, ZYD_CR203, 0x6);
| 1098 zyd_write16_m(sc, ZYD_CR9, 0xe1); 1099 1100 zyd_write16_m(sc, ZYD_CR203, 0x6); 1101fail: 1102 return (error); 1103#undef N
|
1310} 1311
| 1104} 1105
|
1312static void 1313zyd_cfg_rf_al2230_init_b(struct zyd_softc *sc, struct zyd_rf *rf)
| 1106static int 1107zyd_al2230_init_b(struct zyd_rf *rf)
|
1314{
| 1108{
|
1315 static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B;
| 1109#define N(a) (sizeof(a) / sizeof((a)[0])) 1110 struct zyd_softc *sc = rf->rf_sc;
|
1316 static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1; 1317 static const struct zyd_phy_pair phy2[] = ZYD_AL2230_PHY_PART2; 1318 static const struct zyd_phy_pair phy3[] = ZYD_AL2230_PHY_PART3; 1319 static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
| 1111 static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1; 1112 static const struct zyd_phy_pair phy2[] = ZYD_AL2230_PHY_PART2; 1113 static const struct zyd_phy_pair phy3[] = ZYD_AL2230_PHY_PART3; 1114 static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
|
| 1115 static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B;
|
1320 static const uint32_t rfini_part1[] = ZYD_AL2230_RF_B_PART1; 1321 static const uint32_t rfini_part2[] = ZYD_AL2230_RF_B_PART2; 1322 static const uint32_t rfini_part3[] = ZYD_AL2230_RF_B_PART3; 1323 static const uint32_t zyd_al2230_chtable[][3] = ZYD_AL2230_CHANTABLE;
| 1116 static const uint32_t rfini_part1[] = ZYD_AL2230_RF_B_PART1; 1117 static const uint32_t rfini_part2[] = ZYD_AL2230_RF_B_PART2; 1118 static const uint32_t rfini_part3[] = ZYD_AL2230_RF_B_PART3; 1119 static const uint32_t zyd_al2230_chtable[][3] = ZYD_AL2230_CHANTABLE;
|
1324 uint32_t i;
| 1120 int i, error;
|
1325
| 1121
|
1326 for (i = 0; i != INDEXES(phy1); i++) 1327 zyd_cfg_write16(sc, phy1[i].reg, phy1[i].val);
| 1122 for (i = 0; i < N(phy1); i++) 1123 zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
|
1328 1329 /* init RF-dependent PHY registers */
| 1124 1125 /* init RF-dependent PHY registers */
|
1330 for (i = 0; i != INDEXES(phyini); i++) 1331 zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val);
| 1126 for (i = 0; i < N(phyini); i++) 1127 zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
|
1332
| 1128
|
1333 if ((sc->sc_rf_rev == ZYD_RF_AL2230S) || (sc->sc_al2230s != 0)) 1334 for (i = 0; i != INDEXES(phy2230s); i++) 1335 zyd_cfg_write16(sc, phy2230s[i].reg, phy2230s[i].val);
| 1129 if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) { 1130 for (i = 0; i < N(phy2230s); i++) 1131 zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val); 1132 }
|
1336
| 1133
|
1337 for (i = 0; i != 3; i++) 1338 zyd_cfg_rfwrite_cr(sc, zyd_al2230_chtable[0][i]);
| 1134 for (i = 0; i < 3; i++) { 1135 error = zyd_rfwrite_cr(sc, zyd_al2230_chtable[0][i]); 1136 if (error != 0) 1137 return (error); 1138 }
|
1339
| 1139
|
1340 for (i = 0; i != INDEXES(rfini_part1); i++) 1341 zyd_cfg_rfwrite_cr(sc, rfini_part1[i]);
| 1140 for (i = 0; i < N(rfini_part1); i++) { 1141 error = zyd_rfwrite_cr(sc, rfini_part1[i]); 1142 if (error != 0) 1143 return (error); 1144 }
|
1342
| 1145
|
1343 if ((sc->sc_rf_rev == ZYD_RF_AL2230S) || (sc->sc_al2230s != 0)) 1344 zyd_cfg_rfwrite(sc, 0x241000);
| 1146 if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) 1147 error = zyd_rfwrite(sc, 0x241000);
|
1345 else
| 1148 else
|
1346 zyd_cfg_rfwrite(sc, 0x25a000);
| 1149 error = zyd_rfwrite(sc, 0x25a000); 1150 if (error != 0) 1151 goto fail;
|
1347
| 1152
|
1348 for (i = 0; i != INDEXES(rfini_part2); i++) 1349 zyd_cfg_rfwrite_cr(sc, rfini_part2[i]);
| 1153 for (i = 0; i < N(rfini_part2); i++) { 1154 error = zyd_rfwrite_cr(sc, rfini_part2[i]); 1155 if (error != 0) 1156 return (error); 1157 }
|
1350
| 1158
|
1351 for (i = 0; i != INDEXES(phy2); i++) 1352 zyd_cfg_write16(sc, phy2[i].reg, phy2[i].val);
| 1159 for (i = 0; i < N(phy2); i++) 1160 zyd_write16_m(sc, phy2[i].reg, phy2[i].val);
|
1353
| 1161
|
1354 for (i = 0; i != INDEXES(rfini_part3); i++) 1355 zyd_cfg_rfwrite_cr(sc, rfini_part3[i]);
| 1162 for (i = 0; i < N(rfini_part3); i++) { 1163 error = zyd_rfwrite_cr(sc, rfini_part3[i]); 1164 if (error != 0) 1165 return (error); 1166 }
|
1356
| 1167
|
1357 for (i = 0; i < INDEXES(phy3); i++) 1358 zyd_cfg_write16(sc, phy3[i].reg, phy3[i].val);
| 1168 for (i = 0; i < N(phy3); i++) 1169 zyd_write16_m(sc, phy3[i].reg, phy3[i].val);
|
1359
| 1170
|
1360 zyd_cfg_rf_al2230_fini(sc, rf);
| 1171 error = zyd_al2230_fini(rf); 1172fail: 1173 return (error); 1174#undef N
|
1361} 1362
| 1175} 1176
|
1363/* 1364 * RF driver: Channel setting for AL2230 chip 1365 */ 1366static void 1367zyd_cfg_rf_al2230_set_channel(struct zyd_softc *sc, struct zyd_rf *rf, 1368 uint8_t channel)
| 1177static int 1178zyd_al2230_switch_radio(struct zyd_rf *rf, int on)
|
1369{
| 1179{
|
| 1180 struct zyd_softc *sc = rf->rf_sc; 1181 int error, on251 = (sc->sc_macrev == ZYD_ZD1211) ? 0x3f : 0x7f; 1182 1183 zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04); 1184 zyd_write16_m(sc, ZYD_CR251, on ? on251 : 0x2f); 1185fail: 1186 return (error); 1187} 1188 1189static int 1190zyd_al2230_set_channel(struct zyd_rf *rf, uint8_t chan) 1191{ 1192#define N(a) (sizeof(a) / sizeof((a)[0])) 1193 int error, i; 1194 struct zyd_softc *sc = rf->rf_sc;
|
1370 static const struct zyd_phy_pair phy1[] = {
| 1195 static const struct zyd_phy_pair phy1[] = {
|
1371 {ZYD_CR138, 0x28}, {ZYD_CR203, 0x06},
| 1196 { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 },
|
1372 }; 1373 static const struct {
| 1197 }; 1198 static const struct {
|
1374 uint32_t r1, r2, r3; 1375 } rfprog[] = ZYD_AL2230_CHANTABLE; 1376 uint32_t i;
| 1199 uint32_t r1, r2, r3; 1200 } rfprog[] = ZYD_AL2230_CHANTABLE;
|
1377
| 1201
|
1378 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r1); 1379 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r2); 1380 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r3);
| 1202 error = zyd_rfwrite(sc, rfprog[chan - 1].r1); 1203 if (error != 0) 1204 goto fail; 1205 error = zyd_rfwrite(sc, rfprog[chan - 1].r2); 1206 if (error != 0) 1207 goto fail; 1208 error = zyd_rfwrite(sc, rfprog[chan - 1].r3); 1209 if (error != 0) 1210 goto fail;
|
1381
| 1211
|
1382 for (i = 0; i != INDEXES(phy1); i++) 1383 zyd_cfg_write16(sc, phy1[i].reg, phy1[i].val);
| 1212 for (i = 0; i < N(phy1); i++) 1213 zyd_write16_m(sc, phy1[i].reg, phy1[i].val); 1214fail: 1215 return (error); 1216#undef N
|
1384} 1385
| 1217} 1218
|
1386static void 1387zyd_cfg_rf_al2230_set_channel_b(struct zyd_softc *sc, 1388 struct zyd_rf *rf, uint8_t chan)
| 1219static int 1220zyd_al2230_set_channel_b(struct zyd_rf *rf, uint8_t chan)
|
1389{
| 1221{
|
| 1222#define N(a) (sizeof(a) / sizeof((a)[0])) 1223 int error, i; 1224 struct zyd_softc *sc = rf->rf_sc;
|
1390 static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1; 1391 static const struct {
| 1225 static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1; 1226 static const struct {
|
1392 uint32_t r1, r2, r3; 1393 } rfprog[] = ZYD_AL2230_CHANTABLE_B; 1394 uint32_t i;
| 1227 uint32_t r1, r2, r3; 1228 } rfprog[] = ZYD_AL2230_CHANTABLE_B;
|
1395
| 1229
|
1396 for (i = 0; i != INDEXES(phy1); i++) 1397 zyd_cfg_write16(sc, phy1[i].reg, phy1[i].val);
| 1230 for (i = 0; i < N(phy1); i++) 1231 zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
|
1398
| 1232
|
1399 zyd_cfg_rfwrite_cr(sc, rfprog[chan - 1].r1); 1400 zyd_cfg_rfwrite_cr(sc, rfprog[chan - 1].r2); 1401 zyd_cfg_rfwrite_cr(sc, rfprog[chan - 1].r3); 1402 1403 zyd_cfg_rf_al2230_fini(sc, rf);
| 1233 error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r1); 1234 if (error != 0) 1235 goto fail; 1236 error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r2); 1237 if (error != 0) 1238 goto fail; 1239 error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r3); 1240 if (error != 0) 1241 goto fail; 1242 error = zyd_al2230_fini(rf); 1243fail: 1244 return (error); 1245#undef N
|
1404} 1405 1406#define ZYD_AL2230_PHY_BANDEDGE6 \ 1407{ \
| 1246} 1247 1248#define ZYD_AL2230_PHY_BANDEDGE6 \ 1249{ \
|
1408 { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \
| 1250 { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \
|
1409 { ZYD_CR47, 0x1e } \ 1410} 1411
| 1251 { ZYD_CR47, 0x1e } \ 1252} 1253
|
1412static void 1413zyd_cfg_rf_al2230_bandedge6(struct zyd_softc *sc, 1414 struct zyd_rf *rf, uint8_t chan)
| 1254static int 1255zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c)
|
1415{
| 1256{
|
| 1257#define N(a) (sizeof(a) / sizeof((a)[0])) 1258 int error = 0, i; 1259 struct zyd_softc *sc = rf->rf_sc; 1260 struct ifnet *ifp = sc->sc_ifp; 1261 struct ieee80211com *ic = ifp->if_l2com;
|
1416 struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6;
| 1262 struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6;
|
1417 uint32_t i;
| 1263 u_int chan = ieee80211_chan2ieee(ic, c);
|
1418
| 1264
|
1419 if ((chan == 1) || (chan == 11))
| 1265 if (chan == 1 || chan == 11)
|
1420 r[0].val = 0x12;
| 1266 r[0].val = 0x12;
|
1421 1422 for (i = 0; i < INDEXES(r); i++) 1423 zyd_cfg_write16(sc, r[i].reg, r[i].val);
| 1267 1268 for (i = 0; i < N(r); i++) 1269 zyd_write16_m(sc, r[i].reg, r[i].val); 1270fail: 1271 return (error); 1272#undef N
|
1424} 1425 1426/* 1427 * AL7230B RF methods. 1428 */
| 1273} 1274 1275/* 1276 * AL7230B RF methods. 1277 */
|
1429static void 1430zyd_cfg_rf_al7230b_switch_radio(struct zyd_softc *sc, uint8_t on)
| 1278static int 1279zyd_al7230B_init(struct zyd_rf *rf)
|
1431{
| 1280{
|
1432 zyd_cfg_write16(sc, ZYD_CR11, on ? 0x00 : 0x04); 1433 zyd_cfg_write16(sc, ZYD_CR251, on ? 0x3f : 0x2f); 1434} 1435 1436static void 1437zyd_cfg_rf_al7230b_init(struct zyd_softc *sc, struct zyd_rf *rf) 1438{
| 1281#define N(a) (sizeof(a) / sizeof((a)[0])) 1282 struct zyd_softc *sc = rf->rf_sc;
|
1439 static const struct zyd_phy_pair phyini_1[] = ZYD_AL7230B_PHY_1; 1440 static const struct zyd_phy_pair phyini_2[] = ZYD_AL7230B_PHY_2; 1441 static const struct zyd_phy_pair phyini_3[] = ZYD_AL7230B_PHY_3; 1442 static const uint32_t rfini_1[] = ZYD_AL7230B_RF_1; 1443 static const uint32_t rfini_2[] = ZYD_AL7230B_RF_2;
| 1283 static const struct zyd_phy_pair phyini_1[] = ZYD_AL7230B_PHY_1; 1284 static const struct zyd_phy_pair phyini_2[] = ZYD_AL7230B_PHY_2; 1285 static const struct zyd_phy_pair phyini_3[] = ZYD_AL7230B_PHY_3; 1286 static const uint32_t rfini_1[] = ZYD_AL7230B_RF_1; 1287 static const uint32_t rfini_2[] = ZYD_AL7230B_RF_2;
|
1444 uint32_t i;
| 1288 int i, error;
|
1445 1446 /* for AL7230B, PHY and RF need to be initialized in "phases" */ 1447 1448 /* init RF-dependent PHY registers, part one */
| 1289 1290 /* for AL7230B, PHY and RF need to be initialized in "phases" */ 1291 1292 /* init RF-dependent PHY registers, part one */
|
1449 for (i = 0; i != INDEXES(phyini_1); i++) { 1450 zyd_cfg_write16(sc, phyini_1[i].reg, phyini_1[i].val); 1451 }
| 1293 for (i = 0; i < N(phyini_1); i++) 1294 zyd_write16_m(sc, phyini_1[i].reg, phyini_1[i].val); 1295
|
1452 /* init AL7230B radio, part one */
| 1296 /* init AL7230B radio, part one */
|
1453 for (i = 0; i != INDEXES(rfini_1); i++) { 1454 zyd_cfg_rfwrite(sc, rfini_1[i]);
| 1297 for (i = 0; i < N(rfini_1); i++) { 1298 if ((error = zyd_rfwrite(sc, rfini_1[i])) != 0) 1299 return (error);
|
1455 } 1456 /* init RF-dependent PHY registers, part two */
| 1300 } 1301 /* init RF-dependent PHY registers, part two */
|
1457 for (i = 0; i != INDEXES(phyini_2); i++) { 1458 zyd_cfg_write16(sc, phyini_2[i].reg, phyini_2[i].val); 1459 }
| 1302 for (i = 0; i < N(phyini_2); i++) 1303 zyd_write16_m(sc, phyini_2[i].reg, phyini_2[i].val); 1304
|
1460 /* init AL7230B radio, part two */
| 1305 /* init AL7230B radio, part two */
|
1461 for (i = 0; i != INDEXES(rfini_2); i++) { 1462 zyd_cfg_rfwrite(sc, rfini_2[i]);
| 1306 for (i = 0; i < N(rfini_2); i++) { 1307 if ((error = zyd_rfwrite(sc, rfini_2[i])) != 0) 1308 return (error);
|
1463 } 1464 /* init RF-dependent PHY registers, part three */
| 1309 } 1310 /* init RF-dependent PHY registers, part three */
|
1465 for (i = 0; i != INDEXES(phyini_3); i++) { 1466 zyd_cfg_write16(sc, phyini_3[i].reg, phyini_3[i].val); 1467 }
| 1311 for (i = 0; i < N(phyini_3); i++) 1312 zyd_write16_m(sc, phyini_3[i].reg, phyini_3[i].val); 1313fail: 1314 return (error); 1315#undef N
|
1468} 1469
| 1316} 1317
|
1470static void 1471zyd_cfg_rf_al7230b_set_channel(struct zyd_softc *sc, struct zyd_rf *rf, 1472 uint8_t channel)
| 1318static int 1319zyd_al7230B_switch_radio(struct zyd_rf *rf, int on)
|
1473{
| 1320{
|
| 1321 int error; 1322 struct zyd_softc *sc = rf->rf_sc; 1323 1324 zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04); 1325 zyd_write16_m(sc, ZYD_CR251, on ? 0x3f : 0x2f); 1326fail: 1327 return (error); 1328} 1329 1330static int 1331zyd_al7230B_set_channel(struct zyd_rf *rf, uint8_t chan) 1332{ 1333#define N(a) (sizeof(a) / sizeof((a)[0])) 1334 struct zyd_softc *sc = rf->rf_sc;
|
1474 static const struct {
| 1335 static const struct {
|
1475 uint32_t r1, r2; 1476 } rfprog[] = ZYD_AL7230B_CHANTABLE;
| 1336 uint32_t r1, r2; 1337 } rfprog[] = ZYD_AL7230B_CHANTABLE;
|
1477 static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL;
| 1338 static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL;
|
1478 uint32_t i;
| 1339 int i, error;
|
1479
| 1340
|
1480 zyd_cfg_write16(sc, ZYD_CR240, 0x57); 1481 zyd_cfg_write16(sc, ZYD_CR251, 0x2f);
| 1341 zyd_write16_m(sc, ZYD_CR240, 0x57); 1342 zyd_write16_m(sc, ZYD_CR251, 0x2f);
|
1482
| 1343
|
1483 for (i = 0; i != INDEXES(rfsc); i++) { 1484 zyd_cfg_rfwrite(sc, rfsc[i]);
| 1344 for (i = 0; i < N(rfsc); i++) { 1345 if ((error = zyd_rfwrite(sc, rfsc[i])) != 0) 1346 return (error);
|
1485 } 1486
| 1347 } 1348
|
1487 zyd_cfg_write16(sc, ZYD_CR128, 0x14); 1488 zyd_cfg_write16(sc, ZYD_CR129, 0x12); 1489 zyd_cfg_write16(sc, ZYD_CR130, 0x10); 1490 zyd_cfg_write16(sc, ZYD_CR38, 0x38); 1491 zyd_cfg_write16(sc, ZYD_CR136, 0xdf);
| 1349 zyd_write16_m(sc, ZYD_CR128, 0x14); 1350 zyd_write16_m(sc, ZYD_CR129, 0x12); 1351 zyd_write16_m(sc, ZYD_CR130, 0x10); 1352 zyd_write16_m(sc, ZYD_CR38, 0x38); 1353 zyd_write16_m(sc, ZYD_CR136, 0xdf);
|
1492
| 1354
|
1493 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r1); 1494 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r2); 1495 zyd_cfg_rfwrite(sc, 0x3c9000);
| 1355 error = zyd_rfwrite(sc, rfprog[chan - 1].r1); 1356 if (error != 0) 1357 goto fail; 1358 error = zyd_rfwrite(sc, rfprog[chan - 1].r2); 1359 if (error != 0) 1360 goto fail; 1361 error = zyd_rfwrite(sc, 0x3c9000); 1362 if (error != 0) 1363 goto fail;
|
1496
| 1364
|
1497 zyd_cfg_write16(sc, ZYD_CR251, 0x3f); 1498 zyd_cfg_write16(sc, ZYD_CR203, 0x06); 1499 zyd_cfg_write16(sc, ZYD_CR240, 0x08); 1500
| 1365 zyd_write16_m(sc, ZYD_CR251, 0x3f); 1366 zyd_write16_m(sc, ZYD_CR203, 0x06); 1367 zyd_write16_m(sc, ZYD_CR240, 0x08); 1368fail: 1369 return (error); 1370#undef N
|
1501} 1502 1503/* 1504 * AL2210 RF methods. 1505 */
| 1371} 1372 1373/* 1374 * AL2210 RF methods. 1375 */
|
1506static void 1507zyd_cfg_rf_al2210_switch_radio(struct zyd_softc *sc, uint8_t on)
| 1376static int 1377zyd_al2210_init(struct zyd_rf *rf)
|
1508{
| 1378{
|
1509 1510} 1511 1512static void 1513zyd_cfg_rf_al2210_init(struct zyd_softc *sc, struct zyd_rf *rf) 1514{
| 1379#define N(a) (sizeof(a) / sizeof((a)[0])) 1380 struct zyd_softc *sc = rf->rf_sc;
|
1515 static const struct zyd_phy_pair phyini[] = ZYD_AL2210_PHY; 1516 static const uint32_t rfini[] = ZYD_AL2210_RF; 1517 uint32_t tmp;
| 1381 static const struct zyd_phy_pair phyini[] = ZYD_AL2210_PHY; 1382 static const uint32_t rfini[] = ZYD_AL2210_RF; 1383 uint32_t tmp;
|
1518 uint32_t i;
| 1384 int i, error;
|
1519
| 1385
|
1520 zyd_cfg_write32(sc, ZYD_CR18, 2);
| 1386 zyd_write32_m(sc, ZYD_CR18, 2);
|
1521 1522 /* init RF-dependent PHY registers */
| 1387 1388 /* init RF-dependent PHY registers */
|
1523 for (i = 0; i != INDEXES(phyini); i++) { 1524 zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val); 1525 }
| 1389 for (i = 0; i < N(phyini); i++) 1390 zyd_write16_m(sc, phyini[i].reg, phyini[i].val); 1391
|
1526 /* init AL2210 radio */
| 1392 /* init AL2210 radio */
|
1527 for (i = 0; i != INDEXES(rfini); i++) { 1528 zyd_cfg_rfwrite(sc, rfini[i]);
| 1393 for (i = 0; i < N(rfini); i++) { 1394 if ((error = zyd_rfwrite(sc, rfini[i])) != 0) 1395 return (error);
|
1529 }
| 1396 }
|
1530 zyd_cfg_write16(sc, ZYD_CR47, 0x1e); 1531 zyd_cfg_read32(sc, ZYD_CR_RADIO_PD, &tmp); 1532 zyd_cfg_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1); 1533 zyd_cfg_write32(sc, ZYD_CR_RADIO_PD, tmp | 1); 1534 zyd_cfg_write32(sc, ZYD_CR_RFCFG, 0x05); 1535 zyd_cfg_write32(sc, ZYD_CR_RFCFG, 0x00); 1536 zyd_cfg_write16(sc, ZYD_CR47, 0x1e); 1537 zyd_cfg_write32(sc, ZYD_CR18, 3);
| 1397 zyd_write16_m(sc, ZYD_CR47, 0x1e); 1398 zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp); 1399 zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1); 1400 zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1); 1401 zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05); 1402 zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00); 1403 zyd_write16_m(sc, ZYD_CR47, 0x1e); 1404 zyd_write32_m(sc, ZYD_CR18, 3); 1405fail: 1406 return (error); 1407#undef N
|
1538} 1539
| 1408} 1409
|
1540static void 1541zyd_cfg_rf_al2210_set_channel(struct zyd_softc *sc, struct zyd_rf *rf, 1542 uint8_t channel)
| 1410static int 1411zyd_al2210_switch_radio(struct zyd_rf *rf, int on)
|
1543{
| 1412{
|
| 1413 /* vendor driver does nothing for this RF chip */ 1414 1415 return (0); 1416} 1417 1418static int 1419zyd_al2210_set_channel(struct zyd_rf *rf, uint8_t chan) 1420{ 1421 int error; 1422 struct zyd_softc *sc = rf->rf_sc;
|
1544 static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE; 1545 uint32_t tmp; 1546
| 1423 static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE; 1424 uint32_t tmp; 1425
|
1547 zyd_cfg_write32(sc, ZYD_CR18, 2); 1548 zyd_cfg_write16(sc, ZYD_CR47, 0x1e); 1549 zyd_cfg_read32(sc, ZYD_CR_RADIO_PD, &tmp); 1550 zyd_cfg_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1); 1551 zyd_cfg_write32(sc, ZYD_CR_RADIO_PD, tmp | 1); 1552 zyd_cfg_write32(sc, ZYD_CR_RFCFG, 0x05); 1553 zyd_cfg_write32(sc, ZYD_CR_RFCFG, 0x00); 1554 zyd_cfg_write16(sc, ZYD_CR47, 0x1e);
| 1426 zyd_write32_m(sc, ZYD_CR18, 2); 1427 zyd_write16_m(sc, ZYD_CR47, 0x1e); 1428 zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp); 1429 zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1); 1430 zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1); 1431 zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05); 1432 zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00); 1433 zyd_write16_m(sc, ZYD_CR47, 0x1e);
|
1555 1556 /* actually set the channel */
| 1434 1435 /* actually set the channel */
|
1557 zyd_cfg_rfwrite(sc, rfprog[channel - 1]);
| 1436 error = zyd_rfwrite(sc, rfprog[chan - 1]); 1437 if (error != 0) 1438 goto fail;
|
1558
| 1439
|
1559 zyd_cfg_write32(sc, ZYD_CR18, 3);
| 1440 zyd_write32_m(sc, ZYD_CR18, 3); 1441fail: 1442 return (error);
|
1560} 1561 1562/* 1563 * GCT RF methods. 1564 */
| 1443} 1444 1445/* 1446 * GCT RF methods. 1447 */
|
1565static void 1566zyd_cfg_rf_gct_switch_radio(struct zyd_softc *sc, uint8_t on)
| 1448static int 1449zyd_gct_init(struct zyd_rf *rf)
|
1567{
| 1450{
|
1568 /* vendor driver does nothing for this RF chip */ 1569} 1570 1571static void 1572zyd_cfg_rf_gct_init(struct zyd_softc *sc, struct zyd_rf *rf) 1573{
| 1451#define N(a) (sizeof(a) / sizeof((a)[0])) 1452 struct zyd_softc *sc = rf->rf_sc;
|
1574 static const struct zyd_phy_pair phyini[] = ZYD_GCT_PHY; 1575 static const uint32_t rfini[] = ZYD_GCT_RF;
| 1453 static const struct zyd_phy_pair phyini[] = ZYD_GCT_PHY; 1454 static const uint32_t rfini[] = ZYD_GCT_RF;
|
1576 uint32_t i;
| 1455 int i, error;
|
1577 1578 /* init RF-dependent PHY registers */
| 1456 1457 /* init RF-dependent PHY registers */
|
1579 for (i = 0; i != INDEXES(phyini); i++) { 1580 zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val); 1581 }
| 1458 for (i = 0; i < N(phyini); i++) 1459 zyd_write16_m(sc, phyini[i].reg, phyini[i].val); 1460
|
1582 /* init cgt radio */
| 1461 /* init cgt radio */
|
1583 for (i = 0; i != INDEXES(rfini); i++) { 1584 zyd_cfg_rfwrite(sc, rfini[i]);
| 1462 for (i = 0; i < N(rfini); i++) { 1463 if ((error = zyd_rfwrite(sc, rfini[i])) != 0) 1464 return (error);
|
1585 }
| 1465 }
|
| 1466fail: 1467 return (error); 1468#undef N
|
1586} 1587
| 1469} 1470
|
1588static void 1589zyd_cfg_rf_gct_set_channel(struct zyd_softc *sc, struct zyd_rf *rf, 1590 uint8_t channel)
| 1471static int 1472zyd_gct_switch_radio(struct zyd_rf *rf, int on)
|
1591{
| 1473{
|
| 1474 /* vendor driver does nothing for this RF chip */ 1475 1476 return (0); 1477} 1478 1479static int 1480zyd_gct_set_channel(struct zyd_rf *rf, uint8_t chan) 1481{ 1482 int error; 1483 struct zyd_softc *sc = rf->rf_sc;
|
1592 static const uint32_t rfprog[] = ZYD_GCT_CHANTABLE; 1593
| 1484 static const uint32_t rfprog[] = ZYD_GCT_CHANTABLE; 1485
|
1594 zyd_cfg_rfwrite(sc, 0x1c0000); 1595 zyd_cfg_rfwrite(sc, rfprog[channel - 1]); 1596 zyd_cfg_rfwrite(sc, 0x1c0008);
| 1486 error = zyd_rfwrite(sc, 0x1c0000); 1487 if (error != 0) 1488 goto fail; 1489 error = zyd_rfwrite(sc, rfprog[chan - 1]); 1490 if (error != 0) 1491 goto fail; 1492 error = zyd_rfwrite(sc, 0x1c0008); 1493fail: 1494 return (error);
|
1597} 1598 1599/* 1600 * Maxim RF methods. 1601 */
| 1495} 1496 1497/* 1498 * Maxim RF methods. 1499 */
|
1602static void 1603zyd_cfg_rf_maxim_switch_radio(struct zyd_softc *sc, uint8_t on)
| 1500static int 1501zyd_maxim_init(struct zyd_rf *rf)
|
1604{
| 1502{
|
1605 /* vendor driver does nothing for this RF chip */ 1606 1607} 1608 1609static void 1610zyd_cfg_rf_maxim_init(struct zyd_softc *sc, struct zyd_rf *rf) 1611{
| 1503#define N(a) (sizeof(a) / sizeof((a)[0])) 1504 struct zyd_softc *sc = rf->rf_sc;
|
1612 static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY; 1613 static const uint32_t rfini[] = ZYD_MAXIM_RF; 1614 uint16_t tmp;
| 1505 static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY; 1506 static const uint32_t rfini[] = ZYD_MAXIM_RF; 1507 uint16_t tmp;
|
1615 uint32_t i;
| 1508 int i, error;
|
1616 1617 /* init RF-dependent PHY registers */
| 1509 1510 /* init RF-dependent PHY registers */
|
1618 for (i = 0; i != INDEXES(phyini); i++) { 1619 zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val); 1620 } 1621 zyd_cfg_read16(sc, ZYD_CR203, &tmp); 1622 zyd_cfg_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
| 1511 for (i = 0; i < N(phyini); i++) 1512 zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
|
1623
| 1513
|
| 1514 zyd_read16_m(sc, ZYD_CR203, &tmp); 1515 zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); 1516
|
1624 /* init maxim radio */
| 1517 /* init maxim radio */
|
1625 for (i = 0; i != INDEXES(rfini); i++) { 1626 zyd_cfg_rfwrite(sc, rfini[i]);
| 1518 for (i = 0; i < N(rfini); i++) { 1519 if ((error = zyd_rfwrite(sc, rfini[i])) != 0) 1520 return (error);
|
1627 }
| 1521 }
|
1628 zyd_cfg_read16(sc, ZYD_CR203, &tmp); 1629 zyd_cfg_write16(sc, ZYD_CR203, tmp | (1 << 4));
| 1522 zyd_read16_m(sc, ZYD_CR203, &tmp); 1523 zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); 1524fail: 1525 return (error); 1526#undef N
|
1630} 1631
| 1527} 1528
|
1632static void 1633zyd_cfg_rf_maxim_set_channel(struct zyd_softc *sc, struct zyd_rf *rf, 1634 uint8_t channel)
| 1529static int 1530zyd_maxim_switch_radio(struct zyd_rf *rf, int on)
|
1635{
| 1531{
|
| 1532 1533 /* vendor driver does nothing for this RF chip */ 1534 return (0); 1535} 1536 1537static int 1538zyd_maxim_set_channel(struct zyd_rf *rf, uint8_t chan) 1539{ 1540#define N(a) (sizeof(a) / sizeof((a)[0])) 1541 struct zyd_softc *sc = rf->rf_sc;
|
1636 static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY; 1637 static const uint32_t rfini[] = ZYD_MAXIM_RF; 1638 static const struct {
| 1542 static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY; 1543 static const uint32_t rfini[] = ZYD_MAXIM_RF; 1544 static const struct {
|
1639 uint32_t r1, r2; 1640 } rfprog[] = ZYD_MAXIM_CHANTABLE;
| 1545 uint32_t r1, r2; 1546 } rfprog[] = ZYD_MAXIM_CHANTABLE;
|
1641 uint16_t tmp;
| 1547 uint16_t tmp;
|
1642 uint32_t i;
| 1548 int i, error;
|
1643 1644 /* 1645 * Do the same as we do when initializing it, except for the channel 1646 * values coming from the two channel tables. 1647 */ 1648 1649 /* init RF-dependent PHY registers */
| 1549 1550 /* 1551 * Do the same as we do when initializing it, except for the channel 1552 * values coming from the two channel tables. 1553 */ 1554 1555 /* init RF-dependent PHY registers */
|
1650 for (i = 0; i != INDEXES(phyini); i++) { 1651 zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val); 1652 } 1653 zyd_cfg_read16(sc, ZYD_CR203, &tmp); 1654 zyd_cfg_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
| 1556 for (i = 0; i < N(phyini); i++) 1557 zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
|
1655
| 1558
|
| 1559 zyd_read16_m(sc, ZYD_CR203, &tmp); 1560 zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); 1561
|
1656 /* first two values taken from the chantables */
| 1562 /* first two values taken from the chantables */
|
1657 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r1); 1658 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r2);
| 1563 error = zyd_rfwrite(sc, rfprog[chan - 1].r1); 1564 if (error != 0) 1565 goto fail; 1566 error = zyd_rfwrite(sc, rfprog[chan - 1].r2); 1567 if (error != 0) 1568 goto fail;
|
1659 1660 /* init maxim radio - skipping the two first values */
| 1569 1570 /* init maxim radio - skipping the two first values */
|
1661 if (INDEXES(rfini) > 2) { 1662 for (i = 2; i != INDEXES(rfini); i++) { 1663 zyd_cfg_rfwrite(sc, rfini[i]); 1664 }
| 1571 for (i = 2; i < N(rfini); i++) { 1572 if ((error = zyd_rfwrite(sc, rfini[i])) != 0) 1573 return (error);
|
1665 }
| 1574 }
|
1666 zyd_cfg_read16(sc, ZYD_CR203, &tmp); 1667 zyd_cfg_write16(sc, ZYD_CR203, tmp | (1 << 4));
| 1575 zyd_read16_m(sc, ZYD_CR203, &tmp); 1576 zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); 1577fail: 1578 return (error); 1579#undef N
|
1668} 1669 1670/* 1671 * Maxim2 RF methods. 1672 */
| 1580} 1581 1582/* 1583 * Maxim2 RF methods. 1584 */
|
1673static void 1674zyd_cfg_rf_maxim2_switch_radio(struct zyd_softc *sc, uint8_t on)
| 1585static int 1586zyd_maxim2_init(struct zyd_rf *rf)
|
1675{
| 1587{
|
1676 /* vendor driver does nothing for this RF chip */ 1677} 1678 1679static void 1680zyd_cfg_rf_maxim2_init(struct zyd_softc *sc, struct zyd_rf *rf) 1681{
| 1588#define N(a) (sizeof(a) / sizeof((a)[0])) 1589 struct zyd_softc *sc = rf->rf_sc;
|
1682 static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY; 1683 static const uint32_t rfini[] = ZYD_MAXIM2_RF; 1684 uint16_t tmp;
| 1590 static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY; 1591 static const uint32_t rfini[] = ZYD_MAXIM2_RF; 1592 uint16_t tmp;
|
1685 uint32_t i;
| 1593 int i, error;
|
1686 1687 /* init RF-dependent PHY registers */
| 1594 1595 /* init RF-dependent PHY registers */
|
1688 for (i = 0; i != INDEXES(phyini); i++) { 1689 zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val); 1690 } 1691 zyd_cfg_read16(sc, ZYD_CR203, &tmp); 1692 zyd_cfg_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
| 1596 for (i = 0; i < N(phyini); i++) 1597 zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
|
1693
| 1598
|
| 1599 zyd_read16_m(sc, ZYD_CR203, &tmp); 1600 zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); 1601
|
1694 /* init maxim2 radio */
| 1602 /* init maxim2 radio */
|
1695 for (i = 0; i != INDEXES(rfini); i++) { 1696 zyd_cfg_rfwrite(sc, rfini[i]);
| 1603 for (i = 0; i < N(rfini); i++) { 1604 if ((error = zyd_rfwrite(sc, rfini[i])) != 0) 1605 return (error);
|
1697 }
| 1606 }
|
1698 zyd_cfg_read16(sc, ZYD_CR203, &tmp); 1699 zyd_cfg_write16(sc, ZYD_CR203, tmp | (1 << 4));
| 1607 zyd_read16_m(sc, ZYD_CR203, &tmp); 1608 zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); 1609fail: 1610 return (error); 1611#undef N
|
1700} 1701
| 1612} 1613
|
1702static void 1703zyd_cfg_rf_maxim2_set_channel(struct zyd_softc *sc, struct zyd_rf *rf, 1704 uint8_t channel)
| 1614static int 1615zyd_maxim2_switch_radio(struct zyd_rf *rf, int on)
|
1705{
| 1616{
|
| 1617 1618 /* vendor driver does nothing for this RF chip */ 1619 return (0); 1620} 1621 1622static int 1623zyd_maxim2_set_channel(struct zyd_rf *rf, uint8_t chan) 1624{ 1625#define N(a) (sizeof(a) / sizeof((a)[0])) 1626 struct zyd_softc *sc = rf->rf_sc;
|
1706 static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY; 1707 static const uint32_t rfini[] = ZYD_MAXIM2_RF; 1708 static const struct {
| 1627 static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY; 1628 static const uint32_t rfini[] = ZYD_MAXIM2_RF; 1629 static const struct {
|
1709 uint32_t r1, r2; 1710 } rfprog[] = ZYD_MAXIM2_CHANTABLE;
| 1630 uint32_t r1, r2; 1631 } rfprog[] = ZYD_MAXIM2_CHANTABLE;
|
1711 uint16_t tmp;
| 1632 uint16_t tmp;
|
1712 uint32_t i;
| 1633 int i, error;
|
1713 1714 /* 1715 * Do the same as we do when initializing it, except for the channel 1716 * values coming from the two channel tables. 1717 */ 1718 1719 /* init RF-dependent PHY registers */
| 1634 1635 /* 1636 * Do the same as we do when initializing it, except for the channel 1637 * values coming from the two channel tables. 1638 */ 1639 1640 /* init RF-dependent PHY registers */
|
1720 for (i = 0; i != INDEXES(phyini); i++) { 1721 zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val); 1722 } 1723 zyd_cfg_read16(sc, ZYD_CR203, &tmp); 1724 zyd_cfg_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
| 1641 for (i = 0; i < N(phyini); i++) 1642 zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
|
1725
| 1643
|
| 1644 zyd_read16_m(sc, ZYD_CR203, &tmp); 1645 zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); 1646
|
1726 /* first two values taken from the chantables */
| 1647 /* first two values taken from the chantables */
|
1727 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r1); 1728 zyd_cfg_rfwrite(sc, rfprog[channel - 1].r2);
| 1648 error = zyd_rfwrite(sc, rfprog[chan - 1].r1); 1649 if (error != 0) 1650 goto fail; 1651 error = zyd_rfwrite(sc, rfprog[chan - 1].r2); 1652 if (error != 0) 1653 goto fail;
|
1729 1730 /* init maxim2 radio - skipping the two first values */
| 1654 1655 /* init maxim2 radio - skipping the two first values */
|
1731 if (INDEXES(rfini) > 2) { 1732 for (i = 2; i != INDEXES(rfini); i++) { 1733 zyd_cfg_rfwrite(sc, rfini[i]); 1734 }
| 1656 for (i = 2; i < N(rfini); i++) { 1657 if ((error = zyd_rfwrite(sc, rfini[i])) != 0) 1658 return (error);
|
1735 }
| 1659 }
|
1736 zyd_cfg_read16(sc, ZYD_CR203, &tmp); 1737 zyd_cfg_write16(sc, ZYD_CR203, tmp | (1 << 4));
| 1660 zyd_read16_m(sc, ZYD_CR203, &tmp); 1661 zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); 1662fail: 1663 return (error); 1664#undef N
|
1738} 1739
| 1665} 1666
|
1740/* 1741 * Assign drivers and init the RF 1742 */ 1743static uint8_t 1744zyd_cfg_rf_init_hw(struct zyd_softc *sc, struct zyd_rf *rf)
| 1667static int 1668zyd_rf_attach(struct zyd_softc *sc, uint8_t type)
|
1745{
| 1669{
|
1746 ; /* fix for indent */
| 1670 struct zyd_rf *rf = &sc->sc_rf;
|
1747
| 1671
|
1748 switch (sc->sc_rf_rev) {
| 1672 rf->rf_sc = sc; 1673 1674 switch (type) {
|
1749 case ZYD_RF_RFMD:
| 1675 case ZYD_RF_RFMD:
|
1750 rf->cfg_init_hw = zyd_cfg_rf_rfmd_init; 1751 rf->cfg_switch_radio = zyd_cfg_rf_rfmd_switch_radio; 1752 rf->cfg_set_channel = zyd_cfg_rf_rfmd_set_channel; 1753 rf->width = 24; /* 24-bit RF values */
| 1676 rf->init = zyd_rfmd_init; 1677 rf->switch_radio = zyd_rfmd_switch_radio; 1678 rf->set_channel = zyd_rfmd_set_channel; 1679 rf->width = 24; /* 24-bit RF values */
|
1754 break; 1755 case ZYD_RF_AL2230: 1756 case ZYD_RF_AL2230S:
| 1680 break; 1681 case ZYD_RF_AL2230: 1682 case ZYD_RF_AL2230S:
|
1757 if (sc->sc_mac_rev == ZYD_ZD1211B) { 1758 rf->cfg_init_hw = zyd_cfg_rf_al2230_init_b; 1759 rf->cfg_set_channel = zyd_cfg_rf_al2230_set_channel_b;
| 1683 if (sc->sc_macrev == ZYD_ZD1211B) { 1684 rf->init = zyd_al2230_init_b; 1685 rf->set_channel = zyd_al2230_set_channel_b;
|
1760 } else {
| 1686 } else {
|
1761 rf->cfg_init_hw = zyd_cfg_rf_al2230_init; 1762 rf->cfg_set_channel = zyd_cfg_rf_al2230_set_channel;
| 1687 rf->init = zyd_al2230_init; 1688 rf->set_channel = zyd_al2230_set_channel;
|
1763 }
| 1689 }
|
1764 rf->cfg_switch_radio = zyd_cfg_rf_al2230_switch_radio; 1765 rf->cfg_bandedge6 = zyd_cfg_rf_al2230_bandedge6; 1766 rf->width = 24; /* 24-bit RF values */
| 1690 rf->switch_radio = zyd_al2230_switch_radio; 1691 rf->bandedge6 = zyd_al2230_bandedge6; 1692 rf->width = 24; /* 24-bit RF values */
|
1767 break; 1768 case ZYD_RF_AL7230B:
| 1693 break; 1694 case ZYD_RF_AL7230B:
|
1769 rf->cfg_init_hw = zyd_cfg_rf_al7230b_init; 1770 rf->cfg_switch_radio = zyd_cfg_rf_al7230b_switch_radio; 1771 rf->cfg_set_channel = zyd_cfg_rf_al7230b_set_channel; 1772 rf->width = 24; /* 24-bit RF values */
| 1695 rf->init = zyd_al7230B_init; 1696 rf->switch_radio = zyd_al7230B_switch_radio; 1697 rf->set_channel = zyd_al7230B_set_channel; 1698 rf->width = 24; /* 24-bit RF values */
|
1773 break; 1774 case ZYD_RF_AL2210:
| 1699 break; 1700 case ZYD_RF_AL2210:
|
1775 rf->cfg_init_hw = zyd_cfg_rf_al2210_init; 1776 rf->cfg_switch_radio = zyd_cfg_rf_al2210_switch_radio; 1777 rf->cfg_set_channel = zyd_cfg_rf_al2210_set_channel; 1778 rf->width = 24; /* 24-bit RF values */
| 1701 rf->init = zyd_al2210_init; 1702 rf->switch_radio = zyd_al2210_switch_radio; 1703 rf->set_channel = zyd_al2210_set_channel; 1704 rf->width = 24; /* 24-bit RF values */
|
1779 break; 1780 case ZYD_RF_GCT:
| 1705 break; 1706 case ZYD_RF_GCT:
|
1781 rf->cfg_init_hw = zyd_cfg_rf_gct_init; 1782 rf->cfg_switch_radio = zyd_cfg_rf_gct_switch_radio; 1783 rf->cfg_set_channel = zyd_cfg_rf_gct_set_channel; 1784 rf->width = 21; /* 21-bit RF values */
| 1707 rf->init = zyd_gct_init; 1708 rf->switch_radio = zyd_gct_switch_radio; 1709 rf->set_channel = zyd_gct_set_channel; 1710 rf->width = 21; /* 21-bit RF values */
|
1785 break; 1786 case ZYD_RF_MAXIM_NEW:
| 1711 break; 1712 case ZYD_RF_MAXIM_NEW:
|
1787 rf->cfg_init_hw = zyd_cfg_rf_maxim_init; 1788 rf->cfg_switch_radio = zyd_cfg_rf_maxim_switch_radio; 1789 rf->cfg_set_channel = zyd_cfg_rf_maxim_set_channel; 1790 rf->width = 18; /* 18-bit RF values */
| 1713 rf->init = zyd_maxim_init; 1714 rf->switch_radio = zyd_maxim_switch_radio; 1715 rf->set_channel = zyd_maxim_set_channel; 1716 rf->width = 18; /* 18-bit RF values */
|
1791 break; 1792 case ZYD_RF_MAXIM_NEW2:
| 1717 break; 1718 case ZYD_RF_MAXIM_NEW2:
|
1793 rf->cfg_init_hw = zyd_cfg_rf_maxim2_init; 1794 rf->cfg_switch_radio = zyd_cfg_rf_maxim2_switch_radio; 1795 rf->cfg_set_channel = zyd_cfg_rf_maxim2_set_channel; 1796 rf->width = 18; /* 18-bit RF values */
| 1719 rf->init = zyd_maxim2_init; 1720 rf->switch_radio = zyd_maxim2_switch_radio; 1721 rf->set_channel = zyd_maxim2_set_channel; 1722 rf->width = 18; /* 18-bit RF values */
|
1797 break; 1798 default:
| 1723 break; 1724 default:
|
1799 DPRINTFN(0, "%s: Sorry, radio %s is not supported yet\n", 1800 sc->sc_name, zyd_rf_name(sc->sc_rf_rev)); 1801 return (1);
| 1725 device_printf(sc->sc_dev, 1726 "sorry, radio \"%s\" is not supported yet\n", 1727 zyd_rf_name(type)); 1728 return (EINVAL);
|
1802 }
| 1729 }
|
| 1730 return (0); 1731}
|
1803
| 1732
|
1804 zyd_cfg_lock_phy(sc); 1805 (rf->cfg_init_hw) (sc, rf); 1806 zyd_cfg_unlock_phy(sc);
| 1733static const char * 1734zyd_rf_name(uint8_t type) 1735{ 1736 static const char * const zyd_rfs[] = { 1737 "unknown", "unknown", "UW2451", "UCHIP", "AL2230", 1738 "AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT", 1739 "AL2230S", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2", 1740 "PHILIPS" 1741 };
|
1807
| 1742
|
1808 return (0); /* success */
| 1743 return zyd_rfs[(type > 15) ? 0 : type];
|
1809} 1810
| 1744} 1745
|
1811/* 1812 * Init the hardware 1813 */ 1814static uint8_t 1815zyd_cfg_hw_init(struct zyd_softc *sc)
| 1746static int 1747zyd_hw_init(struct zyd_softc *sc)
|
1816{
| 1748{
|
| 1749 int error;
|
1817 const struct zyd_phy_pair *phyp;
| 1750 const struct zyd_phy_pair *phyp;
|
1818 uint32_t tmp;
| 1751 struct zyd_rf *rf = &sc->sc_rf; 1752 uint16_t val;
|
1819 1820 /* specify that the plug and play is finished */
| 1753 1754 /* specify that the plug and play is finished */
|
1821 zyd_cfg_write32(sc, ZYD_MAC_AFTER_PNP, 1);
| 1755 zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1); 1756 zyd_read16_m(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->sc_fwbase); 1757 DPRINTF(sc, ZYD_DEBUG_FW, "firmware base address=0x%04x\n", 1758 sc->sc_fwbase);
|
1822
| 1759
|
1823 zyd_cfg_read16(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->sc_firmware_base); 1824 DPRINTF("firmware base address=0x%04x\n", sc->sc_firmware_base); 1825
| |
1826 /* retrieve firmware revision number */
| 1760 /* retrieve firmware revision number */
|
1827 zyd_cfg_read16(sc, sc->sc_firmware_base + ZYD_FW_FIRMWARE_REV, &sc->sc_fw_rev); 1828 1829 zyd_cfg_write32(sc, ZYD_CR_GPI_EN, 0); 1830 zyd_cfg_write32(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f); 1831
| 1761 zyd_read16_m(sc, sc->sc_fwbase + ZYD_FW_FIRMWARE_REV, &sc->sc_fwrev); 1762 zyd_write32_m(sc, ZYD_CR_GPI_EN, 0); 1763 zyd_write32_m(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f);
|
1832 /* set mandatory rates - XXX assumes 802.11b/g */
| 1764 /* set mandatory rates - XXX assumes 802.11b/g */
|
1833 zyd_cfg_write32(sc, ZYD_MAC_MAN_RATE, 0x150f);
| 1765 zyd_write32_m(sc, ZYD_MAC_MAN_RATE, 0x150f);
|
1834 1835 /* disable interrupts */
| 1766 1767 /* disable interrupts */
|
1836 zyd_cfg_write32(sc, ZYD_CR_INTERRUPT, 0);
| 1768 zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0);
|
1837
| 1769
|
1838 /* PHY init */ 1839 zyd_cfg_lock_phy(sc); 1840 phyp = (sc->sc_mac_rev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy; 1841 for (; phyp->reg != 0; phyp++) { 1842 zyd_cfg_write16(sc, phyp->reg, phyp->val);
| 1770 if ((error = zyd_read_pod(sc)) != 0) { 1771 device_printf(sc->sc_dev, "could not read EEPROM\n"); 1772 goto fail;
|
1843 }
| 1773 }
|
1844 if ((sc->sc_mac_rev == ZYD_ZD1211) && sc->sc_fix_cr157) { 1845 zyd_cfg_read32(sc, ZYD_EEPROM_PHY_REG, &tmp); 1846 zyd_cfg_write32(sc, ZYD_CR157, tmp >> 8);
| 1774 1775 /* PHY init (resetting) */ 1776 error = zyd_lock_phy(sc); 1777 if (error != 0) 1778 goto fail; 1779 phyp = (sc->sc_macrev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy; 1780 for (; phyp->reg != 0; phyp++) 1781 zyd_write16_m(sc, phyp->reg, phyp->val); 1782 if (sc->sc_macrev == ZYD_ZD1211 && sc->sc_fix_cr157 != 0) { 1783 zyd_read16_m(sc, ZYD_EEPROM_PHY_REG, &val); 1784 zyd_write32_m(sc, ZYD_CR157, val >> 8);
|
1847 }
| 1785 }
|
1848 zyd_cfg_unlock_phy(sc);
| 1786 error = zyd_unlock_phy(sc); 1787 if (error != 0) 1788 goto fail;
|
1849 1850 /* HMAC init */
| 1789 1790 /* HMAC init */
|
1851 zyd_cfg_write32(sc, ZYD_MAC_ACK_EXT, 0x00000020); 1852 zyd_cfg_write32(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808); 1853 zyd_cfg_write32(sc, ZYD_MAC_SNIFFER, 0x00000000); 1854 zyd_cfg_write32(sc, ZYD_MAC_RXFILTER, 0x00000000); 1855 zyd_cfg_write32(sc, ZYD_MAC_GHTBL, 0x00000000); 1856 zyd_cfg_write32(sc, ZYD_MAC_GHTBH, 0x80000000); 1857 zyd_cfg_write32(sc, ZYD_MAC_MISC, 0x000000a4); 1858 zyd_cfg_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f); 1859 zyd_cfg_write32(sc, ZYD_MAC_BCNCFG, 0x00f00401); 1860 zyd_cfg_write32(sc, ZYD_MAC_PHY_DELAY2, 0x00000000); 1861 zyd_cfg_write32(sc, ZYD_MAC_ACK_EXT, 0x00000080); 1862 zyd_cfg_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000); 1863 zyd_cfg_write32(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100); 1864 zyd_cfg_write32(sc, ZYD_CR_RX_PE_DELAY, 0x00000070); 1865 zyd_cfg_write32(sc, ZYD_CR_PS_CTRL, 0x10000000); 1866 zyd_cfg_write32(sc, ZYD_MAC_RTSCTSRATE, 0x02030203); 1867 zyd_cfg_write32(sc, ZYD_MAC_AFTER_PNP, 1); 1868 zyd_cfg_write32(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114); 1869 zyd_cfg_write32(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0a47c032); 1870 zyd_cfg_write32(sc, ZYD_MAC_CAM_MODE, 0x3);
| 1791 zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000020); 1792 zyd_write32_m(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808); 1793 zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0x00000000); 1794 zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0x00000000); 1795 zyd_write32_m(sc, ZYD_MAC_GHTBL, 0x00000000); 1796 zyd_write32_m(sc, ZYD_MAC_GHTBH, 0x80000000); 1797 zyd_write32_m(sc, ZYD_MAC_MISC, 0x000000a4); 1798 zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f); 1799 zyd_write32_m(sc, ZYD_MAC_BCNCFG, 0x00f00401); 1800 zyd_write32_m(sc, ZYD_MAC_PHY_DELAY2, 0x00000000); 1801 zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000080); 1802 zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000); 1803 zyd_write32_m(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100); 1804 zyd_write32_m(sc, ZYD_CR_RX_PE_DELAY, 0x00000070); 1805 zyd_write32_m(sc, ZYD_CR_PS_CTRL, 0x10000000); 1806 zyd_write32_m(sc, ZYD_MAC_RTSCTSRATE, 0x02030203); 1807 zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1); 1808 zyd_write32_m(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114); 1809 zyd_write32_m(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0a47c032); 1810 zyd_write32_m(sc, ZYD_MAC_CAM_MODE, 0x3);
|
1871
| 1811
|
1872 if (sc->sc_mac_rev == ZYD_ZD1211) { 1873 zyd_cfg_write32(sc, ZYD_MAC_RETRY, 0x00000002); 1874 zyd_cfg_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
| 1812 if (sc->sc_macrev == ZYD_ZD1211) { 1813 zyd_write32_m(sc, ZYD_MAC_RETRY, 0x00000002); 1814 zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
|
1875 } else {
| 1815 } else {
|
1876 zyd_cfg_write32(sc, ZYD_MACB_MAX_RETRY, 0x02020202); 1877 zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f); 1878 zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f); 1879 zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f); 1880 zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f); 1881 zyd_cfg_write32(sc, ZYD_MACB_AIFS_CTL1, 0x00280028); 1882 zyd_cfg_write32(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C); 1883 zyd_cfg_write32(sc, ZYD_MACB_TXOP, 0x01800824); 1884 zyd_cfg_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0eff);
| 1816 zyd_write32_m(sc, ZYD_MACB_MAX_RETRY, 0x02020202); 1817 zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f); 1818 zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f); 1819 zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f); 1820 zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f); 1821 zyd_write32_m(sc, ZYD_MACB_AIFS_CTL1, 0x00280028); 1822 zyd_write32_m(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C); 1823 zyd_write32_m(sc, ZYD_MACB_TXOP, 0x01800824); 1824 zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0eff);
|
1885 } 1886 1887 /* init beacon interval to 100ms */
| 1825 } 1826 1827 /* init beacon interval to 100ms */
|
1888 zyd_cfg_set_beacon_interval(sc, 100);
| 1828 if ((error = zyd_set_beacon_interval(sc, 100)) != 0) 1829 goto fail;
|
1889
| 1830
|
1890 return (0); /* success */
| 1831 if ((error = zyd_rf_attach(sc, sc->sc_rfrev)) != 0) { 1832 device_printf(sc->sc_dev, "could not attach RF, rev 0x%x\n", 1833 sc->sc_rfrev); 1834 goto fail; 1835 } 1836 1837 /* RF chip init */ 1838 error = zyd_lock_phy(sc); 1839 if (error != 0) 1840 goto fail; 1841 error = (*rf->init)(rf); 1842 if (error != 0) { 1843 device_printf(sc->sc_dev, 1844 "radio initialization failed, error %d\n", error); 1845 goto fail; 1846 } 1847 error = zyd_unlock_phy(sc); 1848 if (error != 0) 1849 goto fail; 1850 1851 if ((error = zyd_read_eeprom(sc)) != 0) { 1852 device_printf(sc->sc_dev, "could not read EEPROM\n"); 1853 goto fail; 1854 } 1855 1856fail: return (error);
|
1891} 1892
| 1857} 1858
|
1893/* 1894 * Read information from EEPROM 1895 */ 1896static void 1897zyd_cfg_read_eeprom(struct zyd_softc *sc)
| 1859static int 1860zyd_read_pod(struct zyd_softc *sc)
|
1898{
| 1861{
|
| 1862 int error;
|
1899 uint32_t tmp;
| 1863 uint32_t tmp;
|
1900 uint16_t i; 1901 uint16_t val;
| |
1902
| 1864
|
1903 /* read MAC address */ 1904 zyd_cfg_get_macaddr(sc); 1905 1906 /* read product data */ 1907 zyd_cfg_read32(sc, ZYD_EEPROM_POD, &tmp); 1908 sc->sc_rf_rev = tmp & 0x0f; 1909 sc->sc_ledtype = (tmp >> 4) & 0x01; 1910 sc->sc_cckgain = (tmp >> 8) & 0x01;
| 1865 zyd_read32_m(sc, ZYD_EEPROM_POD, &tmp); 1866 sc->sc_rfrev = tmp & 0x0f; 1867 sc->sc_ledtype = (tmp >> 4) & 0x01; 1868 sc->sc_al2230s = (tmp >> 7) & 0x01; 1869 sc->sc_cckgain = (tmp >> 8) & 0x01;
|
1911 sc->sc_fix_cr157 = (tmp >> 13) & 0x01;
| 1870 sc->sc_fix_cr157 = (tmp >> 13) & 0x01;
|
1912 sc->sc_pa_rev = (tmp >> 16) & 0x0f; 1913 sc->sc_al2230s = (tmp >> 7) & 0x01;
| 1871 sc->sc_parev = (tmp >> 16) & 0x0f;
|
1914 sc->sc_bandedge6 = (tmp >> 21) & 0x01;
| 1872 sc->sc_bandedge6 = (tmp >> 21) & 0x01;
|
1915 sc->sc_newphy = (tmp >> 31) & 0x01; 1916 sc->sc_txled = ((tmp & (1 << 24)) && (tmp & (1 << 29))) ? 0 : 1;
| 1873 sc->sc_newphy = (tmp >> 31) & 0x01; 1874 sc->sc_txled = ((tmp & (1 << 24)) && (tmp & (1 << 29))) ? 0 : 1; 1875fail: 1876 return (error); 1877}
|
1917
| 1878
|
1918 /* read regulatory domain (currently unused) */ 1919 zyd_cfg_read32(sc, ZYD_EEPROM_SUBID, &tmp); 1920 sc->sc_regdomain = tmp >> 16; 1921 DPRINTF("regulatory domain %x\n", sc->sc_regdomain);
| 1879static int 1880zyd_read_eeprom(struct zyd_softc *sc) 1881{ 1882 uint16_t val; 1883 int error, i;
|
1922 1923 /* read Tx power calibration tables */ 1924 for (i = 0; i < 7; i++) {
| 1884 1885 /* read Tx power calibration tables */ 1886 for (i = 0; i < 7; i++) {
|
1925 zyd_cfg_read16(sc, ZYD_EEPROM_PWR_CAL + i, &val); 1926 sc->sc_pwr_cal[(i * 2)] = val >> 8; 1927 sc->sc_pwr_cal[(i * 2) + 1] = val & 0xff; 1928 1929 zyd_cfg_read16(sc, ZYD_EEPROM_PWR_INT + i, &val); 1930 sc->sc_pwr_int[(i * 2)] = val >> 8; 1931 sc->sc_pwr_int[(i * 2) + 1] = val & 0xff; 1932 1933 zyd_cfg_read16(sc, ZYD_EEPROM_36M_CAL + i, &val); 1934 sc->sc_ofdm36_cal[(i * 2)] = val >> 8; 1935 sc->sc_ofdm36_cal[(i * 2) + 1] = val & 0xff; 1936 1937 zyd_cfg_read16(sc, ZYD_EEPROM_48M_CAL + i, &val); 1938 sc->sc_ofdm48_cal[(i * 2)] = val >> 8; 1939 sc->sc_ofdm48_cal[(i * 2) + 1] = val & 0xff; 1940 1941 zyd_cfg_read16(sc, ZYD_EEPROM_54M_CAL + i, &val); 1942 sc->sc_ofdm54_cal[(i * 2)] = val >> 8; 1943 sc->sc_ofdm54_cal[(i * 2) + 1] = val & 0xff;
| 1887 zyd_read16_m(sc, ZYD_EEPROM_PWR_CAL + i, &val); 1888 sc->sc_pwrcal[i * 2] = val >> 8; 1889 sc->sc_pwrcal[i * 2 + 1] = val & 0xff; 1890 zyd_read16_m(sc, ZYD_EEPROM_PWR_INT + i, &val); 1891 sc->sc_pwrint[i * 2] = val >> 8; 1892 sc->sc_pwrint[i * 2 + 1] = val & 0xff; 1893 zyd_read16_m(sc, ZYD_EEPROM_36M_CAL + i, &val); 1894 sc->sc_ofdm36_cal[i * 2] = val >> 8; 1895 sc->sc_ofdm36_cal[i * 2 + 1] = val & 0xff; 1896 zyd_read16_m(sc, ZYD_EEPROM_48M_CAL + i, &val); 1897 sc->sc_ofdm48_cal[i * 2] = val >> 8; 1898 sc->sc_ofdm48_cal[i * 2 + 1] = val & 0xff; 1899 zyd_read16_m(sc, ZYD_EEPROM_54M_CAL + i, &val); 1900 sc->sc_ofdm54_cal[i * 2] = val >> 8; 1901 sc->sc_ofdm54_cal[i * 2 + 1] = val & 0xff;
|
1944 }
| 1902 }
|
| 1903fail: 1904 return (error);
|
1945} 1946
| 1905} 1906
|
1947static void 1948zyd_cfg_get_macaddr(struct zyd_softc *sc)
| 1907static int 1908zyd_get_macaddr(struct zyd_softc *sc)
|
1949{ 1950 struct usb2_device_request req;
| 1909{ 1910 struct usb2_device_request req;
|
| 1911 usb2_error_t error;
|
1951 1952 req.bmRequestType = UT_READ_VENDOR_DEVICE; 1953 req.bRequest = ZYD_READFWDATAREQ; 1954 USETW(req.wValue, ZYD_EEPROM_MAC_ADDR_P1); 1955 USETW(req.wIndex, 0); 1956 USETW(req.wLength, IEEE80211_ADDR_LEN); 1957
| 1912 1913 req.bmRequestType = UT_READ_VENDOR_DEVICE; 1914 req.bRequest = ZYD_READFWDATAREQ; 1915 USETW(req.wValue, ZYD_EEPROM_MAC_ADDR_P1); 1916 USETW(req.wIndex, 0); 1917 USETW(req.wLength, IEEE80211_ADDR_LEN); 1918
|
1958 zyd_cfg_usbrequest(sc, &req, sc->sc_myaddr); 1959 return;
| 1919 error = zyd_do_request(sc, &req, sc->sc_bssid); 1920 if (error != 0) { 1921 device_printf(sc->sc_dev, "could not read EEPROM: %s\n", 1922 usb2_errstr(error)); 1923 } 1924 1925 return (error);
|
1960} 1961
| 1926} 1927
|
1962static void 1963zyd_cfg_set_mac_addr(struct zyd_softc *sc, const uint8_t *addr)
| 1928static int 1929zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr)
|
1964{
| 1930{
|
| 1931 int error;
|
1965 uint32_t tmp; 1966
| 1932 uint32_t tmp; 1933
|
1967 tmp = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; 1968 zyd_cfg_write32(sc, ZYD_MAC_MACADRL, tmp);
| 1934 tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]; 1935 zyd_write32_m(sc, ZYD_MAC_MACADRL, tmp); 1936 tmp = addr[5] << 8 | addr[4]; 1937 zyd_write32_m(sc, ZYD_MAC_MACADRH, tmp); 1938fail: 1939 return (error); 1940}
|
1969
| 1941
|
1970 tmp = (addr[5] << 8) | addr[4]; 1971 zyd_cfg_write32(sc, ZYD_MAC_MACADRH, tmp);
| 1942static int 1943zyd_set_bssid(struct zyd_softc *sc, const uint8_t *addr) 1944{ 1945 int error; 1946 uint32_t tmp; 1947 1948 tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]; 1949 zyd_write32_m(sc, ZYD_MAC_BSSADRL, tmp); 1950 tmp = addr[5] << 8 | addr[4]; 1951 zyd_write32_m(sc, ZYD_MAC_BSSADRH, tmp); 1952fail: 1953 return (error);
|
1972} 1973
| 1954} 1955
|
1974/* 1975 * Switch radio on/off 1976 */ 1977static void 1978zyd_cfg_switch_radio(struct zyd_softc *sc, uint8_t onoff)
| 1956static int 1957zyd_switch_radio(struct zyd_softc *sc, int on)
|
1979{
| 1958{
|
1980 zyd_cfg_lock_phy(sc); 1981 (sc->sc_rf.cfg_switch_radio) (sc, onoff); 1982 zyd_cfg_unlock_phy(sc);
| 1959 struct zyd_rf *rf = &sc->sc_rf; 1960 int error; 1961 1962 error = zyd_lock_phy(sc); 1963 if (error != 0) 1964 goto fail; 1965 error = (*rf->switch_radio)(rf, on); 1966 if (error != 0) 1967 goto fail; 1968 error = zyd_unlock_phy(sc); 1969fail: 1970 return (error);
|
1983} 1984
| 1971} 1972
|
1985/* 1986 * Set BSSID 1987 */ 1988static void 1989zyd_cfg_set_bssid(struct zyd_softc *sc, uint8_t *addr)
| 1973static int 1974zyd_set_led(struct zyd_softc *sc, int which, int on)
|
1990{
| 1975{
|
| 1976 int error;
|
1991 uint32_t tmp; 1992
| 1977 uint32_t tmp; 1978
|
1993 tmp = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; 1994 zyd_cfg_write32(sc, ZYD_MAC_BSSADRL, tmp);
| 1979 zyd_read32_m(sc, ZYD_MAC_TX_PE_CONTROL, &tmp); 1980 tmp &= ~which; 1981 if (on) 1982 tmp |= which; 1983 zyd_write32_m(sc, ZYD_MAC_TX_PE_CONTROL, tmp); 1984fail: 1985 return (error); 1986}
|
1995
| 1987
|
1996 tmp = (addr[5] << 8) | addr[4]; 1997 zyd_cfg_write32(sc, ZYD_MAC_BSSADRH, tmp);
| 1988static void 1989zyd_multitask(struct usb2_proc_msg *pm) 1990{ 1991 struct zyd_task *task = (struct zyd_task *)pm; 1992 struct zyd_softc *sc = task->sc; 1993 1994 zyd_set_multi(sc);
|
1998} 1999
| 1995} 1996
|
2000/* 2001 * Complete the attach process 2002 */
| |
2003static void
| 1997static void
|
2004zyd_cfg_first_time_setup(struct zyd_softc *sc, 2005 struct usb2_config_td_cc *cc, uint16_t refcount)
| 1998zyd_set_multi(struct zyd_softc *sc)
|
2006{
| 1999{
|
2007 struct usb2_config_descriptor *cd; 2008 struct ieee80211com *ic; 2009 struct ifnet *ifp; 2010 const uint8_t *fw_ptr; 2011 uint32_t fw_len; 2012 uint8_t bands; 2013 usb2_error_t err;
| 2000 int error; 2001 struct ifnet *ifp = sc->sc_ifp; 2002 struct ieee80211com *ic = ifp->if_l2com; 2003 struct ifmultiaddr *ifma; 2004 uint32_t low, high; 2005 uint8_t v;
|
2014
| 2006
|
2015 /* setup RX tap header */ 2016 sc->sc_rxtap_len = sizeof(sc->sc_rxtap); 2017 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 2018 sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT);
| 2007 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 2008 return;
|
2019
| 2009
|
2020 /* setup TX tap header */ 2021 sc->sc_txtap_len = sizeof(sc->sc_txtap); 2022 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 2023 sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT);
| 2010 low = 0x00000000; 2011 high = 0x80000000;
|
2024
| 2012
|
2025 if (sc->sc_mac_rev == ZYD_ZD1211) { 2026 fw_ptr = zd1211_firmware; 2027 fw_len = sizeof(zd1211_firmware);
| 2013 if (ic->ic_opmode == IEEE80211_M_MONITOR || 2014 (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) { 2015 low = 0xffffffff; 2016 high = 0xffffffff;
|
2028 } else {
| 2017 } else {
|
2029 fw_ptr = zd1211b_firmware; 2030 fw_len = sizeof(zd1211b_firmware);
| 2018 IF_ADDR_LOCK(ifp); 2019 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 2020 if (ifma->ifma_addr->sa_family != AF_LINK) 2021 continue; 2022 v = ((uint8_t *)LLADDR((struct sockaddr_dl *) 2023 ifma->ifma_addr))[5] >> 2; 2024 if (v < 32) 2025 low |= 1 << v; 2026 else 2027 high |= 1 << (v - 32); 2028 } 2029 IF_ADDR_UNLOCK(ifp);
|
2031 } 2032
| 2030 } 2031
|
2033 if (zyd_cfg_uploadfirmware(sc, fw_ptr, fw_len)) { 2034 DPRINTFN(0, "%s: could not " 2035 "upload firmware!\n", sc->sc_name); 2036 return; 2037 } 2038 cd = usb2_get_config_descriptor(sc->sc_udev);
| 2032 /* reprogram multicast global hash table */ 2033 zyd_write32_m(sc, ZYD_MAC_GHTBL, low); 2034 zyd_write32_m(sc, ZYD_MAC_GHTBH, high); 2035fail: 2036 if (error != 0) 2037 device_printf(sc->sc_dev, 2038 "could not set multicast hash table\n"); 2039}
|
2039
| 2040
|
2040 /* reset device */ 2041 err = usb2_req_set_config(sc->sc_udev, &sc->sc_mtx, 2042 cd->bConfigurationValue); 2043 if (err) { 2044 DPRINTF("reset failed (ignored)\n"); 2045 } 2046 /* Read MAC and other stuff rom EEPROM */ 2047 zyd_cfg_read_eeprom(sc);
| 2041static void 2042zyd_update_mcast(struct ifnet *ifp) 2043{ 2044 struct zyd_softc *sc = ifp->if_softc;
|
2048
| 2045
|
2049 /* Init hardware */ 2050 if (zyd_cfg_hw_init(sc)) { 2051 DPRINTFN(0, "%s: HW init failed!\n", sc->sc_name);
| 2046 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
2052 return;
| 2047 return;
|
2053 } 2054 /* Now init the RF chip */ 2055 if (zyd_cfg_rf_init_hw(sc, &sc->sc_rf)) { 2056 DPRINTFN(0, "%s: RF init failed!\n", sc->sc_name); 2057 return; 2058 } 2059 printf("%s: HMAC ZD1211%s, FW %02x.%02x, RF %s, PA %x, address %02x:%02x:%02x:%02x:%02x:%02x\n", 2060 sc->sc_name, (sc->sc_mac_rev == ZYD_ZD1211) ? "" : "B", 2061 sc->sc_fw_rev >> 8, sc->sc_fw_rev & 0xff, zyd_rf_name(sc->sc_rf_rev), 2062 sc->sc_pa_rev, sc->sc_myaddr[0], 2063 sc->sc_myaddr[1], sc->sc_myaddr[2], 2064 sc->sc_myaddr[3], sc->sc_myaddr[4], 2065 sc->sc_myaddr[5]);
| |
2066
| 2048
|
2067 mtx_unlock(&sc->sc_mtx);
| 2049 ZYD_LOCK(sc); 2050 zyd_queue_command(sc, zyd_multitask, 2051 &sc->sc_mcasttask[0].hdr, &sc->sc_mcasttask[1].hdr); 2052 ZYD_UNLOCK(sc); 2053}
|
2068
| 2054
|
2069 ifp = if_alloc(IFT_IEEE80211);
| 2055static int 2056zyd_set_rxfilter(struct zyd_softc *sc) 2057{ 2058 struct ifnet *ifp = sc->sc_ifp; 2059 struct ieee80211com *ic = ifp->if_l2com; 2060 uint32_t rxfilter;
|
2070
| 2061
|
2071 mtx_lock(&sc->sc_mtx); 2072 2073 if (ifp == NULL) { 2074 DPRINTFN(0, "%s: could not if_alloc()!\n", 2075 sc->sc_name); 2076 goto done;
| 2062 switch (ic->ic_opmode) { 2063 case IEEE80211_M_STA: 2064 rxfilter = ZYD_FILTER_BSS; 2065 break; 2066 case IEEE80211_M_IBSS: 2067 case IEEE80211_M_HOSTAP: 2068 rxfilter = ZYD_FILTER_HOSTAP; 2069 break; 2070 case IEEE80211_M_MONITOR: 2071 rxfilter = ZYD_FILTER_MONITOR; 2072 break; 2073 default: 2074 /* should not get there */ 2075 return (EINVAL);
|
2077 }
| 2076 }
|
2078 sc->sc_ifp = ifp; 2079 ic = ifp->if_l2com;
| 2077 return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter); 2078}
|
2080
| 2079
|
2081 ifp->if_softc = sc; 2082 if_initname(ifp, "zyd", sc->sc_unit); 2083 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 2084 ifp->if_init = &zyd_init_cb; 2085 ifp->if_ioctl = &zyd_ioctl_cb; 2086 ifp->if_start = &zyd_start_cb; 2087 ifp->if_watchdog = NULL; 2088 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 2089 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 2090 IFQ_SET_READY(&ifp->if_snd);
| 2080static void 2081zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c) 2082{ 2083 int error; 2084 struct ifnet *ifp = sc->sc_ifp; 2085 struct ieee80211com *ic = ifp->if_l2com; 2086 struct zyd_rf *rf = &sc->sc_rf; 2087 uint32_t tmp; 2088 u_int chan;
|
2091
| 2089
|
2092 bcopy(sc->sc_myaddr, ic->ic_myaddr, sizeof(ic->ic_myaddr));
| 2090 chan = ieee80211_chan2ieee(ic, c); 2091 if (chan == 0 || chan == IEEE80211_CHAN_ANY) { 2092 /* XXX should NEVER happen */ 2093 device_printf(sc->sc_dev, 2094 "%s: invalid channel %x\n", __func__, chan); 2095 return; 2096 }
|
2093
| 2097
|
2094 ic->ic_ifp = ifp; 2095 ic->ic_phytype = IEEE80211_T_OFDM; 2096 ic->ic_opmode = IEEE80211_M_STA;
| 2098 error = zyd_lock_phy(sc); 2099 if (error != 0) 2100 goto fail;
|
2097
| 2101
|
2098 /* Set device capabilities */ 2099 ic->ic_caps = 2100 IEEE80211_C_STA /* station mode supported */ 2101 | IEEE80211_C_MONITOR /* monitor mode */ 2102 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 2103 | IEEE80211_C_SHSLOT /* short slot time supported */ 2104 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 2105 | IEEE80211_C_WPA /* 802.11i */ 2106 ;
| 2102 error = (*rf->set_channel)(rf, chan); 2103 if (error != 0) 2104 goto fail;
|
2107
| 2105
|
2108 bands = 0; 2109 setbit(&bands, IEEE80211_MODE_11B); 2110 setbit(&bands, IEEE80211_MODE_11G); 2111 ieee80211_init_channels(ic, NULL, &bands);
| 2106 /* update Tx power */ 2107 zyd_write16_m(sc, ZYD_CR31, sc->sc_pwrint[chan - 1]);
|
2112
| 2108
|
2113 mtx_unlock(&sc->sc_mtx);
| 2109 if (sc->sc_macrev == ZYD_ZD1211B) { 2110 zyd_write16_m(sc, ZYD_CR67, sc->sc_ofdm36_cal[chan - 1]); 2111 zyd_write16_m(sc, ZYD_CR66, sc->sc_ofdm48_cal[chan - 1]); 2112 zyd_write16_m(sc, ZYD_CR65, sc->sc_ofdm54_cal[chan - 1]); 2113 zyd_write16_m(sc, ZYD_CR68, sc->sc_pwrcal[chan - 1]); 2114 zyd_write16_m(sc, ZYD_CR69, 0x28); 2115 zyd_write16_m(sc, ZYD_CR69, 0x2a); 2116 } 2117 if (sc->sc_cckgain) { 2118 /* set CCK baseband gain from EEPROM */ 2119 if (zyd_read32(sc, ZYD_EEPROM_PHY_REG, &tmp) == 0) 2120 zyd_write16_m(sc, ZYD_CR47, tmp & 0xff); 2121 } 2122 if (sc->sc_bandedge6 && rf->bandedge6 != NULL) { 2123 error = (*rf->bandedge6)(rf, c); 2124 if (error != 0) 2125 goto fail; 2126 } 2127 zyd_write32_m(sc, ZYD_CR_CONFIG_PHILIPS, 0);
|
2114
| 2128
|
2115 ieee80211_ifattach(ic);
| 2129 error = zyd_unlock_phy(sc); 2130 if (error != 0) 2131 goto fail;
|
2116
| 2132
|
2117 mtx_lock(&sc->sc_mtx); 2118 2119 ic->ic_node_alloc = &zyd_node_alloc_cb; 2120 ic->ic_raw_xmit = &zyd_raw_xmit_cb; 2121 ic->ic_newassoc = &zyd_newassoc_cb; 2122 2123 ic->ic_scan_start = &zyd_scan_start_cb; 2124 ic->ic_scan_end = &zyd_scan_end_cb; 2125 ic->ic_set_channel = &zyd_set_channel_cb; 2126 ic->ic_vap_create = &zyd_vap_create; 2127 ic->ic_vap_delete = &zyd_vap_delete; 2128 ic->ic_update_mcast = &zyd_update_mcast_cb; 2129 ic->ic_update_promisc = &zyd_update_promisc_cb; 2130 2131 sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); 2132 2133 mtx_unlock(&sc->sc_mtx); 2134 2135 bpfattach(ifp, DLT_IEEE802_11_RADIO, 2136 sizeof(struct ieee80211_frame) + 2137 sizeof(sc->sc_txtap)); 2138 2139 mtx_lock(&sc->sc_mtx); 2140 2141 if (bootverbose) { 2142 ieee80211_announce(ic); 2143 } 2144 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_RD]); 2145done:
| 2133 sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq = 2134 htole16(c->ic_freq); 2135 sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags = 2136 htole16(c->ic_flags); 2137fail:
|
2146 return; 2147} 2148
| 2138 return; 2139} 2140
|
2149/* 2150 * Detach device 2151 */
| |
2152static int
| 2141static int
|
2153zyd_detach(device_t dev)
| 2142zyd_set_beacon_interval(struct zyd_softc *sc, int bintval)
|
2154{
| 2143{
|
2155 struct zyd_softc *sc = device_get_softc(dev); 2156 struct ieee80211com *ic; 2157 struct ifnet *ifp;
| 2144 int error; 2145 uint32_t val;
|
2158
| 2146
|
2159 usb2_config_td_drain(&sc->sc_config_td);
| 2147 zyd_read32_m(sc, ZYD_CR_ATIM_WND_PERIOD, &val); 2148 sc->sc_atim_wnd = val; 2149 zyd_read32_m(sc, ZYD_CR_PRE_TBTT, &val); 2150 sc->sc_pre_tbtt = val; 2151 sc->sc_bcn_int = bintval;
|
2160
| 2152
|
2161 mtx_lock(&sc->sc_mtx);
| 2153 if (sc->sc_bcn_int <= 5) 2154 sc->sc_bcn_int = 5; 2155 if (sc->sc_pre_tbtt < 4 || sc->sc_pre_tbtt >= sc->sc_bcn_int) 2156 sc->sc_pre_tbtt = sc->sc_bcn_int - 1; 2157 if (sc->sc_atim_wnd >= sc->sc_pre_tbtt) 2158 sc->sc_atim_wnd = sc->sc_pre_tbtt - 1;
|
2162
| 2159
|
2163 usb2_callout_stop(&sc->sc_watchdog);
| 2160 zyd_write32_m(sc, ZYD_CR_ATIM_WND_PERIOD, sc->sc_atim_wnd); 2161 zyd_write32_m(sc, ZYD_CR_PRE_TBTT, sc->sc_pre_tbtt); 2162 zyd_write32_m(sc, ZYD_CR_BCN_INTERVAL, sc->sc_bcn_int); 2163fail: 2164 return (error); 2165}
|
2164
| 2166
|
2165 zyd_cfg_pre_stop(sc, NULL, 0);
| 2167static void 2168zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len) 2169{ 2170 struct zyd_softc *sc = xfer->priv_sc; 2171 struct ifnet *ifp = sc->sc_ifp; 2172 struct zyd_plcphdr plcp; 2173 struct zyd_rx_stat stat; 2174 struct mbuf *m; 2175 int rlen, rssi;
|
2166
| 2176
|
2167 ifp = sc->sc_ifp; 2168 ic = ifp->if_l2com;
| 2177 if (len < ZYD_MIN_FRAGSZ) { 2178 DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n", 2179 device_get_nameunit(sc->sc_dev), len); 2180 ifp->if_ierrors++; 2181 return; 2182 } 2183 usb2_copy_out(xfer->frbuffers, offset, &plcp, sizeof(plcp)); 2184 usb2_copy_out(xfer->frbuffers, offset + len - sizeof(stat), 2185 &stat, sizeof(stat));
|
2169
| 2186
|
2170 mtx_unlock(&sc->sc_mtx);
| 2187 if (stat.flags & ZYD_RX_ERROR) { 2188 DPRINTF(sc, ZYD_DEBUG_RECV, 2189 "%s: RX status indicated error (%x)\n", 2190 device_get_nameunit(sc->sc_dev), stat.flags); 2191 ifp->if_ierrors++; 2192 return; 2193 }
|
2171
| 2194
|
2172 /* stop all USB transfers first */ 2173 usb2_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER);
| 2195 /* compute actual frame length */ 2196 rlen = len - sizeof(struct zyd_plcphdr) - 2197 sizeof(struct zyd_rx_stat) - IEEE80211_CRC_LEN;
|
2174
| 2198
|
2175 /* get rid of any late children */ 2176 bus_generic_detach(dev); 2177 2178 if (ifp) { 2179 bpfdetach(ifp); 2180 ieee80211_ifdetach(ic); 2181 if_free(ifp);
| 2199 /* allocate a mbuf to store the frame */ 2200 if (rlen > MCLBYTES) { 2201 DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too long (length=%d)\n", 2202 device_get_nameunit(sc->sc_dev), rlen); 2203 ifp->if_ierrors++; 2204 return; 2205 } else if (rlen > MHLEN) 2206 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 2207 else 2208 m = m_gethdr(M_DONTWAIT, MT_DATA); 2209 if (m == NULL) { 2210 DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n", 2211 device_get_nameunit(sc->sc_dev)); 2212 ifp->if_ierrors++; 2213 return;
|
2182 }
| 2214 }
|
2183 usb2_config_td_unsetup(&sc->sc_config_td);
| 2215 m->m_pkthdr.rcvif = ifp; 2216 m->m_pkthdr.len = m->m_len = rlen; 2217 usb2_copy_out(xfer->frbuffers, offset + sizeof(plcp), 2218 mtod(m, uint8_t *), rlen);
|
2184
| 2219
|
2185 usb2_callout_drain(&sc->sc_watchdog);
| 2220 if (bpf_peers_present(ifp->if_bpf)) { 2221 struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
|
2186
| 2222
|
2187 usb2_cv_destroy(&sc->sc_intr_cv);
| 2223 tap->wr_flags = 0; 2224 if (stat.flags & (ZYD_RX_BADCRC16 | ZYD_RX_BADCRC32)) 2225 tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; 2226 /* XXX toss, no way to express errors */ 2227 if (stat.flags & ZYD_RX_DECRYPTERR) 2228 tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; 2229 tap->wr_rate = ieee80211_plcp2rate(plcp.signal, 2230 (stat.flags & ZYD_RX_OFDM) ? 2231 IEEE80211_T_OFDM : IEEE80211_T_CCK); 2232 tap->wr_antsignal = stat.rssi + -95; 2233 tap->wr_antnoise = -95; /* XXX */
|
2188
| 2234
|
2189 mtx_destroy(&sc->sc_mtx);
| 2235 bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); 2236 } 2237 rssi = (stat.rssi > 63) ? 127 : 2 * stat.rssi;
|
2190
| 2238
|
2191 return (0);
| 2239 sc->sc_rx_data[sc->sc_rx_count].rssi = rssi; 2240 sc->sc_rx_data[sc->sc_rx_count].m = m; 2241 sc->sc_rx_count++;
|
2192} 2193 2194static void
| 2242} 2243 2244static void
|
2195zyd_cfg_newstate(struct zyd_softc *sc, 2196 struct usb2_config_td_cc *cc, uint16_t refcount)
| 2245zyd_bulk_read_callback(struct usb2_xfer *xfer)
|
2197{
| 2246{
|
| 2247 struct zyd_softc *sc = xfer->priv_sc;
|
2198 struct ifnet *ifp = sc->sc_ifp; 2199 struct ieee80211com *ic = ifp->if_l2com;
| 2248 struct ifnet *ifp = sc->sc_ifp; 2249 struct ieee80211com *ic = ifp->if_l2com;
|
2200 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 2201 struct zyd_vap *uvp = ZYD_VAP(vap); 2202 enum ieee80211_state ostate; 2203 enum ieee80211_state nstate; 2204 int arg;
| 2250 struct ieee80211_node *ni; 2251 struct zyd_rx_desc desc; 2252 struct mbuf *m; 2253 uint32_t offset; 2254 uint8_t rssi; 2255 int8_t nf; 2256 int i;
|
2205
| 2257
|
2206 ostate = vap->iv_state; 2207 nstate = sc->sc_ns_state; 2208 arg = sc->sc_ns_arg;
| 2258 sc->sc_rx_count = 0; 2259 switch (USB_GET_STATE(xfer)) { 2260 case USB_ST_TRANSFERRED: 2261 usb2_copy_out(xfer->frbuffers, xfer->actlen - sizeof(desc), 2262 &desc, sizeof(desc));
|
2209
| 2263
|
2210 switch (nstate) { 2211 case IEEE80211_S_INIT: 2212 break;
| 2264 offset = 0; 2265 if (UGETW(desc.tag) == ZYD_TAG_MULTIFRAME) { 2266 DPRINTF(sc, ZYD_DEBUG_RECV, 2267 "%s: received multi-frame transfer\n", __func__);
|
2213
| 2268
|
2214 case IEEE80211_S_RUN: 2215 zyd_cfg_set_run(sc, cc); 2216 break;
| 2269 for (i = 0; i < ZYD_MAX_RXFRAMECNT; i++) { 2270 uint16_t len16 = UGETW(desc.len[i]);
|
2217
| 2271
|
2218 default: 2219 break; 2220 }
| 2272 if (len16 == 0 || len16 > xfer->actlen) 2273 break;
|
2221
| 2274
|
2222 mtx_unlock(&sc->sc_mtx); 2223 IEEE80211_LOCK(ic); 2224 uvp->newstate(vap, nstate, arg); 2225 if (vap->iv_newstate_cb != NULL) 2226 vap->iv_newstate_cb(vap, nstate, arg); 2227 IEEE80211_UNLOCK(ic); 2228 mtx_lock(&sc->sc_mtx); 2229}
| 2275 zyd_rx_data(xfer, offset, len16);
|
2230
| 2276
|
2231static void 2232zyd_cfg_set_run(struct zyd_softc *sc, 2233 struct usb2_config_td_cc *cc) 2234{ 2235 zyd_cfg_set_chan(sc, cc, 0);
| 2277 /* next frame is aligned on a 32-bit boundary */ 2278 len16 = (len16 + 3) & ~3; 2279 offset += len16; 2280 if (len16 > xfer->actlen) 2281 break; 2282 xfer->actlen -= len16; 2283 } 2284 } else { 2285 DPRINTF(sc, ZYD_DEBUG_RECV, 2286 "%s: received single-frame transfer\n", __func__);
|
2236
| 2287
|
2237 if (cc->ic_opmode != IEEE80211_M_MONITOR) { 2238 /* turn link LED on */ 2239 zyd_cfg_set_led(sc, ZYD_LED1, 1);
| 2288 zyd_rx_data(xfer, 0, xfer->actlen); 2289 } 2290 /* FALLTHROUGH */ 2291 case USB_ST_SETUP: 2292tr_setup: 2293 xfer->frlengths[0] = xfer->max_data_length; 2294 usb2_start_hardware(xfer);
|
2240
| 2295
|
2241 /* make data LED blink upon Tx */ 2242 zyd_cfg_write32(sc, sc->sc_firmware_base + ZYD_FW_LINK_STATUS, 1);
| 2296 /* 2297 * At the end of a USB callback it is always safe to unlock 2298 * the private mutex of a device! That is why we do the 2299 * "ieee80211_input" here, and not some lines up! 2300 */ 2301 ZYD_UNLOCK(sc); 2302 for (i = 0; i < sc->sc_rx_count; i++) { 2303 rssi = sc->sc_rx_data[i].rssi; 2304 m = sc->sc_rx_data[i].m; 2305 sc->sc_rx_data[i].m = NULL;
|
2243
| 2306
|
2244 zyd_cfg_set_bssid(sc, cc->iv_bss.ni_bssid); 2245 } 2246 if (cc->iv_bss.fixed_rate_none) { 2247 /* enable automatic rate adaptation */ 2248 zyd_cfg_amrr_start(sc); 2249 } 2250}
| 2307 nf = -95; /* XXX */
|
2251
| 2308
|
2252static int 2253zyd_newstate_cb(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 2254{ 2255 struct zyd_vap *uvp = ZYD_VAP(vap); 2256 struct ieee80211com *ic = vap->iv_ic; 2257 struct zyd_softc *sc = ic->ic_ifp->if_softc;
| 2309 ni = ieee80211_find_rxnode(ic, 2310 mtod(m, struct ieee80211_frame_min *)); 2311 if (ni != NULL) { 2312 (void)ieee80211_input(ni, m, rssi, nf, 0); 2313 ieee80211_free_node(ni); 2314 } else 2315 (void)ieee80211_input_all(ic, m, rssi, nf, 0); 2316 } 2317 ZYD_LOCK(sc); 2318 break;
|
2258
| 2319
|
2259 DPRINTF("setting new state: %d\n", nstate);
| 2320 default: /* Error */ 2321 DPRINTF(sc, ZYD_DEBUG_ANY, "frame error: %s\n", usb2_errstr(xfer->error));
|
2260
| 2322
|
2261 mtx_lock(&sc->sc_mtx); 2262 if (usb2_config_td_is_gone(&sc->sc_config_td)) { 2263 mtx_unlock(&sc->sc_mtx); 2264 /* Special case which happens at detach. */ 2265 if (nstate == IEEE80211_S_INIT) { 2266 (uvp->newstate) (vap, nstate, arg);
| 2323 if (xfer->error != USB_ERR_CANCELLED) { 2324 /* try to clear stall first */ 2325 xfer->flags.stall_pipe = 1; 2326 goto tr_setup;
|
2267 }
| 2327 }
|
2268 return (0); /* nothing to do */
| 2328 break;
|
2269 }
| 2329 }
|
2270 /* store next state */ 2271 sc->sc_ns_state = nstate; 2272 sc->sc_ns_arg = arg; 2273 2274 /* stop timers */ 2275 sc->sc_amrr_timer = 0; 2276 2277 /* 2278 * USB configuration can only be done from the USB configuration 2279 * thread: 2280 */ 2281 usb2_config_td_queue_command 2282 (&sc->sc_config_td, &zyd_config_copy, 2283 &zyd_cfg_newstate, 0, 0); 2284 2285 mtx_unlock(&sc->sc_mtx); 2286 2287 return EINPROGRESS;
| |
2288} 2289
| 2330} 2331
|
2290static void 2291zyd_cfg_update_promisc(struct zyd_softc *sc, 2292 struct usb2_config_td_cc *cc, uint16_t refcount) 2293{ 2294 uint32_t low; 2295 uint32_t high; 2296 2297 if ((cc->ic_opmode == IEEE80211_M_MONITOR) || 2298 (cc->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) { 2299 low = 0xffffffff; 2300 high = 0xffffffff; 2301 } else { 2302 low = cc->zyd_multi_low; 2303 high = cc->zyd_multi_high; 2304 } 2305 2306 /* reprogram multicast global hash table */ 2307 zyd_cfg_write32(sc, ZYD_MAC_GHTBL, low); 2308 zyd_cfg_write32(sc, ZYD_MAC_GHTBH, high); 2309} 2310 2311/* 2312 * Rate-to-bit-converter (Field "rate" in zyd_controlsetformat) 2313 */
| |
2314static uint8_t
| 2332static uint8_t
|
2315zyd_plcp_signal(uint8_t rate)
| 2333zyd_plcp_signal(int rate)
|
2316{
| 2334{
|
2317 ; /* fix for indent */ 2318
| |
2319 switch (rate) {
| 2335 switch (rate) {
|
2320 /* CCK rates (NB: not IEEE std, device-specific) */ 2321 case 2: 2322 return (0x0); 2323 case 4: 2324 return (0x1); 2325 case 11: 2326 return (0x2); 2327 case 22: 2328 return (0x3); 2329 2330 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
| 2336 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
|
2331 case 12: 2332 return (0xb); 2333 case 18: 2334 return (0xf); 2335 case 24: 2336 return (0xa); 2337 case 36: 2338 return (0xe); 2339 case 48: 2340 return (0x9); 2341 case 72: 2342 return (0xd); 2343 case 96: 2344 return (0x8); 2345 case 108: 2346 return (0xc);
| 2337 case 12: 2338 return (0xb); 2339 case 18: 2340 return (0xf); 2341 case 24: 2342 return (0xa); 2343 case 36: 2344 return (0xe); 2345 case 48: 2346 return (0x9); 2347 case 72: 2348 return (0xd); 2349 case 96: 2350 return (0x8); 2351 case 108: 2352 return (0xc);
|
2347 2348 /* XXX unsupported/unknown rate */ 2349 default: 2350 return (0xff);
| 2353 /* CCK rates (NB: not IEEE std, device-specific) */ 2354 case 2: 2355 return (0x0); 2356 case 4: 2357 return (0x1); 2358 case 11: 2359 return (0x2); 2360 case 22: 2361 return (0x3);
|
2351 }
| 2362 }
|
| 2363 return (0xff); /* XXX unsupported/unknown rate */
|
2352} 2353
| 2364} 2365
|
2354static void 2355zyd_std_command(struct ieee80211com *ic, usb2_config_td_command_t *func)
| 2366static int 2367zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
2356{
| 2368{
|
2357 struct zyd_softc *sc = ic->ic_ifp->if_softc;
| 2369 struct ieee80211vap *vap = ni->ni_vap; 2370 struct ieee80211com *ic = ni->ni_ic; 2371 struct ifnet *ifp = sc->sc_ifp; 2372 struct zyd_tx_desc *desc; 2373 struct zyd_tx_data *data; 2374 struct ieee80211_frame *wh; 2375 struct ieee80211_key *k; 2376 int rate, totlen; 2377 uint16_t pktlen;
|
2358
| 2378
|
2359 mtx_lock(&sc->sc_mtx);
| 2379 data = STAILQ_FIRST(&sc->tx_free); 2380 STAILQ_REMOVE_HEAD(&sc->tx_free, next); 2381 sc->tx_nfree--; 2382 desc = &data->desc;
|
2360
| 2383
|
2361 sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
| 2384 rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
|
2362
| 2385
|
2363 usb2_config_td_queue_command 2364 (&sc->sc_config_td, &zyd_config_copy, func, 0, 0);
| 2386 wh = mtod(m0, struct ieee80211_frame *);
|
2365
| 2387
|
2366 mtx_unlock(&sc->sc_mtx); 2367}
| 2388 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2389 k = ieee80211_crypto_encap(ni, m0); 2390 if (k == NULL) { 2391 m_freem(m0); 2392 return (ENOBUFS); 2393 } 2394 }
|
2368
| 2395
|
2369static void 2370zyd_scan_start_cb(struct ieee80211com *ic) 2371{ 2372 zyd_std_command(ic, &zyd_cfg_scan_start); 2373}
| 2396 data->ni = ni; 2397 data->m = m0; 2398 data->rate = rate;
|
2374
| 2399
|
2375static void 2376zyd_scan_end_cb(struct ieee80211com *ic) 2377{ 2378 zyd_std_command(ic, &zyd_cfg_scan_end); 2379}
| 2400 wh = mtod(m0, struct ieee80211_frame *);
|
2380
| 2401
|
2381static void 2382zyd_set_channel_cb(struct ieee80211com *ic) 2383{ 2384 zyd_std_command(ic, &zyd_cfg_set_chan); 2385}
| 2402 totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
|
2386
| 2403
|
2387/*========================================================================* 2388 * configure sub-routines, zyd_cfg_xxx 2389 *========================================================================*/
| 2404 /* fill Tx descriptor */ 2405 desc->len = htole16(totlen);
|
2390
| 2406
|
2391static void 2392zyd_cfg_scan_start(struct zyd_softc *sc, 2393 struct usb2_config_td_cc *cc, uint16_t refcount) 2394{ 2395 zyd_cfg_set_bssid(sc, cc->if_broadcastaddr); 2396}
| 2407 desc->flags = ZYD_TX_FLAG_BACKOFF; 2408 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 2409 /* multicast frames are not sent at OFDM rates in 802.11b/g */ 2410 if (totlen > vap->iv_rtsthreshold) { 2411 desc->flags |= ZYD_TX_FLAG_RTS; 2412 } else if (ZYD_RATE_IS_OFDM(rate) && 2413 (ic->ic_flags & IEEE80211_F_USEPROT)) { 2414 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 2415 desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF; 2416 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 2417 desc->flags |= ZYD_TX_FLAG_RTS; 2418 } 2419 } else 2420 desc->flags |= ZYD_TX_FLAG_MULTICAST;
|
2397
| 2421
|
2398static void 2399zyd_cfg_scan_end(struct zyd_softc *sc, 2400 struct usb2_config_td_cc *cc, uint16_t refcount) 2401{ 2402 zyd_cfg_set_bssid(sc, cc->iv_bss.ni_bssid); 2403}
| 2422 if ((wh->i_fc[0] & 2423 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == 2424 (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) 2425 desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
|
2404
| 2426
|
2405static void 2406zyd_cfg_set_chan(struct zyd_softc *sc, 2407 struct usb2_config_td_cc *cc, uint16_t refcount) 2408{ 2409 uint32_t chan; 2410 uint32_t tmp;
| 2427 desc->phy = zyd_plcp_signal(rate); 2428 if (ZYD_RATE_IS_OFDM(rate)) { 2429 desc->phy |= ZYD_TX_PHY_OFDM; 2430 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 2431 desc->phy |= ZYD_TX_PHY_5GHZ; 2432 } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) 2433 desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
|
2411
| 2434
|
2412 chan = cc->ic_curchan.chan_to_ieee;
| 2435 /* actual transmit length (XXX why +10?) */ 2436 pktlen = ZYD_TX_DESC_SIZE + 10; 2437 if (sc->sc_macrev == ZYD_ZD1211) 2438 pktlen += totlen; 2439 desc->pktlen = htole16(pktlen);
|
2413
| 2440
|
2414 DPRINTF("Will try %d\n", chan); 2415 2416 if ((chan == 0) || (chan == IEEE80211_CHAN_ANY)) { 2417 DPRINTF("0 or ANY, exiting\n"); 2418 return;
| 2441 desc->plcp_length = (16 * totlen + rate - 1) / rate; 2442 desc->plcp_service = 0; 2443 if (rate == 22) { 2444 const int remainder = (16 * totlen) % 22; 2445 if (remainder != 0 && remainder < 7) 2446 desc->plcp_service |= ZYD_PLCP_LENGEXT;
|
2419 }
| 2447 }
|
2420 zyd_cfg_lock_phy(sc);
| |
2421
| 2448
|
2422 (sc->sc_rf.cfg_set_channel) (sc, &sc->sc_rf, chan);
| 2449 if (bpf_peers_present(ifp->if_bpf)) { 2450 struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
|
2423
| 2451
|
2424 /* update Tx power */ 2425 zyd_cfg_write16(sc, ZYD_CR31, sc->sc_pwr_int[chan - 1]);
| 2452 tap->wt_flags = 0; 2453 tap->wt_rate = rate;
|
2426
| 2454
|
2427 if (sc->sc_mac_rev == ZYD_ZD1211B) { 2428 zyd_cfg_write16(sc, ZYD_CR67, sc->sc_ofdm36_cal[chan - 1]); 2429 zyd_cfg_write16(sc, ZYD_CR66, sc->sc_ofdm48_cal[chan - 1]); 2430 zyd_cfg_write16(sc, ZYD_CR65, sc->sc_ofdm54_cal[chan - 1]); 2431 zyd_cfg_write16(sc, ZYD_CR68, sc->sc_pwr_cal[chan - 1]); 2432 zyd_cfg_write16(sc, ZYD_CR69, 0x28); 2433 zyd_cfg_write16(sc, ZYD_CR69, 0x2a);
| 2455 bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
2434 }
| 2456 }
|
2435 if (sc->sc_cckgain) { 2436 /* set CCK baseband gain from EEPROM */ 2437 zyd_cfg_read32(sc, ZYD_EEPROM_PHY_REG, &tmp); 2438 zyd_cfg_write16(sc, ZYD_CR47, tmp & 0xff); 2439 } 2440 if (sc->sc_bandedge6 && (sc->sc_rf.cfg_bandedge6 != NULL)) { 2441 (sc->sc_rf.cfg_bandedge6) (sc, &sc->sc_rf, chan); 2442 } 2443 zyd_cfg_write32(sc, ZYD_CR_CONFIG_PHILIPS, 0);
| |
2444
| 2457
|
2445 zyd_cfg_unlock_phy(sc);
| 2458 DPRINTF(sc, ZYD_DEBUG_XMIT, 2459 "%s: sending mgt frame len=%zu rate=%u\n", 2460 device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len, 2461 rate);
|
2446
| 2462
|
2447 sc->sc_rxtap.wr_chan_freq = 2448 sc->sc_txtap.wt_chan_freq = 2449 htole16(cc->ic_curchan.ic_freq);
| 2463 STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 2464 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_WR]);
|
2450
| 2465
|
2451 sc->sc_rxtap.wr_chan_flags = 2452 sc->sc_txtap.wt_chan_flags = 2453 htole16(cc->ic_flags);
| 2466 return (0);
|
2454} 2455
| 2467} 2468
|
2456/* 2457 * Interface: init 2458 */ 2459 2460/* immediate configuration */ 2461
| |
2462static void
| 2469static void
|
2463zyd_cfg_pre_init(struct zyd_softc *sc, 2464 struct usb2_config_td_cc *cc, uint16_t refcount)
| 2470zyd_bulk_write_callback(struct usb2_xfer *xfer)
|
2465{
| 2471{
|
| 2472 struct zyd_softc *sc = xfer->priv_sc;
|
2466 struct ifnet *ifp = sc->sc_ifp; 2467 struct ieee80211com *ic = ifp->if_l2com;
| 2473 struct ifnet *ifp = sc->sc_ifp; 2474 struct ieee80211com *ic = ifp->if_l2com;
|
| 2475 struct ieee80211_channel *c = ic->ic_curchan; 2476 struct zyd_tx_data *data; 2477 struct mbuf *m;
|
2468
| 2478
|
2469 zyd_cfg_pre_stop(sc, cc, 0);
| 2479 switch (USB_GET_STATE(xfer)) { 2480 case USB_ST_TRANSFERRED: 2481 DPRINTF(sc, ZYD_DEBUG_ANY, "transfer complete, %u bytes\n", 2482 xfer->actlen);
|
2470
| 2483
|
2471 ifp->if_drv_flags |= IFF_DRV_RUNNING;
| 2484 /* free resources */ 2485 data = xfer->priv_fifo; 2486 zyd_tx_free(data, 0); 2487 xfer->priv_fifo = NULL;
|
2472
| 2488
|
2473 sc->sc_flags |= ZYD_FLAG_HL_READY;
| 2489 ifp->if_opackets++; 2490 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
2474
| 2491
|
2475 IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); 2476}
| 2492 /* FALLTHROUGH */ 2493 case USB_ST_SETUP: 2494tr_setup: 2495 data = STAILQ_FIRST(&sc->tx_q); 2496 if (data) { 2497 STAILQ_REMOVE_HEAD(&sc->tx_q, next); 2498 m = data->m;
|
2477
| 2499
|
2478/* delayed configuration */
| 2500 if (m->m_pkthdr.len > ZYD_MAX_TXBUFSZ) { 2501 DPRINTF(sc, ZYD_DEBUG_ANY, "data overflow, %u bytes\n", 2502 m->m_pkthdr.len); 2503 m->m_pkthdr.len = ZYD_MAX_TXBUFSZ; 2504 } 2505 usb2_copy_in(xfer->frbuffers, 0, &data->desc, 2506 ZYD_TX_DESC_SIZE); 2507 usb2_m_copy_in(xfer->frbuffers, ZYD_TX_DESC_SIZE, m, 0, 2508 m->m_pkthdr.len);
|
2479
| 2509
|
2480static void 2481zyd_cfg_init(struct zyd_softc *sc, 2482 struct usb2_config_td_cc *cc, uint16_t refcount) 2483{ 2484 zyd_cfg_stop(sc, cc, 0);
| 2510 if (bpf_peers_present(ifp->if_bpf)) { 2511 struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
|
2485
| 2512
|
2486 /* Do initial setup */
| 2513 tap->wt_flags = 0; 2514 tap->wt_rate = data->rate; 2515 tap->wt_chan_freq = htole16(c->ic_freq); 2516 tap->wt_chan_flags = htole16(c->ic_flags);
|
2487
| 2517
|
2488 zyd_cfg_set_mac_addr(sc, cc->ic_myaddr);
| 2518 bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); 2519 }
|
2489
| 2520
|
2490 zyd_cfg_write32(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER);
| 2521 xfer->frlengths[0] = ZYD_TX_DESC_SIZE + m->m_pkthdr.len; 2522 xfer->priv_fifo = data; 2523 usb2_start_hardware(xfer); 2524 } 2525 break;
|
2491
| 2526
|
2492 /* promiscuous mode */ 2493 zyd_cfg_write32(sc, ZYD_MAC_SNIFFER, 2494 (cc->ic_opmode == IEEE80211_M_MONITOR) ? 1 : 0);
| 2527 default: /* Error */ 2528 DPRINTF(sc, ZYD_DEBUG_ANY, "transfer error, %s\n", 2529 usb2_errstr(xfer->error));
|
2495
| 2530
|
2496 /* multicast setup */ 2497 zyd_cfg_update_promisc(sc, cc, refcount);
| 2531 ifp->if_oerrors++; 2532 data = xfer->priv_fifo; 2533 xfer->priv_fifo = NULL; 2534 if (data != NULL) 2535 zyd_tx_free(data, xfer->error);
|
2498
| 2536
|
2499 zyd_cfg_set_rxfilter(sc, cc, refcount); 2500 2501 /* switch radio transmitter ON */ 2502 zyd_cfg_switch_radio(sc, 1); 2503 2504 /* XXX wrong, can't set here */ 2505 /* set basic rates */ 2506 if (cc->ic_curmode == IEEE80211_MODE_11B) 2507 zyd_cfg_write32(sc, ZYD_MAC_BAS_RATE, 0x0003); 2508 else if (cc->ic_curmode == IEEE80211_MODE_11A) 2509 zyd_cfg_write32(sc, ZYD_MAC_BAS_RATE, 0x1500); 2510 else /* assumes 802.11b/g */ 2511 zyd_cfg_write32(sc, ZYD_MAC_BAS_RATE, 0xff0f); 2512 2513 /* set mandatory rates */ 2514 if (cc->ic_curmode == IEEE80211_MODE_11B) 2515 zyd_cfg_write32(sc, ZYD_MAC_MAN_RATE, 0x000f); 2516 else if (cc->ic_curmode == IEEE80211_MODE_11A) 2517 zyd_cfg_write32(sc, ZYD_MAC_MAN_RATE, 0x1500); 2518 else /* assumes 802.11b/g */ 2519 zyd_cfg_write32(sc, ZYD_MAC_MAN_RATE, 0x150f); 2520 2521 /* set default BSS channel */ 2522 zyd_cfg_set_chan(sc, cc, 0); 2523 2524 /* enable interrupts */ 2525 zyd_cfg_write32(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK); 2526 2527 /* make sure that the transfers get started */ 2528 sc->sc_flags |= ( 2529 ZYD_FLAG_BULK_READ_STALL | 2530 ZYD_FLAG_BULK_WRITE_STALL | 2531 ZYD_FLAG_LL_READY); 2532 2533 if ((sc->sc_flags & ZYD_FLAG_LL_READY) && 2534 (sc->sc_flags & ZYD_FLAG_HL_READY)) { 2535 struct ifnet *ifp = sc->sc_ifp; 2536 struct ieee80211com *ic = ifp->if_l2com; 2537 2538 /* 2539 * start the USB transfers, if not already started: 2540 */ 2541 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_RD]); 2542 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_WR]); 2543 2544 /* 2545 * start IEEE802.11 layer 2546 */ 2547 mtx_unlock(&sc->sc_mtx); 2548 ieee80211_start_all(ic); 2549 mtx_lock(&sc->sc_mtx); 2550 } 2551} 2552 2553/* immediate configuration */ 2554 2555static void 2556zyd_cfg_pre_stop(struct zyd_softc *sc, 2557 struct usb2_config_td_cc *cc, uint16_t refcount) 2558{ 2559 struct ifnet *ifp = sc->sc_ifp; 2560 2561 if (cc) { 2562 /* copy the needed configuration */ 2563 zyd_config_copy(sc, cc, refcount); 2564 } 2565 if (ifp) { 2566 /* clear flags */ 2567 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 2568 } 2569 sc->sc_flags &= ~(ZYD_FLAG_HL_READY | 2570 ZYD_FLAG_LL_READY); 2571 2572 /* 2573 * stop all the transfers, if not already stopped: 2574 */ 2575 usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_DT_WR]); 2576 usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_DT_RD]); 2577 usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_CS_WR]); 2578 usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_CS_RD]); 2579 2580 /* clean up transmission */ 2581 zyd_tx_clean_queue(sc); 2582} 2583 2584/* delayed configuration */ 2585 2586static void 2587zyd_cfg_stop(struct zyd_softc *sc, 2588 struct usb2_config_td_cc *cc, uint16_t refcount) 2589{ 2590 /* switch radio transmitter OFF */ 2591 zyd_cfg_switch_radio(sc, 0); 2592 2593 /* disable Rx */ 2594 zyd_cfg_write32(sc, ZYD_MAC_RXFILTER, 0); 2595 2596 /* disable interrupts */ 2597 zyd_cfg_write32(sc, ZYD_CR_INTERRUPT, 0); 2598} 2599 2600static void 2601zyd_update_mcast_cb(struct ifnet *ifp) 2602{ 2603 struct zyd_softc *sc = ifp->if_softc; 2604 2605 mtx_lock(&sc->sc_mtx); 2606 usb2_config_td_queue_command 2607 (&sc->sc_config_td, &zyd_config_copy, 2608 &zyd_cfg_update_promisc, 0, 0); 2609 mtx_unlock(&sc->sc_mtx); 2610} 2611 2612static void 2613zyd_update_promisc_cb(struct ifnet *ifp) 2614{ 2615 struct zyd_softc *sc = ifp->if_softc; 2616 2617 mtx_lock(&sc->sc_mtx); 2618 usb2_config_td_queue_command 2619 (&sc->sc_config_td, &zyd_config_copy, 2620 &zyd_cfg_update_promisc, 0, 0); 2621 mtx_unlock(&sc->sc_mtx); 2622} 2623 2624static void 2625zyd_cfg_set_rxfilter(struct zyd_softc *sc, 2626 struct usb2_config_td_cc *cc, uint16_t refcount) 2627{ 2628 uint32_t rxfilter; 2629 2630 switch (cc->ic_opmode) { 2631 case IEEE80211_M_STA: 2632 rxfilter = ZYD_FILTER_BSS;
| 2537 if (xfer->error == USB_ERR_STALLED) { 2538 /* try to clear stall first */ 2539 xfer->flags.stall_pipe = 1; 2540 goto tr_setup; 2541 } 2542 if (xfer->error == USB_ERR_TIMEOUT) 2543 device_printf(sc->sc_dev, "device timeout\n");
|
2633 break;
| 2544 break;
|
2634 case IEEE80211_M_IBSS: 2635 case IEEE80211_M_HOSTAP: 2636 rxfilter = ZYD_FILTER_HOSTAP; 2637 break; 2638 case IEEE80211_M_MONITOR: 2639 rxfilter = ZYD_FILTER_MONITOR; 2640 break; 2641 default: 2642 /* should not get there */ 2643 return;
| |
2644 }
| 2545 }
|
2645 zyd_cfg_write32(sc, ZYD_MAC_RXFILTER, rxfilter);
| |
2646} 2647
| 2546} 2547
|
2648static void 2649zyd_cfg_set_led(struct zyd_softc *sc, uint32_t which, uint8_t on)
| 2548static int 2549zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
2650{
| 2550{
|
2651 uint32_t tmp;
| 2551 struct ieee80211vap *vap = ni->ni_vap; 2552 struct ieee80211com *ic = ni->ni_ic; 2553 struct zyd_tx_desc *desc; 2554 struct zyd_tx_data *data; 2555 struct ieee80211_frame *wh; 2556 const struct ieee80211_txparam *tp; 2557 struct ieee80211_key *k; 2558 int rate, totlen; 2559 uint16_t pktlen;
|
2652
| 2560
|
2653 zyd_cfg_read32(sc, ZYD_MAC_TX_PE_CONTROL, &tmp); 2654 if (on) 2655 tmp |= which; 2656 else 2657 tmp &= ~which;
| 2561 wh = mtod(m0, struct ieee80211_frame *); 2562 data = STAILQ_FIRST(&sc->tx_free); 2563 STAILQ_REMOVE_HEAD(&sc->tx_free, next); 2564 sc->tx_nfree--; 2565 desc = &data->desc;
|
2658
| 2566
|
2659 zyd_cfg_write32(sc, ZYD_MAC_TX_PE_CONTROL, tmp); 2660} 2661 2662static void 2663zyd_start_cb(struct ifnet *ifp) 2664{ 2665 struct zyd_softc *sc = ifp->if_softc; 2666 2667 mtx_lock(&sc->sc_mtx); 2668 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_WR]); 2669 mtx_unlock(&sc->sc_mtx); 2670} 2671 2672static void 2673zyd_bulk_write_clear_stall_callback(struct usb2_xfer *xfer) 2674{ 2675 struct zyd_softc *sc = xfer->priv_sc; 2676 struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_BULK_DT_WR]; 2677 2678 if (usb2_clear_stall_callback(xfer, xfer_other)) { 2679 DPRINTF("stall cleared\n"); 2680 sc->sc_flags &= ~ZYD_FLAG_BULK_WRITE_STALL; 2681 usb2_transfer_start(xfer_other);
| 2567 desc->flags = ZYD_TX_FLAG_BACKOFF; 2568 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; 2569 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 2570 rate = tp->mcastrate; 2571 desc->flags |= ZYD_TX_FLAG_MULTICAST; 2572 } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { 2573 rate = tp->ucastrate; 2574 } else { 2575 (void) ieee80211_amrr_choose(ni, &ZYD_NODE(ni)->amn); 2576 rate = ni->ni_txrate;
|
2682 }
| 2577 }
|
2683}
| |
2684
| 2578
|
2685/* 2686 * We assume that "m->m_pkthdr.rcvif" is pointing to the "ni" that 2687 * should be freed, when "zyd_setup_desc_and_tx" is called. 2688 */ 2689static void 2690zyd_setup_desc_and_tx(struct zyd_softc *sc, struct mbuf *m, 2691 uint16_t rate) 2692{ 2693 struct ifnet *ifp = sc->sc_ifp; 2694 struct ieee80211com *ic = ifp->if_l2com; 2695 struct mbuf *mm; 2696 enum ieee80211_phytype phytype; 2697 uint16_t len; 2698 uint16_t totlen; 2699 uint16_t pktlen; 2700 uint8_t remainder; 2701 2702 if (sc->sc_tx_queue.ifq_len >= IFQ_MAXLEN) { 2703 /* free packet */ 2704 zyd_tx_freem(m); 2705 ifp->if_oerrors++; 2706 return;
| 2579 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2580 k = ieee80211_crypto_encap(ni, m0); 2581 if (k == NULL) { 2582 m_freem(m0); 2583 return (ENOBUFS); 2584 } 2585 /* packet header may have moved, reset our local pointer */ 2586 wh = mtod(m0, struct ieee80211_frame *);
|
2707 }
| 2587 }
|
2708 if (!((sc->sc_flags & ZYD_FLAG_LL_READY) && 2709 (sc->sc_flags & ZYD_FLAG_HL_READY))) { 2710 /* free packet */ 2711 zyd_tx_freem(m); 2712 ifp->if_oerrors++; 2713 return; 2714 } 2715 if (rate < 2) { 2716 DPRINTF("rate < 2!\n");
| |
2717
| 2588
|
2718 /* avoid division by zero */ 2719 rate = 2; 2720 } 2721 ic->ic_lastdata = ticks;
| 2589 data->ni = ni; 2590 data->m = m0;
|
2722
| 2591
|
2723 if (bpf_peers_present(ifp->if_bpf)) { 2724 struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
| 2592 totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
|
2725
| 2593
|
2726 tap->wt_flags = 0; 2727 tap->wt_rate = rate; 2728 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); 2729 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
| 2594 /* fill Tx descriptor */ 2595 desc->len = htole16(totlen);
|
2730
| 2596
|
2731 bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
| 2597 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 2598 /* multicast frames are not sent at OFDM rates in 802.11b/g */ 2599 if (totlen > vap->iv_rtsthreshold) { 2600 desc->flags |= ZYD_TX_FLAG_RTS; 2601 } else if (ZYD_RATE_IS_OFDM(rate) && 2602 (ic->ic_flags & IEEE80211_F_USEPROT)) { 2603 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 2604 desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF; 2605 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 2606 desc->flags |= ZYD_TX_FLAG_RTS; 2607 }
|
2732 }
| 2608 }
|
2733 len = m->m_pkthdr.len; 2734 totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; 2735 phytype = ieee80211_rate2phytype(sc->sc_rates, rate);
| |
2736
| 2609
|
2737 sc->sc_tx_desc.len = htole16(totlen); 2738 sc->sc_tx_desc.phy = zyd_plcp_signal(rate); 2739 if (phytype == IEEE80211_T_OFDM) { 2740 sc->sc_tx_desc.phy |= ZYD_TX_PHY_OFDM;
| 2610 if ((wh->i_fc[0] & 2611 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == 2612 (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) 2613 desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); 2614 2615 desc->phy = zyd_plcp_signal(rate); 2616 if (ZYD_RATE_IS_OFDM(rate)) { 2617 desc->phy |= ZYD_TX_PHY_OFDM;
|
2741 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
| 2618 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
|
2742 sc->sc_tx_desc.phy |= ZYD_TX_PHY_5GHZ;
| 2619 desc->phy |= ZYD_TX_PHY_5GHZ;
|
2743 } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
| 2620 } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
|
2744 sc->sc_tx_desc.phy |= ZYD_TX_PHY_SHPREAMBLE;
| 2621 desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
|
2745 2746 /* actual transmit length (XXX why +10?) */ 2747 pktlen = sizeof(struct zyd_tx_desc) + 10;
| 2622 2623 /* actual transmit length (XXX why +10?) */ 2624 pktlen = sizeof(struct zyd_tx_desc) + 10;
|
2748 if (sc->sc_mac_rev == ZYD_ZD1211)
| 2625 if (sc->sc_macrev == ZYD_ZD1211)
|
2749 pktlen += totlen;
| 2626 pktlen += totlen;
|
2750 sc->sc_tx_desc.pktlen = htole16(pktlen);
| 2627 desc->pktlen = htole16(pktlen);
|
2751
| 2628
|
2752 sc->sc_tx_desc.plcp_length = ((16 * totlen) + rate - 1) / rate; 2753 sc->sc_tx_desc.plcp_service = 0;
| 2629 desc->plcp_length = (16 * totlen + rate - 1) / rate; 2630 desc->plcp_service = 0;
|
2754 if (rate == 22) {
| 2631 if (rate == 22) {
|
2755 remainder = (16 * totlen) % 22; 2756 if ((remainder != 0) && (remainder < 7)) 2757 sc->sc_tx_desc.plcp_service |= ZYD_PLCP_LENGEXT;
| 2632 const int remainder = (16 * totlen) % 22; 2633 if (remainder != 0 && remainder < 7) 2634 desc->plcp_service |= ZYD_PLCP_LENGEXT;
|
2758 }
| 2635 }
|
2759 if (sizeof(sc->sc_tx_desc) > MHLEN) { 2760 DPRINTF("No room for header structure!\n"); 2761 zyd_tx_freem(m); 2762 return; 2763 } 2764 mm = m_gethdr(M_NOWAIT, MT_DATA); 2765 if (mm == NULL) { 2766 DPRINTF("Could not allocate header mbuf!\n"); 2767 zyd_tx_freem(m); 2768 return; 2769 } 2770 bcopy(&sc->sc_tx_desc, mm->m_data, sizeof(sc->sc_tx_desc)); 2771 mm->m_len = sizeof(sc->sc_tx_desc);
| |
2772
| 2636
|
2773 mm->m_next = m; 2774 mm->m_pkthdr.len = mm->m_len + m->m_pkthdr.len; 2775 mm->m_pkthdr.rcvif = NULL;
| 2637 DPRINTF(sc, ZYD_DEBUG_XMIT, 2638 "%s: sending data frame len=%zu rate=%u\n", 2639 device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len, 2640 rate);
|
2776
| 2641
|
2777 /* start write transfer, if not started */ 2778 _IF_ENQUEUE(&sc->sc_tx_queue, mm);
| 2642 STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 2643 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_WR]);
|
2779
| 2644
|
2780 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_WR]);
| 2645 return (0);
|
2781} 2782 2783static void
| 2646} 2647 2648static void
|
2784zyd_bulk_write_callback(struct usb2_xfer *xfer)
| 2649zyd_start(struct ifnet *ifp)
|
2785{
| 2650{
|
2786 struct zyd_softc *sc = xfer->priv_sc; 2787 struct ifnet *ifp = sc->sc_ifp;
| 2651 struct zyd_softc *sc = ifp->if_softc; 2652 struct ieee80211_node *ni;
|
2788 struct mbuf *m;
| 2653 struct mbuf *m;
|
2789 uint16_t temp_len;
| |
2790
| 2654
|
2791 DPRINTF("\n"); 2792 2793 switch (USB_GET_STATE(xfer)) { 2794 case USB_ST_TRANSFERRED: 2795 DPRINTFN(11, "transfer complete\n"); 2796 2797 ifp->if_opackets++; 2798 2799 case USB_ST_SETUP: 2800 if (sc->sc_flags & ZYD_FLAG_BULK_WRITE_STALL) { 2801 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_CS_WR]); 2802 DPRINTFN(11, "write stalled\n");
| 2655 ZYD_LOCK(sc); 2656 for (;;) { 2657 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 2658 if (m == NULL)
|
2803 break;
| 2659 break;
|
2804 } 2805 if (sc->sc_flags & ZYD_FLAG_WAIT_COMMAND) { 2806 /* 2807 * don't send anything while a command is pending ! 2808 */ 2809 DPRINTFN(11, "wait command\n");
| 2660 if (sc->tx_nfree == 0) { 2661 IFQ_DRV_PREPEND(&ifp->if_snd, m); 2662 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
2810 break; 2811 }
| 2663 break; 2664 }
|
2812 zyd_fill_write_queue(sc); 2813 2814 _IF_DEQUEUE(&sc->sc_tx_queue, m); 2815 2816 if (m) { 2817 if (m->m_pkthdr.len > ZYD_MAX_TXBUFSZ) { 2818 DPRINTFN(0, "data overflow, %u bytes\n", 2819 m->m_pkthdr.len); 2820 m->m_pkthdr.len = ZYD_MAX_TXBUFSZ; 2821 } 2822 usb2_m_copy_in(xfer->frbuffers, 0, 2823 m, 0, m->m_pkthdr.len); 2824 2825 /* get transfer length */ 2826 temp_len = m->m_pkthdr.len; 2827 2828 DPRINTFN(11, "sending frame len=%u xferlen=%u\n", 2829 m->m_pkthdr.len, temp_len); 2830 2831 xfer->frlengths[0] = temp_len; 2832 2833 usb2_start_hardware(xfer); 2834 2835 /* free mbuf and node */ 2836 zyd_tx_freem(m);
| 2665 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 2666 m = ieee80211_encap(ni, m); 2667 if (m == NULL) { 2668 ieee80211_free_node(ni); 2669 ifp->if_oerrors++; 2670 continue;
|
2837 }
| 2671 }
|
2838 break; 2839 2840 default: /* Error */ 2841 DPRINTFN(11, "transfer error, %s\n", 2842 usb2_errstr(xfer->error)); 2843 2844 if (xfer->error != USB_ERR_CANCELLED) { 2845 /* try to clear stall first */ 2846 sc->sc_flags |= ZYD_FLAG_BULK_WRITE_STALL; 2847 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_CS_WR]);
| 2672 if (zyd_tx_data(sc, m, ni) != 0) { 2673 ieee80211_free_node(ni); 2674 ifp->if_oerrors++; 2675 break;
|
2848 }
| 2676 }
|
2849 ifp->if_oerrors++; 2850 break;
| |
2851 }
| 2677 }
|
| 2678 ZYD_UNLOCK(sc);
|
2852} 2853
| 2679} 2680
|
2854static void 2855zyd_init_cb(void *arg)
| 2681static int 2682zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2683 const struct ieee80211_bpf_params *params)
|
2856{
| 2684{
|
2857 struct zyd_softc *sc = arg;
| 2685 struct ieee80211com *ic = ni->ni_ic; 2686 struct ifnet *ifp = ic->ic_ifp; 2687 struct zyd_softc *sc = ifp->if_softc;
|
2858
| 2688
|
2859 mtx_lock(&sc->sc_mtx); 2860 usb2_config_td_queue_command 2861 (&sc->sc_config_td, &zyd_cfg_pre_init, 2862 &zyd_cfg_init, 0, 0); 2863 mtx_unlock(&sc->sc_mtx);
| 2689 ZYD_LOCK(sc); 2690 /* prevent management frames from being sent if we're not ready */ 2691 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 2692 ZYD_UNLOCK(sc); 2693 m_freem(m); 2694 ieee80211_free_node(ni); 2695 return (ENETDOWN); 2696 } 2697 if (sc->tx_nfree == 0) { 2698 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 2699 ZYD_UNLOCK(sc); 2700 m_freem(m); 2701 ieee80211_free_node(ni); 2702 return (ENOBUFS); /* XXX */ 2703 } 2704 2705 /* 2706 * Legacy path; interpret frame contents to decide 2707 * precisely how to send the frame. 2708 * XXX raw path 2709 */ 2710 if (zyd_tx_mgt(sc, m, ni) != 0) { 2711 ZYD_UNLOCK(sc); 2712 ifp->if_oerrors++; 2713 ieee80211_free_node(ni); 2714 return (EIO); 2715 } 2716 ZYD_UNLOCK(sc); 2717 return (0);
|
2864} 2865 2866static int
| 2718} 2719 2720static int
|
2867zyd_ioctl_cb(struct ifnet *ifp, u_long cmd, caddr_t data)
| 2721zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
2868{ 2869 struct zyd_softc *sc = ifp->if_softc; 2870 struct ieee80211com *ic = ifp->if_l2com;
| 2722{ 2723 struct zyd_softc *sc = ifp->if_softc; 2724 struct ieee80211com *ic = ifp->if_l2com;
|
2871 int error;
| 2725 struct ifreq *ifr = (struct ifreq *) data; 2726 int error = 0, startall = 0;
|
2872 2873 switch (cmd) { 2874 case SIOCSIFFLAGS:
| 2727 2728 switch (cmd) { 2729 case SIOCSIFFLAGS:
|
2875 mtx_lock(&sc->sc_mtx);
| 2730 ZYD_LOCK(sc);
|
2876 if (ifp->if_flags & IFF_UP) {
| 2731 if (ifp->if_flags & IFF_UP) {
|
2877 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 2878 usb2_config_td_queue_command 2879 (&sc->sc_config_td, &zyd_cfg_pre_init, 2880 &zyd_cfg_init, 0, 0);
| 2732 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 2733 if ((ifp->if_flags ^ sc->sc_if_flags) & 2734 (IFF_ALLMULTI | IFF_PROMISC)) 2735 zyd_set_multi(sc); 2736 } else { 2737 zyd_queue_command(sc, zyd_init_task, 2738 &sc->sc_synctask[0].hdr, 2739 &sc->sc_synctask[1].hdr); 2740 startall = 1;
|
2881 } 2882 } else { 2883 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
| 2741 } 2742 } else { 2743 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
2884 usb2_config_td_queue_command 2885 (&sc->sc_config_td, &zyd_cfg_pre_stop, 2886 &zyd_cfg_stop, 0, 0);
| 2744 zyd_queue_command(sc, zyd_stop_task, 2745 &sc->sc_synctask[0].hdr, 2746 &sc->sc_synctask[1].hdr);
|
2887 } 2888 }
| 2747 } 2748 }
|
2889 mtx_unlock(&sc->sc_mtx); 2890 error = 0;
| 2749 sc->sc_if_flags = ifp->if_flags; 2750 ZYD_UNLOCK(sc); 2751 if (startall) 2752 ieee80211_start_all(ic);
|
2891 break;
| 2753 break;
|
2892
| |
2893 case SIOCGIFMEDIA:
| 2754 case SIOCGIFMEDIA:
|
2894 case SIOCADDMULTI: 2895 case SIOCDELMULTI: 2896 error = ifmedia_ioctl(ifp, (void *)data, &ic->ic_media, cmd);
| 2755 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
2897 break;
| 2756 break;
|
2898 2899 default:
| 2757 case SIOCGIFADDR:
|
2900 error = ether_ioctl(ifp, cmd, data); 2901 break;
| 2758 error = ether_ioctl(ifp, cmd, data); 2759 break;
|
| 2760 default: 2761 error = EINVAL; 2762 break;
|
2902 } 2903 return (error); 2904} 2905 2906static void
| 2763 } 2764 return (error); 2765} 2766 2767static void
|
2907zyd_watchdog(void *arg)
| 2768zyd_init_task(struct usb2_proc_msg *pm)
|
2908{
| 2769{
|
2909 struct zyd_softc *sc = arg;
| 2770 struct zyd_task *task = (struct zyd_task *)pm; 2771 struct zyd_softc *sc = task->sc; 2772 struct ifnet *ifp = sc->sc_ifp; 2773 struct ieee80211com *ic = ifp->if_l2com; 2774 struct usb2_config_descriptor *cd; 2775 int error; 2776 uint32_t val;
|
2910
| 2777
|
2911 mtx_assert(&sc->sc_mtx, MA_OWNED);
| 2778 ZYD_LOCK_ASSERT(sc, MA_OWNED);
|
2912
| 2779
|
2913 if (sc->sc_amrr_timer) { 2914 usb2_config_td_queue_command 2915 (&sc->sc_config_td, NULL, 2916 &zyd_cfg_amrr_timeout, 0, 0);
| 2780 if (!(sc->sc_flags & ZYD_FLAG_INITONCE)) { 2781 error = zyd_loadfirmware(sc); 2782 if (error != 0) { 2783 device_printf(sc->sc_dev, 2784 "could not load firmware (error=%d)\n", error); 2785 goto fail; 2786 } 2787 2788 /* reset device */ 2789 cd = usb2_get_config_descriptor(sc->sc_udev); 2790 error = usb2_req_set_config(sc->sc_udev, &sc->sc_mtx, 2791 cd->bConfigurationValue); 2792 if (error) 2793 device_printf(sc->sc_dev, "reset failed, continuing\n"); 2794 2795 error = zyd_hw_init(sc); 2796 if (error) { 2797 device_printf(sc->sc_dev, 2798 "hardware initialization failed\n"); 2799 goto fail; 2800 } 2801 2802 device_printf(sc->sc_dev, 2803 "HMAC ZD1211%s, FW %02x.%02x, RF %s S%x, PA%x LED %x " 2804 "BE%x NP%x Gain%x F%x\n", 2805 (sc->sc_macrev == ZYD_ZD1211) ? "": "B", 2806 sc->sc_fwrev >> 8, sc->sc_fwrev & 0xff, 2807 zyd_rf_name(sc->sc_rfrev), sc->sc_al2230s, sc->sc_parev, 2808 sc->sc_ledtype, sc->sc_bandedge6, sc->sc_newphy, 2809 sc->sc_cckgain, sc->sc_fix_cr157); 2810 2811 /* read regulatory domain (currently unused) */ 2812 zyd_read32_m(sc, ZYD_EEPROM_SUBID, &val); 2813 sc->sc_regdomain = val >> 16; 2814 DPRINTF(sc, ZYD_DEBUG_INIT, "regulatory domain %x\n", 2815 sc->sc_regdomain); 2816 2817 /* we'll do software WEP decryption for now */ 2818 DPRINTF(sc, ZYD_DEBUG_INIT, "%s: setting encryption type\n", 2819 __func__); 2820 zyd_write32_m(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER); 2821 2822 sc->sc_flags |= ZYD_FLAG_INITONCE;
|
2917 }
| 2823 }
|
2918 usb2_callout_reset(&sc->sc_watchdog, 2919 hz, &zyd_watchdog, sc); 2920}
| |
2921
| 2824
|
2922static void 2923zyd_config_copy_chan(struct zyd_config_copy_chan *cc, 2924 struct ieee80211com *ic, struct ieee80211_channel *c) 2925{ 2926 if (!c)
| 2825 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 2826 zyd_stop_task(pm); 2827 2828 IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); 2829 DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %s\n", 2830 ether_sprintf(ic->ic_myaddr)); 2831 error = zyd_set_macaddr(sc, ic->ic_myaddr); 2832 if (error != 0)
|
2927 return;
| 2833 return;
|
2928 cc->chan_to_ieee = 2929 ieee80211_chan2ieee(ic, c); 2930 if (c != IEEE80211_CHAN_ANYC) { 2931 cc->chan_to_mode = 2932 ieee80211_chan2mode(c); 2933 cc->ic_freq = c->ic_freq; 2934 if (IEEE80211_IS_CHAN_B(c)) 2935 cc->chan_is_b = 1; 2936 if (IEEE80211_IS_CHAN_A(c)) 2937 cc->chan_is_a = 1; 2938 if (IEEE80211_IS_CHAN_2GHZ(c)) 2939 cc->chan_is_2ghz = 1; 2940 if (IEEE80211_IS_CHAN_5GHZ(c)) 2941 cc->chan_is_5ghz = 1; 2942 if (IEEE80211_IS_CHAN_ANYG(c)) 2943 cc->chan_is_g = 1; 2944 } 2945}
| |
2946
| 2834
|
2947static void 2948zyd_config_copy(struct zyd_softc *sc, 2949 struct usb2_config_td_cc *cc, uint16_t refcount) 2950{ 2951 const struct ieee80211_txparam *tp; 2952 struct ieee80211vap *vap; 2953 struct ifmultiaddr *ifma; 2954 struct ieee80211_node *ni; 2955 struct ieee80211com *ic; 2956 struct ifnet *ifp;
| 2835 /* set basic rates */ 2836 if (ic->ic_curmode == IEEE80211_MODE_11B) 2837 zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x0003); 2838 else if (ic->ic_curmode == IEEE80211_MODE_11A) 2839 zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x1500); 2840 else /* assumes 802.11b/g */ 2841 zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0xff0f);
|
2957
| 2842
|
2958 bzero(cc, sizeof(*cc));
| 2843 /* promiscuous mode */ 2844 zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0); 2845 /* multicast setup */ 2846 zyd_set_multi(sc); 2847 /* set RX filter */ 2848 error = zyd_set_rxfilter(sc); 2849 if (error != 0) 2850 goto fail;
|
2959
| 2851
|
2960 ifp = sc->sc_ifp; 2961 if (ifp) { 2962 cc->if_flags = ifp->if_flags; 2963 bcopy(ifp->if_broadcastaddr, cc->if_broadcastaddr, 2964 sizeof(cc->if_broadcastaddr));
| 2852 /* switch radio transmitter ON */ 2853 error = zyd_switch_radio(sc, 1); 2854 if (error != 0) 2855 goto fail; 2856 /* set default BSS channel */ 2857 zyd_set_chan(sc, ic->ic_curchan);
|
2965
| 2858
|
2966 cc->zyd_multi_low = 0x00000000; 2967 cc->zyd_multi_high = 0x80000000;
| 2859 /* 2860 * Allocate Tx and Rx xfer queues. 2861 */ 2862 zyd_setup_tx_list(sc);
|
2968
| 2863
|
2969 IF_ADDR_LOCK(ifp); 2970 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 2971 uint8_t v;
| 2864 /* enable interrupts */ 2865 zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
|
2972
| 2866
|
2973 if (ifma->ifma_addr->sa_family != AF_LINK) 2974 continue; 2975 v = ((uint8_t *)LLADDR((struct sockaddr_dl *) 2976 ifma->ifma_addr))[5] >> 2; 2977 if (v < 32) 2978 cc->zyd_multi_low |= 1 << v; 2979 else 2980 cc->zyd_multi_high |= 1 << (v - 32); 2981 } 2982 IF_ADDR_UNLOCK(ifp);
| 2867 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 2868 ifp->if_drv_flags |= IFF_DRV_RUNNING; 2869 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_RD]); 2870 usb2_transfer_start(sc->sc_xfer[ZYD_INTR_RD]);
|
2983
| 2871
|
2984 ic = ifp->if_l2com; 2985 if (ic) { 2986 zyd_config_copy_chan(&cc->ic_curchan, ic, ic->ic_curchan); 2987 zyd_config_copy_chan(&cc->ic_bsschan, ic, ic->ic_bsschan); 2988 vap = TAILQ_FIRST(&ic->ic_vaps); 2989 if (vap) { 2990 ni = vap->iv_bss; 2991 if (ni) { 2992 cc->iv_bss.ni_intval = ni->ni_intval; 2993 bcopy(ni->ni_bssid, cc->iv_bss.ni_bssid, 2994 sizeof(cc->iv_bss.ni_bssid)); 2995 } 2996 tp = vap->iv_txparms + cc->ic_bsschan.chan_to_mode; 2997 if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { 2998 cc->iv_bss.fixed_rate_none = 1; 2999 } 3000 } 3001 cc->ic_opmode = ic->ic_opmode; 3002 cc->ic_flags = ic->ic_flags; 3003 cc->ic_txpowlimit = ic->ic_txpowlimit; 3004 cc->ic_curmode = ic->ic_curmode;
| 2872 return;
|
3005
| 2873
|
3006 bcopy(ic->ic_myaddr, cc->ic_myaddr, 3007 sizeof(cc->ic_myaddr)); 3008 } 3009 } 3010 sc->sc_flags |= ZYD_FLAG_WAIT_COMMAND;
| 2874fail: zyd_stop_task(pm); 2875 return;
|
3011} 3012 3013static void
| 2876} 2877 2878static void
|
3014zyd_end_of_commands(struct zyd_softc *sc)
| 2879zyd_init(void *priv)
|
3015{
| 2880{
|
3016 sc->sc_flags &= ~ZYD_FLAG_WAIT_COMMAND;
| 2881 struct zyd_softc *sc = priv; 2882 struct ifnet *ifp = sc->sc_ifp; 2883 struct ieee80211com *ic = ifp->if_l2com;
|
3017
| 2884
|
3018 /* start write transfer, if not started */ 3019 usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_WR]);
| 2885 ZYD_LOCK(sc); 2886 zyd_queue_command(sc, zyd_init_task, 2887 &sc->sc_synctask[0].hdr, 2888 &sc->sc_synctask[1].hdr); 2889 ZYD_UNLOCK(sc); 2890 2891 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 2892 ieee80211_start_all(ic); /* start all vap's */
|
3020} 3021 3022static void
| 2893} 2894 2895static void
|
3023zyd_newassoc_cb(struct ieee80211_node *ni, int isnew)
| 2896zyd_stop_task(struct usb2_proc_msg *pm)
|
3024{
| 2897{
|
3025 struct ieee80211vap *vap = ni->ni_vap;
| 2898 struct zyd_task *task = (struct zyd_task *)pm; 2899 struct zyd_softc *sc = task->sc; 2900 struct ifnet *ifp = sc->sc_ifp; 2901 int error;
|
3026
| 2902
|
3027 ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni); 3028}
| 2903 ZYD_LOCK_ASSERT(sc, MA_OWNED);
|
3029
| 2904
|
3030static void 3031zyd_cfg_amrr_timeout(struct zyd_softc *sc, 3032 struct usb2_config_td_cc *cc, uint16_t refcount) 3033{ 3034 struct ieee80211vap *vap; 3035 struct ieee80211_node *ni;
| 2905 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
3036
| 2906
|
3037 vap = zyd_get_vap(sc); 3038 if (vap == NULL) {
| 2907 /* 2908 * Drain all the transfers, if not already drained: 2909 */ 2910 ZYD_UNLOCK(sc); 2911 usb2_transfer_drain(sc->sc_xfer[ZYD_BULK_WR]); 2912 usb2_transfer_drain(sc->sc_xfer[ZYD_BULK_RD]); 2913 ZYD_LOCK(sc); 2914 2915 zyd_unsetup_tx_list(sc); 2916 2917 /* Stop now if the device was never set up */ 2918 if (!(sc->sc_flags & ZYD_FLAG_INITONCE))
|
3039 return;
| 2919 return;
|
3040 } 3041 ni = vap->iv_bss; 3042 if (ni == NULL) { 3043 return; 3044 } 3045 if ((sc->sc_flags & ZYD_FLAG_LL_READY) && 3046 (sc->sc_flags & ZYD_FLAG_HL_READY)) {
| |
3047
| 2920
|
3048 if (sc->sc_amrr_timer) {
| 2921 /* switch radio transmitter OFF */ 2922 error = zyd_switch_radio(sc, 0); 2923 if (error != 0) 2924 goto fail; 2925 /* disable Rx */ 2926 zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0); 2927 /* disable interrupts */ 2928 zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0);
|
3049
| 2929
|
3050 if (ieee80211_amrr_choose(ni, &ZYD_NODE(ni)->amn)) { 3051 /* ignore */ 3052 } 3053 } 3054 }
| 2930fail: 2931 return;
|
3055} 3056
| 2932} 2933
|
3057static void 3058zyd_cfg_amrr_start(struct zyd_softc *sc)
| 2934static int 2935zyd_loadfirmware(struct zyd_softc *sc)
|
3059{
| 2936{
|
3060 struct ieee80211vap *vap; 3061 struct ieee80211_node *ni;
| 2937 struct usb2_device_request req; 2938 size_t size; 2939 u_char *fw; 2940 uint8_t stat; 2941 uint16_t addr;
|
3062
| 2942
|
3063 vap = zyd_get_vap(sc);
| 2943 if (sc->sc_flags & ZYD_FLAG_FWLOADED) 2944 return (0);
|
3064
| 2945
|
3065 if (vap == NULL) { 3066 return;
| 2946 if (sc->sc_macrev == ZYD_ZD1211) { 2947 fw = (u_char *)zd1211_firmware; 2948 size = sizeof(zd1211_firmware); 2949 } else { 2950 fw = (u_char *)zd1211b_firmware; 2951 size = sizeof(zd1211b_firmware);
|
3067 }
| 2952 }
|
3068 ni = vap->iv_bss; 3069 if (ni == NULL) { 3070 return; 3071 } 3072 /* init AMRR */
| |
3073
| 2953
|
3074 ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni);
| 2954 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 2955 req.bRequest = ZYD_DOWNLOADREQ; 2956 USETW(req.wIndex, 0);
|
3075
| 2957
|
3076 /* enable AMRR timer */
| 2958 addr = ZYD_FIRMWARE_START_ADDR; 2959 while (size > 0) { 2960 /* 2961 * When the transfer size is 4096 bytes, it is not 2962 * likely to be able to transfer it. 2963 * The cause is port or machine or chip? 2964 */ 2965 const int mlen = min(size, 64);
|
3077
| 2966
|
3078 sc->sc_amrr_timer = 1; 3079}
| 2967 DPRINTF(sc, ZYD_DEBUG_FW, 2968 "loading firmware block: len=%d, addr=0x%x\n", mlen, addr);
|
3080
| 2969
|
3081static struct ieee80211vap * 3082zyd_vap_create(struct ieee80211com *ic, 3083 const char name[IFNAMSIZ], int unit, int opmode, int flags, 3084 const uint8_t bssid[IEEE80211_ADDR_LEN], 3085 const uint8_t mac[IEEE80211_ADDR_LEN]) 3086{ 3087 struct zyd_vap *zvp; 3088 struct ieee80211vap *vap; 3089 struct zyd_softc *sc = ic->ic_ifp->if_softc;
| 2970 USETW(req.wValue, addr); 2971 USETW(req.wLength, mlen); 2972 if (zyd_do_request(sc, &req, fw) != 0) 2973 return (EIO);
|
3090
| 2974
|
3091 /* Need to sync with config thread: */ 3092 mtx_lock(&sc->sc_mtx); 3093 if (usb2_config_td_sync(&sc->sc_config_td)) { 3094 mtx_unlock(&sc->sc_mtx); 3095 /* config thread is gone */ 3096 return (NULL);
| 2975 addr += mlen / 2; 2976 fw += mlen; 2977 size -= mlen;
|
3097 }
| 2978 }
|
3098 mtx_unlock(&sc->sc_mtx);
| |
3099
| 2979
|
3100 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 3101 return NULL; 3102 zvp = (struct zyd_vap *)malloc(sizeof(struct zyd_vap), 3103 M_80211_VAP, M_NOWAIT | M_ZERO); 3104 if (zvp == NULL) 3105 return NULL; 3106 vap = &zvp->vap; 3107 /* enable s/w bmiss handling for sta mode */ 3108 ieee80211_vap_setup(ic, vap, name, unit, opmode, 3109 flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
| 2980 /* check whether the upload succeeded */ 2981 req.bmRequestType = UT_READ_VENDOR_DEVICE; 2982 req.bRequest = ZYD_DOWNLOADSTS; 2983 USETW(req.wValue, 0); 2984 USETW(req.wIndex, 0); 2985 USETW(req.wLength, sizeof(stat)); 2986 if (zyd_do_request(sc, &req, &stat) != 0) 2987 return (EIO);
|
3110
| 2988
|
3111 /* override state transition machine */ 3112 zvp->newstate = vap->iv_newstate; 3113 vap->iv_newstate = &zyd_newstate_cb;
| 2989 sc->sc_flags |= ZYD_FLAG_FWLOADED;
|
3114
| 2990
|
3115 ieee80211_amrr_init(&zvp->amrr, vap, 3116 IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, 3117 IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, 3118 1000 /* 1 sec */ ); 3119 3120 /* complete setup */ 3121 ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); 3122 ic->ic_opmode = opmode; 3123 3124 return (vap);
| 2991 return (stat & 0x80) ? (EIO) : (0);
|
3125} 3126 3127static void
| 2992} 2993 2994static void
|
3128zyd_vap_delete(struct ieee80211vap *vap)
| 2995zyd_newassoc(struct ieee80211_node *ni, int isnew)
|
3129{
| 2996{
|
3130 struct zyd_vap *zvp = ZYD_VAP(vap); 3131 struct zyd_softc *sc = vap->iv_ic->ic_ifp->if_softc;
| 2997 struct ieee80211vap *vap = ni->ni_vap;
|
3132
| 2998
|
3133 /* Need to sync with config thread: */ 3134 mtx_lock(&sc->sc_mtx); 3135 if (usb2_config_td_sync(&sc->sc_config_td)) { 3136 /* ignore */ 3137 } 3138 mtx_unlock(&sc->sc_mtx); 3139 3140 ieee80211_amrr_cleanup(&zvp->amrr); 3141 ieee80211_vap_detach(vap); 3142 free(zvp, M_80211_VAP);
| 2999 ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni);
|
3143} 3144
| 3000} 3001
|
3145/* ARGUSED */ 3146static struct ieee80211_node * 3147zyd_node_alloc_cb(struct ieee80211vap *vap __unused, 3148 const uint8_t mac[IEEE80211_ADDR_LEN] __unused) 3149{ 3150 struct zyd_node *zn; 3151 3152 zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO); 3153 return ((zn != NULL) ? &zn->ni : NULL); 3154} 3155
| |
3156static void
| 3002static void
|
3157zyd_fill_write_queue(struct zyd_softc *sc)
| 3003zyd_scan_start(struct ieee80211com *ic)
|
3158{
| 3004{
|
3159 struct ifnet *ifp = sc->sc_ifp; 3160 struct ieee80211_node *ni; 3161 struct mbuf *m;
| 3005 struct zyd_softc *sc = ic->ic_ifp->if_softc;
|
3162
| 3006
|
3163 /* 3164 * We only fill up half of the queue with data frames. The rest is 3165 * reserved for other kinds of frames. 3166 */ 3167 3168 while (sc->sc_tx_queue.ifq_len < (IFQ_MAXLEN / 2)) { 3169 3170 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 3171 if (m == NULL) 3172 break; 3173 3174 ni = (void *)(m->m_pkthdr.rcvif); 3175 m = ieee80211_encap(ni, m); 3176 if (m == NULL) { 3177 ieee80211_free_node(ni); 3178 continue; 3179 } 3180 zyd_tx_data(sc, m, ni); 3181 }
| 3007 ZYD_LOCK(sc); 3008 /* do it in a process context */ 3009 sc->sc_scan_action = ZYD_SCAN_START; 3010 zyd_queue_command(sc, zyd_scantask, 3011 &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); 3012 ZYD_UNLOCK(sc);
|
3182} 3183 3184static void
| 3013} 3014 3015static void
|
3185zyd_tx_clean_queue(struct zyd_softc *sc)
| 3016zyd_scan_end(struct ieee80211com *ic)
|
3186{
| 3017{
|
3187 struct mbuf *m;
| 3018 struct zyd_softc *sc = ic->ic_ifp->if_softc;
|
3188
| 3019
|
3189 for (;;) { 3190 _IF_DEQUEUE(&sc->sc_tx_queue, m); 3191 3192 if (!m) { 3193 break; 3194 } 3195 zyd_tx_freem(m); 3196 }
| 3020 ZYD_LOCK(sc); 3021 /* do it in a process context */ 3022 sc->sc_scan_action = ZYD_SCAN_END; 3023 zyd_queue_command(sc, zyd_scantask, 3024 &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); 3025 ZYD_UNLOCK(sc);
|
3197} 3198 3199static void
| 3026} 3027 3028static void
|
3200zyd_tx_freem(struct mbuf *m)
| 3029zyd_set_channel(struct ieee80211com *ic)
|
3201{
| 3030{
|
3202 struct ieee80211_node *ni;
| 3031 struct zyd_softc *sc = ic->ic_ifp->if_softc;
|
3203
| 3032
|
3204 while (m) { 3205 ni = (void *)(m->m_pkthdr.rcvif); 3206 if (!ni) { 3207 m = m_free(m); 3208 continue; 3209 } 3210 if (m->m_flags & M_TXCB) { 3211 ieee80211_process_callback(ni, m, 0); 3212 } 3213 m_freem(m); 3214 ieee80211_free_node(ni); 3215 3216 break; 3217 }
| 3033 ZYD_LOCK(sc); 3034 /* do it in a process context */ 3035 sc->sc_scan_action = ZYD_SET_CHANNEL; 3036 zyd_queue_command(sc, zyd_scantask, 3037 &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); 3038 ZYD_UNLOCK(sc);
|
3218} 3219 3220static void
| 3039} 3040 3041static void
|
3221zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
| 3042zyd_scantask(struct usb2_proc_msg *pm)
|
3222{
| 3043{
|
3223 struct ieee80211vap *vap = ni->ni_vap; 3224 struct ieee80211com *ic = ni->ni_ic; 3225 const struct ieee80211_txparam *tp; 3226 struct ieee80211_frame *wh; 3227 struct ieee80211_key *k; 3228 uint16_t totlen; 3229 uint16_t rate;
| 3044 struct zyd_task *task = (struct zyd_task *)pm; 3045 struct zyd_softc *sc = task->sc; 3046 struct ifnet *ifp = sc->sc_ifp; 3047 struct ieee80211com *ic = ifp->if_l2com;
|
3230
| 3048
|
3231 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 3232 rate = tp->mgmtrate;
| 3049 ZYD_LOCK_ASSERT(sc, MA_OWNED);
|
3233
| 3050
|
3234 wh = mtod(m, struct ieee80211_frame *); 3235 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 3236 k = ieee80211_crypto_encap(ni, m); 3237 if (k == NULL) { 3238 m_freem(m); 3239 ieee80211_free_node(ni); 3240 return; 3241 } 3242 wh = mtod(m, struct ieee80211_frame *); 3243 } 3244 /* fill Tx descriptor */
| 3051 switch (sc->sc_scan_action) { 3052 case ZYD_SCAN_START: 3053 /* want broadcast address while scanning */ 3054 zyd_set_bssid(sc, ifp->if_broadcastaddr); 3055 break;
|
3245
| 3056
|
3246 sc->sc_tx_desc.flags = ZYD_TX_FLAG_BACKOFF; 3247 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 3248 /* get total length */ 3249 totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; 3250 /* multicast frames are not sent at OFDM rates in 802.11b/g */ 3251 if (totlen > vap->iv_rtsthreshold) { 3252 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_RTS; 3253 } else if (ZYD_RATE_IS_OFDM(rate) && 3254 (ic->ic_flags & IEEE80211_F_USEPROT)) { 3255 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 3256 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_CTS_TO_SELF; 3257 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 3258 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_RTS; 3259 } 3260 } else 3261 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_MULTICAST;
| 3057 case ZYD_SET_CHANNEL: 3058 zyd_set_chan(sc, ic->ic_curchan); 3059 break;
|
3262
| 3060
|
3263 if ((wh->i_fc[0] & 3264 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == 3265 (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) 3266 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); 3267 3268 m->m_pkthdr.rcvif = (void *)ni; 3269 zyd_setup_desc_and_tx(sc, m, rate);
| 3061 default: /* ZYD_SCAN_END */ 3062 /* restore previous bssid */ 3063 zyd_set_bssid(sc, sc->sc_bssid); 3064 break; 3065 }
|
3270} 3271 3272static void
| 3066} 3067 3068static void
|
3273zyd_tx_data(struct zyd_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
| 3069zyd_queue_command(struct zyd_softc *sc, usb2_proc_callback_t *fn, 3070 struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
|
3274{
| 3071{
|
3275 struct ieee80211vap *vap = ni->ni_vap; 3276 struct ieee80211com *ic = ni->ni_ic; 3277 const struct ieee80211_txparam *tp; 3278 struct ieee80211_frame *wh; 3279 struct ieee80211_key *k; 3280 uint16_t rate;
| 3072 struct zyd_task *task;
|
3281
| 3073
|
3282 wh = mtod(m, struct ieee80211_frame *);
| 3074 ZYD_LOCK_ASSERT(sc, MA_OWNED);
|
3283
| 3075
|
3284 sc->sc_tx_desc.flags = ZYD_TX_FLAG_BACKOFF; 3285 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; 3286 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 3287 rate = tp->mcastrate; 3288 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_MULTICAST; 3289 } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { 3290 rate = tp->ucastrate; 3291 } else 3292 rate = ni->ni_txrate; 3293 3294 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 3295 k = ieee80211_crypto_encap(ni, m); 3296 if (k == NULL) { 3297 m_freem(m); 3298 ieee80211_free_node(ni); 3299 return; 3300 } 3301 /* packet header may have moved, reset our local pointer */ 3302 wh = mtod(m, struct ieee80211_frame *);
| 3076 if (usb2_proc_is_gone(&sc->sc_tq)) { 3077 DPRINTF(sc, ZYD_DEBUG_STATE, "proc is gone\n"); 3078 return; /* nothing to do */
|
3303 }
| 3079 }
|
3304 /* fill Tx descriptor */
| 3080 /* 3081 * NOTE: The task cannot get executed before we drop the 3082 * "sc_mtx" mutex. It is safe to update fields in the message 3083 * structure after that the message got queued. 3084 */ 3085 task = (struct zyd_task *) 3086 usb2_proc_msignal(&sc->sc_tq, t0, t1);
|
3305
| 3087
|
3306 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 3307 uint16_t totlen;
| 3088 /* Setup callback and softc pointers */ 3089 task->hdr.pm_callback = fn; 3090 task->sc = sc;
|
3308
| 3091
|
3309 totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; 3310 3311 /* multicast frames are not sent at OFDM rates in 802.11b/g */ 3312 if (totlen > vap->iv_rtsthreshold) { 3313 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_RTS; 3314 } else if (ZYD_RATE_IS_OFDM(rate) && 3315 (ic->ic_flags & IEEE80211_F_USEPROT)) { 3316 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 3317 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_CTS_TO_SELF; 3318 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 3319 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_RTS; 3320 } 3321 } 3322 if ((wh->i_fc[0] & 3323 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == 3324 (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) 3325 sc->sc_tx_desc.flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); 3326 3327 m->m_pkthdr.rcvif = (void *)ni; 3328 zyd_setup_desc_and_tx(sc, m, rate);
| 3092 /* 3093 * Init and stop must be synchronous! 3094 */ 3095 if ((fn == zyd_init_task) || (fn == zyd_stop_task)) 3096 usb2_proc_mwait(&sc->sc_tq, t0, t1);
|
3329} 3330
| 3097} 3098
|
3331static int 3332zyd_raw_xmit_cb(struct ieee80211_node *ni, struct mbuf *m, 3333 const struct ieee80211_bpf_params *params) 3334{ 3335 struct ieee80211com *ic = ni->ni_ic; 3336 struct ifnet *ifp = ic->ic_ifp; 3337 struct zyd_softc *sc = ifp->if_softc;
| 3099static device_method_t zyd_methods[] = { 3100 /* Device interface */ 3101 DEVMETHOD(device_probe, zyd_match), 3102 DEVMETHOD(device_attach, zyd_attach), 3103 DEVMETHOD(device_detach, zyd_detach), 3104 3105 { 0, 0 } 3106};
|
3338
| 3107
|
3339 mtx_lock(&sc->sc_mtx); 3340 if (params == NULL) { 3341 /* 3342 * Legacy path; interpret frame contents to decide 3343 * precisely how to send the frame. 3344 */ 3345 zyd_tx_mgt(sc, m, ni); 3346 } else { 3347 /* 3348 * Caller supplied explicit parameters to use in 3349 * sending the frame. 3350 */ 3351 zyd_tx_mgt(sc, m, ni); /* XXX zyd_tx_raw() */ 3352 } 3353 mtx_unlock(&sc->sc_mtx); 3354 return (0); 3355}
| 3108static driver_t zyd_driver = { 3109 "zyd", 3110 zyd_methods, 3111 sizeof(struct zyd_softc) 3112};
|
3356
| 3113
|
3357static struct ieee80211vap * 3358zyd_get_vap(struct zyd_softc *sc) 3359{ 3360 struct ifnet *ifp; 3361 struct ieee80211com *ic;
| 3114static devclass_t zyd_devclass;
|
3362
| 3115
|
3363 if (sc == NULL) { 3364 return NULL; 3365 } 3366 ifp = sc->sc_ifp; 3367 if (ifp == NULL) { 3368 return NULL; 3369 } 3370 ic = ifp->if_l2com; 3371 if (ic == NULL) { 3372 return NULL; 3373 } 3374 return TAILQ_FIRST(&ic->ic_vaps); 3375}
| 3116DRIVER_MODULE(zyd, ushub, zyd_driver, zyd_devclass, NULL, 0); 3117MODULE_DEPEND(zyd, usb2_wlan, 1, 1, 1); 3118MODULE_DEPEND(zyd, usb2_core, 1, 1, 1); 3119MODULE_DEPEND(zyd, wlan, 1, 1, 1); 3120MODULE_DEPEND(zyd, wlan_amrr, 1, 1, 1);
|
| |