| 1/* $FreeBSD: head/sys/dev/usb2/wlan/if_rum2.c 188417 2009-02-09 22:12:47Z thompsa $ */ 2
|
1/*- 2 * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr> 3 * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org> 4 * Copyright (c) 2007-2008 Hans Petter Selasky <hselasky@freebsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18
| 3/*- 4 * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr> 5 * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org> 6 * Copyright (c) 2007-2008 Hans Petter Selasky <hselasky@freebsd.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20
|
19/* 20 * NOTE: all function names beginning like "rum_cfg_" can only 21 * be called from within the config thread function ! 22 */ 23
| |
24#include <sys/cdefs.h>
| 21#include <sys/cdefs.h>
|
25__FBSDID("$FreeBSD: head/sys/dev/usb2/wlan/if_rum2.c 188234 2009-02-06 15:03:17Z kevlo $");
| 22__FBSDID("$FreeBSD: head/sys/dev/usb2/wlan/if_rum2.c 188417 2009-02-09 22:12:47Z thompsa $");
|
26 27/*- 28 * Ralink Technology RT2501USB/RT2601USB chipset driver 29 * http://www.ralinktech.com.tw/ 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
| 23 24/*- 25 * Ralink Technology RT2501USB/RT2601USB chipset driver 26 * http://www.ralinktech.com.tw/ 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 rum_config_copy 38#define usb2_config_td_softc rum_softc 39
| |
40#define USB_DEBUG_VAR rum_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#define USB_DEBUG_VAR rum_debug 35 36#include <dev/usb2/core/usb2_core.h> 37#include <dev/usb2/core/usb2_lookup.h> 38#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_rumreg.h> 53#include <dev/usb2/wlan/if_rumvar.h> 54#include <dev/usb2/wlan/if_rumfw.h> 55 56#if USB_DEBUG 57static int rum_debug = 0; 58 59SYSCTL_NODE(_hw_usb2, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum"); 60SYSCTL_INT(_hw_usb2_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0, 61 "Debug level"); 62#endif 63
| 39#include <dev/usb2/core/usb2_debug.h> 40#include <dev/usb2/core/usb2_request.h> 41#include <dev/usb2/core/usb2_busdma.h> 42#include <dev/usb2/core/usb2_util.h> 43 44#include <dev/usb2/wlan/usb2_wlan.h> 45#include <dev/usb2/wlan/if_rumreg.h> 46#include <dev/usb2/wlan/if_rumvar.h> 47#include <dev/usb2/wlan/if_rumfw.h> 48 49#if USB_DEBUG 50static int rum_debug = 0; 51 52SYSCTL_NODE(_hw_usb2, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum"); 53SYSCTL_INT(_hw_usb2_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0, 54 "Debug level"); 55#endif 56
|
64/* prototypes */
| 57#define rum_do_request(sc,req,data) \ 58 usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000)
|
65
| 59
|
66static device_probe_t rum_probe;
| 60static const struct usb2_device_id rum_devs[] = { 61 { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM) }, 62 { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2) }, 63 { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3) }, 64 { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4) }, 65 { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700) }, 66 { USB_VP(USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO) }, 67 { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1) }, 68 { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2) }, 69 { USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A) }, 70 { USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3) }, 71 { USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC) }, 72 { USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR) }, 73 { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2) }, 74 { USB_VP(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL) }, 75 { USB_VP(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX) }, 76 { USB_VP(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F) }, 77 { USB_VP(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573) }, 78 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1) }, 79 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340) }, 80 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111) }, 81 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110) }, 82 { USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS) }, 83 { USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS) }, 84 { USB_VP(USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573) }, 85 { USB_VP(USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573) }, 86 { USB_VP(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB) }, 87 { USB_VP(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP) }, 88 { USB_VP(USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G) }, 89 { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP) }, 90 { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP) }, 91 { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1) }, 92 { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2) }, 93 { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3) }, 94 { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4) }, 95 { USB_VP(USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573) }, 96 { USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP) }, 97 { USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2) }, 98 { USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM) }, 99 { USB_VP(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573) }, 100 { USB_VP(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2) }, 101 { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573) }, 102 { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2) }, 103 { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671) }, 104 { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2) }, 105 { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172) }, 106 { USB_VP(USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573) }, 107 { USB_VP(USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573) }, 108}; 109 110MODULE_DEPEND(rum, wlan, 1, 1, 1); 111MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1); 112MODULE_DEPEND(rum, usb2_wlan, 1, 1, 1); 113MODULE_DEPEND(rum, usb2_core, 1, 1, 1); 114 115static device_probe_t rum_match;
|
67static device_attach_t rum_attach; 68static device_detach_t rum_detach; 69 70static usb2_callback_t rum_bulk_read_callback;
| 116static device_attach_t rum_attach; 117static device_detach_t rum_detach; 118 119static usb2_callback_t rum_bulk_read_callback;
|
71static usb2_callback_t rum_bulk_read_clear_stall_callback;
| |
72static usb2_callback_t rum_bulk_write_callback;
| 120static usb2_callback_t rum_bulk_write_callback;
|
73static usb2_callback_t rum_bulk_write_clear_stall_callback;
| |
74
| 121
|
75static usb2_config_td_command_t rum_cfg_first_time_setup; 76static usb2_config_td_command_t rum_config_copy; 77static usb2_config_td_command_t rum_cfg_scan_start; 78static usb2_config_td_command_t rum_cfg_scan_end; 79static usb2_config_td_command_t rum_cfg_select_band; 80static usb2_config_td_command_t rum_cfg_set_chan; 81static usb2_config_td_command_t rum_cfg_enable_tsf_sync; 82static usb2_config_td_command_t rum_cfg_enable_mrr; 83static usb2_config_td_command_t rum_cfg_update_slot; 84static usb2_config_td_command_t rum_cfg_select_antenna; 85static usb2_config_td_command_t rum_cfg_set_txpreamble; 86static usb2_config_td_command_t rum_cfg_update_promisc; 87static usb2_config_td_command_t rum_cfg_pre_init; 88static usb2_config_td_command_t rum_cfg_init; 89static usb2_config_td_command_t rum_cfg_pre_stop; 90static usb2_config_td_command_t rum_cfg_stop; 91static usb2_config_td_command_t rum_cfg_amrr_timeout; 92static usb2_config_td_command_t rum_cfg_prepare_beacon; 93static usb2_config_td_command_t rum_cfg_newstate;
| 122static usb2_proc_callback_t rum_attach_post; 123static usb2_proc_callback_t rum_task; 124static usb2_proc_callback_t rum_scantask; 125static usb2_proc_callback_t rum_promisctask; 126static usb2_proc_callback_t rum_amrr_task; 127static usb2_proc_callback_t rum_init_task; 128static usb2_proc_callback_t rum_stop_task;
|
94
| 129
|
95static const char *rum_get_rf(uint32_t); 96static int rum_ioctl_cb(struct ifnet *, u_long, caddr_t); 97static void rum_std_command(struct ieee80211com *, usb2_config_td_command_t *); 98static void rum_scan_start_cb(struct ieee80211com *); 99static void rum_scan_end_cb(struct ieee80211com *); 100static void rum_set_channel_cb(struct ieee80211com *); 101static uint16_t rum_cfg_eeprom_read_2(struct rum_softc *, uint16_t); 102static uint32_t rum_cfg_bbp_disbusy(struct rum_softc *); 103static uint32_t rum_cfg_read(struct rum_softc *, uint16_t); 104static uint8_t rum_cfg_bbp_init(struct rum_softc *); 105static uint8_t rum_cfg_bbp_read(struct rum_softc *, uint8_t); 106static void rum_cfg_amrr_start(struct rum_softc *); 107static void rum_cfg_bbp_write(struct rum_softc *, uint8_t, uint8_t); 108static void rum_cfg_do_request(struct rum_softc *, 109 struct usb2_device_request *, void *); 110static void rum_cfg_eeprom_read(struct rum_softc *, uint16_t, void *, 111 uint16_t); 112static void rum_cfg_load_microcode(struct rum_softc *, const uint8_t *, 113 uint16_t); 114static void rum_cfg_read_eeprom(struct rum_softc *); 115static void rum_cfg_read_multi(struct rum_softc *, uint16_t, void *, 116 uint16_t); 117static void rum_cfg_rf_write(struct rum_softc *, uint8_t, uint32_t); 118static void rum_cfg_set_bssid(struct rum_softc *, uint8_t *); 119static void rum_cfg_set_macaddr(struct rum_softc *, uint8_t *); 120static void rum_cfg_write(struct rum_softc *, uint16_t, uint32_t); 121static void rum_cfg_write_multi(struct rum_softc *, uint16_t, void *, 122 uint16_t); 123static void rum_end_of_commands(struct rum_softc *); 124static void rum_init_cb(void *); 125static void rum_start_cb(struct ifnet *); 126static void rum_watchdog(void *); 127static uint8_t rum_get_rssi(struct rum_softc *, uint8_t);
| |
128static struct ieee80211vap *rum_vap_create(struct ieee80211com *,
| 130static struct ieee80211vap *rum_vap_create(struct ieee80211com *,
|
129 const char[], int, int, int, const uint8_t[], 130 const uint8_t[]); 131static void rum_vap_delete(struct ieee80211vap *);
| 131 const char name[IFNAMSIZ], int unit, int opmode, 132 int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], 133 const uint8_t mac[IEEE80211_ADDR_LEN]); 134static void rum_vap_delete(struct ieee80211vap *); 135static void rum_tx_free(struct rum_tx_data *, int); 136static void rum_setup_tx_list(struct rum_softc *); 137static void rum_unsetup_tx_list(struct rum_softc *); 138static int rum_newstate(struct ieee80211vap *, 139 enum ieee80211_state, int); 140static void rum_setup_tx_desc(struct rum_softc *, 141 struct rum_tx_desc *, uint32_t, uint16_t, int, 142 int); 143static int rum_tx_mgt(struct rum_softc *, struct mbuf *, 144 struct ieee80211_node *); 145static int rum_tx_raw(struct rum_softc *, struct mbuf *, 146 struct ieee80211_node *, 147 const struct ieee80211_bpf_params *); 148static int rum_tx_data(struct rum_softc *, struct mbuf *, 149 struct ieee80211_node *); 150static void rum_start(struct ifnet *); 151static int rum_ioctl(struct ifnet *, u_long, caddr_t); 152static void rum_eeprom_read(struct rum_softc *, uint16_t, void *, 153 int); 154static uint32_t rum_read(struct rum_softc *, uint16_t); 155static void rum_read_multi(struct rum_softc *, uint16_t, void *, 156 int); 157static void rum_write(struct rum_softc *, uint16_t, uint32_t); 158static void rum_write_multi(struct rum_softc *, uint16_t, void *, 159 size_t); 160static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t); 161static uint8_t rum_bbp_read(struct rum_softc *, uint8_t); 162static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t); 163static void rum_select_antenna(struct rum_softc *); 164static void rum_enable_mrr(struct rum_softc *); 165static void rum_set_txpreamble(struct rum_softc *); 166static void rum_set_basicrates(struct rum_softc *); 167static void rum_select_band(struct rum_softc *, 168 struct ieee80211_channel *); 169static void rum_set_chan(struct rum_softc *, 170 struct ieee80211_channel *); 171static void rum_enable_tsf_sync(struct rum_softc *); 172static void rum_update_slot(struct ifnet *); 173static void rum_set_bssid(struct rum_softc *, const uint8_t *); 174static void rum_set_macaddr(struct rum_softc *, const uint8_t *); 175static const char *rum_get_rf(int); 176static void rum_read_eeprom(struct rum_softc *); 177static int rum_bbp_init(struct rum_softc *); 178static void rum_init(void *); 179static int rum_load_microcode(struct rum_softc *, const u_char *, 180 size_t); 181static int rum_prepare_beacon(struct rum_softc *, 182 struct ieee80211vap *); 183static int rum_raw_xmit(struct ieee80211_node *, struct mbuf *, 184 const struct ieee80211_bpf_params *);
|
132static struct ieee80211_node *rum_node_alloc(struct ieee80211vap *,
| 185static struct ieee80211_node *rum_node_alloc(struct ieee80211vap *,
|
133 const uint8_t[]); 134static void rum_newassoc(struct ieee80211_node *, int); 135static void rum_cfg_disable_tsf_sync(struct rum_softc *); 136static void rum_cfg_set_run(struct rum_softc *, struct rum_config_copy *); 137static void rum_fill_write_queue(struct rum_softc *); 138static void rum_tx_clean_queue(struct rum_softc *); 139static void rum_tx_freem(struct mbuf *); 140static void rum_tx_mgt(struct rum_softc *, struct mbuf *, 141 struct ieee80211_node *); 142static struct ieee80211vap *rum_get_vap(struct rum_softc *); 143static void rum_tx_data(struct rum_softc *, struct mbuf *, 144 struct ieee80211_node *); 145static void rum_tx_prot(struct rum_softc *, const struct mbuf *, 146 struct ieee80211_node *, uint8_t, uint16_t); 147static void rum_tx_raw(struct rum_softc *, struct mbuf *, 148 struct ieee80211_node *, 149 const struct ieee80211_bpf_params *); 150static int rum_raw_xmit_cb(struct ieee80211_node *, struct mbuf *, 151 const struct ieee80211_bpf_params *); 152static void rum_setup_desc_and_tx(struct rum_softc *, struct mbuf *, 153 uint32_t, uint16_t, uint16_t); 154static int rum_newstate_cb(struct ieee80211vap *, 155 enum ieee80211_state nstate, int arg); 156static void rum_update_mcast_cb(struct ifnet *); 157static void rum_update_promisc_cb(struct ifnet *);
| 186 const uint8_t mac[IEEE80211_ADDR_LEN]); 187static void rum_newassoc(struct ieee80211_node *, int); 188static void rum_scan_start(struct ieee80211com *); 189static void rum_scan_end(struct ieee80211com *); 190static void rum_set_channel(struct ieee80211com *); 191static int rum_get_rssi(struct rum_softc *, uint8_t); 192static void rum_amrr_start(struct rum_softc *, 193 struct ieee80211_node *); 194static void rum_amrr_timeout(void *); 195static void rum_queue_command(struct rum_softc *, 196 usb2_proc_callback_t *, struct usb2_proc_msg *, 197 struct usb2_proc_msg *);
|
158
| 198
|
159/* various supported device vendors/products */ 160static const struct usb2_device_id rum_devs[] = { 161 {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM, 0)}, 162 {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2, 0)}, 163 {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3, 0)}, 164 {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4, 0)}, 165 {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700, 0)}, 166 {USB_VPI(USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO, 0)}, 167 {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1, 0)}, 168 {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2, 0)}, 169 {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A, 0)}, 170 {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3, 0)}, 171 {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC, 0)}, 172 {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR, 0)}, 173 {USB_VPI(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2, 0)}, 174 {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL, 0)}, 175 {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX, 0)}, 176 {USB_VPI(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F, 0)}, 177 {USB_VPI(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573, 0)}, 178 {USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1, 0)}, 179 {USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340, 0)}, 180 {USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111, 0)}, 181 {USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110, 0)}, 182 {USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS, 0)}, 183 {USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS, 0)}, 184 {USB_VPI(USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573, 0)}, 185 {USB_VPI(USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573, 0)}, 186 {USB_VPI(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB, 0)}, 187 {USB_VPI(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP, 0)}, 188 {USB_VPI(USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G, 0)}, 189 {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP, 0)}, 190 {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP, 0)}, 191 {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HG, 0)}, 192 {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1, 0)}, 193 {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2, 0)}, 194 {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3, 0)}, 195 {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4, 0)}, 196 {USB_VPI(USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573, 0)}, 197 {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP, 0)}, 198 {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2, 0)}, 199 {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM, 0)}, 200 {USB_VPI(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573, 0)}, 201 {USB_VPI(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2, 0)}, 202 {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573, 0)}, 203 {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2, 0)}, 204 {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671, 0)}, 205 {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2, 0)}, 206 {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172, 0)}, 207 {USB_VPI(USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573, 0)}, 208 {USB_VPI(USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573, 0)},
| 199static const struct { 200 uint32_t reg; 201 uint32_t val; 202} rum_def_mac[] = { 203 { RT2573_TXRX_CSR0, 0x025fb032 }, 204 { RT2573_TXRX_CSR1, 0x9eaa9eaf }, 205 { RT2573_TXRX_CSR2, 0x8a8b8c8d }, 206 { RT2573_TXRX_CSR3, 0x00858687 }, 207 { RT2573_TXRX_CSR7, 0x2e31353b }, 208 { RT2573_TXRX_CSR8, 0x2a2a2a2c }, 209 { RT2573_TXRX_CSR15, 0x0000000f }, 210 { RT2573_MAC_CSR6, 0x00000fff }, 211 { RT2573_MAC_CSR8, 0x016c030a }, 212 { RT2573_MAC_CSR10, 0x00000718 }, 213 { RT2573_MAC_CSR12, 0x00000004 }, 214 { RT2573_MAC_CSR13, 0x00007f00 }, 215 { RT2573_SEC_CSR0, 0x00000000 }, 216 { RT2573_SEC_CSR1, 0x00000000 }, 217 { RT2573_SEC_CSR5, 0x00000000 }, 218 { RT2573_PHY_CSR1, 0x000023b0 }, 219 { RT2573_PHY_CSR5, 0x00040a06 }, 220 { RT2573_PHY_CSR6, 0x00080606 }, 221 { RT2573_PHY_CSR7, 0x00000408 }, 222 { RT2573_AIFSN_CSR, 0x00002273 }, 223 { RT2573_CWMIN_CSR, 0x00002344 }, 224 { RT2573_CWMAX_CSR, 0x000034aa }
|
209}; 210
| 225}; 226
|
211struct rum_def_mac { 212 uint32_t reg; 213 uint32_t val; 214}; 215 216static const struct rum_def_mac rum_def_mac[] = { 217 {RT2573_TXRX_CSR0, 0x025fb032}, 218 {RT2573_TXRX_CSR1, 0x9eaa9eaf}, 219 {RT2573_TXRX_CSR2, 0x8a8b8c8d}, 220 {RT2573_TXRX_CSR3, 0x00858687}, 221 {RT2573_TXRX_CSR7, 0x2e31353b}, 222 {RT2573_TXRX_CSR8, 0x2a2a2a2c}, 223 {RT2573_TXRX_CSR15, 0x0000000f}, 224 {RT2573_MAC_CSR6, 0x00000fff}, 225 {RT2573_MAC_CSR8, 0x016c030a}, 226 {RT2573_MAC_CSR10, 0x00000718}, 227 {RT2573_MAC_CSR12, 0x00000004}, 228 {RT2573_MAC_CSR13, 0x00007f00}, 229 {RT2573_SEC_CSR0, 0x00000000}, 230 {RT2573_SEC_CSR1, 0x00000000}, 231 {RT2573_SEC_CSR5, 0x00000000}, 232 {RT2573_PHY_CSR1, 0x000023b0}, 233 {RT2573_PHY_CSR5, 0x00040a06}, 234 {RT2573_PHY_CSR6, 0x00080606}, 235 {RT2573_PHY_CSR7, 0x00000408}, 236 {RT2573_AIFSN_CSR, 0x00002273}, 237 {RT2573_CWMIN_CSR, 0x00002344}, 238 {RT2573_CWMAX_CSR, 0x000034aa} 239}; 240 241struct rum_def_bbp {
| 227static const struct {
|
242 uint8_t reg; 243 uint8_t val;
| 228 uint8_t reg; 229 uint8_t val;
|
| 230} rum_def_bbp[] = { 231 { 3, 0x80 }, 232 { 15, 0x30 }, 233 { 17, 0x20 }, 234 { 21, 0xc8 }, 235 { 22, 0x38 }, 236 { 23, 0x06 }, 237 { 24, 0xfe }, 238 { 25, 0x0a }, 239 { 26, 0x0d }, 240 { 32, 0x0b }, 241 { 34, 0x12 }, 242 { 37, 0x07 }, 243 { 39, 0xf8 }, 244 { 41, 0x60 }, 245 { 53, 0x10 }, 246 { 54, 0x18 }, 247 { 60, 0x10 }, 248 { 61, 0x04 }, 249 { 62, 0x04 }, 250 { 75, 0xfe }, 251 { 86, 0xfe }, 252 { 88, 0xfe }, 253 { 90, 0x0f }, 254 { 99, 0x00 }, 255 { 102, 0x16 }, 256 { 107, 0x04 }
|
244}; 245
| 257}; 258
|
246static const struct rum_def_bbp rum_def_bbp[] = { 247 {3, 0x80}, 248 {15, 0x30}, 249 {17, 0x20}, 250 {21, 0xc8}, 251 {22, 0x38}, 252 {23, 0x06}, 253 {24, 0xfe}, 254 {25, 0x0a}, 255 {26, 0x0d}, 256 {32, 0x0b}, 257 {34, 0x12}, 258 {37, 0x07}, 259 {39, 0xf8}, 260 {41, 0x60}, 261 {53, 0x10}, 262 {54, 0x18}, 263 {60, 0x10}, 264 {61, 0x04}, 265 {62, 0x04}, 266 {75, 0xfe}, 267 {86, 0xfe}, 268 {88, 0xfe}, 269 {90, 0x0f}, 270 {99, 0x00}, 271 {102, 0x16}, 272 {107, 0x04} 273};
| 259static const struct rfprog { 260 uint8_t chan; 261 uint32_t r1, r2, r3, r4; 262} rum_rf5226[] = { 263 { 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 }, 264 { 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 }, 265 { 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 }, 266 { 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 }, 267 { 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 }, 268 { 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 }, 269 { 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 }, 270 { 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 }, 271 { 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 }, 272 { 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 }, 273 { 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 }, 274 { 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 }, 275 { 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 }, 276 { 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
|
274
| 277
|
275struct rfprog { 276 uint8_t chan; 277 uint32_t r1, r2, r3, r4; 278};
| 278 { 34, 0x00b03, 0x20266, 0x36014, 0x30282 }, 279 { 38, 0x00b03, 0x20267, 0x36014, 0x30284 }, 280 { 42, 0x00b03, 0x20268, 0x36014, 0x30286 }, 281 { 46, 0x00b03, 0x20269, 0x36014, 0x30288 },
|
279
| 282
|
280static const struct rfprog rum_rf5226[] = { 281 {1, 0x00b03, 0x001e1, 0x1a014, 0x30282}, 282 {2, 0x00b03, 0x001e1, 0x1a014, 0x30287}, 283 {3, 0x00b03, 0x001e2, 0x1a014, 0x30282}, 284 {4, 0x00b03, 0x001e2, 0x1a014, 0x30287}, 285 {5, 0x00b03, 0x001e3, 0x1a014, 0x30282}, 286 {6, 0x00b03, 0x001e3, 0x1a014, 0x30287}, 287 {7, 0x00b03, 0x001e4, 0x1a014, 0x30282}, 288 {8, 0x00b03, 0x001e4, 0x1a014, 0x30287}, 289 {9, 0x00b03, 0x001e5, 0x1a014, 0x30282}, 290 {10, 0x00b03, 0x001e5, 0x1a014, 0x30287}, 291 {11, 0x00b03, 0x001e6, 0x1a014, 0x30282}, 292 {12, 0x00b03, 0x001e6, 0x1a014, 0x30287}, 293 {13, 0x00b03, 0x001e7, 0x1a014, 0x30282}, 294 {14, 0x00b03, 0x001e8, 0x1a014, 0x30284},
| 283 { 36, 0x00b03, 0x00266, 0x26014, 0x30288 }, 284 { 40, 0x00b03, 0x00268, 0x26014, 0x30280 }, 285 { 44, 0x00b03, 0x00269, 0x26014, 0x30282 }, 286 { 48, 0x00b03, 0x0026a, 0x26014, 0x30284 }, 287 { 52, 0x00b03, 0x0026b, 0x26014, 0x30286 }, 288 { 56, 0x00b03, 0x0026c, 0x26014, 0x30288 }, 289 { 60, 0x00b03, 0x0026e, 0x26014, 0x30280 }, 290 { 64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
|
295
| 291
|
296 {34, 0x00b03, 0x20266, 0x36014, 0x30282}, 297 {38, 0x00b03, 0x20267, 0x36014, 0x30284}, 298 {42, 0x00b03, 0x20268, 0x36014, 0x30286}, 299 {46, 0x00b03, 0x20269, 0x36014, 0x30288},
| 292 { 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 }, 293 { 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 }, 294 { 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 }, 295 { 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 }, 296 { 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 }, 297 { 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 }, 298 { 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 }, 299 { 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 }, 300 { 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 }, 301 { 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 }, 302 { 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
|
300
| 303
|
301 {36, 0x00b03, 0x00266, 0x26014, 0x30288}, 302 {40, 0x00b03, 0x00268, 0x26014, 0x30280}, 303 {44, 0x00b03, 0x00269, 0x26014, 0x30282}, 304 {48, 0x00b03, 0x0026a, 0x26014, 0x30284}, 305 {52, 0x00b03, 0x0026b, 0x26014, 0x30286}, 306 {56, 0x00b03, 0x0026c, 0x26014, 0x30288}, 307 {60, 0x00b03, 0x0026e, 0x26014, 0x30280}, 308 {64, 0x00b03, 0x0026f, 0x26014, 0x30282},
| 304 { 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 }, 305 { 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 }, 306 { 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 }, 307 { 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 }, 308 { 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 } 309}, rum_rf5225[] = { 310 { 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 }, 311 { 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 }, 312 { 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 }, 313 { 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 }, 314 { 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 }, 315 { 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 }, 316 { 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 }, 317 { 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 }, 318 { 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 }, 319 { 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 }, 320 { 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 }, 321 { 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 }, 322 { 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 }, 323 { 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
|
309
| 324
|
310 {100, 0x00b03, 0x0028a, 0x2e014, 0x30280}, 311 {104, 0x00b03, 0x0028b, 0x2e014, 0x30282}, 312 {108, 0x00b03, 0x0028c, 0x2e014, 0x30284}, 313 {112, 0x00b03, 0x0028d, 0x2e014, 0x30286}, 314 {116, 0x00b03, 0x0028e, 0x2e014, 0x30288}, 315 {120, 0x00b03, 0x002a0, 0x2e014, 0x30280}, 316 {124, 0x00b03, 0x002a1, 0x2e014, 0x30282}, 317 {128, 0x00b03, 0x002a2, 0x2e014, 0x30284}, 318 {132, 0x00b03, 0x002a3, 0x2e014, 0x30286}, 319 {136, 0x00b03, 0x002a4, 0x2e014, 0x30288}, 320 {140, 0x00b03, 0x002a6, 0x2e014, 0x30280},
| 325 { 34, 0x00b33, 0x01266, 0x26014, 0x30282 }, 326 { 38, 0x00b33, 0x01267, 0x26014, 0x30284 }, 327 { 42, 0x00b33, 0x01268, 0x26014, 0x30286 }, 328 { 46, 0x00b33, 0x01269, 0x26014, 0x30288 },
|
321
| 329
|
322 {149, 0x00b03, 0x002a8, 0x2e014, 0x30287}, 323 {153, 0x00b03, 0x002a9, 0x2e014, 0x30289}, 324 {157, 0x00b03, 0x002ab, 0x2e014, 0x30281}, 325 {161, 0x00b03, 0x002ac, 0x2e014, 0x30283}, 326 {165, 0x00b03, 0x002ad, 0x2e014, 0x30285} 327};
| 330 { 36, 0x00b33, 0x01266, 0x26014, 0x30288 }, 331 { 40, 0x00b33, 0x01268, 0x26014, 0x30280 }, 332 { 44, 0x00b33, 0x01269, 0x26014, 0x30282 }, 333 { 48, 0x00b33, 0x0126a, 0x26014, 0x30284 }, 334 { 52, 0x00b33, 0x0126b, 0x26014, 0x30286 }, 335 { 56, 0x00b33, 0x0126c, 0x26014, 0x30288 }, 336 { 60, 0x00b33, 0x0126e, 0x26014, 0x30280 }, 337 { 64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
|
328
| 338
|
329static const struct rfprog rum_rf5225[] = { 330 {1, 0x00b33, 0x011e1, 0x1a014, 0x30282}, 331 {2, 0x00b33, 0x011e1, 0x1a014, 0x30287}, 332 {3, 0x00b33, 0x011e2, 0x1a014, 0x30282}, 333 {4, 0x00b33, 0x011e2, 0x1a014, 0x30287}, 334 {5, 0x00b33, 0x011e3, 0x1a014, 0x30282}, 335 {6, 0x00b33, 0x011e3, 0x1a014, 0x30287}, 336 {7, 0x00b33, 0x011e4, 0x1a014, 0x30282}, 337 {8, 0x00b33, 0x011e4, 0x1a014, 0x30287}, 338 {9, 0x00b33, 0x011e5, 0x1a014, 0x30282}, 339 {10, 0x00b33, 0x011e5, 0x1a014, 0x30287}, 340 {11, 0x00b33, 0x011e6, 0x1a014, 0x30282}, 341 {12, 0x00b33, 0x011e6, 0x1a014, 0x30287}, 342 {13, 0x00b33, 0x011e7, 0x1a014, 0x30282}, 343 {14, 0x00b33, 0x011e8, 0x1a014, 0x30284},
| 339 { 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 }, 340 { 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 }, 341 { 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 }, 342 { 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 }, 343 { 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 }, 344 { 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 }, 345 { 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 }, 346 { 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 }, 347 { 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 }, 348 { 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 }, 349 { 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
|
344
| 350
|
345 {34, 0x00b33, 0x01266, 0x26014, 0x30282}, 346 {38, 0x00b33, 0x01267, 0x26014, 0x30284}, 347 {42, 0x00b33, 0x01268, 0x26014, 0x30286}, 348 {46, 0x00b33, 0x01269, 0x26014, 0x30288}, 349 350 {36, 0x00b33, 0x01266, 0x26014, 0x30288}, 351 {40, 0x00b33, 0x01268, 0x26014, 0x30280}, 352 {44, 0x00b33, 0x01269, 0x26014, 0x30282}, 353 {48, 0x00b33, 0x0126a, 0x26014, 0x30284}, 354 {52, 0x00b33, 0x0126b, 0x26014, 0x30286}, 355 {56, 0x00b33, 0x0126c, 0x26014, 0x30288}, 356 {60, 0x00b33, 0x0126e, 0x26014, 0x30280}, 357 {64, 0x00b33, 0x0126f, 0x26014, 0x30282}, 358 359 {100, 0x00b33, 0x0128a, 0x2e014, 0x30280}, 360 {104, 0x00b33, 0x0128b, 0x2e014, 0x30282}, 361 {108, 0x00b33, 0x0128c, 0x2e014, 0x30284}, 362 {112, 0x00b33, 0x0128d, 0x2e014, 0x30286}, 363 {116, 0x00b33, 0x0128e, 0x2e014, 0x30288}, 364 {120, 0x00b33, 0x012a0, 0x2e014, 0x30280}, 365 {124, 0x00b33, 0x012a1, 0x2e014, 0x30282}, 366 {128, 0x00b33, 0x012a2, 0x2e014, 0x30284}, 367 {132, 0x00b33, 0x012a3, 0x2e014, 0x30286}, 368 {136, 0x00b33, 0x012a4, 0x2e014, 0x30288}, 369 {140, 0x00b33, 0x012a6, 0x2e014, 0x30280}, 370 371 {149, 0x00b33, 0x012a8, 0x2e014, 0x30287}, 372 {153, 0x00b33, 0x012a9, 0x2e014, 0x30289}, 373 {157, 0x00b33, 0x012ab, 0x2e014, 0x30281}, 374 {161, 0x00b33, 0x012ac, 0x2e014, 0x30283}, 375 {165, 0x00b33, 0x012ad, 0x2e014, 0x30285}
| 351 { 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 }, 352 { 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 }, 353 { 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 }, 354 { 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 }, 355 { 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
|
376}; 377 378static const struct usb2_config rum_config[RUM_N_TRANSFER] = {
| 356}; 357 358static const struct usb2_config rum_config[RUM_N_TRANSFER] = {
|
379 [RUM_BULK_DT_WR] = {
| 359 [RUM_BULK_WR] = {
|
380 .type = UE_BULK, 381 .endpoint = UE_ADDR_ANY, 382 .direction = UE_DIR_OUT, 383 .mh.bufsize = (MCLBYTES + RT2573_TX_DESC_SIZE + 8), 384 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
| 360 .type = UE_BULK, 361 .endpoint = UE_ADDR_ANY, 362 .direction = UE_DIR_OUT, 363 .mh.bufsize = (MCLBYTES + RT2573_TX_DESC_SIZE + 8), 364 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
|
385 .mh.callback = &rum_bulk_write_callback,
| 365 .mh.callback = rum_bulk_write_callback,
|
386 .mh.timeout = 5000, /* ms */ 387 },
| 366 .mh.timeout = 5000, /* ms */ 367 },
|
388 389 [RUM_BULK_DT_RD] = {
| 368 [RUM_BULK_RD] = {
|
390 .type = UE_BULK, 391 .endpoint = UE_ADDR_ANY, 392 .direction = UE_DIR_IN, 393 .mh.bufsize = (MCLBYTES + RT2573_RX_DESC_SIZE), 394 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
| 369 .type = UE_BULK, 370 .endpoint = UE_ADDR_ANY, 371 .direction = UE_DIR_IN, 372 .mh.bufsize = (MCLBYTES + RT2573_RX_DESC_SIZE), 373 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
|
395 .mh.callback = &rum_bulk_read_callback,
| 374 .mh.callback = rum_bulk_read_callback,
|
396 },
| 375 },
|
397 398 [RUM_BULK_CS_WR] = { 399 .type = UE_CONTROL, 400 .endpoint = 0x00, /* Control pipe */ 401 .direction = UE_DIR_ANY, 402 .mh.bufsize = sizeof(struct usb2_device_request), 403 .mh.callback = &rum_bulk_write_clear_stall_callback, 404 .mh.timeout = 1000, /* 1 second */ 405 .mh.interval = 50, /* 50ms */ 406 }, 407 408 [RUM_BULK_CS_RD] = { 409 .type = UE_CONTROL, 410 .endpoint = 0x00, /* Control pipe */ 411 .direction = UE_DIR_ANY, 412 .mh.bufsize = sizeof(struct usb2_device_request), 413 .mh.callback = &rum_bulk_read_clear_stall_callback, 414 .mh.timeout = 1000, /* 1 second */ 415 .mh.interval = 50, /* 50ms */ 416 },
| |
417}; 418
| 376}; 377
|
419static devclass_t rum_devclass; 420 421static device_method_t rum_methods[] = { 422 DEVMETHOD(device_probe, rum_probe), 423 DEVMETHOD(device_attach, rum_attach), 424 DEVMETHOD(device_detach, rum_detach), 425 {0, 0} 426}; 427 428static driver_t rum_driver = { 429 .name = "rum", 430 .methods = rum_methods, 431 .size = sizeof(struct rum_softc), 432}; 433 434DRIVER_MODULE(rum, ushub, rum_driver, rum_devclass, NULL, 0); 435MODULE_DEPEND(rum, usb2_wlan, 1, 1, 1); 436MODULE_DEPEND(rum, usb2_core, 1, 1, 1); 437MODULE_DEPEND(rum, wlan, 1, 1, 1); 438MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1); 439
| |
440static int
| 378static int
|
441rum_probe(device_t dev)
| 379rum_match(device_t self)
|
442{
| 380{
|
443 struct usb2_attach_arg *uaa = device_get_ivars(dev);
| 381 struct usb2_attach_arg *uaa = device_get_ivars(self);
|
444
| 382
|
445 if (uaa->usb2_mode != USB_MODE_HOST) {
| 383 if (uaa->usb2_mode != USB_MODE_HOST)
|
446 return (ENXIO);
| 384 return (ENXIO);
|
447 } 448 if (uaa->info.bConfigIndex != 0) {
| 385 if (uaa->info.bConfigIndex != 0)
|
449 return (ENXIO);
| 386 return (ENXIO);
|
450 } 451 if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX) {
| 387 if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX)
|
452 return (ENXIO);
| 388 return (ENXIO);
|
453 }
| 389
|
454 return (usb2_lookup_id_by_uaa(rum_devs, sizeof(rum_devs), uaa)); 455} 456 457static int
| 390 return (usb2_lookup_id_by_uaa(rum_devs, sizeof(rum_devs), uaa)); 391} 392 393static int
|
458rum_attach(device_t dev)
| 394rum_attach(device_t self)
|
459{
| 395{
|
460 struct usb2_attach_arg *uaa = device_get_ivars(dev); 461 struct rum_softc *sc = device_get_softc(dev); 462 int error;
| 396 struct usb2_attach_arg *uaa = device_get_ivars(self); 397 struct rum_softc *sc = device_get_softc(self);
|
463 uint8_t iface_index;
| 398 uint8_t iface_index;
|
| 399 int error;
|
464
| 400
|
465 device_set_usb2_desc(dev); 466 467 mtx_init(&sc->sc_mtx, "rum lock", MTX_NETWORK_LOCK, 468 MTX_DEF | MTX_RECURSE); 469 470 snprintf(sc->sc_name, sizeof(sc->sc_name), "%s", 471 device_get_nameunit(dev)); 472
| 401 device_set_usb2_desc(self);
|
473 sc->sc_udev = uaa->device;
| 402 sc->sc_udev = uaa->device;
|
474 sc->sc_unit = device_get_unit(dev);
| 403 sc->sc_dev = self;
|
475
| 404
|
476 usb2_callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
| 405 mtx_init(&sc->sc_mtx, device_get_nameunit(self), 406 MTX_NETWORK_LOCK, MTX_DEF);
|
477 478 iface_index = RT2573_IFACE_INDEX; 479 error = usb2_transfer_setup(uaa->device, &iface_index, 480 sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx); 481 if (error) {
| 407 408 iface_index = RT2573_IFACE_INDEX; 409 error = usb2_transfer_setup(uaa->device, &iface_index, 410 sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx); 411 if (error) {
|
482 device_printf(dev, "could not allocate USB transfers, "
| 412 device_printf(self, "could not allocate USB transfers, "
|
483 "err=%s\n", usb2_errstr(error)); 484 goto detach; 485 }
| 413 "err=%s\n", usb2_errstr(error)); 414 goto detach; 415 }
|
486 error = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_mtx, 487 &rum_end_of_commands, 488 sizeof(struct usb2_config_td_cc), 24);
| 416 error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx, 417 device_get_nameunit(self), USB_PRI_MED);
|
489 if (error) {
| 418 if (error) {
|
490 device_printf(dev, "could not setup config " 491 "thread!\n");
| 419 device_printf(self, "could not setup config thread!\n");
|
492 goto detach; 493 }
| 420 goto detach; 421 }
|
494 mtx_lock(&sc->sc_mtx);
| |
495
| 422
|
496 /* start setup */
| 423 /* fork rest of the attach code */ 424 RUM_LOCK(sc); 425 rum_queue_command(sc, rum_attach_post, 426 &sc->sc_synctask[0].hdr, 427 &sc->sc_synctask[1].hdr); 428 RUM_UNLOCK(sc); 429 return (0);
|
497
| 430
|
498 usb2_config_td_queue_command 499 (&sc->sc_config_td, NULL, &rum_cfg_first_time_setup, 0, 0); 500 501 rum_watchdog(sc); 502 mtx_unlock(&sc->sc_mtx); 503 return (0); /* success */ 504
| |
505detach:
| 431detach:
|
506 rum_detach(dev);
| 432 rum_detach(self);
|
507 return (ENXIO); /* failure */ 508} 509
| 433 return (ENXIO); /* failure */ 434} 435
|
510static int 511rum_detach(device_t dev)
| 436static void 437rum_attach_post(struct usb2_proc_msg *pm)
|
512{
| 438{
|
513 struct rum_softc *sc = device_get_softc(dev); 514 struct ieee80211com *ic;
| 439 struct rum_task *task = (struct rum_task *)pm; 440 struct rum_softc *sc = task->sc;
|
515 struct ifnet *ifp;
| 441 struct ifnet *ifp;
|
| 442 struct ieee80211com *ic; 443 unsigned int ntries; 444 int error; 445 uint32_t tmp; 446 uint8_t bands;
|
516
| 447
|
517 usb2_config_td_drain(&sc->sc_config_td);
| 448 /* retrieve RT2573 rev. no */ 449 for (ntries = 0; ntries != 1000; ntries++) { 450 if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0) 451 break; 452 usb2_pause_mtx(&sc->sc_mtx, hz / 1000); 453 } 454 if (ntries == 1000) { 455 device_printf(sc->sc_dev, "timeout waiting for chip to settle\n"); 456 return; 457 }
|
518
| 458
|
519 mtx_lock(&sc->sc_mtx);
| 459 /* retrieve MAC address and various other things from EEPROM */ 460 rum_read_eeprom(sc);
|
520
| 461
|
521 usb2_callout_stop(&sc->sc_watchdog);
| 462 device_printf(sc->sc_dev, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n", 463 tmp, rum_get_rf(sc->rf_rev));
|
522
| 464
|
523 rum_cfg_pre_stop(sc, NULL, 0);
| 465 error = rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); 466 if (error != 0) { 467 RUM_UNLOCK(sc); 468 device_printf(sc->sc_dev, "could not load 8051 microcode\n"); 469 return; 470 } 471 RUM_UNLOCK(sc);
|
524
| 472
|
525 ifp = sc->sc_ifp;
| 473 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 474 if (ifp == NULL) { 475 device_printf(sc->sc_dev, "can not if_alloc()\n"); 476 RUM_LOCK(sc); 477 return; 478 }
|
526 ic = ifp->if_l2com; 527
| 479 ic = ifp->if_l2com; 480
|
528 mtx_unlock(&sc->sc_mtx);
| 481 ifp->if_softc = sc; 482 if_initname(ifp, "rum", device_get_unit(sc->sc_dev)); 483 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 484 ifp->if_init = rum_init; 485 ifp->if_ioctl = rum_ioctl; 486 ifp->if_start = rum_start; 487 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 488 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 489 IFQ_SET_READY(&ifp->if_snd);
|
529
| 490
|
530 /* stop all USB transfers first */ 531 usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
| 491 ic->ic_ifp = ifp; 492 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 493 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
|
532
| 494
|
533 /* get rid of any late children */ 534 bus_generic_detach(dev);
| 495 /* set device capabilities */ 496 ic->ic_caps = 497 IEEE80211_C_STA /* station mode supported */ 498 | IEEE80211_C_IBSS /* IBSS mode supported */ 499 | IEEE80211_C_MONITOR /* monitor mode supported */ 500 | IEEE80211_C_HOSTAP /* HostAp mode supported */ 501 | IEEE80211_C_TXPMGT /* tx power management */ 502 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 503 | IEEE80211_C_SHSLOT /* short slot time supported */ 504 | IEEE80211_C_BGSCAN /* bg scanning supported */ 505 | IEEE80211_C_WPA /* 802.11i */ 506 ;
|
535
| 507
|
536 if (ifp) { 537 bpfdetach(ifp); 538 ieee80211_ifdetach(ic); 539 if_free(ifp); 540 } 541 usb2_config_td_unsetup(&sc->sc_config_td);
| 508 bands = 0; 509 setbit(&bands, IEEE80211_MODE_11B); 510 setbit(&bands, IEEE80211_MODE_11G); 511 if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) 512 setbit(&bands, IEEE80211_MODE_11A); 513 ieee80211_init_channels(ic, NULL, &bands);
|
542
| 514
|
543 usb2_callout_drain(&sc->sc_watchdog);
| 515 ieee80211_ifattach(ic); 516 ic->ic_newassoc = rum_newassoc; 517 ic->ic_raw_xmit = rum_raw_xmit; 518 ic->ic_node_alloc = rum_node_alloc; 519 ic->ic_scan_start = rum_scan_start; 520 ic->ic_scan_end = rum_scan_end; 521 ic->ic_set_channel = rum_set_channel;
|
544
| 522
|
545 mtx_destroy(&sc->sc_mtx);
| 523 ic->ic_vap_create = rum_vap_create; 524 ic->ic_vap_delete = rum_vap_delete;
|
546
| 525
|
547 return (0); 548}
| 526 sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
|
549
| 527
|
550static void 551rum_cfg_do_request(struct rum_softc *sc, struct usb2_device_request *req, 552 void *data) 553{ 554 uint16_t length; 555 usb2_error_t err;
| 528 bpfattach(ifp, DLT_IEEE802_11_RADIO, 529 sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
|
556
| 530
|
557repeat:
| 531 sc->sc_rxtap_len = sizeof sc->sc_rxtap; 532 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 533 sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
|
558
| 534
|
559 if (usb2_config_td_is_gone(&sc->sc_config_td)) { 560 goto error; 561 } 562 err = usb2_do_request_flags 563 (sc->sc_udev, &sc->sc_mtx, req, data, 0, NULL, 1000);
| 535 sc->sc_txtap_len = sizeof sc->sc_txtap; 536 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 537 sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
|
564
| 538
|
565 if (err) {
| 539 if (bootverbose) 540 ieee80211_announce(ic);
|
566
| 541
|
567 DPRINTF("device request failed, err=%s " 568 "(ignored)\n", usb2_errstr(err)); 569 570 /* wait a little before next try */ 571 if (usb2_config_td_sleep(&sc->sc_config_td, hz / 4)) { 572 goto error; 573 } 574 /* try until we are detached */ 575 goto repeat; 576 577error: 578 /* the device has been detached */ 579 length = UGETW(req->wLength); 580 581 if ((req->bmRequestType & UT_READ) && length) { 582 bzero(data, length); 583 } 584 }
| 542 RUM_LOCK(sc);
|
585} 586
| 543} 544
|
587static void 588rum_cfg_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, uint16_t len)
| 545static int 546rum_detach(device_t self)
|
589{
| 547{
|
590 struct usb2_device_request req;
| 548 struct rum_softc *sc = device_get_softc(self); 549 struct ifnet *ifp = sc->sc_ifp; 550 struct ieee80211com *ic = ifp->if_l2com;
|
591
| 551
|
592 req.bmRequestType = UT_READ_VENDOR_DEVICE; 593 req.bRequest = RT2573_READ_EEPROM; 594 USETW(req.wValue, 0); 595 USETW(req.wIndex, addr); 596 USETW(req.wLength, len);
| 552 /* wait for any post attach or other command to complete */ 553 usb2_proc_drain(&sc->sc_tq);
|
597
| 554
|
598 rum_cfg_do_request(sc, &req, buf); 599}
| 555 /* stop all USB transfers */ 556 usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER); 557 usb2_proc_free(&sc->sc_tq);
|
600
| 558
|
601static uint16_t 602rum_cfg_eeprom_read_2(struct rum_softc *sc, uint16_t addr) 603{ 604 uint16_t tmp;
| 559 /* free TX list, if any */ 560 RUM_LOCK(sc); 561 rum_unsetup_tx_list(sc); 562 RUM_UNLOCK(sc);
|
605
| 563
|
606 rum_cfg_eeprom_read(sc, addr, &tmp, sizeof(tmp)); 607 return (le16toh(tmp)); 608}
| 564 if (ifp) { 565 bpfdetach(ifp); 566 ieee80211_ifdetach(ic); 567 if_free(ifp); 568 }
|
609
| 569
|
610static uint32_t 611rum_cfg_read(struct rum_softc *sc, uint16_t reg) 612{ 613 uint32_t val;
| 570 mtx_destroy(&sc->sc_mtx);
|
614
| 571
|
615 rum_cfg_read_multi(sc, reg, &val, sizeof(val)); 616 return (le32toh(val));
| 572 return (0);
|
617} 618
| 573} 574
|
619static void 620rum_cfg_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, uint16_t len)
| 575static struct ieee80211vap * 576rum_vap_create(struct ieee80211com *ic, 577 const char name[IFNAMSIZ], int unit, int opmode, int flags, 578 const uint8_t bssid[IEEE80211_ADDR_LEN], 579 const uint8_t mac[IEEE80211_ADDR_LEN])
|
621{
| 580{
|
622 struct usb2_device_request req;
| 581 struct rum_softc *sc = ic->ic_ifp->if_softc; 582 struct rum_vap *rvp; 583 struct ieee80211vap *vap;
|
623
| 584
|
624 req.bmRequestType = UT_READ_VENDOR_DEVICE; 625 req.bRequest = RT2573_READ_MULTI_MAC; 626 USETW(req.wValue, 0); 627 USETW(req.wIndex, reg); 628 USETW(req.wLength, len);
| 585 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 586 return NULL; 587 rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap), 588 M_80211_VAP, M_NOWAIT | M_ZERO); 589 if (rvp == NULL) 590 return NULL; 591 vap = &rvp->vap; 592 /* enable s/w bmiss handling for sta mode */ 593 ieee80211_vap_setup(ic, vap, name, unit, opmode, 594 flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
|
629
| 595
|
630 rum_cfg_do_request(sc, &req, buf); 631}
| 596 /* override state transition machine */ 597 rvp->newstate = vap->iv_newstate; 598 vap->iv_newstate = rum_newstate;
|
632
| 599
|
633static void 634rum_cfg_write(struct rum_softc *sc, uint16_t reg, uint32_t val) 635{ 636 uint32_t tmp = htole32(val);
| 600 rvp->sc = sc; 601 usb2_callout_init_mtx(&rvp->amrr_ch, &sc->sc_mtx, 0); 602 ieee80211_amrr_init(&rvp->amrr, vap, 603 IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, 604 IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, 605 1000 /* 1 sec */);
|
637
| 606
|
638 rum_cfg_write_multi(sc, reg, &tmp, sizeof(tmp));
| 607 /* complete setup */ 608 ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); 609 ic->ic_opmode = opmode; 610 return vap;
|
639} 640 641static void
| 611} 612 613static void
|
642rum_cfg_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, uint16_t len)
| 614rum_vap_delete(struct ieee80211vap *vap)
|
643{
| 615{
|
644 struct usb2_device_request req;
| 616 struct rum_vap *rvp = RUM_VAP(vap);
|
645
| 617
|
646 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 647 req.bRequest = RT2573_WRITE_MULTI_MAC; 648 USETW(req.wValue, 0); 649 USETW(req.wIndex, reg); 650 USETW(req.wLength, len); 651 652 rum_cfg_do_request(sc, &req, buf);
| 618 usb2_callout_drain(&rvp->amrr_ch); 619 ieee80211_amrr_cleanup(&rvp->amrr); 620 ieee80211_vap_detach(vap); 621 free(rvp, M_80211_VAP);
|
653} 654
| 622} 623
|
655static uint32_t 656rum_cfg_bbp_disbusy(struct rum_softc *sc)
| 624static void 625rum_tx_free(struct rum_tx_data *data, int txerr)
|
657{
| 626{
|
658 uint32_t tmp; 659 uint8_t to;
| 627 struct rum_softc *sc = data->sc;
|
660
| 628
|
661 for (to = 0;; to++) { 662 if (to < 100) { 663 tmp = rum_cfg_read(sc, RT2573_PHY_CSR3);
| 629 if (data->m != NULL) { 630 if (data->m->m_flags & M_TXCB) 631 ieee80211_process_callback(data->ni, data->m, 632 txerr ? ETIMEDOUT : 0); 633 m_freem(data->m); 634 data->m = NULL;
|
664
| 635
|
665 if ((tmp & RT2573_BBP_BUSY) == 0) { 666 return (tmp); 667 } 668 if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 669 break; 670 } 671 } else { 672 break; 673 }
| 636 ieee80211_free_node(data->ni); 637 data->ni = NULL;
|
674 }
| 638 }
|
675 DPRINTF("could not disbusy BBP\n"); 676 return (RT2573_BBP_BUSY); /* failure */
| 639 STAILQ_INSERT_TAIL(&sc->tx_free, data, next); 640 sc->tx_nfree++;
|
677} 678 679static void
| 641} 642 643static void
|
680rum_cfg_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
| 644rum_setup_tx_list(struct rum_softc *sc)
|
681{
| 645{
|
682 uint32_t tmp;
| 646 struct rum_tx_data *data; 647 int i;
|
683
| 648
|
684 if (rum_cfg_bbp_disbusy(sc) & RT2573_BBP_BUSY) { 685 return; 686 } 687 tmp = RT2573_BBP_BUSY | ((reg & 0x7f) << 8) | val; 688 rum_cfg_write(sc, RT2573_PHY_CSR3, tmp); 689}
| 649 sc->tx_nfree = 0; 650 STAILQ_INIT(&sc->tx_q); 651 STAILQ_INIT(&sc->tx_free);
|
690
| 652
|
691static uint8_t 692rum_cfg_bbp_read(struct rum_softc *sc, uint8_t reg) 693{ 694 uint32_t val;
| 653 for (i = 0; i < RUM_TX_LIST_COUNT; i++) { 654 data = &sc->tx_data[i];
|
695
| 655
|
696 if (rum_cfg_bbp_disbusy(sc) & RT2573_BBP_BUSY) { 697 return (0);
| 656 data->sc = sc; 657 STAILQ_INSERT_TAIL(&sc->tx_free, data, next); 658 sc->tx_nfree++;
|
698 }
| 659 }
|
699 val = RT2573_BBP_BUSY | RT2573_BBP_READ | (reg << 8); 700 rum_cfg_write(sc, RT2573_PHY_CSR3, val); 701 702 val = rum_cfg_bbp_disbusy(sc); 703 return (val & 0xff);
| |
704} 705 706static void
| 660} 661 662static void
|
707rum_cfg_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
| 663rum_unsetup_tx_list(struct rum_softc *sc)
|
708{
| 664{
|
709 uint32_t tmp; 710 uint8_t to;
| 665 struct rum_tx_data *data; 666 int i;
|
711
| 667
|
712 reg &= 3;
| 668 /* make sure any subsequent use of the queues will fail */ 669 sc->tx_nfree = 0; 670 STAILQ_INIT(&sc->tx_q); 671 STAILQ_INIT(&sc->tx_free);
|
713
| 672
|
714 for (to = 0;; to++) { 715 if (to < 100) { 716 tmp = rum_cfg_read(sc, RT2573_PHY_CSR4); 717 if (!(tmp & RT2573_RF_BUSY)) { 718 break; 719 } 720 if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 721 return; 722 } 723 } else { 724 DPRINTF("could not write to RF\n"); 725 return;
| 673 /* free up all node references and mbufs */ 674 for (i = 0; i < RUM_TX_LIST_COUNT; i++) { 675 data = &sc->tx_data[i]; 676 677 if (data->m != NULL) { 678 m_freem(data->m); 679 data->m = NULL;
|
726 }
| 680 }
|
| 681 if (data->ni != NULL) { 682 ieee80211_free_node(data->ni); 683 data->ni = NULL; 684 }
|
727 }
| 685 }
|
728 729 tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | ((val & 0xfffff) << 2) | reg; 730 rum_cfg_write(sc, RT2573_PHY_CSR4, tmp); 731 732 DPRINTFN(16, "RF R[%u] <- 0x%05x\n", reg, val & 0xfffff);
| |
733} 734 735static void
| 686} 687 688static void
|
736rum_cfg_first_time_setup(struct rum_softc *sc, 737 struct usb2_config_td_cc *cc, uint16_t refcount)
| 689rum_task(struct usb2_proc_msg *pm)
|
738{
| 690{
|
739 struct ieee80211com *ic; 740 struct ifnet *ifp;
| 691 struct rum_task *task = (struct rum_task *)pm; 692 struct rum_softc *sc = task->sc; 693 struct ifnet *ifp = sc->sc_ifp; 694 struct ieee80211com *ic = ifp->if_l2com; 695 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 696 struct rum_vap *rvp = RUM_VAP(vap); 697 const struct ieee80211_txparam *tp; 698 enum ieee80211_state ostate; 699 struct ieee80211_node *ni;
|
741 uint32_t tmp;
| 700 uint32_t tmp;
|
742 uint16_t i; 743 uint8_t bands;
| |
744
| 701
|
745 /* setup RX tap header */ 746 sc->sc_rxtap_len = sizeof(sc->sc_rxtap); 747 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 748 sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
| 702 ostate = vap->iv_state;
|
749
| 703
|
750 /* setup TX tap header */ 751 sc->sc_txtap_len = sizeof(sc->sc_txtap); 752 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 753 sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
| 704 switch (sc->sc_state) { 705 case IEEE80211_S_INIT: 706 if (ostate == IEEE80211_S_RUN) { 707 /* abort TSF synchronization */ 708 tmp = rum_read(sc, RT2573_TXRX_CSR9); 709 rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); 710 } 711 break;
|
754
| 712
|
755 /* retrieve RT2573 rev. no */ 756 for (i = 0; i < 100; i++) {
| 713 case IEEE80211_S_RUN: 714 ni = vap->iv_bss;
|
757
| 715
|
758 tmp = rum_cfg_read(sc, RT2573_MAC_CSR0); 759 if (tmp != 0) { 760 break;
| 716 if (vap->iv_opmode != IEEE80211_M_MONITOR) { 717 rum_update_slot(ic->ic_ifp); 718 rum_enable_mrr(sc); 719 rum_set_txpreamble(sc); 720 rum_set_basicrates(sc); 721 IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); 722 rum_set_bssid(sc, sc->sc_bssid);
|
761 }
| 723 }
|
762 /* wait a little */ 763 if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 764 /* device detached */ 765 goto done; 766 } 767 }
| |
768
| 724
|
769 if (tmp == 0) { 770 DPRINTF("chip is maybe not ready\n"); 771 } 772 /* retrieve MAC address and various other things from EEPROM */ 773 rum_cfg_read_eeprom(sc);
| 725 if (vap->iv_opmode == IEEE80211_M_HOSTAP || 726 vap->iv_opmode == IEEE80211_M_IBSS) 727 rum_prepare_beacon(sc, vap);
|
774
| 728
|
775 printf("%s: MAC/BBP RT2573 (rev 0x%05x), RF %s\n", 776 sc->sc_name, tmp, rum_get_rf(sc->sc_rf_rev));
| 729 if (vap->iv_opmode != IEEE80211_M_MONITOR) 730 rum_enable_tsf_sync(sc);
|
777
| 731
|
778 rum_cfg_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); 779 780 mtx_unlock(&sc->sc_mtx); 781 782 ifp = if_alloc(IFT_IEEE80211); 783 784 mtx_lock(&sc->sc_mtx); 785 786 if (ifp == NULL) { 787 DPRINTFN(0, "could not if_alloc()!\n"); 788 goto done;
| 732 /* enable automatic rate adaptation */ 733 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; 734 if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) 735 rum_amrr_start(sc, ni); 736 break; 737 default: 738 break;
|
789 }
| 739 }
|
790 sc->sc_ifp = ifp; 791 ic = ifp->if_l2com;
| |
792
| 740
|
793 ifp->if_softc = sc; 794 if_initname(ifp, "rum", sc->sc_unit); 795 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 796 ifp->if_init = &rum_init_cb; 797 ifp->if_ioctl = &rum_ioctl_cb; 798 ifp->if_start = &rum_start_cb; 799 ifp->if_watchdog = NULL; 800 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 801 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 802 IFQ_SET_READY(&ifp->if_snd);
| 741 RUM_UNLOCK(sc); 742 IEEE80211_LOCK(ic); 743 rvp->newstate(vap, sc->sc_state, sc->sc_arg); 744 if (vap->iv_newstate_cb != NULL) 745 vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); 746 IEEE80211_UNLOCK(ic); 747 RUM_LOCK(sc); 748}
|
803
| 749
|
804 bcopy(sc->sc_myaddr, ic->ic_myaddr, sizeof(ic->ic_myaddr));
| 750static int 751rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 752{ 753 struct rum_vap *rvp = RUM_VAP(vap); 754 struct ieee80211com *ic = vap->iv_ic; 755 struct rum_softc *sc = ic->ic_ifp->if_softc;
|
805
| 756
|
806 ic->ic_ifp = ifp; 807 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 808 ic->ic_opmode = IEEE80211_M_STA;
| 757 DPRINTF("%s -> %s\n", 758 ieee80211_state_name[vap->iv_state], 759 ieee80211_state_name[nstate]);
|
809
| 760
|
810 /* set device capabilities */ 811 ic->ic_caps = 812 IEEE80211_C_STA /* station mode supported */ 813 | IEEE80211_C_IBSS /* IBSS mode supported */ 814 | IEEE80211_C_MONITOR /* monitor mode supported */ 815 | IEEE80211_C_HOSTAP /* HostAp mode supported */ 816 | IEEE80211_C_TXPMGT /* tx power management */ 817 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 818 | IEEE80211_C_SHSLOT /* short slot time supported */ 819 | IEEE80211_C_BGSCAN /* bg scanning supported */ 820 | IEEE80211_C_WPA /* 802.11i */ 821 ;
| 761 RUM_LOCK(sc); 762 usb2_callout_stop(&rvp->amrr_ch);
|
822
| 763
|
823 bands = 0; 824 setbit(&bands, IEEE80211_MODE_11B); 825 setbit(&bands, IEEE80211_MODE_11G); 826 ieee80211_init_channels(ic, NULL, &bands);
| 764 /* do it in a process context */ 765 sc->sc_state = nstate; 766 sc->sc_arg = arg; 767 RUM_UNLOCK(sc);
|
827
| 768
|
828 if ((sc->sc_rf_rev == RT2573_RF_5225) || 829 (sc->sc_rf_rev == RT2573_RF_5226)) { 830 831 struct ieee80211_channel *c; 832 833 /* set supported .11a channels */ 834 for (i = 34; i <= 46; i += 4) { 835 c = ic->ic_channels + (ic->ic_nchans++); 836 c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); 837 c->ic_flags = IEEE80211_CHAN_A; 838 c->ic_ieee = i; 839 } 840 for (i = 36; i <= 64; i += 4) { 841 c = ic->ic_channels + (ic->ic_nchans++); 842 c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); 843 c->ic_flags = IEEE80211_CHAN_A; 844 c->ic_ieee = i; 845 } 846 for (i = 100; i <= 140; i += 4) { 847 c = ic->ic_channels + (ic->ic_nchans++); 848 c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); 849 c->ic_flags = IEEE80211_CHAN_A; 850 c->ic_ieee = i; 851 } 852 for (i = 149; i <= 165; i += 4) { 853 c = ic->ic_channels + (ic->ic_nchans++); 854 c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); 855 c->ic_flags = IEEE80211_CHAN_A; 856 c->ic_ieee = i; 857 }
| 769 if (nstate == IEEE80211_S_INIT) { 770 rvp->newstate(vap, nstate, arg); 771 return 0; 772 } else { 773 RUM_LOCK(sc); 774 rum_queue_command(sc, rum_task, &sc->sc_task[0].hdr, 775 &sc->sc_task[1].hdr); 776 RUM_UNLOCK(sc); 777 return EINPROGRESS;
|
858 }
| 778 }
|
859 mtx_unlock(&sc->sc_mtx);
| 779}
|
860
| 780
|
861 ieee80211_ifattach(ic);
| 781static void 782rum_bulk_write_callback(struct usb2_xfer *xfer) 783{ 784 struct rum_softc *sc = xfer->priv_sc; 785 struct ifnet *ifp = sc->sc_ifp; 786 struct ieee80211com *ic = ifp->if_l2com; 787 struct ieee80211_channel *c = ic->ic_curchan; 788 struct rum_tx_data *data; 789 struct mbuf *m; 790 unsigned int len;
|
862
| 791
|
863 mtx_lock(&sc->sc_mtx);
| 792 switch (USB_GET_STATE(xfer)) { 793 case USB_ST_TRANSFERRED: 794 DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen);
|
864
| 795
|
865 ic->ic_newassoc = &rum_newassoc; 866 ic->ic_raw_xmit = &rum_raw_xmit_cb; 867 ic->ic_node_alloc = &rum_node_alloc; 868 ic->ic_update_mcast = &rum_update_mcast_cb; 869 ic->ic_update_promisc = &rum_update_promisc_cb; 870 ic->ic_scan_start = &rum_scan_start_cb; 871 ic->ic_scan_end = &rum_scan_end_cb; 872 ic->ic_set_channel = &rum_set_channel_cb; 873 ic->ic_vap_create = &rum_vap_create; 874 ic->ic_vap_delete = &rum_vap_delete;
| 796 /* free resources */ 797 data = xfer->priv_fifo; 798 rum_tx_free(data, 0); 799 xfer->priv_fifo = NULL;
|
875
| 800
|
876 sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
| 801 ifp->if_opackets++; 802 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
877
| 803
|
878 mtx_unlock(&sc->sc_mtx);
| 804 /* FALLTHROUGH */ 805 case USB_ST_SETUP: 806tr_setup: 807 data = STAILQ_FIRST(&sc->tx_q); 808 if (data) { 809 STAILQ_REMOVE_HEAD(&sc->tx_q, next); 810 m = data->m;
|
879
| 811
|
880 bpfattach(ifp, DLT_IEEE802_11_RADIO, 881 sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap));
| 812 if (m->m_pkthdr.len > (MCLBYTES + RT2573_TX_DESC_SIZE)) { 813 DPRINTFN(0, "data overflow, %u bytes\n", 814 m->m_pkthdr.len); 815 m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE); 816 } 817 usb2_copy_in(xfer->frbuffers, 0, &data->desc, 818 RT2573_TX_DESC_SIZE); 819 usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m, 820 0, m->m_pkthdr.len);
|
882
| 821
|
883 if (bootverbose) { 884 ieee80211_announce(ic); 885 } 886 mtx_lock(&sc->sc_mtx); 887done: 888 return; 889}
| 822 if (bpf_peers_present(ifp->if_bpf)) { 823 struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
|
890
| 824
|
891static void 892rum_end_of_commands(struct rum_softc *sc) 893{ 894 sc->sc_flags &= ~RUM_FLAG_WAIT_COMMAND;
| 825 tap->wt_flags = 0; 826 tap->wt_rate = data->rate; 827 tap->wt_chan_freq = htole16(c->ic_freq); 828 tap->wt_chan_flags = htole16(c->ic_flags); 829 tap->wt_antenna = sc->tx_ant;
|
895
| 830
|
896 /* start write transfer, if not started */ 897 usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]); 898}
| 831 bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); 832 }
|
899
| 833
|
900static void 901rum_config_copy_chan(struct rum_config_copy_chan *cc, 902 struct ieee80211com *ic, struct ieee80211_channel *c) 903{ 904 if (!c) 905 return; 906 cc->chan_to_ieee = 907 ieee80211_chan2ieee(ic, c); 908 if (c != IEEE80211_CHAN_ANYC) { 909 cc->chan_to_mode = 910 ieee80211_chan2mode(c); 911 if (IEEE80211_IS_CHAN_B(c)) 912 cc->chan_is_b = 1; 913 if (IEEE80211_IS_CHAN_A(c)) 914 cc->chan_is_a = 1; 915 if (IEEE80211_IS_CHAN_2GHZ(c)) 916 cc->chan_is_2ghz = 1; 917 if (IEEE80211_IS_CHAN_5GHZ(c)) 918 cc->chan_is_5ghz = 1; 919 if (IEEE80211_IS_CHAN_ANYG(c)) 920 cc->chan_is_g = 1; 921 } 922}
| 834 /* align end on a 4-bytes boundary */ 835 len = (RT2573_TX_DESC_SIZE + m->m_pkthdr.len + 3) & ~3; 836 if ((len % 64) == 0) 837 len += 4;
|
923
| 838
|
924static void 925rum_config_copy(struct rum_softc *sc, 926 struct usb2_config_td_cc *cc, uint16_t refcount) 927{ 928 struct ifnet *ifp; 929 struct ieee80211com *ic; 930 struct ieee80211_node *ni; 931 struct ieee80211vap *vap; 932 const struct ieee80211_txparam *tp;
| 839 DPRINTFN(11, "sending frame len=%u xferlen=%u\n", 840 m->m_pkthdr.len, len);
|
933
| 841
|
934 bzero(cc, sizeof(*cc));
| 842 xfer->frlengths[0] = len; 843 xfer->priv_fifo = data;
|
935
| 844
|
936 ifp = sc->sc_ifp; 937 if (ifp) { 938 cc->if_flags = ifp->if_flags; 939 bcopy(ifp->if_broadcastaddr, cc->if_broadcastaddr, 940 sizeof(cc->if_broadcastaddr));
| 845 usb2_start_hardware(xfer); 846 } 847 break;
|
941
| 848
|
942 ic = ifp->if_l2com; 943 if (ic) { 944 rum_config_copy_chan(&cc->ic_curchan, ic, ic->ic_curchan); 945 rum_config_copy_chan(&cc->ic_bsschan, ic, ic->ic_bsschan); 946 vap = TAILQ_FIRST(&ic->ic_vaps); 947 if (vap) { 948 ni = vap->iv_bss; 949 if (ni) { 950 cc->iv_bss.ni_intval = ni->ni_intval; 951 bcopy(ni->ni_bssid, cc->iv_bss.ni_bssid, 952 sizeof(cc->iv_bss.ni_bssid)); 953 } 954 tp = vap->iv_txparms + cc->ic_bsschan.chan_to_mode; 955 if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { 956 cc->iv_bss.fixed_rate_none = 1; 957 } 958 } 959 cc->ic_opmode = ic->ic_opmode; 960 cc->ic_flags = ic->ic_flags; 961 cc->ic_txpowlimit = ic->ic_txpowlimit; 962 cc->ic_curmode = ic->ic_curmode;
| 849 default: /* Error */ 850 DPRINTFN(11, "transfer error, %s\n", 851 usb2_errstr(xfer->error));
|
963
| 852
|
964 bcopy(ic->ic_myaddr, cc->ic_myaddr, 965 sizeof(cc->ic_myaddr));
| 853 ifp->if_oerrors++; 854 data = xfer->priv_fifo; 855 if (data != NULL) { 856 rum_tx_free(data, xfer->error); 857 xfer->priv_fifo = NULL;
|
966 }
| 858 }
|
967 } 968 sc->sc_flags |= RUM_FLAG_WAIT_COMMAND; 969}
| |
970
| 859
|
971static const char * 972rum_get_rf(uint32_t rev) 973{ 974 ; /* indent fix */ 975 switch (rev) { 976 case RT2573_RF_2527: 977 return "RT2527 (MIMO XR)"; 978 case RT2573_RF_2528: 979 return "RT2528"; 980 case RT2573_RF_5225: 981 return "RT5225 (MIMO XR)"; 982 case RT2573_RF_5226: 983 return "RT5226"; 984 default: 985 return "unknown";
| 860 if (xfer->error == USB_ERR_STALLED) { 861 /* try to clear stall first */ 862 xfer->flags.stall_pipe = 1; 863 goto tr_setup; 864 } 865 if (xfer->error == USB_ERR_TIMEOUT) 866 device_printf(sc->sc_dev, "device timeout\n"); 867 break;
|
986 } 987} 988 989static void 990rum_bulk_read_callback(struct usb2_xfer *xfer) 991{ 992 struct rum_softc *sc = xfer->priv_sc; 993 struct ifnet *ifp = sc->sc_ifp; 994 struct ieee80211com *ic = ifp->if_l2com; 995 struct ieee80211_node *ni;
| 868 } 869} 870 871static void 872rum_bulk_read_callback(struct usb2_xfer *xfer) 873{ 874 struct rum_softc *sc = xfer->priv_sc; 875 struct ifnet *ifp = sc->sc_ifp; 876 struct ieee80211com *ic = ifp->if_l2com; 877 struct ieee80211_node *ni;
|
996
| |
997 struct mbuf *m = NULL; 998 uint32_t flags;
| 878 struct mbuf *m = NULL; 879 uint32_t flags;
|
999 uint32_t max_len;
| |
1000 uint8_t rssi = 0;
| 880 uint8_t rssi = 0;
|
| 881 unsigned int len;
|
1001 1002 switch (USB_GET_STATE(xfer)) { 1003 case USB_ST_TRANSFERRED: 1004 1005 DPRINTFN(15, "rx done, actlen=%d\n", xfer->actlen); 1006
| 882 883 switch (USB_GET_STATE(xfer)) { 884 case USB_ST_TRANSFERRED: 885 886 DPRINTFN(15, "rx done, actlen=%d\n", xfer->actlen); 887
|
1007 if (xfer->actlen < (RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN)) { 1008 DPRINTF("too short transfer, " 1009 "%d bytes\n", xfer->actlen);
| 888 len = xfer->actlen; 889 if (len < RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN) { 890 DPRINTF("%s: xfer too short %d\n", 891 device_get_nameunit(sc->sc_dev), len);
|
1010 ifp->if_ierrors++; 1011 goto tr_setup; 1012 }
| 892 ifp->if_ierrors++; 893 goto tr_setup; 894 }
|
1013 usb2_copy_out(xfer->frbuffers, 0, 1014 &sc->sc_rx_desc, RT2573_RX_DESC_SIZE);
| |
1015
| 895
|
1016 flags = le32toh(sc->sc_rx_desc.flags);
| 896 len -= RT2573_RX_DESC_SIZE; 897 usb2_copy_out(xfer->frbuffers, 0, &sc->sc_rx_desc, 898 RT2573_RX_DESC_SIZE);
|
1017
| 899
|
| 900 rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi); 901 flags = le32toh(sc->sc_rx_desc.flags);
|
1018 if (flags & RT2573_RX_CRC_ERROR) { 1019 /* 1020 * This should not happen since we did not 1021 * request to receive those frames when we
| 902 if (flags & RT2573_RX_CRC_ERROR) { 903 /* 904 * This should not happen since we did not 905 * request to receive those frames when we
|
1022 * filled RAL_TXRX_CSR2:
| 906 * filled RUM_TXRX_CSR2:
|
1023 */
| 907 */
|
1024 DPRINTFN(6, "PHY or CRC error\n");
| 908 DPRINTFN(5, "PHY or CRC error\n");
|
1025 ifp->if_ierrors++; 1026 goto tr_setup; 1027 }
| 909 ifp->if_ierrors++; 910 goto tr_setup; 911 }
|
1028 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
| |
1029
| 912
|
| 913 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
1030 if (m == NULL) { 1031 DPRINTF("could not allocate mbuf\n"); 1032 ifp->if_ierrors++; 1033 goto tr_setup; 1034 }
| 914 if (m == NULL) { 915 DPRINTF("could not allocate mbuf\n"); 916 ifp->if_ierrors++; 917 goto tr_setup; 918 }
|
1035 max_len = (xfer->actlen - RT2573_RX_DESC_SIZE); 1036
| |
1037 usb2_copy_out(xfer->frbuffers, RT2573_RX_DESC_SIZE,
| 919 usb2_copy_out(xfer->frbuffers, RT2573_RX_DESC_SIZE,
|
1038 m->m_data, max_len);
| 920 mtod(m, uint8_t *), len);
|
1039 1040 /* finalize mbuf */ 1041 m->m_pkthdr.rcvif = ifp; 1042 m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; 1043
| 921 922 /* finalize mbuf */ 923 m->m_pkthdr.rcvif = ifp; 924 m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; 925
|
1044 if (m->m_len > max_len) { 1045 DPRINTF("invalid length in RX " 1046 "descriptor, %u bytes, received %u bytes\n", 1047 m->m_len, max_len); 1048 ifp->if_ierrors++; 1049 m_freem(m); 1050 m = NULL; 1051 goto tr_setup; 1052 } 1053 rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi); 1054 1055 DPRINTF("real length=%d bytes, rssi=%d\n", m->m_len, rssi); 1056
| |
1057 if (bpf_peers_present(ifp->if_bpf)) { 1058 struct rum_rx_radiotap_header *tap = &sc->sc_rxtap; 1059 1060 tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; 1061 tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
| 926 if (bpf_peers_present(ifp->if_bpf)) { 927 struct rum_rx_radiotap_header *tap = &sc->sc_rxtap; 928 929 tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; 930 tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
|
1062 (sc->sc_rx_desc.flags & htole32(RT2573_RX_OFDM)) ?
| 931 (flags & RT2573_RX_OFDM) ?
|
1063 IEEE80211_T_OFDM : IEEE80211_T_CCK); 1064 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); 1065 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
| 932 IEEE80211_T_OFDM : IEEE80211_T_CCK); 933 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); 934 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
1066 tap->wr_antenna = sc->sc_rx_ant;
| 935 tap->wr_antenna = sc->rx_ant;
|
1067 tap->wr_antsignal = rssi; 1068 1069 bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); 1070 }
| 936 tap->wr_antsignal = rssi; 937 938 bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); 939 }
|
| 940 /* FALLTHROUGH */
|
1071 case USB_ST_SETUP: 1072tr_setup:
| 941 case USB_ST_SETUP: 942tr_setup:
|
| 943 xfer->frlengths[0] = xfer->max_data_length; 944 usb2_start_hardware(xfer);
|
1073
| 945
|
1074 if (sc->sc_flags & RUM_FLAG_READ_STALL) { 1075 usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_RD]); 1076 } else { 1077 xfer->frlengths[0] = xfer->max_data_length; 1078 usb2_start_hardware(xfer); 1079 } 1080
| |
1081 /* 1082 * At the end of a USB callback it is always safe to unlock 1083 * the private mutex of a device! That is why we do the 1084 * "ieee80211_input" here, and not some lines up! 1085 */ 1086 if (m) {
| 946 /* 947 * At the end of a USB callback it is always safe to unlock 948 * the private mutex of a device! That is why we do the 949 * "ieee80211_input" here, and not some lines up! 950 */ 951 if (m) {
|
1087 mtx_unlock(&sc->sc_mtx); 1088 1089 ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
| 952 RUM_UNLOCK(sc); 953 ni = ieee80211_find_rxnode(ic, 954 mtod(m, struct ieee80211_frame_min *));
|
1090 if (ni != NULL) {
| 955 if (ni != NULL) {
|
1091 if (ieee80211_input(ni, m, rssi, RT2573_NOISE_FLOOR, 0)) { 1092 /* ignore */ 1093 } 1094 /* node is no longer needed */
| 956 (void) ieee80211_input(ni, m, rssi, 957 RT2573_NOISE_FLOOR, 0);
|
1095 ieee80211_free_node(ni);
| 958 ieee80211_free_node(ni);
|
1096 } else { 1097 if (ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR, 0)) { 1098 /* ignore */ 1099 } 1100 } 1101 1102 mtx_lock(&sc->sc_mtx);
| 959 } else 960 (void) ieee80211_input_all(ic, m, rssi, 961 RT2573_NOISE_FLOOR, 0); 962 RUM_LOCK(sc);
|
1103 } 1104 return; 1105 1106 default: /* Error */ 1107 if (xfer->error != USB_ERR_CANCELLED) { 1108 /* try to clear stall first */
| 963 } 964 return; 965 966 default: /* Error */ 967 if (xfer->error != USB_ERR_CANCELLED) { 968 /* try to clear stall first */
|
1109 sc->sc_flags |= RUM_FLAG_READ_STALL; 1110 usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_RD]);
| 969 xfer->flags.stall_pipe = 1; 970 goto tr_setup;
|
1111 } 1112 return;
| 971 } 972 return;
|
1113
| |
1114 } 1115} 1116
| 973 } 974} 975
|
1117static void 1118rum_bulk_read_clear_stall_callback(struct usb2_xfer *xfer) 1119{ 1120 struct rum_softc *sc = xfer->priv_sc; 1121 struct usb2_xfer *xfer_other = sc->sc_xfer[RUM_BULK_DT_RD]; 1122 1123 if (usb2_clear_stall_callback(xfer, xfer_other)) { 1124 DPRINTF("stall cleared\n"); 1125 sc->sc_flags &= ~RUM_FLAG_READ_STALL; 1126 usb2_transfer_start(xfer_other); 1127 } 1128} 1129
| |
1130static uint8_t
| 976static uint8_t
|
1131rum_plcp_signal(uint16_t rate)
| 977rum_plcp_signal(int rate)
|
1132{
| 978{
|
1133 ; /* indent fix */
| |
1134 switch (rate) {
| 979 switch (rate) {
|
1135 /* CCK rates (NB: not IEEE std, device-specific) */ 1136 case 2: 1137 return (0x0); 1138 case 4: 1139 return (0x1); 1140 case 11: 1141 return (0x2); 1142 case 22: 1143 return (0x3);
| 980 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 981 case 12: return 0xb; 982 case 18: return 0xf; 983 case 24: return 0xa; 984 case 36: return 0xe; 985 case 48: return 0x9; 986 case 72: return 0xd; 987 case 96: return 0x8; 988 case 108: return 0xc;
|
1144
| 989
|
1145 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 1146 case 12: 1147 return (0xb); 1148 case 18: 1149 return (0xf); 1150 case 24: 1151 return (0xa); 1152 case 36: 1153 return (0xe); 1154 case 48: 1155 return (0x9); 1156 case 72: 1157 return (0xd); 1158 case 96: 1159 return (0x8); 1160 case 108: 1161 return (0xc); 1162 1163 /* XXX unsupported/unknown rate */ 1164 default: 1165 return (0xff);
| 990 /* CCK rates (NB: not IEEE std, device-specific) */ 991 case 2: return 0x0; 992 case 4: return 0x1; 993 case 11: return 0x2; 994 case 22: return 0x3;
|
1166 }
| 995 }
|
| 996 return 0xff; /* XXX unsupported/unknown rate */
|
1167} 1168
| 997} 998
|
1169/* 1170 * We assume that "m->m_pkthdr.rcvif" is pointing to the "ni" that 1171 * should be freed, when "rum_setup_desc_and_tx" is called. 1172 */ 1173
| |
1174static void
| 999static void
|
1175rum_setup_desc_and_tx(struct rum_softc *sc, struct mbuf *m, uint32_t flags, 1176 uint16_t xflags, uint16_t rate)
| 1000rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, 1001 uint32_t flags, uint16_t xflags, int len, int rate)
|
1177{ 1178 struct ifnet *ifp = sc->sc_ifp; 1179 struct ieee80211com *ic = ifp->if_l2com;
| 1002{ 1003 struct ifnet *ifp = sc->sc_ifp; 1004 struct ieee80211com *ic = ifp->if_l2com;
|
1180 struct mbuf *mm; 1181 enum ieee80211_phytype phytype;
| |
1182 uint16_t plcp_length;
| 1005 uint16_t plcp_length;
|
1183 uint16_t len; 1184 uint8_t remainder; 1185 uint8_t is_beacon;
| 1006 int remainder;
|
1186
| 1007
|
1187 if (xflags & RT2573_TX_BEACON) { 1188 xflags &= ~RT2573_TX_BEACON; 1189 is_beacon = 1; 1190 } else { 1191 is_beacon = 0; 1192 }
| 1008 desc->flags = htole32(flags); 1009 desc->flags |= htole32(RT2573_TX_VALID); 1010 desc->flags |= htole32(len << 16);
|
1193
| 1011
|
1194 if (sc->sc_tx_queue.ifq_len >= IFQ_MAXLEN) { 1195 /* free packet */ 1196 rum_tx_freem(m); 1197 ifp->if_oerrors++; 1198 return; 1199 } 1200 if (!((sc->sc_flags & RUM_FLAG_LL_READY) && 1201 (sc->sc_flags & RUM_FLAG_HL_READY))) { 1202 /* free packet */ 1203 rum_tx_freem(m); 1204 ifp->if_oerrors++; 1205 return; 1206 } 1207 if (rate < 2) { 1208 DPRINTF("rate < 2!\n");
| 1012 desc->xflags = htole16(xflags);
|
1209
| 1013
|
1210 /* avoid division by zero */ 1211 rate = 2; 1212 } 1213 ic->ic_lastdata = ticks; 1214 if (bpf_peers_present(ifp->if_bpf)) { 1215 struct rum_tx_radiotap_header *tap = &sc->sc_txtap; 1216 1217 tap->wt_flags = 0; 1218 tap->wt_rate = rate; 1219 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); 1220 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); 1221 tap->wt_antenna = sc->sc_tx_ant; 1222 1223 bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); 1224 } 1225 len = m->m_pkthdr.len; 1226 1227 flags |= RT2573_TX_VALID; 1228 flags |= (len << 16); 1229 1230 sc->sc_tx_desc.flags = htole32(flags); 1231 sc->sc_tx_desc.xflags = htole16(xflags); 1232 1233 sc->sc_tx_desc.wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
| 1014 desc->wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
|
1234 RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10)); 1235 1236 /* setup PLCP fields */
| 1015 RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10)); 1016 1017 /* setup PLCP fields */
|
1237 sc->sc_tx_desc.plcp_signal = rum_plcp_signal(rate); 1238 sc->sc_tx_desc.plcp_service = 4;
| 1018 desc->plcp_signal = rum_plcp_signal(rate); 1019 desc->plcp_service = 4;
|
1239 1240 len += IEEE80211_CRC_LEN;
| 1020 1021 len += IEEE80211_CRC_LEN;
|
| 1022 if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) { 1023 desc->flags |= htole32(RT2573_TX_OFDM);
|
1241
| 1024
|
1242 phytype = ieee80211_rate2phytype(sc->sc_rates, rate); 1243 1244 if (phytype == IEEE80211_T_OFDM) { 1245 sc->sc_tx_desc.flags |= htole32(RT2573_TX_OFDM); 1246 1247 plcp_length = (len & 0xfff); 1248 sc->sc_tx_desc.plcp_length_hi = plcp_length >> 6; 1249 sc->sc_tx_desc.plcp_length_lo = plcp_length & 0x3f;
| 1025 plcp_length = len & 0xfff; 1026 desc->plcp_length_hi = plcp_length >> 6; 1027 desc->plcp_length_lo = plcp_length & 0x3f;
|
1250 } else {
| 1028 } else {
|
1251 plcp_length = ((16 * len) + rate - 1) / rate;
| 1029 plcp_length = (16 * len + rate - 1) / rate;
|
1252 if (rate == 22) { 1253 remainder = (16 * len) % 22;
| 1030 if (rate == 22) { 1031 remainder = (16 * len) % 22;
|
1254 if ((remainder != 0) && (remainder < 7)) { 1255 sc->sc_tx_desc.plcp_service |= 1256 RT2573_PLCP_LENGEXT; 1257 }
| 1032 if (remainder != 0 && remainder < 7) 1033 desc->plcp_service |= RT2573_PLCP_LENGEXT;
|
1258 }
| 1034 }
|
1259 sc->sc_tx_desc.plcp_length_hi = plcp_length >> 8; 1260 sc->sc_tx_desc.plcp_length_lo = plcp_length & 0xff;
| 1035 desc->plcp_length_hi = plcp_length >> 8; 1036 desc->plcp_length_lo = plcp_length & 0xff;
|
1261
| 1037
|
1262 if ((rate != 2) && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) { 1263 sc->sc_tx_desc.plcp_signal |= 0x08; 1264 }
| 1038 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) 1039 desc->plcp_signal |= 0x08;
|
1265 }
| 1040 }
|
| 1041}
|
1266
| 1042
|
1267 if (sizeof(sc->sc_tx_desc) > MHLEN) { 1268 DPRINTF("No room for header structure!\n"); 1269 rum_tx_freem(m); 1270 return; 1271 } 1272 mm = m_gethdr(M_NOWAIT, MT_DATA); 1273 if (mm == NULL) { 1274 DPRINTF("Could not allocate header mbuf!\n"); 1275 rum_tx_freem(m); 1276 return; 1277 } 1278 bcopy(&sc->sc_tx_desc, mm->m_data, sizeof(sc->sc_tx_desc)); 1279 mm->m_len = sizeof(sc->sc_tx_desc); 1280 mm->m_next = m; 1281 mm->m_pkthdr.len = mm->m_len + m->m_pkthdr.len; 1282 mm->m_pkthdr.rcvif = NULL;
| 1043#define RUM_TX_TIMEOUT 5000
|
1283
| 1044
|
1284 if (is_beacon) {
| 1045static int 1046rum_sendprot(struct rum_softc *sc, 1047 const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) 1048{ 1049 struct ieee80211com *ic = ni->ni_ic; 1050 const struct ieee80211_frame *wh; 1051 struct rum_tx_data *data; 1052 struct mbuf *mprot; 1053 int protrate, ackrate, pktlen, flags, isshort; 1054 uint16_t dur;
|
1285
| 1055
|
1286 if (mm->m_pkthdr.len > sizeof(sc->sc_beacon_buf)) { 1287 DPRINTFN(0, "Truncating beacon" 1288 ", %u bytes!\n", mm->m_pkthdr.len); 1289 mm->m_pkthdr.len = sizeof(sc->sc_beacon_buf); 1290 } 1291 m_copydata(mm, 0, mm->m_pkthdr.len, sc->sc_beacon_buf);
| 1056 RUM_LOCK_ASSERT(sc, MA_OWNED); 1057 KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, 1058 ("protection %d", prot));
|
1292
| 1059
|
1293 /* copy the first 24 bytes of Tx descriptor into NIC memory */ 1294 rum_cfg_write_multi(sc, RT2573_HW_BEACON_BASE0, 1295 sc->sc_beacon_buf, mm->m_pkthdr.len); 1296 rum_tx_freem(mm); 1297 return;
| 1060 wh = mtod(m, const struct ieee80211_frame *); 1061 pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; 1062 1063 protrate = ieee80211_ctl_rate(sc->sc_rates, rate); 1064 ackrate = ieee80211_ack_rate(sc->sc_rates, rate); 1065 1066 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 1067 dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); 1068 + ieee80211_ack_duration(sc->sc_rates, rate, isshort); 1069 flags = RT2573_TX_MORE_FRAG; 1070 if (prot == IEEE80211_PROT_RTSCTS) { 1071 /* NB: CTS is the same size as an ACK */ 1072 dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); 1073 flags |= RT2573_TX_NEED_ACK; 1074 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); 1075 } else { 1076 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
|
1298 }
| 1077 }
|
1299 /* start write transfer, if not started */ 1300 _IF_ENQUEUE(&sc->sc_tx_queue, mm);
| 1078 if (mprot == NULL) { 1079 /* XXX stat + msg */ 1080 return ENOBUFS; 1081 } 1082 data = STAILQ_FIRST(&sc->tx_free); 1083 STAILQ_REMOVE_HEAD(&sc->tx_free, next); 1084 sc->tx_nfree--;
|
1301
| 1085
|
1302 usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]);
| 1086 data->m = mprot; 1087 data->ni = ieee80211_ref_node(ni); 1088 data->rate = protrate; 1089 rum_setup_tx_desc(sc, &data->desc, flags, 0, mprot->m_pkthdr.len, protrate); 1090 1091 STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 1092 usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]); 1093 1094 return 0;
|
1303} 1304
| 1095} 1096
|
1305static void 1306rum_bulk_write_callback(struct usb2_xfer *xfer)
| 1097static int 1098rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
1307{
| 1099{
|
1308 struct rum_softc *sc = xfer->priv_sc;
| 1100 struct ieee80211vap *vap = ni->ni_vap;
|
1309 struct ifnet *ifp = sc->sc_ifp;
| 1101 struct ifnet *ifp = sc->sc_ifp;
|
1310 struct mbuf *m; 1311 uint16_t temp_len; 1312 uint8_t align;
| 1102 struct ieee80211com *ic = ifp->if_l2com; 1103 struct rum_tx_data *data; 1104 struct ieee80211_frame *wh; 1105 const struct ieee80211_txparam *tp; 1106 struct ieee80211_key *k; 1107 uint32_t flags = 0; 1108 uint16_t dur;
|
1313
| 1109
|
1314 switch (USB_GET_STATE(xfer)) { 1315 case USB_ST_TRANSFERRED: 1316 DPRINTFN(11, "transfer complete\n");
| 1110 RUM_LOCK_ASSERT(sc, MA_OWNED);
|
1317
| 1111
|
1318 ifp->if_opackets++;
| 1112 data = STAILQ_FIRST(&sc->tx_free); 1113 STAILQ_REMOVE_HEAD(&sc->tx_free, next); 1114 sc->tx_nfree--;
|
1319
| 1115
|
1320 case USB_ST_SETUP: 1321 if (sc->sc_flags & RUM_FLAG_WRITE_STALL) { 1322 usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_WR]); 1323 break;
| 1116 wh = mtod(m0, struct ieee80211_frame *); 1117 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1118 k = ieee80211_crypto_encap(ni, m0); 1119 if (k == NULL) { 1120 m_freem(m0); 1121 return ENOBUFS;
|
1324 }
| 1122 }
|
1325 if (sc->sc_flags & RUM_FLAG_WAIT_COMMAND) { 1326 /* 1327 * don't send anything while a command is pending ! 1328 */ 1329 break; 1330 } 1331 rum_fill_write_queue(sc);
| 1123 wh = mtod(m0, struct ieee80211_frame *); 1124 }
|
1332
| 1125
|
1333 _IF_DEQUEUE(&sc->sc_tx_queue, m);
| 1126 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
|
1334
| 1127
|
1335 if (m) {
| 1128 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1129 flags |= RT2573_TX_NEED_ACK;
|
1336
| 1130
|
1337 if (m->m_pkthdr.len > (MCLBYTES + RT2573_TX_DESC_SIZE)) { 1338 DPRINTFN(0, "data overflow, %u bytes\n", 1339 m->m_pkthdr.len); 1340 m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE); 1341 } 1342 usb2_m_copy_in(xfer->frbuffers, 0, 1343 m, 0, m->m_pkthdr.len);
| 1131 dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate, 1132 ic->ic_flags & IEEE80211_F_SHPREAMBLE); 1133 *(uint16_t *)wh->i_dur = htole16(dur);
|
1344
| 1134
|
1345 /* compute transfer length */ 1346 temp_len = m->m_pkthdr.len;
| 1135 /* tell hardware to add timestamp for probe responses */ 1136 if ((wh->i_fc[0] & 1137 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == 1138 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) 1139 flags |= RT2573_TX_TIMESTAMP; 1140 }
|
1347
| 1141
|
1348 /* make transfer length 32-bit aligned */ 1349 align = (-(temp_len)) & 3;
| 1142 data->m = m0; 1143 data->ni = ni; 1144 data->rate = tp->mgmtrate;
|
1350
| 1145
|
1351 /* check if we need to add four extra bytes */ 1352 if (((temp_len + align) % 64) == 0) { 1353 align += 4; 1354 } 1355 /* check if we need to align length */ 1356 if (align != 0) { 1357 /* zero the extra bytes */ 1358 usb2_bzero(xfer->frbuffers, temp_len, align); 1359 temp_len += align; 1360 } 1361 DPRINTFN(11, "sending frame len=%u ferlen=%u\n", 1362 m->m_pkthdr.len, temp_len);
| 1146 rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, tp->mgmtrate);
|
1363
| 1147
|
1364 xfer->frlengths[0] = temp_len; 1365 usb2_start_hardware(xfer);
| 1148 DPRINTFN(10, "sending mgt frame len=%d rate=%d\n", 1149 m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate);
|
1366
| 1150
|
1367 /* free mbuf and node */ 1368 rum_tx_freem(m);
| 1151 STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 1152 usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
|
1369
| 1153
|
1370 } 1371 break;
| 1154 return 0; 1155}
|
1372
| 1156
|
1373 default: /* Error */ 1374 DPRINTFN(11, "transfer error, %s\n", 1375 usb2_errstr(xfer->error));
| 1157static int 1158rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, 1159 const struct ieee80211_bpf_params *params) 1160{ 1161 struct rum_tx_data *data; 1162 uint32_t flags; 1163 int rate, error;
|
1376
| 1164
|
1377 if (xfer->error != USB_ERR_CANCELLED) { 1378 /* try to clear stall first */ 1379 sc->sc_flags |= RUM_FLAG_WRITE_STALL; 1380 usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_WR]);
| 1165 RUM_LOCK_ASSERT(sc, MA_OWNED); 1166 KASSERT(params != NULL, ("no raw xmit params")); 1167 1168 data = STAILQ_FIRST(&sc->tx_free); 1169 STAILQ_REMOVE_HEAD(&sc->tx_free, next); 1170 sc->tx_nfree--; 1171 1172 rate = params->ibp_rate0 & IEEE80211_RATE_VAL; 1173 /* XXX validate */ 1174 if (rate == 0) { 1175 m_freem(m0); 1176 return EINVAL; 1177 } 1178 flags = 0; 1179 if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) 1180 flags |= RT2573_TX_NEED_ACK; 1181 if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) { 1182 error = rum_sendprot(sc, m0, ni, 1183 params->ibp_flags & IEEE80211_BPF_RTS ? 1184 IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, 1185 rate); 1186 if (error) { 1187 m_freem(m0); 1188 return error;
|
1381 }
| 1189 }
|
1382 ifp->if_oerrors++; 1383 break;
| 1190 flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
|
1384 }
| 1191 }
|
| 1192 1193 data->m = m0; 1194 data->ni = ni; 1195 data->rate = rate; 1196 1197 /* XXX need to setup descriptor ourself */ 1198 rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate); 1199 1200 DPRINTFN(10, "sending raw frame len=%u rate=%u\n", 1201 m0->m_pkthdr.len, rate); 1202 1203 STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 1204 usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]); 1205 1206 return 0;
|
1385} 1386
| 1207} 1208
|
1387static void 1388rum_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
| 1209static int 1210rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
1389{
| 1211{
|
1390 struct rum_softc *sc = xfer->priv_sc; 1391 struct usb2_xfer *xfer_other = sc->sc_xfer[RUM_BULK_DT_WR];
| 1212 struct ieee80211vap *vap = ni->ni_vap; 1213 struct ifnet *ifp = sc->sc_ifp; 1214 struct ieee80211com *ic = ifp->if_l2com; 1215 struct rum_tx_data *data; 1216 struct ieee80211_frame *wh; 1217 const struct ieee80211_txparam *tp; 1218 struct ieee80211_key *k; 1219 uint32_t flags = 0; 1220 uint16_t dur; 1221 int error, rate;
|
1392
| 1222
|
1393 if (usb2_clear_stall_callback(xfer, xfer_other)) { 1394 DPRINTF("stall cleared\n"); 1395 sc->sc_flags &= ~RUM_FLAG_WRITE_STALL; 1396 usb2_transfer_start(xfer_other);
| 1223 RUM_LOCK_ASSERT(sc, MA_OWNED); 1224 1225 wh = mtod(m0, struct ieee80211_frame *); 1226 1227 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; 1228 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) 1229 rate = tp->mcastrate; 1230 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 1231 rate = tp->ucastrate; 1232 else 1233 rate = ni->ni_txrate; 1234 1235 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1236 k = ieee80211_crypto_encap(ni, m0); 1237 if (k == NULL) { 1238 m_freem(m0); 1239 return ENOBUFS; 1240 } 1241 1242 /* packet header may have moved, reset our local pointer */ 1243 wh = mtod(m0, struct ieee80211_frame *);
|
1397 }
| 1244 }
|
1398}
| |
1399
| 1245
|
1400static void 1401rum_watchdog(void *arg) 1402{ 1403 struct rum_softc *sc = arg;
| 1246 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1247 int prot = IEEE80211_PROT_NONE; 1248 if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 1249 prot = IEEE80211_PROT_RTSCTS; 1250 else if ((ic->ic_flags & IEEE80211_F_USEPROT) && 1251 ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) 1252 prot = ic->ic_protmode; 1253 if (prot != IEEE80211_PROT_NONE) { 1254 error = rum_sendprot(sc, m0, ni, prot, rate); 1255 if (error) { 1256 m_freem(m0); 1257 return error; 1258 } 1259 flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; 1260 } 1261 }
|
1404
| 1262
|
1405 mtx_assert(&sc->sc_mtx, MA_OWNED);
| 1263 data = STAILQ_FIRST(&sc->tx_free); 1264 STAILQ_REMOVE_HEAD(&sc->tx_free, next); 1265 sc->tx_nfree--;
|
1406
| 1266
|
1407 if (sc->sc_amrr_timer) { 1408 usb2_config_td_queue_command 1409 (&sc->sc_config_td, NULL, 1410 &rum_cfg_amrr_timeout, 0, 0);
| 1267 data->m = m0; 1268 data->ni = ni; 1269 data->rate = rate; 1270 1271 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1272 flags |= RT2573_TX_NEED_ACK; 1273 flags |= RT2573_TX_MORE_FRAG; 1274 1275 dur = ieee80211_ack_duration(sc->sc_rates, rate, 1276 ic->ic_flags & IEEE80211_F_SHPREAMBLE); 1277 *(uint16_t *)wh->i_dur = htole16(dur);
|
1411 }
| 1278 }
|
1412 usb2_callout_reset(&sc->sc_watchdog, 1413 hz, &rum_watchdog, sc);
| 1279 1280 rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate); 1281 1282 DPRINTFN(10, "sending frame len=%d rate=%d\n", 1283 m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate); 1284 1285 STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 1286 usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]); 1287 1288 return 0;
|
1414} 1415 1416static void
| 1289} 1290 1291static void
|
1417rum_init_cb(void *arg)
| 1292rum_start(struct ifnet *ifp)
|
1418{
| 1293{
|
1419 struct rum_softc *sc = arg;
| 1294 struct rum_softc *sc = ifp->if_softc; 1295 struct ieee80211_node *ni; 1296 struct mbuf *m;
|
1420
| 1297
|
1421 mtx_lock(&sc->sc_mtx); 1422 usb2_config_td_queue_command 1423 (&sc->sc_config_td, &rum_cfg_pre_init, 1424 &rum_cfg_init, 0, 0); 1425 mtx_unlock(&sc->sc_mtx);
| 1298 RUM_LOCK(sc); 1299 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 1300 RUM_UNLOCK(sc); 1301 return; 1302 } 1303 for (;;) { 1304 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1305 if (m == NULL) 1306 break; 1307 if (sc->tx_nfree == 0) { 1308 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1309 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1310 break; 1311 } 1312 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1313 m = ieee80211_encap(ni, m); 1314 if (m == NULL) { 1315 ieee80211_free_node(ni); 1316 continue; 1317 } 1318 if (rum_tx_data(sc, m, ni) != 0) { 1319 ieee80211_free_node(ni); 1320 ifp->if_oerrors++; 1321 break; 1322 } 1323 } 1324 RUM_UNLOCK(sc);
|
1426} 1427 1428static int
| 1325} 1326 1327static int
|
1429rum_ioctl_cb(struct ifnet *ifp, u_long cmd, caddr_t data)
| 1328rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
1430{ 1431 struct rum_softc *sc = ifp->if_softc; 1432 struct ieee80211com *ic = ifp->if_l2com;
| 1329{ 1330 struct rum_softc *sc = ifp->if_softc; 1331 struct ieee80211com *ic = ifp->if_l2com;
|
1433 int error;
| 1332 struct ifreq *ifr = (struct ifreq *) data; 1333 int error = 0, startall = 0;
|
1434 1435 switch (cmd) { 1436 case SIOCSIFFLAGS:
| 1334 1335 switch (cmd) { 1336 case SIOCSIFFLAGS:
|
1437 mtx_lock(&sc->sc_mtx);
| 1337 RUM_LOCK(sc);
|
1438 if (ifp->if_flags & IFF_UP) {
| 1338 if (ifp->if_flags & IFF_UP) {
|
1439 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 1440 usb2_config_td_queue_command 1441 (&sc->sc_config_td, &rum_cfg_pre_init, 1442 &rum_cfg_init, 0, 0); 1443 }
| 1339 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 1340 rum_queue_command(sc, rum_init_task, 1341 &sc->sc_synctask[0].hdr, 1342 &sc->sc_synctask[1].hdr); 1343 startall = 1; 1344 } else 1345 rum_queue_command(sc, rum_promisctask, 1346 &sc->sc_promisctask[0].hdr, 1347 &sc->sc_promisctask[1].hdr);
|
1444 } else { 1445 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
| 1348 } else { 1349 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
1446 usb2_config_td_queue_command 1447 (&sc->sc_config_td, &rum_cfg_pre_stop, 1448 &rum_cfg_stop, 0, 0);
| 1350 rum_queue_command(sc, rum_stop_task, 1351 &sc->sc_synctask[0].hdr, 1352 &sc->sc_synctask[1].hdr);
|
1449 } 1450 }
| 1353 } 1354 }
|
1451 mtx_unlock(&sc->sc_mtx); 1452 error = 0;
| 1355 RUM_UNLOCK(sc); 1356 if (startall) 1357 ieee80211_start_all(ic);
|
1453 break;
| 1358 break;
|
1454
| |
1455 case SIOCGIFMEDIA:
| 1359 case SIOCGIFMEDIA:
|
1456 case SIOCSIFMEDIA: 1457 error = ifmedia_ioctl(ifp, (void *)data, &ic->ic_media, cmd);
| 1360 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
1458 break;
| 1361 break;
|
1459 1460 default:
| 1362 case SIOCGIFADDR:
|
1461 error = ether_ioctl(ifp, cmd, data);
| 1363 error = ether_ioctl(ifp, cmd, data);
|
| 1364 break; 1365 default: 1366 error = EINVAL; 1367 break;
|
1462 }
| 1368 }
|
1463 return (error);
| 1369 return error;
|
1464} 1465 1466static void
| 1370} 1371 1372static void
|
1467rum_start_cb(struct ifnet *ifp)
| 1373rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
|
1468{
| 1374{
|
1469 struct rum_softc *sc = ifp->if_softc;
| 1375 struct usb2_device_request req; 1376 usb2_error_t error;
|
1470
| 1377
|
1471 mtx_lock(&sc->sc_mtx); 1472 /* start write transfer, if not started */ 1473 usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]); 1474 mtx_unlock(&sc->sc_mtx);
| 1378 req.bmRequestType = UT_READ_VENDOR_DEVICE; 1379 req.bRequest = RT2573_READ_EEPROM; 1380 USETW(req.wValue, 0); 1381 USETW(req.wIndex, addr); 1382 USETW(req.wLength, len); 1383 1384 error = rum_do_request(sc, &req, buf); 1385 if (error != 0) { 1386 device_printf(sc->sc_dev, "could not read EEPROM: %s\n", 1387 usb2_errstr(error)); 1388 }
|
1475} 1476
| 1389} 1390
|
1477static void 1478rum_cfg_newstate(struct rum_softc *sc, 1479 struct usb2_config_td_cc *cc, uint16_t refcount)
| 1391static uint32_t 1392rum_read(struct rum_softc *sc, uint16_t reg)
|
1480{
| 1393{
|
1481 struct ifnet *ifp = sc->sc_ifp; 1482 struct ieee80211com *ic = ifp->if_l2com; 1483 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1484 struct rum_vap *uvp = RUM_VAP(vap); 1485 enum ieee80211_state ostate; 1486 enum ieee80211_state nstate; 1487 int arg;
| 1394 uint32_t val;
|
1488
| 1395
|
1489 ostate = vap->iv_state; 1490 nstate = sc->sc_ns_state; 1491 arg = sc->sc_ns_arg;
| 1396 rum_read_multi(sc, reg, &val, sizeof val);
|
1492
| 1397
|
1493 if (ostate == IEEE80211_S_INIT) { 1494 /* We are leaving INIT. TSF sync should be off. */ 1495 rum_cfg_disable_tsf_sync(sc); 1496 } 1497 switch (nstate) { 1498 case IEEE80211_S_INIT: 1499 break;
| 1398 return le32toh(val); 1399}
|
1500
| 1400
|
1501 case IEEE80211_S_RUN: 1502 rum_cfg_set_run(sc, cc); 1503 break;
| 1401static void 1402rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len) 1403{ 1404 struct usb2_device_request req; 1405 usb2_error_t error;
|
1504
| 1406
|
1505 default: 1506 break;
| 1407 req.bmRequestType = UT_READ_VENDOR_DEVICE; 1408 req.bRequest = RT2573_READ_MULTI_MAC; 1409 USETW(req.wValue, 0); 1410 USETW(req.wIndex, reg); 1411 USETW(req.wLength, len); 1412 1413 error = rum_do_request(sc, &req, buf); 1414 if (error != 0) { 1415 device_printf(sc->sc_dev, 1416 "could not multi read MAC register: %s\n", 1417 usb2_errstr(error));
|
1507 }
| 1418 }
|
| 1419}
|
1508
| 1420
|
1509 mtx_unlock(&sc->sc_mtx); 1510 IEEE80211_LOCK(ic); 1511 uvp->newstate(vap, nstate, arg); 1512 if (vap->iv_newstate_cb != NULL) 1513 vap->iv_newstate_cb(vap, nstate, arg); 1514 IEEE80211_UNLOCK(ic); 1515 mtx_lock(&sc->sc_mtx);
| 1421static void 1422rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val) 1423{ 1424 uint32_t tmp = htole32(val); 1425 1426 rum_write_multi(sc, reg, &tmp, sizeof tmp);
|
1516} 1517
| 1427} 1428
|
1518static int 1519rum_newstate_cb(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
| 1429static void 1430rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
|
1520{
| 1431{
|
1521 struct rum_vap *uvp = RUM_VAP(vap); 1522 struct ieee80211com *ic = vap->iv_ic; 1523 struct rum_softc *sc = ic->ic_ifp->if_softc;
| 1432 struct usb2_device_request req; 1433 usb2_error_t error;
|
1524
| 1434
|
1525 DPRINTF("setting new state: %d\n", nstate);
| 1435 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1436 req.bRequest = RT2573_WRITE_MULTI_MAC; 1437 USETW(req.wValue, 0); 1438 USETW(req.wIndex, reg); 1439 USETW(req.wLength, len);
|
1526
| 1440
|
1527 /* Special case - cannot defer this call and cannot block ! */ 1528 if (nstate == IEEE80211_S_INIT) { 1529 /* stop timers */ 1530 mtx_lock(&sc->sc_mtx); 1531 sc->sc_amrr_timer = 0; 1532 mtx_unlock(&sc->sc_mtx); 1533 return (uvp->newstate(vap, nstate, arg));
| 1441 error = rum_do_request(sc, &req, buf); 1442 if (error != 0) { 1443 device_printf(sc->sc_dev, 1444 "could not multi write MAC register: %s\n", 1445 usb2_errstr(error));
|
1534 }
| 1446 }
|
1535 mtx_lock(&sc->sc_mtx); 1536 if (usb2_config_td_is_gone(&sc->sc_config_td)) { 1537 mtx_unlock(&sc->sc_mtx); 1538 return (0); /* nothing to do */ 1539 } 1540 /* store next state */ 1541 sc->sc_ns_state = nstate; 1542 sc->sc_ns_arg = arg;
| 1447}
|
1543
| 1448
|
1544 /* stop timers */ 1545 sc->sc_amrr_timer = 0;
| 1449static void 1450rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val) 1451{ 1452 uint32_t tmp; 1453 int ntries;
|
1546
| 1454
|
1547 /* 1548 * USB configuration can only be done from the USB configuration 1549 * thread: 1550 */ 1551 usb2_config_td_queue_command 1552 (&sc->sc_config_td, &rum_config_copy, 1553 &rum_cfg_newstate, 0, 0);
| 1455 for (ntries = 0; ntries < 5; ntries++) { 1456 if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) 1457 break; 1458 } 1459 if (ntries == 5) { 1460 device_printf(sc->sc_dev, "could not write to BBP\n"); 1461 return; 1462 }
|
1554
| 1463
|
1555 mtx_unlock(&sc->sc_mtx); 1556 1557 return (EINPROGRESS);
| 1464 tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val; 1465 rum_write(sc, RT2573_PHY_CSR3, tmp);
|
1558} 1559
| 1466} 1467
|
1560static void 1561rum_std_command(struct ieee80211com *ic, usb2_config_td_command_t *func)
| 1468static uint8_t 1469rum_bbp_read(struct rum_softc *sc, uint8_t reg)
|
1562{
| 1470{
|
1563 struct rum_softc *sc = ic->ic_ifp->if_softc;
| 1471 uint32_t val; 1472 int ntries;
|
1564
| 1473
|
1565 mtx_lock(&sc->sc_mtx);
| 1474 for (ntries = 0; ntries < 5; ntries++) { 1475 if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) 1476 break; 1477 } 1478 if (ntries == 5) { 1479 device_printf(sc->sc_dev, "could not read BBP\n"); 1480 return 0; 1481 }
|
1566
| 1482
|
1567 sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
| 1483 val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8; 1484 rum_write(sc, RT2573_PHY_CSR3, val);
|
1568
| 1485
|
1569 usb2_config_td_queue_command 1570 (&sc->sc_config_td, &rum_config_copy, func, 0, 0);
| 1486 for (ntries = 0; ntries < 100; ntries++) { 1487 val = rum_read(sc, RT2573_PHY_CSR3); 1488 if (!(val & RT2573_BBP_BUSY)) 1489 return val & 0xff; 1490 DELAY(1); 1491 }
|
1571
| 1492
|
1572 mtx_unlock(&sc->sc_mtx);
| 1493 device_printf(sc->sc_dev, "could not read BBP\n"); 1494 return 0;
|
1573} 1574 1575static void
| 1495} 1496 1497static void
|
1576rum_scan_start_cb(struct ieee80211com *ic)
| 1498rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
|
1577{
| 1499{
|
1578 rum_std_command(ic, &rum_cfg_scan_start);
| 1500 uint32_t tmp; 1501 int ntries; 1502 1503 for (ntries = 0; ntries < 5; ntries++) { 1504 if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY)) 1505 break; 1506 } 1507 if (ntries == 5) { 1508 device_printf(sc->sc_dev, "could not write to RF\n"); 1509 return; 1510 } 1511 1512 tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 | 1513 (reg & 3); 1514 rum_write(sc, RT2573_PHY_CSR4, tmp); 1515 1516 /* remember last written value in sc */ 1517 sc->rf_regs[reg] = val; 1518 1519 DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff);
|
1579} 1580 1581static void
| 1520} 1521 1522static void
|
1582rum_scan_end_cb(struct ieee80211com *ic)
| 1523rum_select_antenna(struct rum_softc *sc)
|
1583{
| 1524{
|
1584 rum_std_command(ic, &rum_cfg_scan_end);
| 1525 uint8_t bbp4, bbp77; 1526 uint32_t tmp; 1527 1528 bbp4 = rum_bbp_read(sc, 4); 1529 bbp77 = rum_bbp_read(sc, 77); 1530 1531 /* TBD */ 1532 1533 /* make sure Rx is disabled before switching antenna */ 1534 tmp = rum_read(sc, RT2573_TXRX_CSR0); 1535 rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); 1536 1537 rum_bbp_write(sc, 4, bbp4); 1538 rum_bbp_write(sc, 77, bbp77); 1539 1540 rum_write(sc, RT2573_TXRX_CSR0, tmp);
|
1585} 1586
| 1541} 1542
|
| 1543/* 1544 * Enable multi-rate retries for frames sent at OFDM rates. 1545 * In 802.11b/g mode, allow fallback to CCK rates. 1546 */
|
1587static void
| 1547static void
|
1588rum_set_channel_cb(struct ieee80211com *ic)
| 1548rum_enable_mrr(struct rum_softc *sc)
|
1589{
| 1549{
|
1590 rum_std_command(ic, &rum_cfg_set_chan);
| 1550 struct ifnet *ifp = sc->sc_ifp; 1551 struct ieee80211com *ic = ifp->if_l2com; 1552 uint32_t tmp; 1553 1554 tmp = rum_read(sc, RT2573_TXRX_CSR4); 1555 1556 tmp &= ~RT2573_MRR_CCK_FALLBACK; 1557 if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) 1558 tmp |= RT2573_MRR_CCK_FALLBACK; 1559 tmp |= RT2573_MRR_ENABLED; 1560 1561 rum_write(sc, RT2573_TXRX_CSR4, tmp);
|
1591} 1592 1593static void
| 1562} 1563 1564static void
|
1594rum_cfg_scan_start(struct rum_softc *sc, 1595 struct usb2_config_td_cc *cc, uint16_t refcount)
| 1565rum_set_txpreamble(struct rum_softc *sc)
|
1596{
| 1566{
|
1597 /* abort TSF synchronization */ 1598 rum_cfg_disable_tsf_sync(sc); 1599 rum_cfg_set_bssid(sc, cc->if_broadcastaddr);
| 1567 struct ifnet *ifp = sc->sc_ifp; 1568 struct ieee80211com *ic = ifp->if_l2com; 1569 uint32_t tmp; 1570 1571 tmp = rum_read(sc, RT2573_TXRX_CSR4); 1572 1573 tmp &= ~RT2573_SHORT_PREAMBLE; 1574 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) 1575 tmp |= RT2573_SHORT_PREAMBLE; 1576 1577 rum_write(sc, RT2573_TXRX_CSR4, tmp);
|
1600} 1601 1602static void
| 1578} 1579 1580static void
|
1603rum_cfg_scan_end(struct rum_softc *sc, 1604 struct usb2_config_td_cc *cc, uint16_t refcount)
| 1581rum_set_basicrates(struct rum_softc *sc)
|
1605{
| 1582{
|
1606 /* enable TSF synchronization */ 1607 rum_cfg_enable_tsf_sync(sc, cc, 0); 1608 rum_cfg_set_bssid(sc, cc->iv_bss.ni_bssid);
| 1583 struct ifnet *ifp = sc->sc_ifp; 1584 struct ieee80211com *ic = ifp->if_l2com; 1585 1586 /* update basic rate set */ 1587 if (ic->ic_curmode == IEEE80211_MODE_11B) { 1588 /* 11b basic rates: 1, 2Mbps */ 1589 rum_write(sc, RT2573_TXRX_CSR5, 0x3); 1590 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) { 1591 /* 11a basic rates: 6, 12, 24Mbps */ 1592 rum_write(sc, RT2573_TXRX_CSR5, 0x150); 1593 } else { 1594 /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ 1595 rum_write(sc, RT2573_TXRX_CSR5, 0xf); 1596 }
|
1609} 1610 1611/*
| 1597} 1598 1599/*
|
1612 * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
| 1600 * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
|
1613 * driver. 1614 */ 1615static void
| 1601 * driver. 1602 */ 1603static void
|
1616rum_cfg_select_band(struct rum_softc *sc, 1617 struct usb2_config_td_cc *cc, uint16_t refcount)
| 1604rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
|
1618{
| 1605{
|
1619 uint32_t tmp;
| |
1620 uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
| 1606 uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
|
| 1607 uint32_t tmp;
|
1621 1622 /* update all BBP registers that depend on the band */
| 1608 1609 /* update all BBP registers that depend on the band */
|
1623 bbp17 = 0x20; 1624 bbp96 = 0x48; 1625 bbp104 = 0x2c; 1626 bbp35 = 0x50; 1627 bbp97 = 0x48; 1628 bbp98 = 0x48; 1629 1630 if (cc->ic_curchan.chan_is_5ghz) { 1631 bbp17 += 0x08; 1632 bbp96 += 0x10; 1633 bbp104 += 0x0c; 1634 bbp35 += 0x10; 1635 bbp97 += 0x10; 1636 bbp98 += 0x10;
| 1610 bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c; 1611 bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48; 1612 if (IEEE80211_IS_CHAN_5GHZ(c)) { 1613 bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c; 1614 bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10;
|
1637 }
| 1615 }
|
1638 if ((cc->ic_curchan.chan_is_2ghz && sc->sc_ext_2ghz_lna) || 1639 (cc->ic_curchan.chan_is_5ghz && sc->sc_ext_5ghz_lna)) { 1640 bbp17 += 0x10; 1641 bbp96 += 0x10; 1642 bbp104 += 0x10;
| 1616 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || 1617 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { 1618 bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
|
1643 }
| 1619 }
|
1644 sc->sc_bbp17 = bbp17; 1645 rum_cfg_bbp_write(sc, 17, bbp17); 1646 rum_cfg_bbp_write(sc, 96, bbp96); 1647 rum_cfg_bbp_write(sc, 104, bbp104);
| |
1648
| 1620
|
1649 if ((cc->ic_curchan.chan_is_2ghz && sc->sc_ext_2ghz_lna) || 1650 (cc->ic_curchan.chan_is_5ghz && sc->sc_ext_5ghz_lna)) { 1651 rum_cfg_bbp_write(sc, 75, 0x80); 1652 rum_cfg_bbp_write(sc, 86, 0x80); 1653 rum_cfg_bbp_write(sc, 88, 0x80);
| 1621 sc->bbp17 = bbp17; 1622 rum_bbp_write(sc, 17, bbp17); 1623 rum_bbp_write(sc, 96, bbp96); 1624 rum_bbp_write(sc, 104, bbp104); 1625 1626 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || 1627 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { 1628 rum_bbp_write(sc, 75, 0x80); 1629 rum_bbp_write(sc, 86, 0x80); 1630 rum_bbp_write(sc, 88, 0x80);
|
1654 }
| 1631 }
|
1655 rum_cfg_bbp_write(sc, 35, bbp35); 1656 rum_cfg_bbp_write(sc, 97, bbp97); 1657 rum_cfg_bbp_write(sc, 98, bbp98);
| |
1658
| 1632
|
1659 tmp = rum_cfg_read(sc, RT2573_PHY_CSR0);
| 1633 rum_bbp_write(sc, 35, bbp35); 1634 rum_bbp_write(sc, 97, bbp97); 1635 rum_bbp_write(sc, 98, bbp98); 1636 1637 tmp = rum_read(sc, RT2573_PHY_CSR0);
|
1660 tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
| 1638 tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
|
1661 if (cc->ic_curchan.chan_is_2ghz)
| 1639 if (IEEE80211_IS_CHAN_2GHZ(c))
|
1662 tmp |= RT2573_PA_PE_2GHZ; 1663 else 1664 tmp |= RT2573_PA_PE_5GHZ;
| 1640 tmp |= RT2573_PA_PE_2GHZ; 1641 else 1642 tmp |= RT2573_PA_PE_5GHZ;
|
1665 rum_cfg_write(sc, RT2573_PHY_CSR0, tmp); 1666 1667 /* 802.11a uses a 16 microseconds short interframe space */ 1668 sc->sc_sifs = cc->ic_curchan.chan_is_5ghz ? 16 : 10;
| 1643 rum_write(sc, RT2573_PHY_CSR0, tmp);
|
1669} 1670 1671static void
| 1644} 1645 1646static void
|
1672rum_cfg_set_chan(struct rum_softc *sc, 1673 struct usb2_config_td_cc *cc, uint16_t refcount)
| 1647rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
|
1674{
| 1648{
|
1675 enum { 1676 N_RF5225 = (sizeof(rum_rf5225) / sizeof(rum_rf5225[0]))};
| 1649 struct ifnet *ifp = sc->sc_ifp; 1650 struct ieee80211com *ic = ifp->if_l2com;
|
1677 const struct rfprog *rfprog;
| 1651 const struct rfprog *rfprog;
|
1678 uint32_t chan; 1679 uint16_t i; 1680 uint8_t bbp3; 1681 uint8_t bbp94 = RT2573_BBPR94_DEFAULT;
| 1652 uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
|
1682 int8_t power;
| 1653 int8_t power;
|
| 1654 u_int i, chan;
|
1683
| 1655
|
1684 chan = cc->ic_curchan.chan_to_ieee; 1685 1686 if ((chan == 0) || 1687 (chan == IEEE80211_CHAN_ANY)) { 1688 /* nothing to do */
| 1656 chan = ieee80211_chan2ieee(ic, c); 1657 if (chan == 0 || chan == IEEE80211_CHAN_ANY)
|
1689 return;
| 1658 return;
|
1690 } 1691 if (chan == sc->sc_last_chan) { 1692 return; 1693 } 1694 sc->sc_last_chan = chan;
| |
1695 1696 /* select the appropriate RF settings based on what EEPROM says */
| 1659 1660 /* select the appropriate RF settings based on what EEPROM says */
|
1697 rfprog = ((sc->sc_rf_rev == RT2573_RF_5225) || 1698 (sc->sc_rf_rev == RT2573_RF_2527)) ? rum_rf5225 : rum_rf5226;
| 1661 rfprog = (sc->rf_rev == RT2573_RF_5225 || 1662 sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
|
1699
| 1663
|
1700 /* find the settings for this channel */ 1701 for (i = 0;; i++) { 1702 if (i == (N_RF5225 - 1)) 1703 break; 1704 if (rfprog[i].chan == chan) 1705 break; 1706 }
| 1664 /* find the settings for this channel (we know it exists) */ 1665 for (i = 0; rfprog[i].chan != chan; i++);
|
1707
| 1666
|
1708 DPRINTF("chan=%d, i=%d\n", chan, i); 1709 1710 power = sc->sc_txpow[i];
| 1667 power = sc->txpow[i];
|
1711 if (power < 0) { 1712 bbp94 += power; 1713 power = 0; 1714 } else if (power > 31) { 1715 bbp94 += power - 31; 1716 power = 31; 1717 }
| 1668 if (power < 0) { 1669 bbp94 += power; 1670 power = 0; 1671 } else if (power > 31) { 1672 bbp94 += power - 31; 1673 power = 31; 1674 }
|
| 1675
|
1718 /* 1719 * If we are switching from the 2GHz band to the 5GHz band or 1720 * vice-versa, BBP registers need to be reprogrammed. 1721 */
| 1676 /* 1677 * If we are switching from the 2GHz band to the 5GHz band or 1678 * vice-versa, BBP registers need to be reprogrammed. 1679 */
|
1722 rum_cfg_select_band(sc, cc, 0); 1723 rum_cfg_select_antenna(sc, cc, 0);
| 1680 if (c->ic_flags != ic->ic_curchan->ic_flags) { 1681 rum_select_band(sc, c); 1682 rum_select_antenna(sc); 1683 } 1684 ic->ic_curchan = c;
|
1724
| 1685
|
1725 rum_cfg_rf_write(sc, RT2573_RF1, rfprog[i].r1); 1726 rum_cfg_rf_write(sc, RT2573_RF2, rfprog[i].r2); 1727 rum_cfg_rf_write(sc, RT2573_RF3, rfprog[i].r3 | (power << 7)); 1728 rum_cfg_rf_write(sc, RT2573_RF4, rfprog[i].r4 | (sc->sc_rffreq << 10));
| 1686 rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); 1687 rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); 1688 rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7); 1689 rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
|
1729
| 1690
|
1730 rum_cfg_rf_write(sc, RT2573_RF1, rfprog[i].r1); 1731 rum_cfg_rf_write(sc, RT2573_RF2, rfprog[i].r2); 1732 rum_cfg_rf_write(sc, RT2573_RF3, rfprog[i].r3 | (power << 7) | 1); 1733 rum_cfg_rf_write(sc, RT2573_RF4, rfprog[i].r4 | (sc->sc_rffreq << 10));
| 1691 rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); 1692 rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); 1693 rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1); 1694 rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
|
1734
| 1695
|
1735 rum_cfg_rf_write(sc, RT2573_RF1, rfprog[i].r1); 1736 rum_cfg_rf_write(sc, RT2573_RF2, rfprog[i].r2); 1737 rum_cfg_rf_write(sc, RT2573_RF3, rfprog[i].r3 | (power << 7)); 1738 rum_cfg_rf_write(sc, RT2573_RF4, rfprog[i].r4 | (sc->sc_rffreq << 10));
| 1696 rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); 1697 rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); 1698 rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7); 1699 rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
|
1739
| 1700
|
1740 if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 1741 return; 1742 }
| 1701 DELAY(10); 1702
|
1743 /* enable smart mode for MIMO-capable RFs */
| 1703 /* enable smart mode for MIMO-capable RFs */
|
1744 bbp3 = rum_cfg_bbp_read(sc, 3);
| 1704 bbp3 = rum_bbp_read(sc, 3);
|
1745
| 1705
|
1746 if ((sc->sc_rf_rev == RT2573_RF_5225) || 1747 (sc->sc_rf_rev == RT2573_RF_2527)) 1748 bbp3 &= ~RT2573_SMART_MODE; 1749 else
| 1706 bbp3 &= ~RT2573_SMART_MODE; 1707 if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
|
1750 bbp3 |= RT2573_SMART_MODE; 1751
| 1708 bbp3 |= RT2573_SMART_MODE; 1709
|
1752 rum_cfg_bbp_write(sc, 3, bbp3);
| 1710 rum_bbp_write(sc, 3, bbp3);
|
1753
| 1711
|
1754 rum_cfg_bbp_write(sc, 94, bbp94); 1755 1756 /* update basic rate set */ 1757 1758 if (cc->ic_curchan.chan_is_b) { 1759 /* 11b basic rates: 1, 2Mbps */ 1760 rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x3); 1761 } else if (cc->ic_curchan.chan_is_a) { 1762 /* 11a basic rates: 6, 12, 24Mbps */ 1763 rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x150); 1764 } else { 1765 /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ 1766 rum_cfg_write(sc, RT2573_TXRX_CSR5, 0xf); 1767 } 1768 1769 if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 1770 return; 1771 }
| 1712 if (bbp94 != RT2573_BBPR94_DEFAULT) 1713 rum_bbp_write(sc, 94, bbp94);
|
1772} 1773
| 1714} 1715
|
| 1716/* 1717 * Enable TSF synchronization and tell h/w to start sending beacons for IBSS 1718 * and HostAP operating modes. 1719 */
|
1774static void
| 1720static void
|
1775rum_cfg_set_run(struct rum_softc *sc, 1776 struct usb2_config_td_cc *cc)
| 1721rum_enable_tsf_sync(struct rum_softc *sc)
|
1777{
| 1722{
|
1778 1779 if (cc->ic_opmode != IEEE80211_M_MONITOR) { 1780 rum_cfg_update_slot(sc, cc, 0); 1781 rum_cfg_enable_mrr(sc, cc, 0); 1782 rum_cfg_set_txpreamble(sc, cc, 0); 1783 1784 /* update basic rate set */ 1785 1786 if (cc->ic_bsschan.chan_is_5ghz) { 1787 /* 11a basic rates: 6, 12, 24Mbps */ 1788 rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x150); 1789 } else if (cc->ic_bsschan.chan_is_g) { 1790 /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ 1791 rum_cfg_write(sc, RT2573_TXRX_CSR5, 0xf); 1792 } else { 1793 /* 11b basic rates: 1, 2Mbps */ 1794 rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x3); 1795 } 1796 rum_cfg_set_bssid(sc, cc->iv_bss.ni_bssid); 1797 } 1798 if ((cc->ic_opmode == IEEE80211_M_HOSTAP) || 1799 (cc->ic_opmode == IEEE80211_M_IBSS)) { 1800 rum_cfg_prepare_beacon(sc, cc, 0); 1801 } 1802 if (cc->ic_opmode != IEEE80211_M_MONITOR) { 1803 rum_cfg_enable_tsf_sync(sc, cc, 0); 1804 } 1805 if (cc->iv_bss.fixed_rate_none) { 1806 /* enable automatic rate adaptation */ 1807 rum_cfg_amrr_start(sc); 1808 } 1809} 1810 1811static void 1812rum_cfg_enable_tsf_sync(struct rum_softc *sc, 1813 struct usb2_config_td_cc *cc, uint16_t refcount) 1814{
| 1723 struct ifnet *ifp = sc->sc_ifp; 1724 struct ieee80211com *ic = ifp->if_l2com; 1725 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
1815 uint32_t tmp; 1816
| 1726 uint32_t tmp; 1727
|
1817 if (cc->ic_opmode != IEEE80211_M_STA) {
| 1728 if (vap->iv_opmode != IEEE80211_M_STA) {
|
1818 /* 1819 * Change default 16ms TBTT adjustment to 8ms. 1820 * Must be done before enabling beacon generation. 1821 */
| 1729 /* 1730 * Change default 16ms TBTT adjustment to 8ms. 1731 * Must be done before enabling beacon generation. 1732 */
|
1822 rum_cfg_write(sc, RT2573_TXRX_CSR10, (1 << 12) | 8);
| 1733 rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8);
|
1823 }
| 1734 }
|
1824 tmp = rum_cfg_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
| |
1825
| 1735
|
| 1736 tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000; 1737
|
1826 /* set beacon interval (in 1/16ms unit) */
| 1738 /* set beacon interval (in 1/16ms unit) */
|
1827 tmp |= cc->iv_bss.ni_intval * 16;
| 1739 tmp |= vap->iv_bss->ni_intval * 16;
|
1828 1829 tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
| 1740 1741 tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
|
1830 if (cc->ic_opmode == IEEE80211_M_STA)
| 1742 if (vap->iv_opmode == IEEE80211_M_STA)
|
1831 tmp |= RT2573_TSF_MODE(1); 1832 else 1833 tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON; 1834
| 1743 tmp |= RT2573_TSF_MODE(1); 1744 else 1745 tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON; 1746
|
1835 rum_cfg_write(sc, RT2573_TXRX_CSR9, tmp);
| 1747 rum_write(sc, RT2573_TXRX_CSR9, tmp);
|
1836} 1837 1838static void
| 1748} 1749 1750static void
|
1839rum_cfg_disable_tsf_sync(struct rum_softc *sc)
| 1751rum_update_slot(struct ifnet *ifp)
|
1840{
| 1752{
|
| 1753 struct rum_softc *sc = ifp->if_softc; 1754 struct ieee80211com *ic = ifp->if_l2com; 1755 uint8_t slottime;
|
1841 uint32_t tmp; 1842
| 1756 uint32_t tmp; 1757
|
1843 /* abort TSF synchronization */ 1844 tmp = rum_cfg_read(sc, RT2573_TXRX_CSR9); 1845 rum_cfg_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); 1846}
| 1758 slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
|
1847
| 1759
|
1848/* 1849 * Enable multi-rate retries for frames sent at OFDM rates. 1850 * In 802.11b/g mode, allow fallback to CCK rates. 1851 */ 1852static void 1853rum_cfg_enable_mrr(struct rum_softc *sc, 1854 struct usb2_config_td_cc *cc, uint16_t refcount) 1855{ 1856 uint32_t tmp; 1857 1858 tmp = rum_cfg_read(sc, RT2573_TXRX_CSR4); 1859 1860 if (cc->ic_curchan.chan_is_5ghz) 1861 tmp &= ~RT2573_MRR_CCK_FALLBACK; 1862 else 1863 tmp |= RT2573_MRR_CCK_FALLBACK; 1864 1865 tmp |= RT2573_MRR_ENABLED; 1866 1867 rum_cfg_write(sc, RT2573_TXRX_CSR4, tmp); 1868} 1869 1870static void 1871rum_cfg_update_slot(struct rum_softc *sc, 1872 struct usb2_config_td_cc *cc, uint16_t refcount) 1873{ 1874 uint32_t tmp; 1875 uint8_t slottime; 1876 1877 slottime = (cc->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; 1878 1879 tmp = rum_cfg_read(sc, RT2573_MAC_CSR9);
| 1760 tmp = rum_read(sc, RT2573_MAC_CSR9);
|
1880 tmp = (tmp & ~0xff) | slottime;
| 1761 tmp = (tmp & ~0xff) | slottime;
|
1881 rum_cfg_write(sc, RT2573_MAC_CSR9, tmp);
| 1762 rum_write(sc, RT2573_MAC_CSR9, tmp);
|
1882
| 1763
|
1883 DPRINTF("setting slot time to %u us\n", slottime);
| 1764 DPRINTF("setting slot time to %uus\n", slottime);
|
1884} 1885 1886static void
| 1765} 1766 1767static void
|
1887rum_cfg_set_txpreamble(struct rum_softc *sc, 1888 struct usb2_config_td_cc *cc, uint16_t refcount)
| 1768rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
|
1889{ 1890 uint32_t tmp; 1891
| 1769{ 1770 uint32_t tmp; 1771
|
1892 tmp = rum_cfg_read(sc, RT2573_TXRX_CSR4);
| 1772 tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24; 1773 rum_write(sc, RT2573_MAC_CSR4, tmp);
|
1893
| 1774
|
1894 if (cc->ic_flags & IEEE80211_F_SHPREAMBLE) 1895 tmp |= RT2573_SHORT_PREAMBLE; 1896 else 1897 tmp &= ~RT2573_SHORT_PREAMBLE; 1898 1899 rum_cfg_write(sc, RT2573_TXRX_CSR4, tmp);
| 1775 tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16; 1776 rum_write(sc, RT2573_MAC_CSR5, tmp);
|
1900} 1901 1902static void
| 1777} 1778 1779static void
|
1903rum_cfg_set_bssid(struct rum_softc *sc, uint8_t *bssid)
| 1780rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
|
1904{ 1905 uint32_t tmp; 1906
| 1781{ 1782 uint32_t tmp; 1783
|
1907 tmp = bssid[0] | (bssid[1] << 8) | (bssid[2] << 16) | (bssid[3] << 24); 1908 rum_cfg_write(sc, RT2573_MAC_CSR4, tmp);
| 1784 tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24; 1785 rum_write(sc, RT2573_MAC_CSR2, tmp);
|
1909
| 1786
|
1910 tmp = (bssid[4]) | (bssid[5] << 8) | (RT2573_ONE_BSSID << 16); 1911 rum_cfg_write(sc, RT2573_MAC_CSR5, tmp);
| 1787 tmp = addr[4] | addr[5] << 8 | 0xff << 16; 1788 rum_write(sc, RT2573_MAC_CSR3, tmp);
|
1912} 1913 1914static void
| 1789} 1790 1791static void
|
1915rum_cfg_set_macaddr(struct rum_softc *sc, uint8_t *addr)
| 1792rum_promisctask(struct usb2_proc_msg *pm)
|
1916{
| 1793{
|
| 1794 struct rum_task *task = (struct rum_task *)pm; 1795 struct rum_softc *sc = task->sc; 1796 struct ifnet *ifp = sc->sc_ifp;
|
1917 uint32_t tmp; 1918
| 1797 uint32_t tmp; 1798
|
1919 tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24); 1920 rum_cfg_write(sc, RT2573_MAC_CSR2, tmp);
| 1799 tmp = rum_read(sc, RT2573_TXRX_CSR0);
|
1921
| 1800
|
1922 tmp = addr[4] | (addr[5] << 8) | (0xff << 16); 1923 rum_cfg_write(sc, RT2573_MAC_CSR3, tmp); 1924} 1925 1926static void 1927rum_cfg_update_promisc(struct rum_softc *sc, 1928 struct usb2_config_td_cc *cc, uint16_t refcount) 1929{ 1930 uint32_t tmp; 1931 1932 tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0); 1933 1934 if (cc->if_flags & IFF_PROMISC) 1935 tmp &= ~RT2573_DROP_NOT_TO_ME; 1936 else
| 1801 tmp &= ~RT2573_DROP_NOT_TO_ME; 1802 if (!(ifp->if_flags & IFF_PROMISC))
|
1937 tmp |= RT2573_DROP_NOT_TO_ME; 1938
| 1803 tmp |= RT2573_DROP_NOT_TO_ME; 1804
|
1939 rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp);
| 1805 rum_write(sc, RT2573_TXRX_CSR0, tmp);
|
1940
| 1806
|
1941 DPRINTF("%s promiscuous mode\n", 1942 (cc->if_flags & IFF_PROMISC) ?
| 1807 DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
|
1943 "entering" : "leaving"); 1944} 1945
| 1808 "entering" : "leaving"); 1809} 1810
|
1946static void 1947rum_cfg_select_antenna(struct rum_softc *sc, 1948 struct usb2_config_td_cc *cc, uint16_t refcount)
| 1811static const char * 1812rum_get_rf(int rev)
|
1949{
| 1813{
|
1950 uint32_t tmp; 1951 uint8_t bbp3; 1952 uint8_t bbp4; 1953 uint8_t bbp77; 1954 uint8_t rx_ant; 1955 uint8_t is_5ghz; 1956 1957 bbp3 = rum_cfg_bbp_read(sc, 3); 1958 bbp4 = rum_cfg_bbp_read(sc, 4); 1959 bbp77 = rum_cfg_bbp_read(sc, 77); 1960 1961 bbp3 &= ~0x01; 1962 bbp4 &= ~0x23; 1963 1964 rx_ant = sc->sc_rx_ant; 1965 is_5ghz = cc->ic_curchan.chan_is_5ghz; 1966 1967 switch (sc->sc_rf_rev) { 1968 case RT2573_RF_5226: 1969 case RT2573_RF_5225: 1970 if (rx_ant == 0) { 1971 /* Diversity */ 1972 bbp4 |= 0x02; 1973 if (is_5ghz == 0) 1974 bbp4 |= 0x20; 1975 } else if (rx_ant == 1) { 1976 /* RX: Antenna A */ 1977 bbp4 |= 0x01; 1978 if (is_5ghz) 1979 bbp77 &= ~0x03; 1980 else 1981 bbp77 |= 0x03; 1982 } else if (rx_ant == 2) { 1983 /* RX: Antenna B */ 1984 bbp4 |= 0x01; 1985 if (is_5ghz) 1986 bbp77 |= 0x03; 1987 else 1988 bbp77 &= ~0x03; 1989 } 1990 break; 1991 1992 case RT2573_RF_2528: 1993 case RT2573_RF_2527: 1994 if (rx_ant == 0) { 1995 /* Diversity */ 1996 bbp4 |= 0x22; 1997 } else if (rx_ant == 1) { 1998 /* RX: Antenna A */ 1999 bbp4 |= 0x21; 2000 bbp77 |= 0x03; 2001 } else if (rx_ant == 2) { 2002 /* RX: Antenna B */ 2003 bbp4 |= 0x21; 2004 bbp77 &= ~0x03; 2005 } 2006 break; 2007 default: 2008 break;
| 1814 switch (rev) { 1815 case RT2573_RF_2527: return "RT2527 (MIMO XR)"; 1816 case RT2573_RF_2528: return "RT2528"; 1817 case RT2573_RF_5225: return "RT5225 (MIMO XR)"; 1818 case RT2573_RF_5226: return "RT5226"; 1819 default: return "unknown";
|
2009 }
| 1820 }
|
2010 bbp4 &= ~(sc->sc_ftype << 5); 2011 2012 /* make sure Rx is disabled before switching antenna */ 2013 tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0); 2014 rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); 2015 2016 rum_cfg_bbp_write(sc, 3, bbp3); 2017 rum_cfg_bbp_write(sc, 4, bbp4); 2018 rum_cfg_bbp_write(sc, 77, bbp77); 2019 2020 rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp);
| |
2021} 2022 2023static void
| 1821} 1822 1823static void
|
2024rum_cfg_read_eeprom(struct rum_softc *sc)
| 1824rum_read_eeprom(struct rum_softc *sc)
|
2025{ 2026 uint16_t val;
| 1825{ 1826 uint16_t val;
|
| 1827#ifdef RUM_DEBUG 1828 int i; 1829#endif
|
2027 2028 /* read MAC address */
| 1830 1831 /* read MAC address */
|
2029 rum_cfg_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_myaddr, 6);
| 1832 rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_bssid, 6);
|
2030
| 1833
|
2031 val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_ANTENNA); 2032 sc->sc_rf_rev = (val >> 11) & 0x1f; 2033 sc->sc_hw_radio = (val >> 10) & 0x1; 2034 sc->sc_ftype = (val >> 6) & 0x1; 2035 sc->sc_rx_ant = (val >> 4) & 0x3; 2036 sc->sc_tx_ant = (val >> 2) & 0x3; 2037 sc->sc_nb_ant = (val & 0x3);
| 1834 rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2); 1835 val = le16toh(val); 1836 sc->rf_rev = (val >> 11) & 0x1f; 1837 sc->hw_radio = (val >> 10) & 0x1; 1838 sc->rx_ant = (val >> 4) & 0x3; 1839 sc->tx_ant = (val >> 2) & 0x3; 1840 sc->nb_ant = val & 0x3;
|
2038
| 1841
|
2039 DPRINTF("RF revision=%d\n", sc->sc_rf_rev);
| 1842 DPRINTF("RF revision=%d\n", sc->rf_rev);
|
2040
| 1843
|
2041 val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_CONFIG2); 2042 sc->sc_ext_5ghz_lna = (val >> 6) & 0x1; 2043 sc->sc_ext_2ghz_lna = (val >> 4) & 0x1;
| 1844 rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2); 1845 val = le16toh(val); 1846 sc->ext_5ghz_lna = (val >> 6) & 0x1; 1847 sc->ext_2ghz_lna = (val >> 4) & 0x1;
|
2044
| 1848
|
2045 DPRINTF("External 2GHz LNA=%d, External 5GHz LNA=%d\n", 2046 sc->sc_ext_2ghz_lna, sc->sc_ext_5ghz_lna);
| 1849 DPRINTF("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n", 1850 sc->ext_2ghz_lna, sc->ext_5ghz_lna);
|
2047
| 1851
|
2048 val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET);
| 1852 rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2); 1853 val = le16toh(val);
|
2049 if ((val & 0xff) != 0xff)
| 1854 if ((val & 0xff) != 0xff)
|
2050 sc->sc_rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */ 2051 else 2052 sc->sc_rssi_2ghz_corr = 0;
| 1855 sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */
|
2053
| 1856
|
2054 /* range check */ 2055 if ((sc->sc_rssi_2ghz_corr < -10) || 2056 (sc->sc_rssi_2ghz_corr > 10)) { 2057 sc->sc_rssi_2ghz_corr = 0; 2058 } 2059 val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET);
| 1857 /* Only [-10, 10] is valid */ 1858 if (sc->rssi_2ghz_corr < -10 || sc->rssi_2ghz_corr > 10) 1859 sc->rssi_2ghz_corr = 0; 1860 1861 rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2); 1862 val = le16toh(val);
|
2060 if ((val & 0xff) != 0xff)
| 1863 if ((val & 0xff) != 0xff)
|
2061 sc->sc_rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */ 2062 else 2063 sc->sc_rssi_5ghz_corr = 0;
| 1864 sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */
|
2064
| 1865
|
2065 /* range check */ 2066 if ((sc->sc_rssi_5ghz_corr < -10) || 2067 (sc->sc_rssi_5ghz_corr > 10)) { 2068 sc->sc_rssi_5ghz_corr = 0; 2069 } 2070 if (sc->sc_ext_2ghz_lna) { 2071 sc->sc_rssi_2ghz_corr -= 14; 2072 } 2073 if (sc->sc_ext_5ghz_lna) { 2074 sc->sc_rssi_5ghz_corr -= 14; 2075 } 2076 DPRINTF("RSSI 2GHz corr=%d, RSSI 5GHz corr=%d\n", 2077 sc->sc_rssi_2ghz_corr, sc->sc_rssi_5ghz_corr);
| 1866 /* Only [-10, 10] is valid */ 1867 if (sc->rssi_5ghz_corr < -10 || sc->rssi_5ghz_corr > 10) 1868 sc->rssi_5ghz_corr = 0;
|
2078
| 1869
|
2079 val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_FREQ_OFFSET);
| 1870 if (sc->ext_2ghz_lna) 1871 sc->rssi_2ghz_corr -= 14; 1872 if (sc->ext_5ghz_lna) 1873 sc->rssi_5ghz_corr -= 14; 1874 1875 DPRINTF("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n", 1876 sc->rssi_2ghz_corr, sc->rssi_5ghz_corr); 1877 1878 rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2); 1879 val = le16toh(val);
|
2080 if ((val & 0xff) != 0xff)
| 1880 if ((val & 0xff) != 0xff)
|
2081 sc->sc_rffreq = (val & 0xff); 2082 else 2083 sc->sc_rffreq = 0;
| 1881 sc->rffreq = val & 0xff;
|
2084
| 1882
|
2085 DPRINTF("RF freq=%d\n", sc->sc_rffreq);
| 1883 DPRINTF("RF freq=%d\n", sc->rffreq);
|
2086 2087 /* read Tx power for all a/b/g channels */
| 1884 1885 /* read Tx power for all a/b/g channels */
|
2088 rum_cfg_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->sc_txpow, 14); 2089
| 1886 rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
|
2090 /* XXX default Tx power for 802.11a channels */
| 1887 /* XXX default Tx power for 802.11a channels */
|
2091 memset(sc->sc_txpow + 14, 24, sizeof(sc->sc_txpow) - 14);
| 1888 memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14); 1889#ifdef RUM_DEBUG 1890 for (i = 0; i < 14; i++) 1891 DPRINTF("Channel=%d Tx power=%d\n", i + 1, sc->txpow[i]); 1892#endif
|
2092 2093 /* read default values for BBP registers */
| 1893 1894 /* read default values for BBP registers */
|
2094 rum_cfg_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->sc_bbp_prom, 2 * 16);
| 1895 rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16); 1896#ifdef RUM_DEBUG 1897 for (i = 0; i < 14; i++) { 1898 if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff) 1899 continue; 1900 DPRINTF("BBP R%d=%02x\n", sc->bbp_prom[i].reg, 1901 sc->bbp_prom[i].val); 1902 } 1903#endif
|
2095} 2096
| 1904} 1905
|
2097static uint8_t 2098rum_cfg_bbp_init(struct rum_softc *sc)
| 1906static int 1907rum_bbp_init(struct rum_softc *sc)
|
2099{
| 1908{
|
2100 enum { 2101 N_DEF_BBP = (sizeof(rum_def_bbp) / sizeof(rum_def_bbp[0])), 2102 }; 2103 uint16_t i; 2104 uint8_t to; 2105 uint8_t tmp;
| 1909#define N(a) (sizeof (a) / sizeof ((a)[0])) 1910 int i, ntries;
|
2106
| 1911
|
2107 /* wait for BBP to become ready */ 2108 for (to = 0;; to++) { 2109 if (to < 100) { 2110 tmp = rum_cfg_bbp_read(sc, 0); 2111 if ((tmp != 0x00) && 2112 (tmp != 0xff)) { 2113 break; 2114 } 2115 if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 2116 return (1); /* failure */ 2117 } 2118 } else { 2119 DPRINTF("timeout waiting for BBP\n"); 2120 return (1); /* failure */ 2121 }
| 1912 /* wait for BBP to be ready */ 1913 for (ntries = 0; ntries < 100; ntries++) { 1914 const uint8_t val = rum_bbp_read(sc, 0); 1915 if (val != 0 && val != 0xff) 1916 break; 1917 DELAY(1000);
|
2122 }
| 1918 }
|
| 1919 if (ntries == 100) { 1920 device_printf(sc->sc_dev, "timeout waiting for BBP\n"); 1921 return EIO; 1922 }
|
2123 2124 /* initialize BBP registers to default values */
| 1923 1924 /* initialize BBP registers to default values */
|
2125 for (i = 0; i < N_DEF_BBP; i++) { 2126 rum_cfg_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val); 2127 }
| 1925 for (i = 0; i < N(rum_def_bbp); i++) 1926 rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
|
2128 2129 /* write vendor-specific BBP values (from EEPROM) */ 2130 for (i = 0; i < 16; i++) {
| 1927 1928 /* write vendor-specific BBP values (from EEPROM) */ 1929 for (i = 0; i < 16; i++) {
|
2131 if ((sc->sc_bbp_prom[i].reg == 0) || 2132 (sc->sc_bbp_prom[i].reg == 0xff)) {
| 1930 if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
|
2133 continue;
| 1931 continue;
|
2134 } 2135 rum_cfg_bbp_write(sc, sc->sc_bbp_prom[i].reg, sc->sc_bbp_prom[i].val);
| 1932 rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
|
2136 }
| 1933 }
|
2137 return (0);
| 1934 1935 return 0; 1936#undef N
|
2138} 2139 2140static void
| 1937} 1938 1939static void
|
2141rum_cfg_pre_init(struct rum_softc *sc, 2142 struct usb2_config_td_cc *cc, uint16_t refcount)
| 1940rum_init_task(struct usb2_proc_msg *pm)
|
2143{
| 1941{
|
| 1942#define N(a) (sizeof (a) / sizeof ((a)[0])) 1943 struct rum_task *task = (struct rum_task *)pm; 1944 struct rum_softc *sc = task->sc;
|
2144 struct ifnet *ifp = sc->sc_ifp; 2145 struct ieee80211com *ic = ifp->if_l2com;
| 1945 struct ifnet *ifp = sc->sc_ifp; 1946 struct ieee80211com *ic = ifp->if_l2com;
|
2146 2147 /* immediate configuration */ 2148 2149 rum_cfg_pre_stop(sc, cc, 0); 2150 2151 ifp->if_drv_flags |= IFF_DRV_RUNNING; 2152 2153 sc->sc_flags |= RUM_FLAG_HL_READY; 2154 2155 IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); 2156} 2157 2158static void 2159rum_cfg_init(struct rum_softc *sc, 2160 struct usb2_config_td_cc *cc, uint16_t refcount) 2161{ 2162 enum { 2163 N_DEF_MAC = (sizeof(rum_def_mac) / sizeof(rum_def_mac[0])), 2164 }; 2165
| |
2166 uint32_t tmp;
| 1947 uint32_t tmp;
|
2167 uint16_t i; 2168 uint8_t to;
| 1948 usb2_error_t error; 1949 int i, ntries;
|
2169
| 1950
|
2170 /* delayed configuration */
| 1951 RUM_LOCK_ASSERT(sc, MA_OWNED);
|
2171
| 1952
|
2172 rum_cfg_stop(sc, cc, 0);
| 1953 rum_stop_task(pm);
|
2173 2174 /* initialize MAC registers to default values */
| 1954 1955 /* initialize MAC registers to default values */
|
2175 for (i = 0; i < N_DEF_MAC; i++) { 2176 rum_cfg_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val); 2177 }
| 1956 for (i = 0; i < N(rum_def_mac); i++) 1957 rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
|
2178 2179 /* set host ready */
| 1958 1959 /* set host ready */
|
2180 rum_cfg_write(sc, RT2573_MAC_CSR1, 3); 2181 rum_cfg_write(sc, RT2573_MAC_CSR1, 0);
| 1960 rum_write(sc, RT2573_MAC_CSR1, 3); 1961 rum_write(sc, RT2573_MAC_CSR1, 0);
|
2182 2183 /* wait for BBP/RF to wakeup */
| 1962 1963 /* wait for BBP/RF to wakeup */
|
2184 for (to = 0;; to++) { 2185 if (to < 100) { 2186 if (rum_cfg_read(sc, RT2573_MAC_CSR12) & 8) { 2187 break; 2188 } 2189 rum_cfg_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */ 2190 2191 if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 2192 goto fail; 2193 } 2194 } else { 2195 DPRINTF("timeout waiting for " 2196 "BBP/RF to wakeup\n"); 2197 goto fail; 2198 }
| 1964 for (ntries = 0; ntries < 1000; ntries++) { 1965 if (rum_read(sc, RT2573_MAC_CSR12) & 8) 1966 break; 1967 rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */ 1968 DELAY(1000);
|
2199 }
| 1969 }
|
2200 2201 if (rum_cfg_bbp_init(sc)) {
| 1970 if (ntries == 1000) { 1971 device_printf(sc->sc_dev, 1972 "timeout waiting for BBP/RF to wakeup\n");
|
2202 goto fail; 2203 }
| 1973 goto fail; 1974 }
|
2204 /* select default channel */
| |
2205
| 1975
|
2206 sc->sc_last_chan = 0;
| 1976 if ((error = rum_bbp_init(sc)) != 0) 1977 goto fail;
|
2207
| 1978
|
2208 rum_cfg_set_chan(sc, cc, 0);
| 1979 /* select default channel */ 1980 rum_select_band(sc, ic->ic_curchan); 1981 rum_select_antenna(sc); 1982 rum_set_chan(sc, ic->ic_curchan);
|
2209 2210 /* clear STA registers */
| 1983 1984 /* clear STA registers */
|
2211 rum_cfg_read_multi(sc, RT2573_STA_CSR0, sc->sc_sta, sizeof(sc->sc_sta)); 2212 /* set MAC address */ 2213 rum_cfg_set_macaddr(sc, cc->ic_myaddr);
| 1985 rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
|
2214
| 1986
|
| 1987 IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); 1988 rum_set_macaddr(sc, ic->ic_myaddr); 1989
|
2215 /* initialize ASIC */
| 1990 /* initialize ASIC */
|
2216 rum_cfg_write(sc, RT2573_MAC_CSR1, 4);
| 1991 rum_write(sc, RT2573_MAC_CSR1, 4);
|
2217 2218 /*
| 1992 1993 /*
|
2219 * make sure that the first transaction 2220 * clears the stall:
| 1994 * Allocate Tx and Rx xfer queues.
|
2221 */
| 1995 */
|
2222 sc->sc_flags |= (RUM_FLAG_READ_STALL | 2223 RUM_FLAG_WRITE_STALL | 2224 RUM_FLAG_LL_READY);
| 1996 rum_setup_tx_list(sc);
|
2225
| 1997
|
2226 if ((sc->sc_flags & RUM_FLAG_LL_READY) && 2227 (sc->sc_flags & RUM_FLAG_HL_READY)) { 2228 struct ifnet *ifp = sc->sc_ifp; 2229 struct ieee80211com *ic = ifp->if_l2com; 2230 2231 /* 2232 * start the USB transfers, if not already started: 2233 */ 2234 usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_RD]); 2235 usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]); 2236 2237 /* 2238 * start IEEE802.11 layer 2239 */ 2240 mtx_unlock(&sc->sc_mtx); 2241 ieee80211_start_all(ic); 2242 mtx_lock(&sc->sc_mtx); 2243 }
| |
2244 /* update Rx filter */
| 1998 /* update Rx filter */
|
2245 tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0) & 0xffff;
| 1999 tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
|
2246 2247 tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
| 2000 2001 tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
|
2248 2249 if (cc->ic_opmode != IEEE80211_M_MONITOR) {
| 2002 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
|
2250 tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
| 2003 tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
|
2251 RT2573_DROP_ACKCTS; 2252 if (cc->ic_opmode != IEEE80211_M_HOSTAP) {
| 2004 RT2573_DROP_ACKCTS; 2005 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
|
2253 tmp |= RT2573_DROP_TODS;
| 2006 tmp |= RT2573_DROP_TODS;
|
2254 } 2255 if (!(cc->if_flags & IFF_PROMISC)) {
| 2007 if (!(ifp->if_flags & IFF_PROMISC))
|
2256 tmp |= RT2573_DROP_NOT_TO_ME;
| 2008 tmp |= RT2573_DROP_NOT_TO_ME;
|
2257 }
| |
2258 }
| 2009 }
|
2259 rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp);
| 2010 rum_write(sc, RT2573_TXRX_CSR0, tmp);
|
2260
| 2011
|
| 2012 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 2013 ifp->if_drv_flags |= IFF_DRV_RUNNING; 2014 usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
|
2261 return; 2262
| 2015 return; 2016
|
2263fail: 2264 rum_cfg_pre_stop(sc, NULL, 0); 2265 2266 if (cc) { 2267 rum_cfg_stop(sc, cc, 0); 2268 }
| 2017fail: rum_stop_task(pm); 2018#undef N
|
2269} 2270 2271static void
| 2019} 2020 2021static void
|
2272rum_cfg_pre_stop(struct rum_softc *sc, 2273 struct usb2_config_td_cc *cc, uint16_t refcount)
| 2022rum_init(void *priv)
|
2274{
| 2023{
|
| 2024 struct rum_softc *sc = priv;
|
2275 struct ifnet *ifp = sc->sc_ifp;
| 2025 struct ifnet *ifp = sc->sc_ifp;
|
| 2026 struct ieee80211com *ic = ifp->if_l2com;
|
2276
| 2027
|
2277 if (cc) { 2278 /* copy the needed configuration */ 2279 rum_config_copy(sc, cc, refcount); 2280 } 2281 /* immediate configuration */
| 2028 RUM_LOCK(sc); 2029 rum_queue_command(sc, rum_init_task, 2030 &sc->sc_synctask[0].hdr, 2031 &sc->sc_synctask[1].hdr); 2032 RUM_UNLOCK(sc);
|
2282
| 2033
|
2283 if (ifp) { 2284 /* clear flags */ 2285 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 2286 } 2287 sc->sc_flags &= ~(RUM_FLAG_HL_READY | 2288 RUM_FLAG_LL_READY); 2289 2290 /* 2291 * stop all the transfers, if not already stopped: 2292 */ 2293 usb2_transfer_stop(sc->sc_xfer[RUM_BULK_DT_WR]); 2294 usb2_transfer_stop(sc->sc_xfer[RUM_BULK_DT_RD]); 2295 usb2_transfer_stop(sc->sc_xfer[RUM_BULK_CS_WR]); 2296 usb2_transfer_stop(sc->sc_xfer[RUM_BULK_CS_RD]); 2297 2298 /* clean up transmission */ 2299 rum_tx_clean_queue(sc);
| 2034 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 2035 ieee80211_start_all(ic); /* start all vap's */
|
2300} 2301 2302static void
| 2036} 2037 2038static void
|
2303rum_cfg_stop(struct rum_softc *sc, 2304 struct usb2_config_td_cc *cc, uint16_t refcount)
| 2039rum_stop_task(struct usb2_proc_msg *pm)
|
2305{
| 2040{
|
| 2041 struct rum_task *task = (struct rum_task *)pm; 2042 struct rum_softc *sc = task->sc; 2043 struct ifnet *ifp = sc->sc_ifp;
|
2306 uint32_t tmp; 2307
| 2044 uint32_t tmp; 2045
|
2308 /* disable Rx */ 2309 tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0); 2310 rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
| 2046 RUM_LOCK_ASSERT(sc, MA_OWNED);
|
2311
| 2047
|
2312 /* reset ASIC */ 2313 rum_cfg_write(sc, RT2573_MAC_CSR1, 3);
| 2048 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
2314
| 2049
|
2315 /* wait a little */ 2316 usb2_config_td_sleep(&sc->sc_config_td, hz / 10);
| 2050 RUM_UNLOCK(sc);
|
2317
| 2051
|
2318 rum_cfg_write(sc, RT2573_MAC_CSR1, 0);
| 2052 /* 2053 * Drain the USB transfers, if not already drained: 2054 */ 2055 usb2_transfer_drain(sc->sc_xfer[RUM_BULK_WR]); 2056 usb2_transfer_drain(sc->sc_xfer[RUM_BULK_RD]);
|
2319
| 2057
|
2320 /* wait a little */ 2321 usb2_config_td_sleep(&sc->sc_config_td, hz / 10); 2322}
| 2058 RUM_LOCK(sc);
|
2323
| 2059
|
2324static void 2325rum_cfg_amrr_start(struct rum_softc *sc) 2326{ 2327 struct ieee80211vap *vap; 2328 struct ieee80211_node *ni;
| 2060 rum_unsetup_tx_list(sc);
|
2329
| 2061
|
2330 vap = rum_get_vap(sc);
| 2062 /* disable Rx */ 2063 tmp = rum_read(sc, RT2573_TXRX_CSR0); 2064 rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
|
2331
| 2065
|
2332 if (vap == NULL) { 2333 return; 2334 } 2335 ni = vap->iv_bss; 2336 if (ni == NULL) { 2337 return; 2338 } 2339 /* init AMRR */ 2340 2341 ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni); 2342 2343 /* enable AMRR timer */ 2344 2345 sc->sc_amrr_timer = 1;
| 2066 /* reset ASIC */ 2067 rum_write(sc, RT2573_MAC_CSR1, 3); 2068 rum_write(sc, RT2573_MAC_CSR1, 0);
|
2346} 2347
| 2069} 2070
|
2348static void 2349rum_cfg_amrr_timeout(struct rum_softc *sc, 2350 struct usb2_config_td_cc *cc, uint16_t refcount)
| 2071static int 2072rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size)
|
2351{
| 2073{
|
2352 struct ifnet *ifp = sc->sc_ifp; 2353 struct ieee80211vap *vap; 2354 struct ieee80211_node *ni; 2355 uint32_t ok; 2356 uint32_t fail; 2357 2358 /* clear statistic registers (STA_CSR0 to STA_CSR5) */ 2359 rum_cfg_read_multi(sc, RT2573_STA_CSR0, sc->sc_sta, sizeof(sc->sc_sta)); 2360 2361 vap = rum_get_vap(sc); 2362 if (vap == NULL) { 2363 return; 2364 } 2365 ni = vap->iv_bss; 2366 if (ni == NULL) { 2367 return; 2368 } 2369 if ((sc->sc_flags & RUM_FLAG_LL_READY) && 2370 (sc->sc_flags & RUM_FLAG_HL_READY)) { 2371 2372 ok = (le32toh(sc->sc_sta[4]) >> 16) + /* TX ok w/o retry */ 2373 (le32toh(sc->sc_sta[5]) & 0xffff); /* TX ok w/ retry */ 2374 fail = (le32toh(sc->sc_sta[5]) >> 16); /* TX retry-fail count */ 2375 2376 if (sc->sc_amrr_timer) { 2377 ieee80211_amrr_tx_update(&RUM_NODE(vap->iv_bss)->amn, 2378 ok + fail, ok, (le32toh(sc->sc_sta[5]) & 0xffff) + fail); 2379 2380 if (ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn)) { 2381 /* ignore */ 2382 } 2383 } 2384 ifp->if_oerrors += fail;/* count TX retry-fail as Tx errors */ 2385 } 2386} 2387 2388static void 2389rum_cfg_load_microcode(struct rum_softc *sc, const uint8_t *ucode, uint16_t size) 2390{
| |
2391 struct usb2_device_request req; 2392 uint16_t reg = RT2573_MCU_CODE_BASE;
| 2074 struct usb2_device_request req; 2075 uint16_t reg = RT2573_MCU_CODE_BASE;
|
| 2076 usb2_error_t error;
|
2393 2394 /* copy firmware image into NIC */
| 2077 2078 /* copy firmware image into NIC */
|
2395 while (size >= 4) { 2396 rum_cfg_write(sc, reg, UGETDW(ucode)); 2397 reg += 4; 2398 ucode += 4; 2399 size -= 4; 2400 }
| 2079 for (; size >= 4; reg += 4, ucode += 4, size -= 4) 2080 rum_write(sc, reg, UGETDW(ucode));
|
2401
| 2081
|
2402 if (size != 0) { 2403 DPRINTF("possibly invalid firmware\n"); 2404 }
| |
2405 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 2406 req.bRequest = RT2573_MCU_CNTL; 2407 USETW(req.wValue, RT2573_MCU_RUN); 2408 USETW(req.wIndex, 0); 2409 USETW(req.wLength, 0); 2410
| 2082 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 2083 req.bRequest = RT2573_MCU_CNTL; 2084 USETW(req.wValue, RT2573_MCU_RUN); 2085 USETW(req.wIndex, 0); 2086 USETW(req.wLength, 0); 2087
|
2411 rum_cfg_do_request(sc, &req, NULL);
| 2088 error = rum_do_request(sc, &req, NULL); 2089 if (error != 0) { 2090 device_printf(sc->sc_dev, "could not run firmware: %s\n", 2091 usb2_errstr(error)); 2092 } 2093 return error;
|
2412} 2413
| 2094} 2095
|
2414static void 2415rum_cfg_prepare_beacon(struct rum_softc *sc, 2416 struct usb2_config_td_cc *cc, uint16_t refcount)
| 2096static int 2097rum_prepare_beacon(struct rum_softc *sc, struct ieee80211vap *vap)
|
2417{
| 2098{
|
2418 struct ieee80211_node *ni; 2419 struct ieee80211vap *vap; 2420 struct ieee80211com *ic;
| 2099 struct ieee80211com *ic = vap->iv_ic;
|
2421 const struct ieee80211_txparam *tp;
| 2100 const struct ieee80211_txparam *tp;
|
2422 struct mbuf *m;
| 2101 struct rum_tx_desc desc; 2102 struct mbuf *m0;
|
2423
| 2103
|
2424 vap = rum_get_vap(sc); 2425 if (vap == NULL) { 2426 return;
| 2104 m0 = ieee80211_beacon_alloc(vap->iv_bss, &RUM_VAP(vap)->bo); 2105 if (m0 == NULL) { 2106 return ENOBUFS;
|
2427 }
| 2107 }
|
2428 ni = vap->iv_bss; 2429 if (ni == NULL) { 2430 return; 2431 } 2432 ic = vap->iv_ic; 2433 if (ic == NULL) { 2434 return; 2435 } 2436 DPRINTFN(11, "Sending beacon frame.\n");
| |
2437
| 2108
|
2438 m = ieee80211_beacon_alloc(ni, &RUM_VAP(vap)->bo); 2439 if (m == NULL) { 2440 DPRINTFN(0, "could not allocate beacon\n"); 2441 return; 2442 }
| |
2443 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
| 2109 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
|
| 2110 rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ, 2111 m0->m_pkthdr.len, tp->mgmtrate);
|
2444
| 2112
|
2445 m->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ni); 2446 rum_setup_desc_and_tx(sc, m, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ | RT2573_TX_BEACON, tp->mgmtrate);
| 2113 /* copy the first 24 bytes of Tx descriptor into NIC memory */ 2114 rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24); 2115 2116 /* copy beacon header and payload into NIC memory */ 2117 rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *), 2118 m0->m_pkthdr.len); 2119 2120 m_freem(m0); 2121 2122 return 0;
|
2447} 2448
| 2123} 2124
|
2449static uint8_t 2450rum_get_rssi(struct rum_softc *sc, uint8_t raw)
| 2125static int 2126rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2127 const struct ieee80211_bpf_params *params)
|
2451{
| 2128{
|
2452 struct ifnet *ifp = sc->sc_ifp; 2453 struct ieee80211com *ic = ifp->if_l2com; 2454 int16_t rssi; 2455 uint8_t lna; 2456 uint8_t agc;
| 2129 struct ifnet *ifp = ni->ni_ic->ic_ifp; 2130 struct rum_softc *sc = ifp->if_softc;
|
2457
| 2131
|
2458 lna = (raw >> 5) & 0x3; 2459 agc = raw & 0x1f; 2460 2461 if (lna == 0) { 2462 /* 2463 * No RSSI mapping 2464 * 2465 * NB: Since RSSI is relative to noise floor, -1 is 2466 * adequate for caller to know error happened. 2467 */ 2468 return (0);
| 2132 RUM_LOCK(sc); 2133 /* prevent management frames from being sent if we're not ready */ 2134 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 2135 RUM_UNLOCK(sc); 2136 m_freem(m); 2137 ieee80211_free_node(ni); 2138 return ENETDOWN;
|
2469 }
| 2139 }
|
2470 rssi = (2 * agc) - RT2573_NOISE_FLOOR;
| 2140 if (sc->tx_nfree == 0) { 2141 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 2142 RUM_UNLOCK(sc); 2143 m_freem(m); 2144 ieee80211_free_node(ni); 2145 return EIO; 2146 }
|
2471
| 2147
|
2472 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
| 2148 ifp->if_opackets++;
|
2473
| 2149
|
2474 rssi += sc->sc_rssi_2ghz_corr; 2475 2476 if (lna == 1) 2477 rssi -= 64; 2478 else if (lna == 2) 2479 rssi -= 74; 2480 else if (lna == 3) 2481 rssi -= 90;
| 2150 if (params == NULL) { 2151 /* 2152 * Legacy path; interpret frame contents to decide 2153 * precisely how to send the frame. 2154 */ 2155 if (rum_tx_mgt(sc, m, ni) != 0) 2156 goto bad;
|
2482 } else {
| 2157 } else {
|
2483 2484 rssi += sc->sc_rssi_5ghz_corr; 2485 2486 if ((!sc->sc_ext_5ghz_lna) && (lna != 1)) 2487 rssi += 4; 2488 2489 if (lna == 1) 2490 rssi -= 64; 2491 else if (lna == 2) 2492 rssi -= 86; 2493 else if (lna == 3) 2494 rssi -= 100;
| 2158 /* 2159 * Caller supplied explicit parameters to use in 2160 * sending the frame. 2161 */ 2162 if (rum_tx_raw(sc, m, ni, params) != 0) 2163 goto bad;
|
2495 }
| 2164 }
|
| 2165 RUM_UNLOCK(sc);
|
2496
| 2166
|
2497 /* range check */ 2498 2499 if (rssi < 0) 2500 rssi = 0; 2501 else if (rssi > 255) 2502 rssi = 255; 2503 2504 return (rssi);
| 2167 return 0; 2168bad: 2169 ifp->if_oerrors++; 2170 RUM_UNLOCK(sc); 2171 ieee80211_free_node(ni); 2172 return EIO;
|
2505} 2506
| 2173} 2174
|
2507static struct ieee80211vap * 2508rum_vap_create(struct ieee80211com *ic, 2509 const char name[IFNAMSIZ], int unit, int opmode, int flags, 2510 const uint8_t bssid[IEEE80211_ADDR_LEN], 2511 const uint8_t mac[IEEE80211_ADDR_LEN])
| 2175static void 2176rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
|
2512{
| 2177{
|
2513 struct rum_vap *rvp; 2514 struct ieee80211vap *vap; 2515 struct rum_softc *sc = ic->ic_ifp->if_softc;
| 2178 struct ieee80211vap *vap = ni->ni_vap; 2179 struct rum_vap *rvp = RUM_VAP(vap);
|
2516
| 2180
|
2517 DPRINTF("\n");
| 2181 /* clear statistic registers (STA_CSR0 to STA_CSR5) */ 2182 rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
|
2518
| 2183
|
2519 /* Need to sync with config thread: */ 2520 mtx_lock(&sc->sc_mtx); 2521 if (usb2_config_td_sync(&sc->sc_config_td)) { 2522 mtx_unlock(&sc->sc_mtx); 2523 /* config thread is gone */ 2524 return (NULL); 2525 } 2526 mtx_unlock(&sc->sc_mtx);
| 2184 ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni);
|
2527
| 2185
|
2528 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 2529 return NULL; 2530 rvp = (struct rum_vap *)malloc(sizeof(struct rum_vap), 2531 M_80211_VAP, M_NOWAIT | M_ZERO); 2532 if (rvp == NULL) 2533 return NULL; 2534 vap = &rvp->vap; 2535 /* enable s/w bmiss handling for sta mode */ 2536 ieee80211_vap_setup(ic, vap, name, unit, opmode, 2537 flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
| 2186 usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); 2187}
|
2538
| 2188
|
2539 /* override state transition machine */ 2540 rvp->newstate = vap->iv_newstate; 2541 vap->iv_newstate = &rum_newstate_cb;
| 2189static void 2190rum_amrr_timeout(void *arg) 2191{ 2192 struct rum_vap *rvp = arg; 2193 struct rum_softc *sc = rvp->sc;
|
2542
| 2194
|
2543 ieee80211_amrr_init(&rvp->amrr, vap, 2544 IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, 2545 IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, 2546 1000 /* 1 sec */ ); 2547 2548 /* complete setup */ 2549 ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); 2550 2551 /* store current operation mode */ 2552 ic->ic_opmode = opmode; 2553 2554 return (vap);
| 2195 rum_queue_command(sc, rum_amrr_task, 2196 &rvp->amrr_task[0].hdr, &rvp->amrr_task[1].hdr);
|
2555} 2556 2557static void
| 2197} 2198 2199static void
|
2558rum_vap_delete(struct ieee80211vap *vap)
| 2200rum_amrr_task(struct usb2_proc_msg *pm)
|
2559{
| 2201{
|
| 2202 struct rum_task *task = (struct rum_task *)pm; 2203 struct rum_softc *sc = task->sc; 2204 struct ifnet *ifp = sc->sc_ifp; 2205 struct ieee80211com *ic = ifp->if_l2com; 2206 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
2560 struct rum_vap *rvp = RUM_VAP(vap);
| 2207 struct rum_vap *rvp = RUM_VAP(vap);
|
2561 struct rum_softc *sc = vap->iv_ic->ic_ifp->if_softc;
| 2208 struct ieee80211_node *ni = vap->iv_bss; 2209 int ok, fail;
|
2562
| 2210
|
2563 DPRINTF("\n");
| 2211 /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */ 2212 rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta));
|
2564
| 2213
|
2565 /* Need to sync with config thread: */ 2566 mtx_lock(&sc->sc_mtx); 2567 if (usb2_config_td_sync(&sc->sc_config_td)) { 2568 /* ignore */ 2569 } 2570 mtx_unlock(&sc->sc_mtx);
| 2214 ok = (le32toh(sc->sta[4]) >> 16) + /* TX ok w/o retry */ 2215 (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */ 2216 fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */
|
2571
| 2217
|
2572 ieee80211_amrr_cleanup(&rvp->amrr); 2573 ieee80211_vap_detach(vap); 2574 free(rvp, M_80211_VAP);
| 2218 ieee80211_amrr_tx_update(&RUM_NODE(ni)->amn, 2219 ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail); 2220 (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn); 2221 2222 ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ 2223 2224 usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
|
2575} 2576 2577/* ARGUSED */ 2578static struct ieee80211_node * 2579rum_node_alloc(struct ieee80211vap *vap __unused,
| 2225} 2226 2227/* ARGUSED */ 2228static struct ieee80211_node * 2229rum_node_alloc(struct ieee80211vap *vap __unused,
|
2580 const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
| 2230 const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
|
2581{ 2582 struct rum_node *rn; 2583 2584 rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO);
| 2231{ 2232 struct rum_node *rn; 2233 2234 rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO);
|
2585 return ((rn != NULL) ? &rn->ni : NULL);
| 2235 return rn != NULL ? &rn->ni : NULL;
|
2586} 2587 2588static void 2589rum_newassoc(struct ieee80211_node *ni, int isnew) 2590{ 2591 struct ieee80211vap *vap = ni->ni_vap; 2592 2593 ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni); 2594} 2595 2596static void
| 2236} 2237 2238static void 2239rum_newassoc(struct ieee80211_node *ni, int isnew) 2240{ 2241 struct ieee80211vap *vap = ni->ni_vap; 2242 2243 ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni); 2244} 2245 2246static void
|
2597rum_fill_write_queue(struct rum_softc *sc)
| 2247rum_scan_start(struct ieee80211com *ic)
|
2598{
| 2248{
|
2599 struct ifnet *ifp = sc->sc_ifp; 2600 struct ieee80211_node *ni; 2601 struct mbuf *m;
| 2249 struct rum_softc *sc = ic->ic_ifp->if_softc;
|
2602
| 2250
|
2603 /* 2604 * We only fill up half of the queue with data frames. The rest is 2605 * reserved for other kinds of frames. 2606 */
| 2251 RUM_LOCK(sc); 2252 /* do it in a process context */ 2253 sc->sc_scan_action = RUM_SCAN_START; 2254 rum_queue_command(sc, rum_scantask, 2255 &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); 2256 RUM_UNLOCK(sc);
|
2607
| 2257
|
2608 while (sc->sc_tx_queue.ifq_len < (IFQ_MAXLEN / 2)) { 2609 2610 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 2611 if (m == NULL) 2612 break; 2613 2614 ni = (void *)(m->m_pkthdr.rcvif); 2615 m = ieee80211_encap(ni, m); 2616 if (m == NULL) { 2617 ieee80211_free_node(ni); 2618 continue; 2619 } 2620 rum_tx_data(sc, m, ni); 2621 }
| |
2622} 2623 2624static void
| 2258} 2259 2260static void
|
2625rum_tx_clean_queue(struct rum_softc *sc)
| 2261rum_scan_end(struct ieee80211com *ic)
|
2626{
| 2262{
|
2627 struct mbuf *m;
| 2263 struct rum_softc *sc = ic->ic_ifp->if_softc;
|
2628
| 2264
|
2629 for (;;) { 2630 _IF_DEQUEUE(&sc->sc_tx_queue, m);
| 2265 RUM_LOCK(sc); 2266 /* do it in a process context */ 2267 sc->sc_scan_action = RUM_SCAN_END; 2268 rum_queue_command(sc, rum_scantask, 2269 &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); 2270 RUM_UNLOCK(sc);
|
2631
| 2271
|
2632 if (!m) { 2633 break; 2634 } 2635 rum_tx_freem(m); 2636 }
| |
2637} 2638 2639static void
| 2272} 2273 2274static void
|
2640rum_tx_freem(struct mbuf *m)
| 2275rum_set_channel(struct ieee80211com *ic)
|
2641{
| 2276{
|
2642 struct ieee80211_node *ni;
| 2277 struct rum_softc *sc = ic->ic_ifp->if_softc;
|
2643
| 2278
|
2644 while (m) { 2645 ni = (void *)(m->m_pkthdr.rcvif); 2646 if (!ni) { 2647 m = m_free(m); 2648 continue; 2649 } 2650 if (m->m_flags & M_TXCB) { 2651 ieee80211_process_callback(ni, m, 0); 2652 } 2653 m_freem(m); 2654 ieee80211_free_node(ni);
| 2279 RUM_LOCK(sc); 2280 /* do it in a process context */ 2281 sc->sc_scan_action = RUM_SET_CHANNEL; 2282 rum_queue_command(sc, rum_scantask, 2283 &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
|
2655
| 2284
|
2656 break; 2657 }
| 2285 sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); 2286 RUM_UNLOCK(sc);
|
2658} 2659 2660static void
| 2287} 2288 2289static void
|
2661rum_tx_mgt(struct rum_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
| 2290rum_scantask(struct usb2_proc_msg *pm)
|
2662{
| 2291{
|
2663 struct ieee80211vap *vap = ni->ni_vap; 2664 struct ieee80211com *ic = ni->ni_ic; 2665 const struct ieee80211_txparam *tp; 2666 struct ieee80211_frame *wh; 2667 struct ieee80211_key *k; 2668 uint32_t flags; 2669 uint16_t dur;
| 2292 struct rum_task *task = (struct rum_task *)pm; 2293 struct rum_softc *sc = task->sc; 2294 struct ifnet *ifp = sc->sc_ifp; 2295 struct ieee80211com *ic = ifp->if_l2com; 2296 uint32_t tmp;
|
2670
| 2297
|
2671 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
| 2298 RUM_LOCK_ASSERT(sc, MA_OWNED);
|
2672
| 2299
|
2673 wh = mtod(m, struct ieee80211_frame *); 2674 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2675 k = ieee80211_crypto_encap(ni, m); 2676 if (k == NULL) { 2677 m_freem(m); 2678 ieee80211_free_node(ni); 2679 return; 2680 } 2681 wh = mtod(m, struct ieee80211_frame *); 2682 } 2683 flags = 0; 2684 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 2685 flags |= RT2573_TX_NEED_ACK;
| 2300 switch (sc->sc_scan_action) { 2301 case RUM_SCAN_START: 2302 /* abort TSF synchronization */ 2303 tmp = rum_read(sc, RT2573_TXRX_CSR9); 2304 rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); 2305 rum_set_bssid(sc, ifp->if_broadcastaddr); 2306 break;
|
2686
| 2307
|
2687 dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate, 2688 ic->ic_flags & IEEE80211_F_SHPREAMBLE); 2689 USETW(wh->i_dur, dur);
| 2308 case RUM_SET_CHANNEL: 2309 rum_set_chan(sc, ic->ic_curchan); 2310 break;
|
2690
| 2311
|
2691 /* tell hardware to add timestamp for probe responses */ 2692 if ((wh->i_fc[0] & 2693 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == 2694 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) 2695 flags |= RT2573_TX_TIMESTAMP;
| 2312 default: /* RUM_SCAN_END */ 2313 rum_enable_tsf_sync(sc); 2314 rum_set_bssid(sc, sc->sc_bssid); 2315 break;
|
2696 }
| 2316 }
|
2697 m->m_pkthdr.rcvif = (void *)ni; 2698 rum_setup_desc_and_tx(sc, m, flags, 0, tp->mgmtrate);
| |
2699} 2700
| 2317} 2318
|
2701static struct ieee80211vap * 2702rum_get_vap(struct rum_softc *sc)
| 2319static int 2320rum_get_rssi(struct rum_softc *sc, uint8_t raw)
|
2703{
| 2321{
|
2704 struct ifnet *ifp; 2705 struct ieee80211com *ic;
| 2322 struct ifnet *ifp = sc->sc_ifp; 2323 struct ieee80211com *ic = ifp->if_l2com; 2324 int lna, agc, rssi;
|
2706
| 2325
|
2707 if (sc == NULL) { 2708 return NULL;
| 2326 lna = (raw >> 5) & 0x3; 2327 agc = raw & 0x1f; 2328 2329 if (lna == 0) { 2330 /* 2331 * No RSSI mapping 2332 * 2333 * NB: Since RSSI is relative to noise floor, -1 is 2334 * adequate for caller to know error happened. 2335 */ 2336 return -1;
|
2709 }
| 2337 }
|
2710 ifp = sc->sc_ifp; 2711 if (ifp == NULL) { 2712 return NULL; 2713 } 2714 ic = ifp->if_l2com; 2715 if (ic == NULL) { 2716 return NULL; 2717 } 2718 return TAILQ_FIRST(&ic->ic_vaps); 2719}
| |
2720
| 2338
|
2721static void 2722rum_tx_data(struct rum_softc *sc, struct mbuf *m, 2723 struct ieee80211_node *ni) 2724{ 2725 struct ieee80211vap *vap = ni->ni_vap; 2726 struct ieee80211com *ic = ni->ni_ic; 2727 const struct ieee80211_txparam *tp; 2728 struct ieee80211_frame *wh; 2729 struct ieee80211_key *k; 2730 uint32_t flags = 0; 2731 uint16_t dur; 2732 uint16_t rate;
| 2339 rssi = (2 * agc) - RT2573_NOISE_FLOOR;
|
2733
| 2340
|
2734 DPRINTFN(11, "Sending data.\n");
| 2341 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 2342 rssi += sc->rssi_2ghz_corr;
|
2735
| 2343
|
2736 wh = mtod(m, struct ieee80211_frame *);
| 2344 if (lna == 1) 2345 rssi -= 64; 2346 else if (lna == 2) 2347 rssi -= 74; 2348 else if (lna == 3) 2349 rssi -= 90; 2350 } else { 2351 rssi += sc->rssi_5ghz_corr;
|
2737
| 2352
|
2738 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; 2739 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) 2740 rate = tp->mcastrate; 2741 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 2742 rate = tp->ucastrate; 2743 else 2744 rate = ni->ni_txrate;
| 2353 if (!sc->ext_5ghz_lna && lna != 1) 2354 rssi += 4;
|
2745
| 2355
|
2746 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2747 k = ieee80211_crypto_encap(ni, m); 2748 if (k == NULL) { 2749 m_freem(m); 2750 ieee80211_free_node(ni); 2751 return; 2752 } 2753 /* packet header may have moved, reset our local pointer */ 2754 wh = mtod(m, struct ieee80211_frame *);
| 2356 if (lna == 1) 2357 rssi -= 64; 2358 else if (lna == 2) 2359 rssi -= 86; 2360 else if (lna == 3) 2361 rssi -= 100;
|
2755 }
| 2362 }
|
2756 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 2757 uint8_t prot = IEEE80211_PROT_NONE; 2758 2759 if (m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 2760 prot = IEEE80211_PROT_RTSCTS; 2761 else if ((ic->ic_flags & IEEE80211_F_USEPROT) && 2762 ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) 2763 prot = ic->ic_protmode; 2764 if (prot != IEEE80211_PROT_NONE) { 2765 rum_tx_prot(sc, m, ni, prot, rate); 2766 flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; 2767 } 2768 flags |= RT2573_TX_NEED_ACK; 2769 flags |= RT2573_TX_MORE_FRAG; 2770 2771 dur = ieee80211_ack_duration(sc->sc_rates, rate, 2772 ic->ic_flags & IEEE80211_F_SHPREAMBLE); 2773 USETW(wh->i_dur, dur); 2774 } 2775 m->m_pkthdr.rcvif = (void *)ni; 2776 rum_setup_desc_and_tx(sc, m, flags, 0, rate);
| 2363 return rssi;
|
2777} 2778 2779static void
| 2364} 2365 2366static void
|
2780rum_tx_prot(struct rum_softc *sc, 2781 const struct mbuf *m, struct ieee80211_node *ni, 2782 uint8_t prot, uint16_t rate)
| 2367rum_queue_command(struct rum_softc *sc, usb2_proc_callback_t *fn, 2368 struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
|
2783{
| 2369{
|
2784 struct ieee80211com *ic = ni->ni_ic; 2785 const struct ieee80211_frame *wh; 2786 struct mbuf *mprot; 2787 uint32_t flags; 2788 uint16_t protrate; 2789 uint16_t ackrate; 2790 uint16_t pktlen; 2791 uint16_t dur; 2792 uint8_t isshort;
| 2370 struct rum_task *task;
|
2793
| 2371
|
2794 KASSERT((prot == IEEE80211_PROT_RTSCTS) || 2795 (prot == IEEE80211_PROT_CTSONLY), 2796 ("protection %u", prot));
| 2372 RUM_LOCK_ASSERT(sc, MA_OWNED);
|
2797
| 2373
|
2798 DPRINTFN(11, "Sending protection frame.\n"); 2799 2800 wh = mtod(m, const struct ieee80211_frame *); 2801 pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; 2802 2803 protrate = ieee80211_ctl_rate(sc->sc_rates, rate); 2804 ackrate = ieee80211_ack_rate(sc->sc_rates, rate); 2805 2806 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 2807 dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); 2808 +ieee80211_ack_duration(sc->sc_rates, rate, isshort); 2809 flags = RT2573_TX_MORE_FRAG; 2810 if (prot == IEEE80211_PROT_RTSCTS) { 2811 /* NB: CTS is the same size as an ACK */ 2812 dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); 2813 flags |= RT2573_TX_NEED_ACK; 2814 mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); 2815 } else { 2816 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
| 2374 if (usb2_proc_is_gone(&sc->sc_tq)) { 2375 DPRINTF("proc is gone\n"); 2376 return; /* nothing to do */
|
2817 }
| 2377 }
|
2818 if (mprot == NULL) { 2819 return; 2820 } 2821 mprot->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ni); 2822 rum_setup_desc_and_tx(sc, mprot, flags, 0, protrate); 2823}
| 2378 /* 2379 * NOTE: The task cannot get executed before we drop the 2380 * "sc_mtx" mutex. It is safe to update fields in the message 2381 * structure after that the message got queued. 2382 */ 2383 task = (struct rum_task *) 2384 usb2_proc_msignal(&sc->sc_tq, t0, t1);
|
2824
| 2385
|
2825static void 2826rum_tx_raw(struct rum_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2827 const struct ieee80211_bpf_params *params) 2828{ 2829 uint32_t flags; 2830 uint16_t rate;
| 2386 /* Setup callback and softc pointers */ 2387 task->hdr.pm_callback = fn; 2388 task->sc = sc;
|
2831
| 2389
|
2832 DPRINTFN(11, "Sending raw frame.\n"); 2833 2834 rate = params->ibp_rate0 & IEEE80211_RATE_VAL; 2835 2836 /* XXX validate */ 2837 if (rate == 0) { 2838 m_freem(m); 2839 ieee80211_free_node(ni); 2840 return; 2841 } 2842 flags = 0; 2843 if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) 2844 flags |= RT2573_TX_NEED_ACK; 2845 if (params->ibp_flags & (IEEE80211_BPF_RTS | IEEE80211_BPF_CTS)) { 2846 rum_tx_prot(sc, m, ni, 2847 params->ibp_flags & IEEE80211_BPF_RTS ? 2848 IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, 2849 rate); 2850 flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; 2851 } 2852 m->m_pkthdr.rcvif = (void *)ni; 2853 rum_setup_desc_and_tx(sc, m, flags, 0, rate);
| 2390 /* 2391 * Init and stop must be synchronous! 2392 */ 2393 if ((fn == rum_init_task) || (fn == rum_stop_task)) 2394 usb2_proc_mwait(&sc->sc_tq, t0, t1);
|
2854} 2855
| 2395} 2396
|
2856static int 2857rum_raw_xmit_cb(struct ieee80211_node *ni, struct mbuf *m, 2858 const struct ieee80211_bpf_params *params) 2859{ 2860 struct ieee80211com *ic = ni->ni_ic; 2861 struct ifnet *ifp = ic->ic_ifp; 2862 struct rum_softc *sc = ifp->if_softc;
| 2397static device_method_t rum_methods[] = { 2398 /* Device interface */ 2399 DEVMETHOD(device_probe, rum_match), 2400 DEVMETHOD(device_attach, rum_attach), 2401 DEVMETHOD(device_detach, rum_detach),
|
2863
| 2402
|
2864 mtx_lock(&sc->sc_mtx); 2865 if (params == NULL) { 2866 /* 2867 * Legacy path; interpret frame contents to decide 2868 * precisely how to send the frame. 2869 */ 2870 rum_tx_mgt(sc, m, ni); 2871 } else { 2872 /* 2873 * Caller supplied explicit parameters to use in 2874 * sending the frame. 2875 */ 2876 rum_tx_raw(sc, m, ni, params); 2877 } 2878 mtx_unlock(&sc->sc_mtx); 2879 return (0); 2880}
| 2403 { 0, 0 } 2404};
|
2881
| 2405
|
2882static void 2883rum_update_mcast_cb(struct ifnet *ifp) 2884{ 2885 /* not supported */ 2886}
| 2406static driver_t rum_driver = { 2407 .name = "rum", 2408 .methods = rum_methods, 2409 .size = sizeof(struct rum_softc), 2410};
|
2887
| 2411
|
2888static void 2889rum_update_promisc_cb(struct ifnet *ifp) 2890{ 2891 struct rum_softc *sc = ifp->if_softc;
| 2412static devclass_t rum_devclass;
|
2892
| 2413
|
2893 mtx_lock(&sc->sc_mtx); 2894 usb2_config_td_queue_command 2895 (&sc->sc_config_td, &rum_config_copy, 2896 &rum_cfg_update_promisc, 0, 0); 2897 mtx_unlock(&sc->sc_mtx); 2898}
| 2414DRIVER_MODULE(rum, ushub, rum_driver, rum_devclass, NULL, 0);
|
| |