Deleted Added
full compact
0a1,2
> /* $FreeBSD: head/sys/dev/usb2/wlan/if_rum2.c 188417 2009-02-09 22:12:47Z thompsa $ */
>
19,23d20
< /*
< * NOTE: all function names beginning like "rum_cfg_" can only
< * be called from within the config thread function !
< */
<
25c22
< __FBSDID("$FreeBSD: head/sys/dev/usb2/wlan/if_rum2.c 188234 2009-02-06 15:03:17Z kevlo $");
---
> __FBSDID("$FreeBSD: head/sys/dev/usb2/wlan/if_rum2.c 188417 2009-02-09 22:12:47Z thompsa $");
37,39d33
< #define usb2_config_td_cc rum_config_copy
< #define usb2_config_td_softc rum_softc
<
45d38
< #include <dev/usb2/core/usb2_config_td.h>
64c57,58
< /* prototypes */
---
> #define rum_do_request(sc,req,data) \
> usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000)
66c60,115
< static device_probe_t rum_probe;
---
> static const struct usb2_device_id rum_devs[] = {
> { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM) },
> { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2) },
> { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3) },
> { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4) },
> { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700) },
> { USB_VP(USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO) },
> { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1) },
> { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2) },
> { USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A) },
> { USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3) },
> { USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC) },
> { USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR) },
> { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2) },
> { USB_VP(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL) },
> { USB_VP(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX) },
> { USB_VP(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F) },
> { USB_VP(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573) },
> { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1) },
> { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340) },
> { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111) },
> { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110) },
> { USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS) },
> { USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS) },
> { USB_VP(USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573) },
> { USB_VP(USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573) },
> { USB_VP(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB) },
> { USB_VP(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP) },
> { USB_VP(USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G) },
> { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP) },
> { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP) },
> { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1) },
> { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2) },
> { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3) },
> { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4) },
> { USB_VP(USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573) },
> { USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP) },
> { USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2) },
> { USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM) },
> { USB_VP(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573) },
> { USB_VP(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2) },
> { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573) },
> { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2) },
> { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671) },
> { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2) },
> { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172) },
> { USB_VP(USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573) },
> { USB_VP(USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573) },
> };
>
> MODULE_DEPEND(rum, wlan, 1, 1, 1);
> MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1);
> MODULE_DEPEND(rum, usb2_wlan, 1, 1, 1);
> MODULE_DEPEND(rum, usb2_core, 1, 1, 1);
>
> static device_probe_t rum_match;
71d119
< static usb2_callback_t rum_bulk_read_clear_stall_callback;
73d120
< static usb2_callback_t rum_bulk_write_clear_stall_callback;
75,93c122,128
< static usb2_config_td_command_t rum_cfg_first_time_setup;
< static usb2_config_td_command_t rum_config_copy;
< static usb2_config_td_command_t rum_cfg_scan_start;
< static usb2_config_td_command_t rum_cfg_scan_end;
< static usb2_config_td_command_t rum_cfg_select_band;
< static usb2_config_td_command_t rum_cfg_set_chan;
< static usb2_config_td_command_t rum_cfg_enable_tsf_sync;
< static usb2_config_td_command_t rum_cfg_enable_mrr;
< static usb2_config_td_command_t rum_cfg_update_slot;
< static usb2_config_td_command_t rum_cfg_select_antenna;
< static usb2_config_td_command_t rum_cfg_set_txpreamble;
< static usb2_config_td_command_t rum_cfg_update_promisc;
< static usb2_config_td_command_t rum_cfg_pre_init;
< static usb2_config_td_command_t rum_cfg_init;
< static usb2_config_td_command_t rum_cfg_pre_stop;
< static usb2_config_td_command_t rum_cfg_stop;
< static usb2_config_td_command_t rum_cfg_amrr_timeout;
< static usb2_config_td_command_t rum_cfg_prepare_beacon;
< static usb2_config_td_command_t rum_cfg_newstate;
---
> static usb2_proc_callback_t rum_attach_post;
> static usb2_proc_callback_t rum_task;
> static usb2_proc_callback_t rum_scantask;
> static usb2_proc_callback_t rum_promisctask;
> static usb2_proc_callback_t rum_amrr_task;
> static usb2_proc_callback_t rum_init_task;
> static usb2_proc_callback_t rum_stop_task;
95,127d129
< static const char *rum_get_rf(uint32_t);
< static int rum_ioctl_cb(struct ifnet *, u_long, caddr_t);
< static void rum_std_command(struct ieee80211com *, usb2_config_td_command_t *);
< static void rum_scan_start_cb(struct ieee80211com *);
< static void rum_scan_end_cb(struct ieee80211com *);
< static void rum_set_channel_cb(struct ieee80211com *);
< static uint16_t rum_cfg_eeprom_read_2(struct rum_softc *, uint16_t);
< static uint32_t rum_cfg_bbp_disbusy(struct rum_softc *);
< static uint32_t rum_cfg_read(struct rum_softc *, uint16_t);
< static uint8_t rum_cfg_bbp_init(struct rum_softc *);
< static uint8_t rum_cfg_bbp_read(struct rum_softc *, uint8_t);
< static void rum_cfg_amrr_start(struct rum_softc *);
< static void rum_cfg_bbp_write(struct rum_softc *, uint8_t, uint8_t);
< static void rum_cfg_do_request(struct rum_softc *,
< struct usb2_device_request *, void *);
< static void rum_cfg_eeprom_read(struct rum_softc *, uint16_t, void *,
< uint16_t);
< static void rum_cfg_load_microcode(struct rum_softc *, const uint8_t *,
< uint16_t);
< static void rum_cfg_read_eeprom(struct rum_softc *);
< static void rum_cfg_read_multi(struct rum_softc *, uint16_t, void *,
< uint16_t);
< static void rum_cfg_rf_write(struct rum_softc *, uint8_t, uint32_t);
< static void rum_cfg_set_bssid(struct rum_softc *, uint8_t *);
< static void rum_cfg_set_macaddr(struct rum_softc *, uint8_t *);
< static void rum_cfg_write(struct rum_softc *, uint16_t, uint32_t);
< static void rum_cfg_write_multi(struct rum_softc *, uint16_t, void *,
< uint16_t);
< static void rum_end_of_commands(struct rum_softc *);
< static void rum_init_cb(void *);
< static void rum_start_cb(struct ifnet *);
< static void rum_watchdog(void *);
< static uint8_t rum_get_rssi(struct rum_softc *, uint8_t);
129,131c131,184
< const char[], int, int, int, const uint8_t[],
< const uint8_t[]);
< static void rum_vap_delete(struct ieee80211vap *);
---
> const char name[IFNAMSIZ], int unit, int opmode,
> int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
> const uint8_t mac[IEEE80211_ADDR_LEN]);
> static void rum_vap_delete(struct ieee80211vap *);
> static void rum_tx_free(struct rum_tx_data *, int);
> static void rum_setup_tx_list(struct rum_softc *);
> static void rum_unsetup_tx_list(struct rum_softc *);
> static int rum_newstate(struct ieee80211vap *,
> enum ieee80211_state, int);
> static void rum_setup_tx_desc(struct rum_softc *,
> struct rum_tx_desc *, uint32_t, uint16_t, int,
> int);
> static int rum_tx_mgt(struct rum_softc *, struct mbuf *,
> struct ieee80211_node *);
> static int rum_tx_raw(struct rum_softc *, struct mbuf *,
> struct ieee80211_node *,
> const struct ieee80211_bpf_params *);
> static int rum_tx_data(struct rum_softc *, struct mbuf *,
> struct ieee80211_node *);
> static void rum_start(struct ifnet *);
> static int rum_ioctl(struct ifnet *, u_long, caddr_t);
> static void rum_eeprom_read(struct rum_softc *, uint16_t, void *,
> int);
> static uint32_t rum_read(struct rum_softc *, uint16_t);
> static void rum_read_multi(struct rum_softc *, uint16_t, void *,
> int);
> static void rum_write(struct rum_softc *, uint16_t, uint32_t);
> static void rum_write_multi(struct rum_softc *, uint16_t, void *,
> size_t);
> static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t);
> static uint8_t rum_bbp_read(struct rum_softc *, uint8_t);
> static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t);
> static void rum_select_antenna(struct rum_softc *);
> static void rum_enable_mrr(struct rum_softc *);
> static void rum_set_txpreamble(struct rum_softc *);
> static void rum_set_basicrates(struct rum_softc *);
> static void rum_select_band(struct rum_softc *,
> struct ieee80211_channel *);
> static void rum_set_chan(struct rum_softc *,
> struct ieee80211_channel *);
> static void rum_enable_tsf_sync(struct rum_softc *);
> static void rum_update_slot(struct ifnet *);
> static void rum_set_bssid(struct rum_softc *, const uint8_t *);
> static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
> static const char *rum_get_rf(int);
> static void rum_read_eeprom(struct rum_softc *);
> static int rum_bbp_init(struct rum_softc *);
> static void rum_init(void *);
> static int rum_load_microcode(struct rum_softc *, const u_char *,
> size_t);
> static int rum_prepare_beacon(struct rum_softc *,
> struct ieee80211vap *);
> static int rum_raw_xmit(struct ieee80211_node *, struct mbuf *,
> const struct ieee80211_bpf_params *);
133,157c186,197
< const uint8_t[]);
< static void rum_newassoc(struct ieee80211_node *, int);
< static void rum_cfg_disable_tsf_sync(struct rum_softc *);
< static void rum_cfg_set_run(struct rum_softc *, struct rum_config_copy *);
< static void rum_fill_write_queue(struct rum_softc *);
< static void rum_tx_clean_queue(struct rum_softc *);
< static void rum_tx_freem(struct mbuf *);
< static void rum_tx_mgt(struct rum_softc *, struct mbuf *,
< struct ieee80211_node *);
< static struct ieee80211vap *rum_get_vap(struct rum_softc *);
< static void rum_tx_data(struct rum_softc *, struct mbuf *,
< struct ieee80211_node *);
< static void rum_tx_prot(struct rum_softc *, const struct mbuf *,
< struct ieee80211_node *, uint8_t, uint16_t);
< static void rum_tx_raw(struct rum_softc *, struct mbuf *,
< struct ieee80211_node *,
< const struct ieee80211_bpf_params *);
< static int rum_raw_xmit_cb(struct ieee80211_node *, struct mbuf *,
< const struct ieee80211_bpf_params *);
< static void rum_setup_desc_and_tx(struct rum_softc *, struct mbuf *,
< uint32_t, uint16_t, uint16_t);
< static int rum_newstate_cb(struct ieee80211vap *,
< enum ieee80211_state nstate, int arg);
< static void rum_update_mcast_cb(struct ifnet *);
< static void rum_update_promisc_cb(struct ifnet *);
---
> const uint8_t mac[IEEE80211_ADDR_LEN]);
> static void rum_newassoc(struct ieee80211_node *, int);
> static void rum_scan_start(struct ieee80211com *);
> static void rum_scan_end(struct ieee80211com *);
> static void rum_set_channel(struct ieee80211com *);
> static int rum_get_rssi(struct rum_softc *, uint8_t);
> static void rum_amrr_start(struct rum_softc *,
> struct ieee80211_node *);
> static void rum_amrr_timeout(void *);
> static void rum_queue_command(struct rum_softc *,
> usb2_proc_callback_t *, struct usb2_proc_msg *,
> struct usb2_proc_msg *);
159,208c199,224
< /* various supported device vendors/products */
< static const struct usb2_device_id rum_devs[] = {
< {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM, 0)},
< {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2, 0)},
< {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3, 0)},
< {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4, 0)},
< {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700, 0)},
< {USB_VPI(USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO, 0)},
< {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1, 0)},
< {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2, 0)},
< {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A, 0)},
< {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3, 0)},
< {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC, 0)},
< {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR, 0)},
< {USB_VPI(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2, 0)},
< {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL, 0)},
< {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX, 0)},
< {USB_VPI(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F, 0)},
< {USB_VPI(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573, 0)},
< {USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1, 0)},
< {USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340, 0)},
< {USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111, 0)},
< {USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110, 0)},
< {USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS, 0)},
< {USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS, 0)},
< {USB_VPI(USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573, 0)},
< {USB_VPI(USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573, 0)},
< {USB_VPI(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB, 0)},
< {USB_VPI(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP, 0)},
< {USB_VPI(USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G, 0)},
< {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP, 0)},
< {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP, 0)},
< {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HG, 0)},
< {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1, 0)},
< {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2, 0)},
< {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3, 0)},
< {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4, 0)},
< {USB_VPI(USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573, 0)},
< {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP, 0)},
< {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2, 0)},
< {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM, 0)},
< {USB_VPI(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573, 0)},
< {USB_VPI(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2, 0)},
< {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573, 0)},
< {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2, 0)},
< {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671, 0)},
< {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2, 0)},
< {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172, 0)},
< {USB_VPI(USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573, 0)},
< {USB_VPI(USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573, 0)},
---
> static const struct {
> uint32_t reg;
> uint32_t val;
> } rum_def_mac[] = {
> { RT2573_TXRX_CSR0, 0x025fb032 },
> { RT2573_TXRX_CSR1, 0x9eaa9eaf },
> { RT2573_TXRX_CSR2, 0x8a8b8c8d },
> { RT2573_TXRX_CSR3, 0x00858687 },
> { RT2573_TXRX_CSR7, 0x2e31353b },
> { RT2573_TXRX_CSR8, 0x2a2a2a2c },
> { RT2573_TXRX_CSR15, 0x0000000f },
> { RT2573_MAC_CSR6, 0x00000fff },
> { RT2573_MAC_CSR8, 0x016c030a },
> { RT2573_MAC_CSR10, 0x00000718 },
> { RT2573_MAC_CSR12, 0x00000004 },
> { RT2573_MAC_CSR13, 0x00007f00 },
> { RT2573_SEC_CSR0, 0x00000000 },
> { RT2573_SEC_CSR1, 0x00000000 },
> { RT2573_SEC_CSR5, 0x00000000 },
> { RT2573_PHY_CSR1, 0x000023b0 },
> { RT2573_PHY_CSR5, 0x00040a06 },
> { RT2573_PHY_CSR6, 0x00080606 },
> { RT2573_PHY_CSR7, 0x00000408 },
> { RT2573_AIFSN_CSR, 0x00002273 },
> { RT2573_CWMIN_CSR, 0x00002344 },
> { RT2573_CWMAX_CSR, 0x000034aa }
211,241c227
< struct rum_def_mac {
< uint32_t reg;
< uint32_t val;
< };
<
< static const struct rum_def_mac rum_def_mac[] = {
< {RT2573_TXRX_CSR0, 0x025fb032},
< {RT2573_TXRX_CSR1, 0x9eaa9eaf},
< {RT2573_TXRX_CSR2, 0x8a8b8c8d},
< {RT2573_TXRX_CSR3, 0x00858687},
< {RT2573_TXRX_CSR7, 0x2e31353b},
< {RT2573_TXRX_CSR8, 0x2a2a2a2c},
< {RT2573_TXRX_CSR15, 0x0000000f},
< {RT2573_MAC_CSR6, 0x00000fff},
< {RT2573_MAC_CSR8, 0x016c030a},
< {RT2573_MAC_CSR10, 0x00000718},
< {RT2573_MAC_CSR12, 0x00000004},
< {RT2573_MAC_CSR13, 0x00007f00},
< {RT2573_SEC_CSR0, 0x00000000},
< {RT2573_SEC_CSR1, 0x00000000},
< {RT2573_SEC_CSR5, 0x00000000},
< {RT2573_PHY_CSR1, 0x000023b0},
< {RT2573_PHY_CSR5, 0x00040a06},
< {RT2573_PHY_CSR6, 0x00080606},
< {RT2573_PHY_CSR7, 0x00000408},
< {RT2573_AIFSN_CSR, 0x00002273},
< {RT2573_CWMIN_CSR, 0x00002344},
< {RT2573_CWMAX_CSR, 0x000034aa}
< };
<
< struct rum_def_bbp {
---
> static const struct {
243a230,256
> } rum_def_bbp[] = {
> { 3, 0x80 },
> { 15, 0x30 },
> { 17, 0x20 },
> { 21, 0xc8 },
> { 22, 0x38 },
> { 23, 0x06 },
> { 24, 0xfe },
> { 25, 0x0a },
> { 26, 0x0d },
> { 32, 0x0b },
> { 34, 0x12 },
> { 37, 0x07 },
> { 39, 0xf8 },
> { 41, 0x60 },
> { 53, 0x10 },
> { 54, 0x18 },
> { 60, 0x10 },
> { 61, 0x04 },
> { 62, 0x04 },
> { 75, 0xfe },
> { 86, 0xfe },
> { 88, 0xfe },
> { 90, 0x0f },
> { 99, 0x00 },
> { 102, 0x16 },
> { 107, 0x04 }
246,273c259,276
< static const struct rum_def_bbp rum_def_bbp[] = {
< {3, 0x80},
< {15, 0x30},
< {17, 0x20},
< {21, 0xc8},
< {22, 0x38},
< {23, 0x06},
< {24, 0xfe},
< {25, 0x0a},
< {26, 0x0d},
< {32, 0x0b},
< {34, 0x12},
< {37, 0x07},
< {39, 0xf8},
< {41, 0x60},
< {53, 0x10},
< {54, 0x18},
< {60, 0x10},
< {61, 0x04},
< {62, 0x04},
< {75, 0xfe},
< {86, 0xfe},
< {88, 0xfe},
< {90, 0x0f},
< {99, 0x00},
< {102, 0x16},
< {107, 0x04}
< };
---
> static const struct rfprog {
> uint8_t chan;
> uint32_t r1, r2, r3, r4;
> } rum_rf5226[] = {
> { 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 },
> { 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 },
> { 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 },
> { 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 },
> { 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 },
> { 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 },
> { 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 },
> { 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 },
> { 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 },
> { 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 },
> { 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 },
> { 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 },
> { 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 },
> { 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
275,278c278,281
< struct rfprog {
< uint8_t chan;
< uint32_t r1, r2, r3, r4;
< };
---
> { 34, 0x00b03, 0x20266, 0x36014, 0x30282 },
> { 38, 0x00b03, 0x20267, 0x36014, 0x30284 },
> { 42, 0x00b03, 0x20268, 0x36014, 0x30286 },
> { 46, 0x00b03, 0x20269, 0x36014, 0x30288 },
280,294c283,290
< static const struct rfprog rum_rf5226[] = {
< {1, 0x00b03, 0x001e1, 0x1a014, 0x30282},
< {2, 0x00b03, 0x001e1, 0x1a014, 0x30287},
< {3, 0x00b03, 0x001e2, 0x1a014, 0x30282},
< {4, 0x00b03, 0x001e2, 0x1a014, 0x30287},
< {5, 0x00b03, 0x001e3, 0x1a014, 0x30282},
< {6, 0x00b03, 0x001e3, 0x1a014, 0x30287},
< {7, 0x00b03, 0x001e4, 0x1a014, 0x30282},
< {8, 0x00b03, 0x001e4, 0x1a014, 0x30287},
< {9, 0x00b03, 0x001e5, 0x1a014, 0x30282},
< {10, 0x00b03, 0x001e5, 0x1a014, 0x30287},
< {11, 0x00b03, 0x001e6, 0x1a014, 0x30282},
< {12, 0x00b03, 0x001e6, 0x1a014, 0x30287},
< {13, 0x00b03, 0x001e7, 0x1a014, 0x30282},
< {14, 0x00b03, 0x001e8, 0x1a014, 0x30284},
---
> { 36, 0x00b03, 0x00266, 0x26014, 0x30288 },
> { 40, 0x00b03, 0x00268, 0x26014, 0x30280 },
> { 44, 0x00b03, 0x00269, 0x26014, 0x30282 },
> { 48, 0x00b03, 0x0026a, 0x26014, 0x30284 },
> { 52, 0x00b03, 0x0026b, 0x26014, 0x30286 },
> { 56, 0x00b03, 0x0026c, 0x26014, 0x30288 },
> { 60, 0x00b03, 0x0026e, 0x26014, 0x30280 },
> { 64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
296,299c292,302
< {34, 0x00b03, 0x20266, 0x36014, 0x30282},
< {38, 0x00b03, 0x20267, 0x36014, 0x30284},
< {42, 0x00b03, 0x20268, 0x36014, 0x30286},
< {46, 0x00b03, 0x20269, 0x36014, 0x30288},
---
> { 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 },
> { 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 },
> { 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 },
> { 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 },
> { 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 },
> { 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 },
> { 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 },
> { 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 },
> { 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 },
> { 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 },
> { 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
301,308c304,323
< {36, 0x00b03, 0x00266, 0x26014, 0x30288},
< {40, 0x00b03, 0x00268, 0x26014, 0x30280},
< {44, 0x00b03, 0x00269, 0x26014, 0x30282},
< {48, 0x00b03, 0x0026a, 0x26014, 0x30284},
< {52, 0x00b03, 0x0026b, 0x26014, 0x30286},
< {56, 0x00b03, 0x0026c, 0x26014, 0x30288},
< {60, 0x00b03, 0x0026e, 0x26014, 0x30280},
< {64, 0x00b03, 0x0026f, 0x26014, 0x30282},
---
> { 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 },
> { 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 },
> { 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 },
> { 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 },
> { 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 }
> }, rum_rf5225[] = {
> { 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },
> { 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },
> { 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },
> { 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },
> { 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },
> { 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },
> { 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },
> { 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },
> { 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },
> { 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },
> { 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },
> { 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },
> { 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },
> { 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
310,320c325,328
< {100, 0x00b03, 0x0028a, 0x2e014, 0x30280},
< {104, 0x00b03, 0x0028b, 0x2e014, 0x30282},
< {108, 0x00b03, 0x0028c, 0x2e014, 0x30284},
< {112, 0x00b03, 0x0028d, 0x2e014, 0x30286},
< {116, 0x00b03, 0x0028e, 0x2e014, 0x30288},
< {120, 0x00b03, 0x002a0, 0x2e014, 0x30280},
< {124, 0x00b03, 0x002a1, 0x2e014, 0x30282},
< {128, 0x00b03, 0x002a2, 0x2e014, 0x30284},
< {132, 0x00b03, 0x002a3, 0x2e014, 0x30286},
< {136, 0x00b03, 0x002a4, 0x2e014, 0x30288},
< {140, 0x00b03, 0x002a6, 0x2e014, 0x30280},
---
> { 34, 0x00b33, 0x01266, 0x26014, 0x30282 },
> { 38, 0x00b33, 0x01267, 0x26014, 0x30284 },
> { 42, 0x00b33, 0x01268, 0x26014, 0x30286 },
> { 46, 0x00b33, 0x01269, 0x26014, 0x30288 },
322,327c330,337
< {149, 0x00b03, 0x002a8, 0x2e014, 0x30287},
< {153, 0x00b03, 0x002a9, 0x2e014, 0x30289},
< {157, 0x00b03, 0x002ab, 0x2e014, 0x30281},
< {161, 0x00b03, 0x002ac, 0x2e014, 0x30283},
< {165, 0x00b03, 0x002ad, 0x2e014, 0x30285}
< };
---
> { 36, 0x00b33, 0x01266, 0x26014, 0x30288 },
> { 40, 0x00b33, 0x01268, 0x26014, 0x30280 },
> { 44, 0x00b33, 0x01269, 0x26014, 0x30282 },
> { 48, 0x00b33, 0x0126a, 0x26014, 0x30284 },
> { 52, 0x00b33, 0x0126b, 0x26014, 0x30286 },
> { 56, 0x00b33, 0x0126c, 0x26014, 0x30288 },
> { 60, 0x00b33, 0x0126e, 0x26014, 0x30280 },
> { 64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
329,343c339,349
< static const struct rfprog rum_rf5225[] = {
< {1, 0x00b33, 0x011e1, 0x1a014, 0x30282},
< {2, 0x00b33, 0x011e1, 0x1a014, 0x30287},
< {3, 0x00b33, 0x011e2, 0x1a014, 0x30282},
< {4, 0x00b33, 0x011e2, 0x1a014, 0x30287},
< {5, 0x00b33, 0x011e3, 0x1a014, 0x30282},
< {6, 0x00b33, 0x011e3, 0x1a014, 0x30287},
< {7, 0x00b33, 0x011e4, 0x1a014, 0x30282},
< {8, 0x00b33, 0x011e4, 0x1a014, 0x30287},
< {9, 0x00b33, 0x011e5, 0x1a014, 0x30282},
< {10, 0x00b33, 0x011e5, 0x1a014, 0x30287},
< {11, 0x00b33, 0x011e6, 0x1a014, 0x30282},
< {12, 0x00b33, 0x011e6, 0x1a014, 0x30287},
< {13, 0x00b33, 0x011e7, 0x1a014, 0x30282},
< {14, 0x00b33, 0x011e8, 0x1a014, 0x30284},
---
> { 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },
> { 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },
> { 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },
> { 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },
> { 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },
> { 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },
> { 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },
> { 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },
> { 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },
> { 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },
> { 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
345,375c351,355
< {34, 0x00b33, 0x01266, 0x26014, 0x30282},
< {38, 0x00b33, 0x01267, 0x26014, 0x30284},
< {42, 0x00b33, 0x01268, 0x26014, 0x30286},
< {46, 0x00b33, 0x01269, 0x26014, 0x30288},
<
< {36, 0x00b33, 0x01266, 0x26014, 0x30288},
< {40, 0x00b33, 0x01268, 0x26014, 0x30280},
< {44, 0x00b33, 0x01269, 0x26014, 0x30282},
< {48, 0x00b33, 0x0126a, 0x26014, 0x30284},
< {52, 0x00b33, 0x0126b, 0x26014, 0x30286},
< {56, 0x00b33, 0x0126c, 0x26014, 0x30288},
< {60, 0x00b33, 0x0126e, 0x26014, 0x30280},
< {64, 0x00b33, 0x0126f, 0x26014, 0x30282},
<
< {100, 0x00b33, 0x0128a, 0x2e014, 0x30280},
< {104, 0x00b33, 0x0128b, 0x2e014, 0x30282},
< {108, 0x00b33, 0x0128c, 0x2e014, 0x30284},
< {112, 0x00b33, 0x0128d, 0x2e014, 0x30286},
< {116, 0x00b33, 0x0128e, 0x2e014, 0x30288},
< {120, 0x00b33, 0x012a0, 0x2e014, 0x30280},
< {124, 0x00b33, 0x012a1, 0x2e014, 0x30282},
< {128, 0x00b33, 0x012a2, 0x2e014, 0x30284},
< {132, 0x00b33, 0x012a3, 0x2e014, 0x30286},
< {136, 0x00b33, 0x012a4, 0x2e014, 0x30288},
< {140, 0x00b33, 0x012a6, 0x2e014, 0x30280},
<
< {149, 0x00b33, 0x012a8, 0x2e014, 0x30287},
< {153, 0x00b33, 0x012a9, 0x2e014, 0x30289},
< {157, 0x00b33, 0x012ab, 0x2e014, 0x30281},
< {161, 0x00b33, 0x012ac, 0x2e014, 0x30283},
< {165, 0x00b33, 0x012ad, 0x2e014, 0x30285}
---
> { 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },
> { 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },
> { 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },
> { 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },
> { 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
379c359
< [RUM_BULK_DT_WR] = {
---
> [RUM_BULK_WR] = {
385c365
< .mh.callback = &rum_bulk_write_callback,
---
> .mh.callback = rum_bulk_write_callback,
388,389c368
<
< [RUM_BULK_DT_RD] = {
---
> [RUM_BULK_RD] = {
395c374
< .mh.callback = &rum_bulk_read_callback,
---
> .mh.callback = rum_bulk_read_callback,
397,416d375
<
< [RUM_BULK_CS_WR] = {
< .type = UE_CONTROL,
< .endpoint = 0x00, /* Control pipe */
< .direction = UE_DIR_ANY,
< .mh.bufsize = sizeof(struct usb2_device_request),
< .mh.callback = &rum_bulk_write_clear_stall_callback,
< .mh.timeout = 1000, /* 1 second */
< .mh.interval = 50, /* 50ms */
< },
<
< [RUM_BULK_CS_RD] = {
< .type = UE_CONTROL,
< .endpoint = 0x00, /* Control pipe */
< .direction = UE_DIR_ANY,
< .mh.bufsize = sizeof(struct usb2_device_request),
< .mh.callback = &rum_bulk_read_clear_stall_callback,
< .mh.timeout = 1000, /* 1 second */
< .mh.interval = 50, /* 50ms */
< },
419,439d377
< static devclass_t rum_devclass;
<
< static device_method_t rum_methods[] = {
< DEVMETHOD(device_probe, rum_probe),
< DEVMETHOD(device_attach, rum_attach),
< DEVMETHOD(device_detach, rum_detach),
< {0, 0}
< };
<
< static driver_t rum_driver = {
< .name = "rum",
< .methods = rum_methods,
< .size = sizeof(struct rum_softc),
< };
<
< DRIVER_MODULE(rum, ushub, rum_driver, rum_devclass, NULL, 0);
< MODULE_DEPEND(rum, usb2_wlan, 1, 1, 1);
< MODULE_DEPEND(rum, usb2_core, 1, 1, 1);
< MODULE_DEPEND(rum, wlan, 1, 1, 1);
< MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1);
<
441c379
< rum_probe(device_t dev)
---
> rum_match(device_t self)
443c381
< struct usb2_attach_arg *uaa = device_get_ivars(dev);
---
> struct usb2_attach_arg *uaa = device_get_ivars(self);
445c383
< if (uaa->usb2_mode != USB_MODE_HOST) {
---
> if (uaa->usb2_mode != USB_MODE_HOST)
447,448c385
< }
< if (uaa->info.bConfigIndex != 0) {
---
> if (uaa->info.bConfigIndex != 0)
450,451c387
< }
< if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX) {
---
> if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX)
453c389
< }
---
>
458c394
< rum_attach(device_t dev)
---
> rum_attach(device_t self)
460,462c396,397
< struct usb2_attach_arg *uaa = device_get_ivars(dev);
< struct rum_softc *sc = device_get_softc(dev);
< int error;
---
> struct usb2_attach_arg *uaa = device_get_ivars(self);
> struct rum_softc *sc = device_get_softc(self);
463a399
> int error;
465,472c401
< device_set_usb2_desc(dev);
<
< mtx_init(&sc->sc_mtx, "rum lock", MTX_NETWORK_LOCK,
< MTX_DEF | MTX_RECURSE);
<
< snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
< device_get_nameunit(dev));
<
---
> device_set_usb2_desc(self);
474c403
< sc->sc_unit = device_get_unit(dev);
---
> sc->sc_dev = self;
476c405,406
< usb2_callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
---
> mtx_init(&sc->sc_mtx, device_get_nameunit(self),
> MTX_NETWORK_LOCK, MTX_DEF);
482c412
< device_printf(dev, "could not allocate USB transfers, "
---
> device_printf(self, "could not allocate USB transfers, "
486,488c416,417
< error = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_mtx,
< &rum_end_of_commands,
< sizeof(struct usb2_config_td_cc), 24);
---
> error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx,
> device_get_nameunit(self), USB_PRI_MED);
490,491c419
< device_printf(dev, "could not setup config "
< "thread!\n");
---
> device_printf(self, "could not setup config thread!\n");
494d421
< mtx_lock(&sc->sc_mtx);
496c423,429
< /* start setup */
---
> /* fork rest of the attach code */
> RUM_LOCK(sc);
> rum_queue_command(sc, rum_attach_post,
> &sc->sc_synctask[0].hdr,
> &sc->sc_synctask[1].hdr);
> RUM_UNLOCK(sc);
> return (0);
498,504d430
< usb2_config_td_queue_command
< (&sc->sc_config_td, NULL, &rum_cfg_first_time_setup, 0, 0);
<
< rum_watchdog(sc);
< mtx_unlock(&sc->sc_mtx);
< return (0); /* success */
<
506c432
< rum_detach(dev);
---
> rum_detach(self);
510,511c436,437
< static int
< rum_detach(device_t dev)
---
> static void
> rum_attach_post(struct usb2_proc_msg *pm)
513,514c439,440
< struct rum_softc *sc = device_get_softc(dev);
< struct ieee80211com *ic;
---
> struct rum_task *task = (struct rum_task *)pm;
> struct rum_softc *sc = task->sc;
515a442,446
> struct ieee80211com *ic;
> unsigned int ntries;
> int error;
> uint32_t tmp;
> uint8_t bands;
517c448,457
< usb2_config_td_drain(&sc->sc_config_td);
---
> /* retrieve RT2573 rev. no */
> for (ntries = 0; ntries != 1000; ntries++) {
> if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
> break;
> usb2_pause_mtx(&sc->sc_mtx, hz / 1000);
> }
> if (ntries == 1000) {
> device_printf(sc->sc_dev, "timeout waiting for chip to settle\n");
> return;
> }
519c459,460
< mtx_lock(&sc->sc_mtx);
---
> /* retrieve MAC address and various other things from EEPROM */
> rum_read_eeprom(sc);
521c462,463
< usb2_callout_stop(&sc->sc_watchdog);
---
> device_printf(sc->sc_dev, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
> tmp, rum_get_rf(sc->rf_rev));
523c465,471
< rum_cfg_pre_stop(sc, NULL, 0);
---
> error = rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode));
> if (error != 0) {
> RUM_UNLOCK(sc);
> device_printf(sc->sc_dev, "could not load 8051 microcode\n");
> return;
> }
> RUM_UNLOCK(sc);
525c473,478
< ifp = sc->sc_ifp;
---
> ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
> if (ifp == NULL) {
> device_printf(sc->sc_dev, "can not if_alloc()\n");
> RUM_LOCK(sc);
> return;
> }
528c481,489
< mtx_unlock(&sc->sc_mtx);
---
> ifp->if_softc = sc;
> if_initname(ifp, "rum", device_get_unit(sc->sc_dev));
> ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
> ifp->if_init = rum_init;
> ifp->if_ioctl = rum_ioctl;
> ifp->if_start = rum_start;
> IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
> ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
> IFQ_SET_READY(&ifp->if_snd);
530,531c491,493
< /* stop all USB transfers first */
< usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
---
> ic->ic_ifp = ifp;
> ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
> IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
533,534c495,506
< /* get rid of any late children */
< bus_generic_detach(dev);
---
> /* set device capabilities */
> ic->ic_caps =
> IEEE80211_C_STA /* station mode supported */
> | IEEE80211_C_IBSS /* IBSS mode supported */
> | IEEE80211_C_MONITOR /* monitor mode supported */
> | IEEE80211_C_HOSTAP /* HostAp mode supported */
> | IEEE80211_C_TXPMGT /* tx power management */
> | IEEE80211_C_SHPREAMBLE /* short preamble supported */
> | IEEE80211_C_SHSLOT /* short slot time supported */
> | IEEE80211_C_BGSCAN /* bg scanning supported */
> | IEEE80211_C_WPA /* 802.11i */
> ;
536,541c508,513
< if (ifp) {
< bpfdetach(ifp);
< ieee80211_ifdetach(ic);
< if_free(ifp);
< }
< usb2_config_td_unsetup(&sc->sc_config_td);
---
> bands = 0;
> setbit(&bands, IEEE80211_MODE_11B);
> setbit(&bands, IEEE80211_MODE_11G);
> if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226)
> setbit(&bands, IEEE80211_MODE_11A);
> ieee80211_init_channels(ic, NULL, &bands);
543c515,521
< usb2_callout_drain(&sc->sc_watchdog);
---
> ieee80211_ifattach(ic);
> ic->ic_newassoc = rum_newassoc;
> ic->ic_raw_xmit = rum_raw_xmit;
> ic->ic_node_alloc = rum_node_alloc;
> ic->ic_scan_start = rum_scan_start;
> ic->ic_scan_end = rum_scan_end;
> ic->ic_set_channel = rum_set_channel;
545c523,524
< mtx_destroy(&sc->sc_mtx);
---
> ic->ic_vap_create = rum_vap_create;
> ic->ic_vap_delete = rum_vap_delete;
547,548c526
< return (0);
< }
---
> sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
550,555c528,529
< static void
< rum_cfg_do_request(struct rum_softc *sc, struct usb2_device_request *req,
< void *data)
< {
< uint16_t length;
< usb2_error_t err;
---
> bpfattach(ifp, DLT_IEEE802_11_RADIO,
> sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
557c531,533
< repeat:
---
> sc->sc_rxtap_len = sizeof sc->sc_rxtap;
> sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
> sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
559,563c535,537
< if (usb2_config_td_is_gone(&sc->sc_config_td)) {
< goto error;
< }
< err = usb2_do_request_flags
< (sc->sc_udev, &sc->sc_mtx, req, data, 0, NULL, 1000);
---
> sc->sc_txtap_len = sizeof sc->sc_txtap;
> sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
> sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
565c539,540
< if (err) {
---
> if (bootverbose)
> ieee80211_announce(ic);
567,584c542
< DPRINTF("device request failed, err=%s "
< "(ignored)\n", usb2_errstr(err));
<
< /* wait a little before next try */
< if (usb2_config_td_sleep(&sc->sc_config_td, hz / 4)) {
< goto error;
< }
< /* try until we are detached */
< goto repeat;
<
< error:
< /* the device has been detached */
< length = UGETW(req->wLength);
<
< if ((req->bmRequestType & UT_READ) && length) {
< bzero(data, length);
< }
< }
---
> RUM_LOCK(sc);
587,588c545,546
< static void
< rum_cfg_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, uint16_t len)
---
> static int
> rum_detach(device_t self)
590c548,550
< struct usb2_device_request req;
---
> struct rum_softc *sc = device_get_softc(self);
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
592,596c552,553
< req.bmRequestType = UT_READ_VENDOR_DEVICE;
< req.bRequest = RT2573_READ_EEPROM;
< USETW(req.wValue, 0);
< USETW(req.wIndex, addr);
< USETW(req.wLength, len);
---
> /* wait for any post attach or other command to complete */
> usb2_proc_drain(&sc->sc_tq);
598,599c555,557
< rum_cfg_do_request(sc, &req, buf);
< }
---
> /* stop all USB transfers */
> usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
> usb2_proc_free(&sc->sc_tq);
601,604c559,562
< static uint16_t
< rum_cfg_eeprom_read_2(struct rum_softc *sc, uint16_t addr)
< {
< uint16_t tmp;
---
> /* free TX list, if any */
> RUM_LOCK(sc);
> rum_unsetup_tx_list(sc);
> RUM_UNLOCK(sc);
606,608c564,568
< rum_cfg_eeprom_read(sc, addr, &tmp, sizeof(tmp));
< return (le16toh(tmp));
< }
---
> if (ifp) {
> bpfdetach(ifp);
> ieee80211_ifdetach(ic);
> if_free(ifp);
> }
610,613c570
< static uint32_t
< rum_cfg_read(struct rum_softc *sc, uint16_t reg)
< {
< uint32_t val;
---
> mtx_destroy(&sc->sc_mtx);
615,616c572
< rum_cfg_read_multi(sc, reg, &val, sizeof(val));
< return (le32toh(val));
---
> return (0);
619,620c575,579
< static void
< rum_cfg_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, uint16_t len)
---
> static struct ieee80211vap *
> rum_vap_create(struct ieee80211com *ic,
> const char name[IFNAMSIZ], int unit, int opmode, int flags,
> const uint8_t bssid[IEEE80211_ADDR_LEN],
> const uint8_t mac[IEEE80211_ADDR_LEN])
622c581,583
< struct usb2_device_request req;
---
> struct rum_softc *sc = ic->ic_ifp->if_softc;
> struct rum_vap *rvp;
> struct ieee80211vap *vap;
624,628c585,594
< req.bmRequestType = UT_READ_VENDOR_DEVICE;
< req.bRequest = RT2573_READ_MULTI_MAC;
< USETW(req.wValue, 0);
< USETW(req.wIndex, reg);
< USETW(req.wLength, len);
---
> if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
> return NULL;
> rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap),
> M_80211_VAP, M_NOWAIT | M_ZERO);
> if (rvp == NULL)
> return NULL;
> vap = &rvp->vap;
> /* enable s/w bmiss handling for sta mode */
> ieee80211_vap_setup(ic, vap, name, unit, opmode,
> flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
630,631c596,598
< rum_cfg_do_request(sc, &req, buf);
< }
---
> /* override state transition machine */
> rvp->newstate = vap->iv_newstate;
> vap->iv_newstate = rum_newstate;
633,636c600,605
< static void
< rum_cfg_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
< {
< uint32_t tmp = htole32(val);
---
> rvp->sc = sc;
> usb2_callout_init_mtx(&rvp->amrr_ch, &sc->sc_mtx, 0);
> ieee80211_amrr_init(&rvp->amrr, vap,
> IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
> IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
> 1000 /* 1 sec */);
638c607,610
< rum_cfg_write_multi(sc, reg, &tmp, sizeof(tmp));
---
> /* complete setup */
> ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
> ic->ic_opmode = opmode;
> return vap;
642c614
< rum_cfg_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, uint16_t len)
---
> rum_vap_delete(struct ieee80211vap *vap)
644c616
< struct usb2_device_request req;
---
> struct rum_vap *rvp = RUM_VAP(vap);
646,652c618,621
< req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
< req.bRequest = RT2573_WRITE_MULTI_MAC;
< USETW(req.wValue, 0);
< USETW(req.wIndex, reg);
< USETW(req.wLength, len);
<
< rum_cfg_do_request(sc, &req, buf);
---
> usb2_callout_drain(&rvp->amrr_ch);
> ieee80211_amrr_cleanup(&rvp->amrr);
> ieee80211_vap_detach(vap);
> free(rvp, M_80211_VAP);
655,656c624,625
< static uint32_t
< rum_cfg_bbp_disbusy(struct rum_softc *sc)
---
> static void
> rum_tx_free(struct rum_tx_data *data, int txerr)
658,659c627
< uint32_t tmp;
< uint8_t to;
---
> struct rum_softc *sc = data->sc;
661,663c629,634
< for (to = 0;; to++) {
< if (to < 100) {
< tmp = rum_cfg_read(sc, RT2573_PHY_CSR3);
---
> if (data->m != NULL) {
> if (data->m->m_flags & M_TXCB)
> ieee80211_process_callback(data->ni, data->m,
> txerr ? ETIMEDOUT : 0);
> m_freem(data->m);
> data->m = NULL;
665,673c636,637
< if ((tmp & RT2573_BBP_BUSY) == 0) {
< return (tmp);
< }
< if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
< break;
< }
< } else {
< break;
< }
---
> ieee80211_free_node(data->ni);
> data->ni = NULL;
675,676c639,640
< DPRINTF("could not disbusy BBP\n");
< return (RT2573_BBP_BUSY); /* failure */
---
> STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
> sc->tx_nfree++;
680c644
< rum_cfg_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
---
> rum_setup_tx_list(struct rum_softc *sc)
682c646,647
< uint32_t tmp;
---
> struct rum_tx_data *data;
> int i;
684,689c649,651
< if (rum_cfg_bbp_disbusy(sc) & RT2573_BBP_BUSY) {
< return;
< }
< tmp = RT2573_BBP_BUSY | ((reg & 0x7f) << 8) | val;
< rum_cfg_write(sc, RT2573_PHY_CSR3, tmp);
< }
---
> sc->tx_nfree = 0;
> STAILQ_INIT(&sc->tx_q);
> STAILQ_INIT(&sc->tx_free);
691,694c653,654
< static uint8_t
< rum_cfg_bbp_read(struct rum_softc *sc, uint8_t reg)
< {
< uint32_t val;
---
> for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
> data = &sc->tx_data[i];
696,697c656,658
< if (rum_cfg_bbp_disbusy(sc) & RT2573_BBP_BUSY) {
< return (0);
---
> data->sc = sc;
> STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
> sc->tx_nfree++;
699,703d659
< val = RT2573_BBP_BUSY | RT2573_BBP_READ | (reg << 8);
< rum_cfg_write(sc, RT2573_PHY_CSR3, val);
<
< val = rum_cfg_bbp_disbusy(sc);
< return (val & 0xff);
707c663
< rum_cfg_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
---
> rum_unsetup_tx_list(struct rum_softc *sc)
709,710c665,666
< uint32_t tmp;
< uint8_t to;
---
> struct rum_tx_data *data;
> int i;
712c668,671
< reg &= 3;
---
> /* make sure any subsequent use of the queues will fail */
> sc->tx_nfree = 0;
> STAILQ_INIT(&sc->tx_q);
> STAILQ_INIT(&sc->tx_free);
714,725c673,679
< for (to = 0;; to++) {
< if (to < 100) {
< tmp = rum_cfg_read(sc, RT2573_PHY_CSR4);
< if (!(tmp & RT2573_RF_BUSY)) {
< break;
< }
< if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
< return;
< }
< } else {
< DPRINTF("could not write to RF\n");
< return;
---
> /* free up all node references and mbufs */
> for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
> data = &sc->tx_data[i];
>
> if (data->m != NULL) {
> m_freem(data->m);
> data->m = NULL;
726a681,684
> if (data->ni != NULL) {
> ieee80211_free_node(data->ni);
> data->ni = NULL;
> }
728,732d685
<
< tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | ((val & 0xfffff) << 2) | reg;
< rum_cfg_write(sc, RT2573_PHY_CSR4, tmp);
<
< DPRINTFN(16, "RF R[%u] <- 0x%05x\n", reg, val & 0xfffff);
736,737c689
< rum_cfg_first_time_setup(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> rum_task(struct usb2_proc_msg *pm)
739,740c691,699
< struct ieee80211com *ic;
< struct ifnet *ifp;
---
> struct rum_task *task = (struct rum_task *)pm;
> struct rum_softc *sc = task->sc;
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
> struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
> struct rum_vap *rvp = RUM_VAP(vap);
> const struct ieee80211_txparam *tp;
> enum ieee80211_state ostate;
> struct ieee80211_node *ni;
742,743d700
< uint16_t i;
< uint8_t bands;
745,748c702
< /* setup RX tap header */
< sc->sc_rxtap_len = sizeof(sc->sc_rxtap);
< sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
< sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
---
> ostate = vap->iv_state;
750,753c704,711
< /* setup TX tap header */
< sc->sc_txtap_len = sizeof(sc->sc_txtap);
< sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
< sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
---
> switch (sc->sc_state) {
> case IEEE80211_S_INIT:
> if (ostate == IEEE80211_S_RUN) {
> /* abort TSF synchronization */
> tmp = rum_read(sc, RT2573_TXRX_CSR9);
> rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
> }
> break;
755,756c713,714
< /* retrieve RT2573 rev. no */
< for (i = 0; i < 100; i++) {
---
> case IEEE80211_S_RUN:
> ni = vap->iv_bss;
758,760c716,722
< tmp = rum_cfg_read(sc, RT2573_MAC_CSR0);
< if (tmp != 0) {
< break;
---
> if (vap->iv_opmode != IEEE80211_M_MONITOR) {
> rum_update_slot(ic->ic_ifp);
> rum_enable_mrr(sc);
> rum_set_txpreamble(sc);
> rum_set_basicrates(sc);
> IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
> rum_set_bssid(sc, sc->sc_bssid);
762,767d723
< /* wait a little */
< if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
< /* device detached */
< goto done;
< }
< }
769,773c725,727
< if (tmp == 0) {
< DPRINTF("chip is maybe not ready\n");
< }
< /* retrieve MAC address and various other things from EEPROM */
< rum_cfg_read_eeprom(sc);
---
> if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
> vap->iv_opmode == IEEE80211_M_IBSS)
> rum_prepare_beacon(sc, vap);
775,776c729,730
< printf("%s: MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
< sc->sc_name, tmp, rum_get_rf(sc->sc_rf_rev));
---
> if (vap->iv_opmode != IEEE80211_M_MONITOR)
> rum_enable_tsf_sync(sc);
778,788c732,738
< rum_cfg_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode));
<
< mtx_unlock(&sc->sc_mtx);
<
< ifp = if_alloc(IFT_IEEE80211);
<
< mtx_lock(&sc->sc_mtx);
<
< if (ifp == NULL) {
< DPRINTFN(0, "could not if_alloc()!\n");
< goto done;
---
> /* enable automatic rate adaptation */
> tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
> if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
> rum_amrr_start(sc, ni);
> break;
> default:
> break;
790,791d739
< sc->sc_ifp = ifp;
< ic = ifp->if_l2com;
793,802c741,748
< ifp->if_softc = sc;
< if_initname(ifp, "rum", sc->sc_unit);
< ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
< ifp->if_init = &rum_init_cb;
< ifp->if_ioctl = &rum_ioctl_cb;
< ifp->if_start = &rum_start_cb;
< ifp->if_watchdog = NULL;
< IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
< ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
< IFQ_SET_READY(&ifp->if_snd);
---
> RUM_UNLOCK(sc);
> IEEE80211_LOCK(ic);
> rvp->newstate(vap, sc->sc_state, sc->sc_arg);
> if (vap->iv_newstate_cb != NULL)
> vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
> IEEE80211_UNLOCK(ic);
> RUM_LOCK(sc);
> }
804c750,755
< bcopy(sc->sc_myaddr, ic->ic_myaddr, sizeof(ic->ic_myaddr));
---
> static int
> rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
> {
> struct rum_vap *rvp = RUM_VAP(vap);
> struct ieee80211com *ic = vap->iv_ic;
> struct rum_softc *sc = ic->ic_ifp->if_softc;
806,808c757,759
< ic->ic_ifp = ifp;
< ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
< ic->ic_opmode = IEEE80211_M_STA;
---
> DPRINTF("%s -> %s\n",
> ieee80211_state_name[vap->iv_state],
> ieee80211_state_name[nstate]);
810,821c761,762
< /* set device capabilities */
< ic->ic_caps =
< IEEE80211_C_STA /* station mode supported */
< | IEEE80211_C_IBSS /* IBSS mode supported */
< | IEEE80211_C_MONITOR /* monitor mode supported */
< | IEEE80211_C_HOSTAP /* HostAp mode supported */
< | IEEE80211_C_TXPMGT /* tx power management */
< | IEEE80211_C_SHPREAMBLE /* short preamble supported */
< | IEEE80211_C_SHSLOT /* short slot time supported */
< | IEEE80211_C_BGSCAN /* bg scanning supported */
< | IEEE80211_C_WPA /* 802.11i */
< ;
---
> RUM_LOCK(sc);
> usb2_callout_stop(&rvp->amrr_ch);
823,826c764,767
< bands = 0;
< setbit(&bands, IEEE80211_MODE_11B);
< setbit(&bands, IEEE80211_MODE_11G);
< ieee80211_init_channels(ic, NULL, &bands);
---
> /* do it in a process context */
> sc->sc_state = nstate;
> sc->sc_arg = arg;
> RUM_UNLOCK(sc);
828,857c769,777
< if ((sc->sc_rf_rev == RT2573_RF_5225) ||
< (sc->sc_rf_rev == RT2573_RF_5226)) {
<
< struct ieee80211_channel *c;
<
< /* set supported .11a channels */
< for (i = 34; i <= 46; i += 4) {
< c = ic->ic_channels + (ic->ic_nchans++);
< c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
< c->ic_flags = IEEE80211_CHAN_A;
< c->ic_ieee = i;
< }
< for (i = 36; i <= 64; i += 4) {
< c = ic->ic_channels + (ic->ic_nchans++);
< c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
< c->ic_flags = IEEE80211_CHAN_A;
< c->ic_ieee = i;
< }
< for (i = 100; i <= 140; i += 4) {
< c = ic->ic_channels + (ic->ic_nchans++);
< c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
< c->ic_flags = IEEE80211_CHAN_A;
< c->ic_ieee = i;
< }
< for (i = 149; i <= 165; i += 4) {
< c = ic->ic_channels + (ic->ic_nchans++);
< c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
< c->ic_flags = IEEE80211_CHAN_A;
< c->ic_ieee = i;
< }
---
> if (nstate == IEEE80211_S_INIT) {
> rvp->newstate(vap, nstate, arg);
> return 0;
> } else {
> RUM_LOCK(sc);
> rum_queue_command(sc, rum_task, &sc->sc_task[0].hdr,
> &sc->sc_task[1].hdr);
> RUM_UNLOCK(sc);
> return EINPROGRESS;
859c779
< mtx_unlock(&sc->sc_mtx);
---
> }
861c781,790
< ieee80211_ifattach(ic);
---
> static void
> rum_bulk_write_callback(struct usb2_xfer *xfer)
> {
> struct rum_softc *sc = xfer->priv_sc;
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
> struct ieee80211_channel *c = ic->ic_curchan;
> struct rum_tx_data *data;
> struct mbuf *m;
> unsigned int len;
863c792,794
< mtx_lock(&sc->sc_mtx);
---
> switch (USB_GET_STATE(xfer)) {
> case USB_ST_TRANSFERRED:
> DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen);
865,874c796,799
< ic->ic_newassoc = &rum_newassoc;
< ic->ic_raw_xmit = &rum_raw_xmit_cb;
< ic->ic_node_alloc = &rum_node_alloc;
< ic->ic_update_mcast = &rum_update_mcast_cb;
< ic->ic_update_promisc = &rum_update_promisc_cb;
< ic->ic_scan_start = &rum_scan_start_cb;
< ic->ic_scan_end = &rum_scan_end_cb;
< ic->ic_set_channel = &rum_set_channel_cb;
< ic->ic_vap_create = &rum_vap_create;
< ic->ic_vap_delete = &rum_vap_delete;
---
> /* free resources */
> data = xfer->priv_fifo;
> rum_tx_free(data, 0);
> xfer->priv_fifo = NULL;
876c801,802
< sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
---
> ifp->if_opackets++;
> ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
878c804,810
< mtx_unlock(&sc->sc_mtx);
---
> /* FALLTHROUGH */
> case USB_ST_SETUP:
> tr_setup:
> data = STAILQ_FIRST(&sc->tx_q);
> if (data) {
> STAILQ_REMOVE_HEAD(&sc->tx_q, next);
> m = data->m;
880,881c812,820
< bpfattach(ifp, DLT_IEEE802_11_RADIO,
< sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap));
---
> if (m->m_pkthdr.len > (MCLBYTES + RT2573_TX_DESC_SIZE)) {
> DPRINTFN(0, "data overflow, %u bytes\n",
> m->m_pkthdr.len);
> m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE);
> }
> usb2_copy_in(xfer->frbuffers, 0, &data->desc,
> RT2573_TX_DESC_SIZE);
> usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m,
> 0, m->m_pkthdr.len);
883,889c822,823
< if (bootverbose) {
< ieee80211_announce(ic);
< }
< mtx_lock(&sc->sc_mtx);
< done:
< return;
< }
---
> if (bpf_peers_present(ifp->if_bpf)) {
> struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
891,894c825,829
< static void
< rum_end_of_commands(struct rum_softc *sc)
< {
< sc->sc_flags &= ~RUM_FLAG_WAIT_COMMAND;
---
> tap->wt_flags = 0;
> tap->wt_rate = data->rate;
> tap->wt_chan_freq = htole16(c->ic_freq);
> tap->wt_chan_flags = htole16(c->ic_flags);
> tap->wt_antenna = sc->tx_ant;
896,898c831,832
< /* start write transfer, if not started */
< usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]);
< }
---
> bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
> }
900,922c834,837
< static void
< rum_config_copy_chan(struct rum_config_copy_chan *cc,
< struct ieee80211com *ic, struct ieee80211_channel *c)
< {
< if (!c)
< return;
< cc->chan_to_ieee =
< ieee80211_chan2ieee(ic, c);
< if (c != IEEE80211_CHAN_ANYC) {
< cc->chan_to_mode =
< ieee80211_chan2mode(c);
< if (IEEE80211_IS_CHAN_B(c))
< cc->chan_is_b = 1;
< if (IEEE80211_IS_CHAN_A(c))
< cc->chan_is_a = 1;
< if (IEEE80211_IS_CHAN_2GHZ(c))
< cc->chan_is_2ghz = 1;
< if (IEEE80211_IS_CHAN_5GHZ(c))
< cc->chan_is_5ghz = 1;
< if (IEEE80211_IS_CHAN_ANYG(c))
< cc->chan_is_g = 1;
< }
< }
---
> /* align end on a 4-bytes boundary */
> len = (RT2573_TX_DESC_SIZE + m->m_pkthdr.len + 3) & ~3;
> if ((len % 64) == 0)
> len += 4;
924,932c839,840
< static void
< rum_config_copy(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
< {
< struct ifnet *ifp;
< struct ieee80211com *ic;
< struct ieee80211_node *ni;
< struct ieee80211vap *vap;
< const struct ieee80211_txparam *tp;
---
> DPRINTFN(11, "sending frame len=%u xferlen=%u\n",
> m->m_pkthdr.len, len);
934c842,843
< bzero(cc, sizeof(*cc));
---
> xfer->frlengths[0] = len;
> xfer->priv_fifo = data;
936,940c845,847
< ifp = sc->sc_ifp;
< if (ifp) {
< cc->if_flags = ifp->if_flags;
< bcopy(ifp->if_broadcastaddr, cc->if_broadcastaddr,
< sizeof(cc->if_broadcastaddr));
---
> usb2_start_hardware(xfer);
> }
> break;
942,962c849,851
< ic = ifp->if_l2com;
< if (ic) {
< rum_config_copy_chan(&cc->ic_curchan, ic, ic->ic_curchan);
< rum_config_copy_chan(&cc->ic_bsschan, ic, ic->ic_bsschan);
< vap = TAILQ_FIRST(&ic->ic_vaps);
< if (vap) {
< ni = vap->iv_bss;
< if (ni) {
< cc->iv_bss.ni_intval = ni->ni_intval;
< bcopy(ni->ni_bssid, cc->iv_bss.ni_bssid,
< sizeof(cc->iv_bss.ni_bssid));
< }
< tp = vap->iv_txparms + cc->ic_bsschan.chan_to_mode;
< if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) {
< cc->iv_bss.fixed_rate_none = 1;
< }
< }
< cc->ic_opmode = ic->ic_opmode;
< cc->ic_flags = ic->ic_flags;
< cc->ic_txpowlimit = ic->ic_txpowlimit;
< cc->ic_curmode = ic->ic_curmode;
---
> default: /* Error */
> DPRINTFN(11, "transfer error, %s\n",
> usb2_errstr(xfer->error));
964,965c853,857
< bcopy(ic->ic_myaddr, cc->ic_myaddr,
< sizeof(cc->ic_myaddr));
---
> ifp->if_oerrors++;
> data = xfer->priv_fifo;
> if (data != NULL) {
> rum_tx_free(data, xfer->error);
> xfer->priv_fifo = NULL;
967,969d858
< }
< sc->sc_flags |= RUM_FLAG_WAIT_COMMAND;
< }
971,985c860,867
< static const char *
< rum_get_rf(uint32_t rev)
< {
< ; /* indent fix */
< switch (rev) {
< case RT2573_RF_2527:
< return "RT2527 (MIMO XR)";
< case RT2573_RF_2528:
< return "RT2528";
< case RT2573_RF_5225:
< return "RT5225 (MIMO XR)";
< case RT2573_RF_5226:
< return "RT5226";
< default:
< return "unknown";
---
> if (xfer->error == USB_ERR_STALLED) {
> /* try to clear stall first */
> xfer->flags.stall_pipe = 1;
> goto tr_setup;
> }
> if (xfer->error == USB_ERR_TIMEOUT)
> device_printf(sc->sc_dev, "device timeout\n");
> break;
996d877
<
999d879
< uint32_t max_len;
1000a881
> unsigned int len;
1007,1009c888,891
< if (xfer->actlen < (RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN)) {
< DPRINTF("too short transfer, "
< "%d bytes\n", xfer->actlen);
---
> len = xfer->actlen;
> if (len < RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
> DPRINTF("%s: xfer too short %d\n",
> device_get_nameunit(sc->sc_dev), len);
1013,1014d894
< usb2_copy_out(xfer->frbuffers, 0,
< &sc->sc_rx_desc, RT2573_RX_DESC_SIZE);
1016c896,898
< flags = le32toh(sc->sc_rx_desc.flags);
---
> len -= RT2573_RX_DESC_SIZE;
> usb2_copy_out(xfer->frbuffers, 0, &sc->sc_rx_desc,
> RT2573_RX_DESC_SIZE);
1017a900,901
> rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi);
> flags = le32toh(sc->sc_rx_desc.flags);
1022c906
< * filled RAL_TXRX_CSR2:
---
> * filled RUM_TXRX_CSR2:
1024c908
< DPRINTFN(6, "PHY or CRC error\n");
---
> DPRINTFN(5, "PHY or CRC error\n");
1028d911
< m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
1029a913
> m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
1035,1036d918
< max_len = (xfer->actlen - RT2573_RX_DESC_SIZE);
<
1038c920
< m->m_data, max_len);
---
> mtod(m, uint8_t *), len);
1044,1056d925
< if (m->m_len > max_len) {
< DPRINTF("invalid length in RX "
< "descriptor, %u bytes, received %u bytes\n",
< m->m_len, max_len);
< ifp->if_ierrors++;
< m_freem(m);
< m = NULL;
< goto tr_setup;
< }
< rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi);
<
< DPRINTF("real length=%d bytes, rssi=%d\n", m->m_len, rssi);
<
1062c931
< (sc->sc_rx_desc.flags & htole32(RT2573_RX_OFDM)) ?
---
> (flags & RT2573_RX_OFDM) ?
1066c935
< tap->wr_antenna = sc->sc_rx_ant;
---
> tap->wr_antenna = sc->rx_ant;
1070a940
> /* FALLTHROUGH */
1072a943,944
> xfer->frlengths[0] = xfer->max_data_length;
> usb2_start_hardware(xfer);
1074,1080d945
< if (sc->sc_flags & RUM_FLAG_READ_STALL) {
< usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_RD]);
< } else {
< xfer->frlengths[0] = xfer->max_data_length;
< usb2_start_hardware(xfer);
< }
<
1087,1089c952,954
< mtx_unlock(&sc->sc_mtx);
<
< ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
---
> RUM_UNLOCK(sc);
> ni = ieee80211_find_rxnode(ic,
> mtod(m, struct ieee80211_frame_min *));
1091,1094c956,957
< if (ieee80211_input(ni, m, rssi, RT2573_NOISE_FLOOR, 0)) {
< /* ignore */
< }
< /* node is no longer needed */
---
> (void) ieee80211_input(ni, m, rssi,
> RT2573_NOISE_FLOOR, 0);
1096,1102c959,962
< } else {
< if (ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR, 0)) {
< /* ignore */
< }
< }
<
< mtx_lock(&sc->sc_mtx);
---
> } else
> (void) ieee80211_input_all(ic, m, rssi,
> RT2573_NOISE_FLOOR, 0);
> RUM_LOCK(sc);
1109,1110c969,970
< sc->sc_flags |= RUM_FLAG_READ_STALL;
< usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_RD]);
---
> xfer->flags.stall_pipe = 1;
> goto tr_setup;
1113d972
<
1117,1129d975
< static void
< rum_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
< {
< struct rum_softc *sc = xfer->priv_sc;
< struct usb2_xfer *xfer_other = sc->sc_xfer[RUM_BULK_DT_RD];
<
< if (usb2_clear_stall_callback(xfer, xfer_other)) {
< DPRINTF("stall cleared\n");
< sc->sc_flags &= ~RUM_FLAG_READ_STALL;
< usb2_transfer_start(xfer_other);
< }
< }
<
1131c977
< rum_plcp_signal(uint16_t rate)
---
> rum_plcp_signal(int rate)
1133d978
< ; /* indent fix */
1135,1143c980,988
< /* CCK rates (NB: not IEEE std, device-specific) */
< case 2:
< return (0x0);
< case 4:
< return (0x1);
< case 11:
< return (0x2);
< case 22:
< return (0x3);
---
> /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
> case 12: return 0xb;
> case 18: return 0xf;
> case 24: return 0xa;
> case 36: return 0xe;
> case 48: return 0x9;
> case 72: return 0xd;
> case 96: return 0x8;
> case 108: return 0xc;
1145,1165c990,994
< /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
< case 12:
< return (0xb);
< case 18:
< return (0xf);
< case 24:
< return (0xa);
< case 36:
< return (0xe);
< case 48:
< return (0x9);
< case 72:
< return (0xd);
< case 96:
< return (0x8);
< case 108:
< return (0xc);
<
< /* XXX unsupported/unknown rate */
< default:
< return (0xff);
---
> /* CCK rates (NB: not IEEE std, device-specific) */
> case 2: return 0x0;
> case 4: return 0x1;
> case 11: return 0x2;
> case 22: return 0x3;
1166a996
> return 0xff; /* XXX unsupported/unknown rate */
1169,1173d998
< /*
< * We assume that "m->m_pkthdr.rcvif" is pointing to the "ni" that
< * should be freed, when "rum_setup_desc_and_tx" is called.
< */
<
1175,1176c1000,1001
< rum_setup_desc_and_tx(struct rum_softc *sc, struct mbuf *m, uint32_t flags,
< uint16_t xflags, uint16_t rate)
---
> rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
> uint32_t flags, uint16_t xflags, int len, int rate)
1180,1181d1004
< struct mbuf *mm;
< enum ieee80211_phytype phytype;
1183,1185c1006
< uint16_t len;
< uint8_t remainder;
< uint8_t is_beacon;
---
> int remainder;
1187,1192c1008,1010
< if (xflags & RT2573_TX_BEACON) {
< xflags &= ~RT2573_TX_BEACON;
< is_beacon = 1;
< } else {
< is_beacon = 0;
< }
---
> desc->flags = htole32(flags);
> desc->flags |= htole32(RT2573_TX_VALID);
> desc->flags |= htole32(len << 16);
1194,1208c1012
< if (sc->sc_tx_queue.ifq_len >= IFQ_MAXLEN) {
< /* free packet */
< rum_tx_freem(m);
< ifp->if_oerrors++;
< return;
< }
< if (!((sc->sc_flags & RUM_FLAG_LL_READY) &&
< (sc->sc_flags & RUM_FLAG_HL_READY))) {
< /* free packet */
< rum_tx_freem(m);
< ifp->if_oerrors++;
< return;
< }
< if (rate < 2) {
< DPRINTF("rate < 2!\n");
---
> desc->xflags = htole16(xflags);
1210,1233c1014
< /* avoid division by zero */
< rate = 2;
< }
< ic->ic_lastdata = ticks;
< if (bpf_peers_present(ifp->if_bpf)) {
< struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
<
< tap->wt_flags = 0;
< tap->wt_rate = rate;
< tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
< tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
< tap->wt_antenna = sc->sc_tx_ant;
<
< bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
< }
< len = m->m_pkthdr.len;
<
< flags |= RT2573_TX_VALID;
< flags |= (len << 16);
<
< sc->sc_tx_desc.flags = htole32(flags);
< sc->sc_tx_desc.xflags = htole16(xflags);
<
< sc->sc_tx_desc.wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
---
> desc->wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
1237,1238c1018,1019
< sc->sc_tx_desc.plcp_signal = rum_plcp_signal(rate);
< sc->sc_tx_desc.plcp_service = 4;
---
> desc->plcp_signal = rum_plcp_signal(rate);
> desc->plcp_service = 4;
1240a1022,1023
> if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) {
> desc->flags |= htole32(RT2573_TX_OFDM);
1242,1249c1025,1027
< phytype = ieee80211_rate2phytype(sc->sc_rates, rate);
<
< if (phytype == IEEE80211_T_OFDM) {
< sc->sc_tx_desc.flags |= htole32(RT2573_TX_OFDM);
<
< plcp_length = (len & 0xfff);
< sc->sc_tx_desc.plcp_length_hi = plcp_length >> 6;
< sc->sc_tx_desc.plcp_length_lo = plcp_length & 0x3f;
---
> plcp_length = len & 0xfff;
> desc->plcp_length_hi = plcp_length >> 6;
> desc->plcp_length_lo = plcp_length & 0x3f;
1251c1029
< plcp_length = ((16 * len) + rate - 1) / rate;
---
> plcp_length = (16 * len + rate - 1) / rate;
1254,1257c1032,1033
< if ((remainder != 0) && (remainder < 7)) {
< sc->sc_tx_desc.plcp_service |=
< RT2573_PLCP_LENGEXT;
< }
---
> if (remainder != 0 && remainder < 7)
> desc->plcp_service |= RT2573_PLCP_LENGEXT;
1259,1260c1035,1036
< sc->sc_tx_desc.plcp_length_hi = plcp_length >> 8;
< sc->sc_tx_desc.plcp_length_lo = plcp_length & 0xff;
---
> desc->plcp_length_hi = plcp_length >> 8;
> desc->plcp_length_lo = plcp_length & 0xff;
1262,1264c1038,1039
< if ((rate != 2) && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) {
< sc->sc_tx_desc.plcp_signal |= 0x08;
< }
---
> if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
> desc->plcp_signal |= 0x08;
1265a1041
> }
1267,1282c1043
< if (sizeof(sc->sc_tx_desc) > MHLEN) {
< DPRINTF("No room for header structure!\n");
< rum_tx_freem(m);
< return;
< }
< mm = m_gethdr(M_NOWAIT, MT_DATA);
< if (mm == NULL) {
< DPRINTF("Could not allocate header mbuf!\n");
< rum_tx_freem(m);
< return;
< }
< bcopy(&sc->sc_tx_desc, mm->m_data, sizeof(sc->sc_tx_desc));
< mm->m_len = sizeof(sc->sc_tx_desc);
< mm->m_next = m;
< mm->m_pkthdr.len = mm->m_len + m->m_pkthdr.len;
< mm->m_pkthdr.rcvif = NULL;
---
> #define RUM_TX_TIMEOUT 5000
1284c1045,1054
< if (is_beacon) {
---
> static int
> rum_sendprot(struct rum_softc *sc,
> const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
> {
> struct ieee80211com *ic = ni->ni_ic;
> const struct ieee80211_frame *wh;
> struct rum_tx_data *data;
> struct mbuf *mprot;
> int protrate, ackrate, pktlen, flags, isshort;
> uint16_t dur;
1286,1291c1056,1058
< if (mm->m_pkthdr.len > sizeof(sc->sc_beacon_buf)) {
< DPRINTFN(0, "Truncating beacon"
< ", %u bytes!\n", mm->m_pkthdr.len);
< mm->m_pkthdr.len = sizeof(sc->sc_beacon_buf);
< }
< m_copydata(mm, 0, mm->m_pkthdr.len, sc->sc_beacon_buf);
---
> RUM_LOCK_ASSERT(sc, MA_OWNED);
> KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY,
> ("protection %d", prot));
1293,1297c1060,1076
< /* copy the first 24 bytes of Tx descriptor into NIC memory */
< rum_cfg_write_multi(sc, RT2573_HW_BEACON_BASE0,
< sc->sc_beacon_buf, mm->m_pkthdr.len);
< rum_tx_freem(mm);
< return;
---
> wh = mtod(m, const struct ieee80211_frame *);
> pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
>
> protrate = ieee80211_ctl_rate(sc->sc_rates, rate);
> ackrate = ieee80211_ack_rate(sc->sc_rates, rate);
>
> isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
> dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort);
> + ieee80211_ack_duration(sc->sc_rates, rate, isshort);
> flags = RT2573_TX_MORE_FRAG;
> if (prot == IEEE80211_PROT_RTSCTS) {
> /* NB: CTS is the same size as an ACK */
> dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort);
> flags |= RT2573_TX_NEED_ACK;
> mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
> } else {
> mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
1299,1300c1078,1084
< /* start write transfer, if not started */
< _IF_ENQUEUE(&sc->sc_tx_queue, mm);
---
> if (mprot == NULL) {
> /* XXX stat + msg */
> return ENOBUFS;
> }
> data = STAILQ_FIRST(&sc->tx_free);
> STAILQ_REMOVE_HEAD(&sc->tx_free, next);
> sc->tx_nfree--;
1302c1086,1094
< usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]);
---
> data->m = mprot;
> data->ni = ieee80211_ref_node(ni);
> data->rate = protrate;
> rum_setup_tx_desc(sc, &data->desc, flags, 0, mprot->m_pkthdr.len, protrate);
>
> STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
> usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
>
> return 0;
1305,1306c1097,1098
< static void
< rum_bulk_write_callback(struct usb2_xfer *xfer)
---
> static int
> rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1308c1100
< struct rum_softc *sc = xfer->priv_sc;
---
> struct ieee80211vap *vap = ni->ni_vap;
1310,1312c1102,1108
< struct mbuf *m;
< uint16_t temp_len;
< uint8_t align;
---
> struct ieee80211com *ic = ifp->if_l2com;
> struct rum_tx_data *data;
> struct ieee80211_frame *wh;
> const struct ieee80211_txparam *tp;
> struct ieee80211_key *k;
> uint32_t flags = 0;
> uint16_t dur;
1314,1316c1110
< switch (USB_GET_STATE(xfer)) {
< case USB_ST_TRANSFERRED:
< DPRINTFN(11, "transfer complete\n");
---
> RUM_LOCK_ASSERT(sc, MA_OWNED);
1318c1112,1114
< ifp->if_opackets++;
---
> data = STAILQ_FIRST(&sc->tx_free);
> STAILQ_REMOVE_HEAD(&sc->tx_free, next);
> sc->tx_nfree--;
1320,1323c1116,1121
< case USB_ST_SETUP:
< if (sc->sc_flags & RUM_FLAG_WRITE_STALL) {
< usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_WR]);
< break;
---
> wh = mtod(m0, struct ieee80211_frame *);
> if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
> k = ieee80211_crypto_encap(ni, m0);
> if (k == NULL) {
> m_freem(m0);
> return ENOBUFS;
1325,1331c1123,1124
< if (sc->sc_flags & RUM_FLAG_WAIT_COMMAND) {
< /*
< * don't send anything while a command is pending !
< */
< break;
< }
< rum_fill_write_queue(sc);
---
> wh = mtod(m0, struct ieee80211_frame *);
> }
1333c1126
< _IF_DEQUEUE(&sc->sc_tx_queue, m);
---
> tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
1335c1128,1129
< if (m) {
---
> if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
> flags |= RT2573_TX_NEED_ACK;
1337,1343c1131,1133
< if (m->m_pkthdr.len > (MCLBYTES + RT2573_TX_DESC_SIZE)) {
< DPRINTFN(0, "data overflow, %u bytes\n",
< m->m_pkthdr.len);
< m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE);
< }
< usb2_m_copy_in(xfer->frbuffers, 0,
< m, 0, m->m_pkthdr.len);
---
> dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate,
> ic->ic_flags & IEEE80211_F_SHPREAMBLE);
> *(uint16_t *)wh->i_dur = htole16(dur);
1345,1346c1135,1140
< /* compute transfer length */
< temp_len = m->m_pkthdr.len;
---
> /* tell hardware to add timestamp for probe responses */
> if ((wh->i_fc[0] &
> (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
> (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
> flags |= RT2573_TX_TIMESTAMP;
> }
1348,1349c1142,1144
< /* make transfer length 32-bit aligned */
< align = (-(temp_len)) & 3;
---
> data->m = m0;
> data->ni = ni;
> data->rate = tp->mgmtrate;
1351,1362c1146
< /* check if we need to add four extra bytes */
< if (((temp_len + align) % 64) == 0) {
< align += 4;
< }
< /* check if we need to align length */
< if (align != 0) {
< /* zero the extra bytes */
< usb2_bzero(xfer->frbuffers, temp_len, align);
< temp_len += align;
< }
< DPRINTFN(11, "sending frame len=%u ferlen=%u\n",
< m->m_pkthdr.len, temp_len);
---
> rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, tp->mgmtrate);
1364,1365c1148,1149
< xfer->frlengths[0] = temp_len;
< usb2_start_hardware(xfer);
---
> DPRINTFN(10, "sending mgt frame len=%d rate=%d\n",
> m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate);
1367,1368c1151,1152
< /* free mbuf and node */
< rum_tx_freem(m);
---
> STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
> usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
1370,1371c1154,1155
< }
< break;
---
> return 0;
> }
1373,1375c1157,1163
< default: /* Error */
< DPRINTFN(11, "transfer error, %s\n",
< usb2_errstr(xfer->error));
---
> static int
> rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
> const struct ieee80211_bpf_params *params)
> {
> struct rum_tx_data *data;
> uint32_t flags;
> int rate, error;
1377,1380c1165,1188
< if (xfer->error != USB_ERR_CANCELLED) {
< /* try to clear stall first */
< sc->sc_flags |= RUM_FLAG_WRITE_STALL;
< usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_WR]);
---
> RUM_LOCK_ASSERT(sc, MA_OWNED);
> KASSERT(params != NULL, ("no raw xmit params"));
>
> data = STAILQ_FIRST(&sc->tx_free);
> STAILQ_REMOVE_HEAD(&sc->tx_free, next);
> sc->tx_nfree--;
>
> rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
> /* XXX validate */
> if (rate == 0) {
> m_freem(m0);
> return EINVAL;
> }
> flags = 0;
> if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
> flags |= RT2573_TX_NEED_ACK;
> if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) {
> error = rum_sendprot(sc, m0, ni,
> params->ibp_flags & IEEE80211_BPF_RTS ?
> IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
> rate);
> if (error) {
> m_freem(m0);
> return error;
1382,1383c1190
< ifp->if_oerrors++;
< break;
---
> flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
1384a1192,1206
>
> data->m = m0;
> data->ni = ni;
> data->rate = rate;
>
> /* XXX need to setup descriptor ourself */
> rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate);
>
> DPRINTFN(10, "sending raw frame len=%u rate=%u\n",
> m0->m_pkthdr.len, rate);
>
> STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
> usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
>
> return 0;
1387,1388c1209,1210
< static void
< rum_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
---
> static int
> rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1390,1391c1212,1221
< struct rum_softc *sc = xfer->priv_sc;
< struct usb2_xfer *xfer_other = sc->sc_xfer[RUM_BULK_DT_WR];
---
> struct ieee80211vap *vap = ni->ni_vap;
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
> struct rum_tx_data *data;
> struct ieee80211_frame *wh;
> const struct ieee80211_txparam *tp;
> struct ieee80211_key *k;
> uint32_t flags = 0;
> uint16_t dur;
> int error, rate;
1393,1396c1223,1243
< if (usb2_clear_stall_callback(xfer, xfer_other)) {
< DPRINTF("stall cleared\n");
< sc->sc_flags &= ~RUM_FLAG_WRITE_STALL;
< usb2_transfer_start(xfer_other);
---
> RUM_LOCK_ASSERT(sc, MA_OWNED);
>
> wh = mtod(m0, struct ieee80211_frame *);
>
> tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
> if (IEEE80211_IS_MULTICAST(wh->i_addr1))
> rate = tp->mcastrate;
> else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
> rate = tp->ucastrate;
> else
> rate = ni->ni_txrate;
>
> if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
> k = ieee80211_crypto_encap(ni, m0);
> if (k == NULL) {
> m_freem(m0);
> return ENOBUFS;
> }
>
> /* packet header may have moved, reset our local pointer */
> wh = mtod(m0, struct ieee80211_frame *);
1398d1244
< }
1400,1403c1246,1261
< static void
< rum_watchdog(void *arg)
< {
< struct rum_softc *sc = arg;
---
> if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
> int prot = IEEE80211_PROT_NONE;
> if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
> prot = IEEE80211_PROT_RTSCTS;
> else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
> ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM)
> prot = ic->ic_protmode;
> if (prot != IEEE80211_PROT_NONE) {
> error = rum_sendprot(sc, m0, ni, prot, rate);
> if (error) {
> m_freem(m0);
> return error;
> }
> flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
> }
> }
1405c1263,1265
< mtx_assert(&sc->sc_mtx, MA_OWNED);
---
> data = STAILQ_FIRST(&sc->tx_free);
> STAILQ_REMOVE_HEAD(&sc->tx_free, next);
> sc->tx_nfree--;
1407,1410c1267,1277
< if (sc->sc_amrr_timer) {
< usb2_config_td_queue_command
< (&sc->sc_config_td, NULL,
< &rum_cfg_amrr_timeout, 0, 0);
---
> data->m = m0;
> data->ni = ni;
> data->rate = rate;
>
> if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
> flags |= RT2573_TX_NEED_ACK;
> flags |= RT2573_TX_MORE_FRAG;
>
> dur = ieee80211_ack_duration(sc->sc_rates, rate,
> ic->ic_flags & IEEE80211_F_SHPREAMBLE);
> *(uint16_t *)wh->i_dur = htole16(dur);
1412,1413c1279,1288
< usb2_callout_reset(&sc->sc_watchdog,
< hz, &rum_watchdog, sc);
---
>
> rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate);
>
> DPRINTFN(10, "sending frame len=%d rate=%d\n",
> m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate);
>
> STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
> usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
>
> return 0;
1417c1292
< rum_init_cb(void *arg)
---
> rum_start(struct ifnet *ifp)
1419c1294,1296
< struct rum_softc *sc = arg;
---
> struct rum_softc *sc = ifp->if_softc;
> struct ieee80211_node *ni;
> struct mbuf *m;
1421,1425c1298,1324
< mtx_lock(&sc->sc_mtx);
< usb2_config_td_queue_command
< (&sc->sc_config_td, &rum_cfg_pre_init,
< &rum_cfg_init, 0, 0);
< mtx_unlock(&sc->sc_mtx);
---
> RUM_LOCK(sc);
> if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
> RUM_UNLOCK(sc);
> return;
> }
> for (;;) {
> IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
> if (m == NULL)
> break;
> if (sc->tx_nfree == 0) {
> IFQ_DRV_PREPEND(&ifp->if_snd, m);
> ifp->if_drv_flags |= IFF_DRV_OACTIVE;
> break;
> }
> ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
> m = ieee80211_encap(ni, m);
> if (m == NULL) {
> ieee80211_free_node(ni);
> continue;
> }
> if (rum_tx_data(sc, m, ni) != 0) {
> ieee80211_free_node(ni);
> ifp->if_oerrors++;
> break;
> }
> }
> RUM_UNLOCK(sc);
1429c1328
< rum_ioctl_cb(struct ifnet *ifp, u_long cmd, caddr_t data)
---
> rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1433c1332,1333
< int error;
---
> struct ifreq *ifr = (struct ifreq *) data;
> int error = 0, startall = 0;
1437c1337
< mtx_lock(&sc->sc_mtx);
---
> RUM_LOCK(sc);
1439,1443c1339,1347
< if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
< usb2_config_td_queue_command
< (&sc->sc_config_td, &rum_cfg_pre_init,
< &rum_cfg_init, 0, 0);
< }
---
> if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
> rum_queue_command(sc, rum_init_task,
> &sc->sc_synctask[0].hdr,
> &sc->sc_synctask[1].hdr);
> startall = 1;
> } else
> rum_queue_command(sc, rum_promisctask,
> &sc->sc_promisctask[0].hdr,
> &sc->sc_promisctask[1].hdr);
1446,1448c1350,1352
< usb2_config_td_queue_command
< (&sc->sc_config_td, &rum_cfg_pre_stop,
< &rum_cfg_stop, 0, 0);
---
> rum_queue_command(sc, rum_stop_task,
> &sc->sc_synctask[0].hdr,
> &sc->sc_synctask[1].hdr);
1451,1452c1355,1357
< mtx_unlock(&sc->sc_mtx);
< error = 0;
---
> RUM_UNLOCK(sc);
> if (startall)
> ieee80211_start_all(ic);
1454d1358
<
1456,1457c1360
< case SIOCSIFMEDIA:
< error = ifmedia_ioctl(ifp, (void *)data, &ic->ic_media, cmd);
---
> error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1459,1460c1362
<
< default:
---
> case SIOCGIFADDR:
1461a1364,1367
> break;
> default:
> error = EINVAL;
> break;
1463c1369
< return (error);
---
> return error;
1467c1373
< rum_start_cb(struct ifnet *ifp)
---
> rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
1469c1375,1376
< struct rum_softc *sc = ifp->if_softc;
---
> struct usb2_device_request req;
> usb2_error_t error;
1471,1474c1378,1388
< mtx_lock(&sc->sc_mtx);
< /* start write transfer, if not started */
< usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]);
< mtx_unlock(&sc->sc_mtx);
---
> req.bmRequestType = UT_READ_VENDOR_DEVICE;
> req.bRequest = RT2573_READ_EEPROM;
> USETW(req.wValue, 0);
> USETW(req.wIndex, addr);
> USETW(req.wLength, len);
>
> error = rum_do_request(sc, &req, buf);
> if (error != 0) {
> device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
> usb2_errstr(error));
> }
1477,1479c1391,1392
< static void
< rum_cfg_newstate(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> static uint32_t
> rum_read(struct rum_softc *sc, uint16_t reg)
1481,1487c1394
< struct ifnet *ifp = sc->sc_ifp;
< struct ieee80211com *ic = ifp->if_l2com;
< struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
< struct rum_vap *uvp = RUM_VAP(vap);
< enum ieee80211_state ostate;
< enum ieee80211_state nstate;
< int arg;
---
> uint32_t val;
1489,1491c1396
< ostate = vap->iv_state;
< nstate = sc->sc_ns_state;
< arg = sc->sc_ns_arg;
---
> rum_read_multi(sc, reg, &val, sizeof val);
1493,1499c1398,1399
< if (ostate == IEEE80211_S_INIT) {
< /* We are leaving INIT. TSF sync should be off. */
< rum_cfg_disable_tsf_sync(sc);
< }
< switch (nstate) {
< case IEEE80211_S_INIT:
< break;
---
> return le32toh(val);
> }
1501,1503c1401,1405
< case IEEE80211_S_RUN:
< rum_cfg_set_run(sc, cc);
< break;
---
> static void
> rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
> {
> struct usb2_device_request req;
> usb2_error_t error;
1505,1506c1407,1417
< default:
< break;
---
> req.bmRequestType = UT_READ_VENDOR_DEVICE;
> req.bRequest = RT2573_READ_MULTI_MAC;
> USETW(req.wValue, 0);
> USETW(req.wIndex, reg);
> USETW(req.wLength, len);
>
> error = rum_do_request(sc, &req, buf);
> if (error != 0) {
> device_printf(sc->sc_dev,
> "could not multi read MAC register: %s\n",
> usb2_errstr(error));
1507a1419
> }
1509,1515c1421,1426
< mtx_unlock(&sc->sc_mtx);
< IEEE80211_LOCK(ic);
< uvp->newstate(vap, nstate, arg);
< if (vap->iv_newstate_cb != NULL)
< vap->iv_newstate_cb(vap, nstate, arg);
< IEEE80211_UNLOCK(ic);
< mtx_lock(&sc->sc_mtx);
---
> static void
> rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
> {
> uint32_t tmp = htole32(val);
>
> rum_write_multi(sc, reg, &tmp, sizeof tmp);
1518,1519c1429,1430
< static int
< rum_newstate_cb(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
---
> static void
> rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
1521,1523c1432,1433
< struct rum_vap *uvp = RUM_VAP(vap);
< struct ieee80211com *ic = vap->iv_ic;
< struct rum_softc *sc = ic->ic_ifp->if_softc;
---
> struct usb2_device_request req;
> usb2_error_t error;
1525c1435,1439
< DPRINTF("setting new state: %d\n", nstate);
---
> req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
> req.bRequest = RT2573_WRITE_MULTI_MAC;
> USETW(req.wValue, 0);
> USETW(req.wIndex, reg);
> USETW(req.wLength, len);
1527,1533c1441,1445
< /* Special case - cannot defer this call and cannot block ! */
< if (nstate == IEEE80211_S_INIT) {
< /* stop timers */
< mtx_lock(&sc->sc_mtx);
< sc->sc_amrr_timer = 0;
< mtx_unlock(&sc->sc_mtx);
< return (uvp->newstate(vap, nstate, arg));
---
> error = rum_do_request(sc, &req, buf);
> if (error != 0) {
> device_printf(sc->sc_dev,
> "could not multi write MAC register: %s\n",
> usb2_errstr(error));
1535,1542c1447
< mtx_lock(&sc->sc_mtx);
< if (usb2_config_td_is_gone(&sc->sc_config_td)) {
< mtx_unlock(&sc->sc_mtx);
< return (0); /* nothing to do */
< }
< /* store next state */
< sc->sc_ns_state = nstate;
< sc->sc_ns_arg = arg;
---
> }
1544,1545c1449,1453
< /* stop timers */
< sc->sc_amrr_timer = 0;
---
> static void
> rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
> {
> uint32_t tmp;
> int ntries;
1547,1553c1455,1462
< /*
< * USB configuration can only be done from the USB configuration
< * thread:
< */
< usb2_config_td_queue_command
< (&sc->sc_config_td, &rum_config_copy,
< &rum_cfg_newstate, 0, 0);
---
> for (ntries = 0; ntries < 5; ntries++) {
> if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
> break;
> }
> if (ntries == 5) {
> device_printf(sc->sc_dev, "could not write to BBP\n");
> return;
> }
1555,1557c1464,1465
< mtx_unlock(&sc->sc_mtx);
<
< return (EINPROGRESS);
---
> tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val;
> rum_write(sc, RT2573_PHY_CSR3, tmp);
1560,1561c1468,1469
< static void
< rum_std_command(struct ieee80211com *ic, usb2_config_td_command_t *func)
---
> static uint8_t
> rum_bbp_read(struct rum_softc *sc, uint8_t reg)
1563c1471,1472
< struct rum_softc *sc = ic->ic_ifp->if_softc;
---
> uint32_t val;
> int ntries;
1565c1474,1481
< mtx_lock(&sc->sc_mtx);
---
> for (ntries = 0; ntries < 5; ntries++) {
> if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
> break;
> }
> if (ntries == 5) {
> device_printf(sc->sc_dev, "could not read BBP\n");
> return 0;
> }
1567c1483,1484
< sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
---
> val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8;
> rum_write(sc, RT2573_PHY_CSR3, val);
1569,1570c1486,1491
< usb2_config_td_queue_command
< (&sc->sc_config_td, &rum_config_copy, func, 0, 0);
---
> for (ntries = 0; ntries < 100; ntries++) {
> val = rum_read(sc, RT2573_PHY_CSR3);
> if (!(val & RT2573_BBP_BUSY))
> return val & 0xff;
> DELAY(1);
> }
1572c1493,1494
< mtx_unlock(&sc->sc_mtx);
---
> device_printf(sc->sc_dev, "could not read BBP\n");
> return 0;
1576c1498
< rum_scan_start_cb(struct ieee80211com *ic)
---
> rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
1578c1500,1519
< rum_std_command(ic, &rum_cfg_scan_start);
---
> uint32_t tmp;
> int ntries;
>
> for (ntries = 0; ntries < 5; ntries++) {
> if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY))
> break;
> }
> if (ntries == 5) {
> device_printf(sc->sc_dev, "could not write to RF\n");
> return;
> }
>
> tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 |
> (reg & 3);
> rum_write(sc, RT2573_PHY_CSR4, tmp);
>
> /* remember last written value in sc */
> sc->rf_regs[reg] = val;
>
> DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff);
1582c1523
< rum_scan_end_cb(struct ieee80211com *ic)
---
> rum_select_antenna(struct rum_softc *sc)
1584c1525,1540
< rum_std_command(ic, &rum_cfg_scan_end);
---
> uint8_t bbp4, bbp77;
> uint32_t tmp;
>
> bbp4 = rum_bbp_read(sc, 4);
> bbp77 = rum_bbp_read(sc, 77);
>
> /* TBD */
>
> /* make sure Rx is disabled before switching antenna */
> tmp = rum_read(sc, RT2573_TXRX_CSR0);
> rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
>
> rum_bbp_write(sc, 4, bbp4);
> rum_bbp_write(sc, 77, bbp77);
>
> rum_write(sc, RT2573_TXRX_CSR0, tmp);
1586a1543,1546
> /*
> * Enable multi-rate retries for frames sent at OFDM rates.
> * In 802.11b/g mode, allow fallback to CCK rates.
> */
1588c1548
< rum_set_channel_cb(struct ieee80211com *ic)
---
> rum_enable_mrr(struct rum_softc *sc)
1590c1550,1561
< rum_std_command(ic, &rum_cfg_set_chan);
---
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
> uint32_t tmp;
>
> tmp = rum_read(sc, RT2573_TXRX_CSR4);
>
> tmp &= ~RT2573_MRR_CCK_FALLBACK;
> if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan))
> tmp |= RT2573_MRR_CCK_FALLBACK;
> tmp |= RT2573_MRR_ENABLED;
>
> rum_write(sc, RT2573_TXRX_CSR4, tmp);
1594,1595c1565
< rum_cfg_scan_start(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> rum_set_txpreamble(struct rum_softc *sc)
1597,1599c1567,1577
< /* abort TSF synchronization */
< rum_cfg_disable_tsf_sync(sc);
< rum_cfg_set_bssid(sc, cc->if_broadcastaddr);
---
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
> uint32_t tmp;
>
> tmp = rum_read(sc, RT2573_TXRX_CSR4);
>
> tmp &= ~RT2573_SHORT_PREAMBLE;
> if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
> tmp |= RT2573_SHORT_PREAMBLE;
>
> rum_write(sc, RT2573_TXRX_CSR4, tmp);
1603,1604c1581
< rum_cfg_scan_end(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> rum_set_basicrates(struct rum_softc *sc)
1606,1608c1583,1596
< /* enable TSF synchronization */
< rum_cfg_enable_tsf_sync(sc, cc, 0);
< rum_cfg_set_bssid(sc, cc->iv_bss.ni_bssid);
---
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
>
> /* update basic rate set */
> if (ic->ic_curmode == IEEE80211_MODE_11B) {
> /* 11b basic rates: 1, 2Mbps */
> rum_write(sc, RT2573_TXRX_CSR5, 0x3);
> } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) {
> /* 11a basic rates: 6, 12, 24Mbps */
> rum_write(sc, RT2573_TXRX_CSR5, 0x150);
> } else {
> /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
> rum_write(sc, RT2573_TXRX_CSR5, 0xf);
> }
1612c1600
< * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
---
> * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
1616,1617c1604
< rum_cfg_select_band(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
1619d1605
< uint32_t tmp;
1620a1607
> uint32_t tmp;
1623,1636c1610,1614
< bbp17 = 0x20;
< bbp96 = 0x48;
< bbp104 = 0x2c;
< bbp35 = 0x50;
< bbp97 = 0x48;
< bbp98 = 0x48;
<
< if (cc->ic_curchan.chan_is_5ghz) {
< bbp17 += 0x08;
< bbp96 += 0x10;
< bbp104 += 0x0c;
< bbp35 += 0x10;
< bbp97 += 0x10;
< bbp98 += 0x10;
---
> bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
> bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48;
> if (IEEE80211_IS_CHAN_5GHZ(c)) {
> bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
> bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10;
1638,1642c1616,1618
< if ((cc->ic_curchan.chan_is_2ghz && sc->sc_ext_2ghz_lna) ||
< (cc->ic_curchan.chan_is_5ghz && sc->sc_ext_5ghz_lna)) {
< bbp17 += 0x10;
< bbp96 += 0x10;
< bbp104 += 0x10;
---
> if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
> (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
> bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
1644,1647d1619
< sc->sc_bbp17 = bbp17;
< rum_cfg_bbp_write(sc, 17, bbp17);
< rum_cfg_bbp_write(sc, 96, bbp96);
< rum_cfg_bbp_write(sc, 104, bbp104);
1649,1653c1621,1630
< if ((cc->ic_curchan.chan_is_2ghz && sc->sc_ext_2ghz_lna) ||
< (cc->ic_curchan.chan_is_5ghz && sc->sc_ext_5ghz_lna)) {
< rum_cfg_bbp_write(sc, 75, 0x80);
< rum_cfg_bbp_write(sc, 86, 0x80);
< rum_cfg_bbp_write(sc, 88, 0x80);
---
> sc->bbp17 = bbp17;
> rum_bbp_write(sc, 17, bbp17);
> rum_bbp_write(sc, 96, bbp96);
> rum_bbp_write(sc, 104, bbp104);
>
> if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
> (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
> rum_bbp_write(sc, 75, 0x80);
> rum_bbp_write(sc, 86, 0x80);
> rum_bbp_write(sc, 88, 0x80);
1655,1657d1631
< rum_cfg_bbp_write(sc, 35, bbp35);
< rum_cfg_bbp_write(sc, 97, bbp97);
< rum_cfg_bbp_write(sc, 98, bbp98);
1659c1633,1637
< tmp = rum_cfg_read(sc, RT2573_PHY_CSR0);
---
> rum_bbp_write(sc, 35, bbp35);
> rum_bbp_write(sc, 97, bbp97);
> rum_bbp_write(sc, 98, bbp98);
>
> tmp = rum_read(sc, RT2573_PHY_CSR0);
1661c1639
< if (cc->ic_curchan.chan_is_2ghz)
---
> if (IEEE80211_IS_CHAN_2GHZ(c))
1665,1668c1643
< rum_cfg_write(sc, RT2573_PHY_CSR0, tmp);
<
< /* 802.11a uses a 16 microseconds short interframe space */
< sc->sc_sifs = cc->ic_curchan.chan_is_5ghz ? 16 : 10;
---
> rum_write(sc, RT2573_PHY_CSR0, tmp);
1672,1673c1647
< rum_cfg_set_chan(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
1675,1676c1649,1650
< enum {
< N_RF5225 = (sizeof(rum_rf5225) / sizeof(rum_rf5225[0]))};
---
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
1678,1681c1652
< uint32_t chan;
< uint16_t i;
< uint8_t bbp3;
< uint8_t bbp94 = RT2573_BBPR94_DEFAULT;
---
> uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
1682a1654
> u_int i, chan;
1684,1688c1656,1657
< chan = cc->ic_curchan.chan_to_ieee;
<
< if ((chan == 0) ||
< (chan == IEEE80211_CHAN_ANY)) {
< /* nothing to do */
---
> chan = ieee80211_chan2ieee(ic, c);
> if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1690,1694d1658
< }
< if (chan == sc->sc_last_chan) {
< return;
< }
< sc->sc_last_chan = chan;
1697,1698c1661,1662
< rfprog = ((sc->sc_rf_rev == RT2573_RF_5225) ||
< (sc->sc_rf_rev == RT2573_RF_2527)) ? rum_rf5225 : rum_rf5226;
---
> rfprog = (sc->rf_rev == RT2573_RF_5225 ||
> sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
1700,1706c1664,1665
< /* find the settings for this channel */
< for (i = 0;; i++) {
< if (i == (N_RF5225 - 1))
< break;
< if (rfprog[i].chan == chan)
< break;
< }
---
> /* find the settings for this channel (we know it exists) */
> for (i = 0; rfprog[i].chan != chan; i++);
1708,1710c1667
< DPRINTF("chan=%d, i=%d\n", chan, i);
<
< power = sc->sc_txpow[i];
---
> power = sc->txpow[i];
1717a1675
>
1722,1723c1680,1684
< rum_cfg_select_band(sc, cc, 0);
< rum_cfg_select_antenna(sc, cc, 0);
---
> if (c->ic_flags != ic->ic_curchan->ic_flags) {
> rum_select_band(sc, c);
> rum_select_antenna(sc);
> }
> ic->ic_curchan = c;
1725,1728c1686,1689
< rum_cfg_rf_write(sc, RT2573_RF1, rfprog[i].r1);
< rum_cfg_rf_write(sc, RT2573_RF2, rfprog[i].r2);
< rum_cfg_rf_write(sc, RT2573_RF3, rfprog[i].r3 | (power << 7));
< rum_cfg_rf_write(sc, RT2573_RF4, rfprog[i].r4 | (sc->sc_rffreq << 10));
---
> rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
> rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
> rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
> rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1730,1733c1691,1694
< rum_cfg_rf_write(sc, RT2573_RF1, rfprog[i].r1);
< rum_cfg_rf_write(sc, RT2573_RF2, rfprog[i].r2);
< rum_cfg_rf_write(sc, RT2573_RF3, rfprog[i].r3 | (power << 7) | 1);
< rum_cfg_rf_write(sc, RT2573_RF4, rfprog[i].r4 | (sc->sc_rffreq << 10));
---
> rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
> rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
> rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1);
> rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1735,1738c1696,1699
< rum_cfg_rf_write(sc, RT2573_RF1, rfprog[i].r1);
< rum_cfg_rf_write(sc, RT2573_RF2, rfprog[i].r2);
< rum_cfg_rf_write(sc, RT2573_RF3, rfprog[i].r3 | (power << 7));
< rum_cfg_rf_write(sc, RT2573_RF4, rfprog[i].r4 | (sc->sc_rffreq << 10));
---
> rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
> rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
> rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
> rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1740,1742c1701,1702
< if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
< return;
< }
---
> DELAY(10);
>
1744c1704
< bbp3 = rum_cfg_bbp_read(sc, 3);
---
> bbp3 = rum_bbp_read(sc, 3);
1746,1749c1706,1707
< if ((sc->sc_rf_rev == RT2573_RF_5225) ||
< (sc->sc_rf_rev == RT2573_RF_2527))
< bbp3 &= ~RT2573_SMART_MODE;
< else
---
> bbp3 &= ~RT2573_SMART_MODE;
> if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
1752c1710
< rum_cfg_bbp_write(sc, 3, bbp3);
---
> rum_bbp_write(sc, 3, bbp3);
1754,1771c1712,1713
< rum_cfg_bbp_write(sc, 94, bbp94);
<
< /* update basic rate set */
<
< if (cc->ic_curchan.chan_is_b) {
< /* 11b basic rates: 1, 2Mbps */
< rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x3);
< } else if (cc->ic_curchan.chan_is_a) {
< /* 11a basic rates: 6, 12, 24Mbps */
< rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x150);
< } else {
< /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
< rum_cfg_write(sc, RT2573_TXRX_CSR5, 0xf);
< }
<
< if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
< return;
< }
---
> if (bbp94 != RT2573_BBPR94_DEFAULT)
> rum_bbp_write(sc, 94, bbp94);
1773a1716,1719
> /*
> * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
> * and HostAP operating modes.
> */
1775,1776c1721
< rum_cfg_set_run(struct rum_softc *sc,
< struct usb2_config_td_cc *cc)
---
> rum_enable_tsf_sync(struct rum_softc *sc)
1778,1814c1723,1725
<
< if (cc->ic_opmode != IEEE80211_M_MONITOR) {
< rum_cfg_update_slot(sc, cc, 0);
< rum_cfg_enable_mrr(sc, cc, 0);
< rum_cfg_set_txpreamble(sc, cc, 0);
<
< /* update basic rate set */
<
< if (cc->ic_bsschan.chan_is_5ghz) {
< /* 11a basic rates: 6, 12, 24Mbps */
< rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x150);
< } else if (cc->ic_bsschan.chan_is_g) {
< /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
< rum_cfg_write(sc, RT2573_TXRX_CSR5, 0xf);
< } else {
< /* 11b basic rates: 1, 2Mbps */
< rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x3);
< }
< rum_cfg_set_bssid(sc, cc->iv_bss.ni_bssid);
< }
< if ((cc->ic_opmode == IEEE80211_M_HOSTAP) ||
< (cc->ic_opmode == IEEE80211_M_IBSS)) {
< rum_cfg_prepare_beacon(sc, cc, 0);
< }
< if (cc->ic_opmode != IEEE80211_M_MONITOR) {
< rum_cfg_enable_tsf_sync(sc, cc, 0);
< }
< if (cc->iv_bss.fixed_rate_none) {
< /* enable automatic rate adaptation */
< rum_cfg_amrr_start(sc);
< }
< }
<
< static void
< rum_cfg_enable_tsf_sync(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
< {
---
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
> struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1817c1728
< if (cc->ic_opmode != IEEE80211_M_STA) {
---
> if (vap->iv_opmode != IEEE80211_M_STA) {
1822c1733
< rum_cfg_write(sc, RT2573_TXRX_CSR10, (1 << 12) | 8);
---
> rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8);
1824d1734
< tmp = rum_cfg_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
1825a1736,1737
> tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
>
1827c1739
< tmp |= cc->iv_bss.ni_intval * 16;
---
> tmp |= vap->iv_bss->ni_intval * 16;
1830c1742
< if (cc->ic_opmode == IEEE80211_M_STA)
---
> if (vap->iv_opmode == IEEE80211_M_STA)
1835c1747
< rum_cfg_write(sc, RT2573_TXRX_CSR9, tmp);
---
> rum_write(sc, RT2573_TXRX_CSR9, tmp);
1839c1751
< rum_cfg_disable_tsf_sync(struct rum_softc *sc)
---
> rum_update_slot(struct ifnet *ifp)
1840a1753,1755
> struct rum_softc *sc = ifp->if_softc;
> struct ieee80211com *ic = ifp->if_l2com;
> uint8_t slottime;
1843,1846c1758
< /* abort TSF synchronization */
< tmp = rum_cfg_read(sc, RT2573_TXRX_CSR9);
< rum_cfg_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
< }
---
> slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
1848,1879c1760
< /*
< * Enable multi-rate retries for frames sent at OFDM rates.
< * In 802.11b/g mode, allow fallback to CCK rates.
< */
< static void
< rum_cfg_enable_mrr(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
< {
< uint32_t tmp;
<
< tmp = rum_cfg_read(sc, RT2573_TXRX_CSR4);
<
< if (cc->ic_curchan.chan_is_5ghz)
< tmp &= ~RT2573_MRR_CCK_FALLBACK;
< else
< tmp |= RT2573_MRR_CCK_FALLBACK;
<
< tmp |= RT2573_MRR_ENABLED;
<
< rum_cfg_write(sc, RT2573_TXRX_CSR4, tmp);
< }
<
< static void
< rum_cfg_update_slot(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
< {
< uint32_t tmp;
< uint8_t slottime;
<
< slottime = (cc->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
<
< tmp = rum_cfg_read(sc, RT2573_MAC_CSR9);
---
> tmp = rum_read(sc, RT2573_MAC_CSR9);
1881c1762
< rum_cfg_write(sc, RT2573_MAC_CSR9, tmp);
---
> rum_write(sc, RT2573_MAC_CSR9, tmp);
1883c1764
< DPRINTF("setting slot time to %u us\n", slottime);
---
> DPRINTF("setting slot time to %uus\n", slottime);
1887,1888c1768
< rum_cfg_set_txpreamble(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
1892c1772,1773
< tmp = rum_cfg_read(sc, RT2573_TXRX_CSR4);
---
> tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
> rum_write(sc, RT2573_MAC_CSR4, tmp);
1894,1899c1775,1776
< if (cc->ic_flags & IEEE80211_F_SHPREAMBLE)
< tmp |= RT2573_SHORT_PREAMBLE;
< else
< tmp &= ~RT2573_SHORT_PREAMBLE;
<
< rum_cfg_write(sc, RT2573_TXRX_CSR4, tmp);
---
> tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16;
> rum_write(sc, RT2573_MAC_CSR5, tmp);
1903c1780
< rum_cfg_set_bssid(struct rum_softc *sc, uint8_t *bssid)
---
> rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
1907,1908c1784,1785
< tmp = bssid[0] | (bssid[1] << 8) | (bssid[2] << 16) | (bssid[3] << 24);
< rum_cfg_write(sc, RT2573_MAC_CSR4, tmp);
---
> tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
> rum_write(sc, RT2573_MAC_CSR2, tmp);
1910,1911c1787,1788
< tmp = (bssid[4]) | (bssid[5] << 8) | (RT2573_ONE_BSSID << 16);
< rum_cfg_write(sc, RT2573_MAC_CSR5, tmp);
---
> tmp = addr[4] | addr[5] << 8 | 0xff << 16;
> rum_write(sc, RT2573_MAC_CSR3, tmp);
1915c1792
< rum_cfg_set_macaddr(struct rum_softc *sc, uint8_t *addr)
---
> rum_promisctask(struct usb2_proc_msg *pm)
1916a1794,1796
> struct rum_task *task = (struct rum_task *)pm;
> struct rum_softc *sc = task->sc;
> struct ifnet *ifp = sc->sc_ifp;
1919,1920c1799
< tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
< rum_cfg_write(sc, RT2573_MAC_CSR2, tmp);
---
> tmp = rum_read(sc, RT2573_TXRX_CSR0);
1922,1936c1801,1802
< tmp = addr[4] | (addr[5] << 8) | (0xff << 16);
< rum_cfg_write(sc, RT2573_MAC_CSR3, tmp);
< }
<
< static void
< rum_cfg_update_promisc(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
< {
< uint32_t tmp;
<
< tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0);
<
< if (cc->if_flags & IFF_PROMISC)
< tmp &= ~RT2573_DROP_NOT_TO_ME;
< else
---
> tmp &= ~RT2573_DROP_NOT_TO_ME;
> if (!(ifp->if_flags & IFF_PROMISC))
1939c1805
< rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp);
---
> rum_write(sc, RT2573_TXRX_CSR0, tmp);
1941,1942c1807
< DPRINTF("%s promiscuous mode\n",
< (cc->if_flags & IFF_PROMISC) ?
---
> DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
1946,1948c1811,1812
< static void
< rum_cfg_select_antenna(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> static const char *
> rum_get_rf(int rev)
1950,2008c1814,1819
< uint32_t tmp;
< uint8_t bbp3;
< uint8_t bbp4;
< uint8_t bbp77;
< uint8_t rx_ant;
< uint8_t is_5ghz;
<
< bbp3 = rum_cfg_bbp_read(sc, 3);
< bbp4 = rum_cfg_bbp_read(sc, 4);
< bbp77 = rum_cfg_bbp_read(sc, 77);
<
< bbp3 &= ~0x01;
< bbp4 &= ~0x23;
<
< rx_ant = sc->sc_rx_ant;
< is_5ghz = cc->ic_curchan.chan_is_5ghz;
<
< switch (sc->sc_rf_rev) {
< case RT2573_RF_5226:
< case RT2573_RF_5225:
< if (rx_ant == 0) {
< /* Diversity */
< bbp4 |= 0x02;
< if (is_5ghz == 0)
< bbp4 |= 0x20;
< } else if (rx_ant == 1) {
< /* RX: Antenna A */
< bbp4 |= 0x01;
< if (is_5ghz)
< bbp77 &= ~0x03;
< else
< bbp77 |= 0x03;
< } else if (rx_ant == 2) {
< /* RX: Antenna B */
< bbp4 |= 0x01;
< if (is_5ghz)
< bbp77 |= 0x03;
< else
< bbp77 &= ~0x03;
< }
< break;
<
< case RT2573_RF_2528:
< case RT2573_RF_2527:
< if (rx_ant == 0) {
< /* Diversity */
< bbp4 |= 0x22;
< } else if (rx_ant == 1) {
< /* RX: Antenna A */
< bbp4 |= 0x21;
< bbp77 |= 0x03;
< } else if (rx_ant == 2) {
< /* RX: Antenna B */
< bbp4 |= 0x21;
< bbp77 &= ~0x03;
< }
< break;
< default:
< break;
---
> switch (rev) {
> case RT2573_RF_2527: return "RT2527 (MIMO XR)";
> case RT2573_RF_2528: return "RT2528";
> case RT2573_RF_5225: return "RT5225 (MIMO XR)";
> case RT2573_RF_5226: return "RT5226";
> default: return "unknown";
2010,2020d1820
< bbp4 &= ~(sc->sc_ftype << 5);
<
< /* make sure Rx is disabled before switching antenna */
< tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0);
< rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
<
< rum_cfg_bbp_write(sc, 3, bbp3);
< rum_cfg_bbp_write(sc, 4, bbp4);
< rum_cfg_bbp_write(sc, 77, bbp77);
<
< rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp);
2024c1824
< rum_cfg_read_eeprom(struct rum_softc *sc)
---
> rum_read_eeprom(struct rum_softc *sc)
2026a1827,1829
> #ifdef RUM_DEBUG
> int i;
> #endif
2029c1832
< rum_cfg_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_myaddr, 6);
---
> rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_bssid, 6);
2031,2037c1834,1840
< val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_ANTENNA);
< sc->sc_rf_rev = (val >> 11) & 0x1f;
< sc->sc_hw_radio = (val >> 10) & 0x1;
< sc->sc_ftype = (val >> 6) & 0x1;
< sc->sc_rx_ant = (val >> 4) & 0x3;
< sc->sc_tx_ant = (val >> 2) & 0x3;
< sc->sc_nb_ant = (val & 0x3);
---
> rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
> val = le16toh(val);
> sc->rf_rev = (val >> 11) & 0x1f;
> sc->hw_radio = (val >> 10) & 0x1;
> sc->rx_ant = (val >> 4) & 0x3;
> sc->tx_ant = (val >> 2) & 0x3;
> sc->nb_ant = val & 0x3;
2039c1842
< DPRINTF("RF revision=%d\n", sc->sc_rf_rev);
---
> DPRINTF("RF revision=%d\n", sc->rf_rev);
2041,2043c1844,1847
< val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_CONFIG2);
< sc->sc_ext_5ghz_lna = (val >> 6) & 0x1;
< sc->sc_ext_2ghz_lna = (val >> 4) & 0x1;
---
> rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2);
> val = le16toh(val);
> sc->ext_5ghz_lna = (val >> 6) & 0x1;
> sc->ext_2ghz_lna = (val >> 4) & 0x1;
2045,2046c1849,1850
< DPRINTF("External 2GHz LNA=%d, External 5GHz LNA=%d\n",
< sc->sc_ext_2ghz_lna, sc->sc_ext_5ghz_lna);
---
> DPRINTF("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
> sc->ext_2ghz_lna, sc->ext_5ghz_lna);
2048c1852,1853
< val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET);
---
> rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2);
> val = le16toh(val);
2050,2052c1855
< sc->sc_rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */
< else
< sc->sc_rssi_2ghz_corr = 0;
---
> sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */
2054,2059c1857,1862
< /* range check */
< if ((sc->sc_rssi_2ghz_corr < -10) ||
< (sc->sc_rssi_2ghz_corr > 10)) {
< sc->sc_rssi_2ghz_corr = 0;
< }
< val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET);
---
> /* Only [-10, 10] is valid */
> if (sc->rssi_2ghz_corr < -10 || sc->rssi_2ghz_corr > 10)
> sc->rssi_2ghz_corr = 0;
>
> rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2);
> val = le16toh(val);
2061,2063c1864
< sc->sc_rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */
< else
< sc->sc_rssi_5ghz_corr = 0;
---
> sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */
2065,2077c1866,1868
< /* range check */
< if ((sc->sc_rssi_5ghz_corr < -10) ||
< (sc->sc_rssi_5ghz_corr > 10)) {
< sc->sc_rssi_5ghz_corr = 0;
< }
< if (sc->sc_ext_2ghz_lna) {
< sc->sc_rssi_2ghz_corr -= 14;
< }
< if (sc->sc_ext_5ghz_lna) {
< sc->sc_rssi_5ghz_corr -= 14;
< }
< DPRINTF("RSSI 2GHz corr=%d, RSSI 5GHz corr=%d\n",
< sc->sc_rssi_2ghz_corr, sc->sc_rssi_5ghz_corr);
---
> /* Only [-10, 10] is valid */
> if (sc->rssi_5ghz_corr < -10 || sc->rssi_5ghz_corr > 10)
> sc->rssi_5ghz_corr = 0;
2079c1870,1879
< val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_FREQ_OFFSET);
---
> if (sc->ext_2ghz_lna)
> sc->rssi_2ghz_corr -= 14;
> if (sc->ext_5ghz_lna)
> sc->rssi_5ghz_corr -= 14;
>
> DPRINTF("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
> sc->rssi_2ghz_corr, sc->rssi_5ghz_corr);
>
> rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2);
> val = le16toh(val);
2081,2083c1881
< sc->sc_rffreq = (val & 0xff);
< else
< sc->sc_rffreq = 0;
---
> sc->rffreq = val & 0xff;
2085c1883
< DPRINTF("RF freq=%d\n", sc->sc_rffreq);
---
> DPRINTF("RF freq=%d\n", sc->rffreq);
2088,2089c1886
< rum_cfg_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->sc_txpow, 14);
<
---
> rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
2091c1888,1892
< memset(sc->sc_txpow + 14, 24, sizeof(sc->sc_txpow) - 14);
---
> memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14);
> #ifdef RUM_DEBUG
> for (i = 0; i < 14; i++)
> DPRINTF("Channel=%d Tx power=%d\n", i + 1, sc->txpow[i]);
> #endif
2094c1895,1903
< rum_cfg_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->sc_bbp_prom, 2 * 16);
---
> rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
> #ifdef RUM_DEBUG
> for (i = 0; i < 14; i++) {
> if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
> continue;
> DPRINTF("BBP R%d=%02x\n", sc->bbp_prom[i].reg,
> sc->bbp_prom[i].val);
> }
> #endif
2097,2098c1906,1907
< static uint8_t
< rum_cfg_bbp_init(struct rum_softc *sc)
---
> static int
> rum_bbp_init(struct rum_softc *sc)
2100,2105c1909,1910
< enum {
< N_DEF_BBP = (sizeof(rum_def_bbp) / sizeof(rum_def_bbp[0])),
< };
< uint16_t i;
< uint8_t to;
< uint8_t tmp;
---
> #define N(a) (sizeof (a) / sizeof ((a)[0]))
> int i, ntries;
2107,2121c1912,1917
< /* wait for BBP to become ready */
< for (to = 0;; to++) {
< if (to < 100) {
< tmp = rum_cfg_bbp_read(sc, 0);
< if ((tmp != 0x00) &&
< (tmp != 0xff)) {
< break;
< }
< if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
< return (1); /* failure */
< }
< } else {
< DPRINTF("timeout waiting for BBP\n");
< return (1); /* failure */
< }
---
> /* wait for BBP to be ready */
> for (ntries = 0; ntries < 100; ntries++) {
> const uint8_t val = rum_bbp_read(sc, 0);
> if (val != 0 && val != 0xff)
> break;
> DELAY(1000);
2122a1919,1922
> if (ntries == 100) {
> device_printf(sc->sc_dev, "timeout waiting for BBP\n");
> return EIO;
> }
2125,2127c1925,1926
< for (i = 0; i < N_DEF_BBP; i++) {
< rum_cfg_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
< }
---
> for (i = 0; i < N(rum_def_bbp); i++)
> rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
2131,2132c1930
< if ((sc->sc_bbp_prom[i].reg == 0) ||
< (sc->sc_bbp_prom[i].reg == 0xff)) {
---
> if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
2134,2135c1932
< }
< rum_cfg_bbp_write(sc, sc->sc_bbp_prom[i].reg, sc->sc_bbp_prom[i].val);
---
> rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
2137c1934,1936
< return (0);
---
>
> return 0;
> #undef N
2141,2142c1940
< rum_cfg_pre_init(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> rum_init_task(struct usb2_proc_msg *pm)
2143a1942,1944
> #define N(a) (sizeof (a) / sizeof ((a)[0]))
> struct rum_task *task = (struct rum_task *)pm;
> struct rum_softc *sc = task->sc;
2146,2165d1946
<
< /* immediate configuration */
<
< rum_cfg_pre_stop(sc, cc, 0);
<
< ifp->if_drv_flags |= IFF_DRV_RUNNING;
<
< sc->sc_flags |= RUM_FLAG_HL_READY;
<
< IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
< }
<
< static void
< rum_cfg_init(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
< {
< enum {
< N_DEF_MAC = (sizeof(rum_def_mac) / sizeof(rum_def_mac[0])),
< };
<
2167,2168c1948,1949
< uint16_t i;
< uint8_t to;
---
> usb2_error_t error;
> int i, ntries;
2170c1951
< /* delayed configuration */
---
> RUM_LOCK_ASSERT(sc, MA_OWNED);
2172c1953
< rum_cfg_stop(sc, cc, 0);
---
> rum_stop_task(pm);
2175,2177c1956,1957
< for (i = 0; i < N_DEF_MAC; i++) {
< rum_cfg_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
< }
---
> for (i = 0; i < N(rum_def_mac); i++)
> rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
2180,2181c1960,1961
< rum_cfg_write(sc, RT2573_MAC_CSR1, 3);
< rum_cfg_write(sc, RT2573_MAC_CSR1, 0);
---
> rum_write(sc, RT2573_MAC_CSR1, 3);
> rum_write(sc, RT2573_MAC_CSR1, 0);
2184,2198c1964,1968
< for (to = 0;; to++) {
< if (to < 100) {
< if (rum_cfg_read(sc, RT2573_MAC_CSR12) & 8) {
< break;
< }
< rum_cfg_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */
<
< if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
< goto fail;
< }
< } else {
< DPRINTF("timeout waiting for "
< "BBP/RF to wakeup\n");
< goto fail;
< }
---
> for (ntries = 0; ntries < 1000; ntries++) {
> if (rum_read(sc, RT2573_MAC_CSR12) & 8)
> break;
> rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */
> DELAY(1000);
2200,2201c1970,1972
<
< if (rum_cfg_bbp_init(sc)) {
---
> if (ntries == 1000) {
> device_printf(sc->sc_dev,
> "timeout waiting for BBP/RF to wakeup\n");
2204d1974
< /* select default channel */
2206c1976,1977
< sc->sc_last_chan = 0;
---
> if ((error = rum_bbp_init(sc)) != 0)
> goto fail;
2208c1979,1982
< rum_cfg_set_chan(sc, cc, 0);
---
> /* select default channel */
> rum_select_band(sc, ic->ic_curchan);
> rum_select_antenna(sc);
> rum_set_chan(sc, ic->ic_curchan);
2211,2213c1985
< rum_cfg_read_multi(sc, RT2573_STA_CSR0, sc->sc_sta, sizeof(sc->sc_sta));
< /* set MAC address */
< rum_cfg_set_macaddr(sc, cc->ic_myaddr);
---
> rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
2214a1987,1989
> IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
> rum_set_macaddr(sc, ic->ic_myaddr);
>
2216c1991
< rum_cfg_write(sc, RT2573_MAC_CSR1, 4);
---
> rum_write(sc, RT2573_MAC_CSR1, 4);
2219,2220c1994
< * make sure that the first transaction
< * clears the stall:
---
> * Allocate Tx and Rx xfer queues.
2222,2224c1996
< sc->sc_flags |= (RUM_FLAG_READ_STALL |
< RUM_FLAG_WRITE_STALL |
< RUM_FLAG_LL_READY);
---
> rum_setup_tx_list(sc);
2226,2243d1997
< if ((sc->sc_flags & RUM_FLAG_LL_READY) &&
< (sc->sc_flags & RUM_FLAG_HL_READY)) {
< struct ifnet *ifp = sc->sc_ifp;
< struct ieee80211com *ic = ifp->if_l2com;
<
< /*
< * start the USB transfers, if not already started:
< */
< usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_RD]);
< usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]);
<
< /*
< * start IEEE802.11 layer
< */
< mtx_unlock(&sc->sc_mtx);
< ieee80211_start_all(ic);
< mtx_lock(&sc->sc_mtx);
< }
2245c1999
< tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0) & 0xffff;
---
> tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
2248,2249c2002
<
< if (cc->ic_opmode != IEEE80211_M_MONITOR) {
---
> if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2251,2252c2004,2005
< RT2573_DROP_ACKCTS;
< if (cc->ic_opmode != IEEE80211_M_HOSTAP) {
---
> RT2573_DROP_ACKCTS;
> if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2254,2255c2007
< }
< if (!(cc->if_flags & IFF_PROMISC)) {
---
> if (!(ifp->if_flags & IFF_PROMISC))
2257d2008
< }
2259c2010
< rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp);
---
> rum_write(sc, RT2573_TXRX_CSR0, tmp);
2260a2012,2014
> ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
> ifp->if_drv_flags |= IFF_DRV_RUNNING;
> usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
2263,2268c2017,2018
< fail:
< rum_cfg_pre_stop(sc, NULL, 0);
<
< if (cc) {
< rum_cfg_stop(sc, cc, 0);
< }
---
> fail: rum_stop_task(pm);
> #undef N
2272,2273c2022
< rum_cfg_pre_stop(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> rum_init(void *priv)
2274a2024
> struct rum_softc *sc = priv;
2275a2026
> struct ieee80211com *ic = ifp->if_l2com;
2277,2281c2028,2032
< if (cc) {
< /* copy the needed configuration */
< rum_config_copy(sc, cc, refcount);
< }
< /* immediate configuration */
---
> RUM_LOCK(sc);
> rum_queue_command(sc, rum_init_task,
> &sc->sc_synctask[0].hdr,
> &sc->sc_synctask[1].hdr);
> RUM_UNLOCK(sc);
2283,2299c2034,2035
< if (ifp) {
< /* clear flags */
< ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
< }
< sc->sc_flags &= ~(RUM_FLAG_HL_READY |
< RUM_FLAG_LL_READY);
<
< /*
< * stop all the transfers, if not already stopped:
< */
< usb2_transfer_stop(sc->sc_xfer[RUM_BULK_DT_WR]);
< usb2_transfer_stop(sc->sc_xfer[RUM_BULK_DT_RD]);
< usb2_transfer_stop(sc->sc_xfer[RUM_BULK_CS_WR]);
< usb2_transfer_stop(sc->sc_xfer[RUM_BULK_CS_RD]);
<
< /* clean up transmission */
< rum_tx_clean_queue(sc);
---
> if (ifp->if_drv_flags & IFF_DRV_RUNNING)
> ieee80211_start_all(ic); /* start all vap's */
2303,2304c2039
< rum_cfg_stop(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> rum_stop_task(struct usb2_proc_msg *pm)
2305a2041,2043
> struct rum_task *task = (struct rum_task *)pm;
> struct rum_softc *sc = task->sc;
> struct ifnet *ifp = sc->sc_ifp;
2308,2310c2046
< /* disable Rx */
< tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0);
< rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
---
> RUM_LOCK_ASSERT(sc, MA_OWNED);
2312,2313c2048
< /* reset ASIC */
< rum_cfg_write(sc, RT2573_MAC_CSR1, 3);
---
> ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
2315,2316c2050
< /* wait a little */
< usb2_config_td_sleep(&sc->sc_config_td, hz / 10);
---
> RUM_UNLOCK(sc);
2318c2052,2056
< rum_cfg_write(sc, RT2573_MAC_CSR1, 0);
---
> /*
> * Drain the USB transfers, if not already drained:
> */
> usb2_transfer_drain(sc->sc_xfer[RUM_BULK_WR]);
> usb2_transfer_drain(sc->sc_xfer[RUM_BULK_RD]);
2320,2322c2058
< /* wait a little */
< usb2_config_td_sleep(&sc->sc_config_td, hz / 10);
< }
---
> RUM_LOCK(sc);
2324,2328c2060
< static void
< rum_cfg_amrr_start(struct rum_softc *sc)
< {
< struct ieee80211vap *vap;
< struct ieee80211_node *ni;
---
> rum_unsetup_tx_list(sc);
2330c2062,2064
< vap = rum_get_vap(sc);
---
> /* disable Rx */
> tmp = rum_read(sc, RT2573_TXRX_CSR0);
> rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
2332,2345c2066,2068
< if (vap == NULL) {
< return;
< }
< ni = vap->iv_bss;
< if (ni == NULL) {
< return;
< }
< /* init AMRR */
<
< ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni);
<
< /* enable AMRR timer */
<
< sc->sc_amrr_timer = 1;
---
> /* reset ASIC */
> rum_write(sc, RT2573_MAC_CSR1, 3);
> rum_write(sc, RT2573_MAC_CSR1, 0);
2348,2350c2071,2072
< static void
< rum_cfg_amrr_timeout(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> static int
> rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size)
2352,2390d2073
< struct ifnet *ifp = sc->sc_ifp;
< struct ieee80211vap *vap;
< struct ieee80211_node *ni;
< uint32_t ok;
< uint32_t fail;
<
< /* clear statistic registers (STA_CSR0 to STA_CSR5) */
< rum_cfg_read_multi(sc, RT2573_STA_CSR0, sc->sc_sta, sizeof(sc->sc_sta));
<
< vap = rum_get_vap(sc);
< if (vap == NULL) {
< return;
< }
< ni = vap->iv_bss;
< if (ni == NULL) {
< return;
< }
< if ((sc->sc_flags & RUM_FLAG_LL_READY) &&
< (sc->sc_flags & RUM_FLAG_HL_READY)) {
<
< ok = (le32toh(sc->sc_sta[4]) >> 16) + /* TX ok w/o retry */
< (le32toh(sc->sc_sta[5]) & 0xffff); /* TX ok w/ retry */
< fail = (le32toh(sc->sc_sta[5]) >> 16); /* TX retry-fail count */
<
< if (sc->sc_amrr_timer) {
< ieee80211_amrr_tx_update(&RUM_NODE(vap->iv_bss)->amn,
< ok + fail, ok, (le32toh(sc->sc_sta[5]) & 0xffff) + fail);
<
< if (ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn)) {
< /* ignore */
< }
< }
< ifp->if_oerrors += fail;/* count TX retry-fail as Tx errors */
< }
< }
<
< static void
< rum_cfg_load_microcode(struct rum_softc *sc, const uint8_t *ucode, uint16_t size)
< {
2392a2076
> usb2_error_t error;
2395,2400c2079,2080
< while (size >= 4) {
< rum_cfg_write(sc, reg, UGETDW(ucode));
< reg += 4;
< ucode += 4;
< size -= 4;
< }
---
> for (; size >= 4; reg += 4, ucode += 4, size -= 4)
> rum_write(sc, reg, UGETDW(ucode));
2402,2404d2081
< if (size != 0) {
< DPRINTF("possibly invalid firmware\n");
< }
2411c2088,2093
< rum_cfg_do_request(sc, &req, NULL);
---
> error = rum_do_request(sc, &req, NULL);
> if (error != 0) {
> device_printf(sc->sc_dev, "could not run firmware: %s\n",
> usb2_errstr(error));
> }
> return error;
2414,2416c2096,2097
< static void
< rum_cfg_prepare_beacon(struct rum_softc *sc,
< struct usb2_config_td_cc *cc, uint16_t refcount)
---
> static int
> rum_prepare_beacon(struct rum_softc *sc, struct ieee80211vap *vap)
2418,2420c2099
< struct ieee80211_node *ni;
< struct ieee80211vap *vap;
< struct ieee80211com *ic;
---
> struct ieee80211com *ic = vap->iv_ic;
2422c2101,2102
< struct mbuf *m;
---
> struct rum_tx_desc desc;
> struct mbuf *m0;
2424,2426c2104,2106
< vap = rum_get_vap(sc);
< if (vap == NULL) {
< return;
---
> m0 = ieee80211_beacon_alloc(vap->iv_bss, &RUM_VAP(vap)->bo);
> if (m0 == NULL) {
> return ENOBUFS;
2428,2436d2107
< ni = vap->iv_bss;
< if (ni == NULL) {
< return;
< }
< ic = vap->iv_ic;
< if (ic == NULL) {
< return;
< }
< DPRINTFN(11, "Sending beacon frame.\n");
2438,2442d2108
< m = ieee80211_beacon_alloc(ni, &RUM_VAP(vap)->bo);
< if (m == NULL) {
< DPRINTFN(0, "could not allocate beacon\n");
< return;
< }
2443a2110,2111
> rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ,
> m0->m_pkthdr.len, tp->mgmtrate);
2445,2446c2113,2122
< m->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ni);
< rum_setup_desc_and_tx(sc, m, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ | RT2573_TX_BEACON, tp->mgmtrate);
---
> /* copy the first 24 bytes of Tx descriptor into NIC memory */
> rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24);
>
> /* copy beacon header and payload into NIC memory */
> rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *),
> m0->m_pkthdr.len);
>
> m_freem(m0);
>
> return 0;
2449,2450c2125,2127
< static uint8_t
< rum_get_rssi(struct rum_softc *sc, uint8_t raw)
---
> static int
> rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
> const struct ieee80211_bpf_params *params)
2452,2456c2129,2130
< struct ifnet *ifp = sc->sc_ifp;
< struct ieee80211com *ic = ifp->if_l2com;
< int16_t rssi;
< uint8_t lna;
< uint8_t agc;
---
> struct ifnet *ifp = ni->ni_ic->ic_ifp;
> struct rum_softc *sc = ifp->if_softc;
2458,2468c2132,2138
< lna = (raw >> 5) & 0x3;
< agc = raw & 0x1f;
<
< if (lna == 0) {
< /*
< * No RSSI mapping
< *
< * NB: Since RSSI is relative to noise floor, -1 is
< * adequate for caller to know error happened.
< */
< return (0);
---
> RUM_LOCK(sc);
> /* prevent management frames from being sent if we're not ready */
> if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
> RUM_UNLOCK(sc);
> m_freem(m);
> ieee80211_free_node(ni);
> return ENETDOWN;
2470c2140,2146
< rssi = (2 * agc) - RT2573_NOISE_FLOOR;
---
> if (sc->tx_nfree == 0) {
> ifp->if_drv_flags |= IFF_DRV_OACTIVE;
> RUM_UNLOCK(sc);
> m_freem(m);
> ieee80211_free_node(ni);
> return EIO;
> }
2472c2148
< if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
---
> ifp->if_opackets++;
2474,2481c2150,2156
< rssi += sc->sc_rssi_2ghz_corr;
<
< if (lna == 1)
< rssi -= 64;
< else if (lna == 2)
< rssi -= 74;
< else if (lna == 3)
< rssi -= 90;
---
> if (params == NULL) {
> /*
> * Legacy path; interpret frame contents to decide
> * precisely how to send the frame.
> */
> if (rum_tx_mgt(sc, m, ni) != 0)
> goto bad;
2483,2494c2158,2163
<
< rssi += sc->sc_rssi_5ghz_corr;
<
< if ((!sc->sc_ext_5ghz_lna) && (lna != 1))
< rssi += 4;
<
< if (lna == 1)
< rssi -= 64;
< else if (lna == 2)
< rssi -= 86;
< else if (lna == 3)
< rssi -= 100;
---
> /*
> * Caller supplied explicit parameters to use in
> * sending the frame.
> */
> if (rum_tx_raw(sc, m, ni, params) != 0)
> goto bad;
2495a2165
> RUM_UNLOCK(sc);
2497,2504c2167,2172
< /* range check */
<
< if (rssi < 0)
< rssi = 0;
< else if (rssi > 255)
< rssi = 255;
<
< return (rssi);
---
> return 0;
> bad:
> ifp->if_oerrors++;
> RUM_UNLOCK(sc);
> ieee80211_free_node(ni);
> return EIO;
2507,2511c2175,2176
< static struct ieee80211vap *
< rum_vap_create(struct ieee80211com *ic,
< const char name[IFNAMSIZ], int unit, int opmode, int flags,
< const uint8_t bssid[IEEE80211_ADDR_LEN],
< const uint8_t mac[IEEE80211_ADDR_LEN])
---
> static void
> rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
2513,2515c2178,2179
< struct rum_vap *rvp;
< struct ieee80211vap *vap;
< struct rum_softc *sc = ic->ic_ifp->if_softc;
---
> struct ieee80211vap *vap = ni->ni_vap;
> struct rum_vap *rvp = RUM_VAP(vap);
2517c2181,2182
< DPRINTF("\n");
---
> /* clear statistic registers (STA_CSR0 to STA_CSR5) */
> rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
2519,2526c2184
< /* Need to sync with config thread: */
< mtx_lock(&sc->sc_mtx);
< if (usb2_config_td_sync(&sc->sc_config_td)) {
< mtx_unlock(&sc->sc_mtx);
< /* config thread is gone */
< return (NULL);
< }
< mtx_unlock(&sc->sc_mtx);
---
> ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni);
2528,2537c2186,2187
< if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
< return NULL;
< rvp = (struct rum_vap *)malloc(sizeof(struct rum_vap),
< M_80211_VAP, M_NOWAIT | M_ZERO);
< if (rvp == NULL)
< return NULL;
< vap = &rvp->vap;
< /* enable s/w bmiss handling for sta mode */
< ieee80211_vap_setup(ic, vap, name, unit, opmode,
< flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
---
> usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
> }
2539,2541c2189,2193
< /* override state transition machine */
< rvp->newstate = vap->iv_newstate;
< vap->iv_newstate = &rum_newstate_cb;
---
> static void
> rum_amrr_timeout(void *arg)
> {
> struct rum_vap *rvp = arg;
> struct rum_softc *sc = rvp->sc;
2543,2554c2195,2196
< ieee80211_amrr_init(&rvp->amrr, vap,
< IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
< IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
< 1000 /* 1 sec */ );
<
< /* complete setup */
< ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
<
< /* store current operation mode */
< ic->ic_opmode = opmode;
<
< return (vap);
---
> rum_queue_command(sc, rum_amrr_task,
> &rvp->amrr_task[0].hdr, &rvp->amrr_task[1].hdr);
2558c2200
< rum_vap_delete(struct ieee80211vap *vap)
---
> rum_amrr_task(struct usb2_proc_msg *pm)
2559a2202,2206
> struct rum_task *task = (struct rum_task *)pm;
> struct rum_softc *sc = task->sc;
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
> struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
2561c2208,2209
< struct rum_softc *sc = vap->iv_ic->ic_ifp->if_softc;
---
> struct ieee80211_node *ni = vap->iv_bss;
> int ok, fail;
2563c2211,2212
< DPRINTF("\n");
---
> /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
> rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta));
2565,2570c2214,2216
< /* Need to sync with config thread: */
< mtx_lock(&sc->sc_mtx);
< if (usb2_config_td_sync(&sc->sc_config_td)) {
< /* ignore */
< }
< mtx_unlock(&sc->sc_mtx);
---
> ok = (le32toh(sc->sta[4]) >> 16) + /* TX ok w/o retry */
> (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */
> fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */
2572,2574c2218,2224
< ieee80211_amrr_cleanup(&rvp->amrr);
< ieee80211_vap_detach(vap);
< free(rvp, M_80211_VAP);
---
> ieee80211_amrr_tx_update(&RUM_NODE(ni)->amn,
> ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail);
> (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn);
>
> ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
>
> usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
2580c2230
< const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
---
> const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
2585c2235
< return ((rn != NULL) ? &rn->ni : NULL);
---
> return rn != NULL ? &rn->ni : NULL;
2597c2247
< rum_fill_write_queue(struct rum_softc *sc)
---
> rum_scan_start(struct ieee80211com *ic)
2599,2601c2249
< struct ifnet *ifp = sc->sc_ifp;
< struct ieee80211_node *ni;
< struct mbuf *m;
---
> struct rum_softc *sc = ic->ic_ifp->if_softc;
2603,2606c2251,2256
< /*
< * We only fill up half of the queue with data frames. The rest is
< * reserved for other kinds of frames.
< */
---
> RUM_LOCK(sc);
> /* do it in a process context */
> sc->sc_scan_action = RUM_SCAN_START;
> rum_queue_command(sc, rum_scantask,
> &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
> RUM_UNLOCK(sc);
2608,2621d2257
< while (sc->sc_tx_queue.ifq_len < (IFQ_MAXLEN / 2)) {
<
< IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
< if (m == NULL)
< break;
<
< ni = (void *)(m->m_pkthdr.rcvif);
< m = ieee80211_encap(ni, m);
< if (m == NULL) {
< ieee80211_free_node(ni);
< continue;
< }
< rum_tx_data(sc, m, ni);
< }
2625c2261
< rum_tx_clean_queue(struct rum_softc *sc)
---
> rum_scan_end(struct ieee80211com *ic)
2627c2263
< struct mbuf *m;
---
> struct rum_softc *sc = ic->ic_ifp->if_softc;
2629,2630c2265,2270
< for (;;) {
< _IF_DEQUEUE(&sc->sc_tx_queue, m);
---
> RUM_LOCK(sc);
> /* do it in a process context */
> sc->sc_scan_action = RUM_SCAN_END;
> rum_queue_command(sc, rum_scantask,
> &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
> RUM_UNLOCK(sc);
2632,2636d2271
< if (!m) {
< break;
< }
< rum_tx_freem(m);
< }
2640c2275
< rum_tx_freem(struct mbuf *m)
---
> rum_set_channel(struct ieee80211com *ic)
2642c2277
< struct ieee80211_node *ni;
---
> struct rum_softc *sc = ic->ic_ifp->if_softc;
2644,2654c2279,2283
< while (m) {
< ni = (void *)(m->m_pkthdr.rcvif);
< if (!ni) {
< m = m_free(m);
< continue;
< }
< if (m->m_flags & M_TXCB) {
< ieee80211_process_callback(ni, m, 0);
< }
< m_freem(m);
< ieee80211_free_node(ni);
---
> RUM_LOCK(sc);
> /* do it in a process context */
> sc->sc_scan_action = RUM_SET_CHANNEL;
> rum_queue_command(sc, rum_scantask,
> &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
2656,2657c2285,2286
< break;
< }
---
> sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
> RUM_UNLOCK(sc);
2661c2290
< rum_tx_mgt(struct rum_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
---
> rum_scantask(struct usb2_proc_msg *pm)
2663,2669c2292,2296
< struct ieee80211vap *vap = ni->ni_vap;
< struct ieee80211com *ic = ni->ni_ic;
< const struct ieee80211_txparam *tp;
< struct ieee80211_frame *wh;
< struct ieee80211_key *k;
< uint32_t flags;
< uint16_t dur;
---
> struct rum_task *task = (struct rum_task *)pm;
> struct rum_softc *sc = task->sc;
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
> uint32_t tmp;
2671c2298
< tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
---
> RUM_LOCK_ASSERT(sc, MA_OWNED);
2673,2685c2300,2306
< wh = mtod(m, struct ieee80211_frame *);
< if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
< k = ieee80211_crypto_encap(ni, m);
< if (k == NULL) {
< m_freem(m);
< ieee80211_free_node(ni);
< return;
< }
< wh = mtod(m, struct ieee80211_frame *);
< }
< flags = 0;
< if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
< flags |= RT2573_TX_NEED_ACK;
---
> switch (sc->sc_scan_action) {
> case RUM_SCAN_START:
> /* abort TSF synchronization */
> tmp = rum_read(sc, RT2573_TXRX_CSR9);
> rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
> rum_set_bssid(sc, ifp->if_broadcastaddr);
> break;
2687,2689c2308,2310
< dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate,
< ic->ic_flags & IEEE80211_F_SHPREAMBLE);
< USETW(wh->i_dur, dur);
---
> case RUM_SET_CHANNEL:
> rum_set_chan(sc, ic->ic_curchan);
> break;
2691,2695c2312,2315
< /* tell hardware to add timestamp for probe responses */
< if ((wh->i_fc[0] &
< (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
< (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
< flags |= RT2573_TX_TIMESTAMP;
---
> default: /* RUM_SCAN_END */
> rum_enable_tsf_sync(sc);
> rum_set_bssid(sc, sc->sc_bssid);
> break;
2697,2698d2316
< m->m_pkthdr.rcvif = (void *)ni;
< rum_setup_desc_and_tx(sc, m, flags, 0, tp->mgmtrate);
2701,2702c2319,2320
< static struct ieee80211vap *
< rum_get_vap(struct rum_softc *sc)
---
> static int
> rum_get_rssi(struct rum_softc *sc, uint8_t raw)
2704,2705c2322,2324
< struct ifnet *ifp;
< struct ieee80211com *ic;
---
> struct ifnet *ifp = sc->sc_ifp;
> struct ieee80211com *ic = ifp->if_l2com;
> int lna, agc, rssi;
2707,2708c2326,2336
< if (sc == NULL) {
< return NULL;
---
> lna = (raw >> 5) & 0x3;
> agc = raw & 0x1f;
>
> if (lna == 0) {
> /*
> * No RSSI mapping
> *
> * NB: Since RSSI is relative to noise floor, -1 is
> * adequate for caller to know error happened.
> */
> return -1;
2710,2719d2337
< ifp = sc->sc_ifp;
< if (ifp == NULL) {
< return NULL;
< }
< ic = ifp->if_l2com;
< if (ic == NULL) {
< return NULL;
< }
< return TAILQ_FIRST(&ic->ic_vaps);
< }
2721,2732c2339
< static void
< rum_tx_data(struct rum_softc *sc, struct mbuf *m,
< struct ieee80211_node *ni)
< {
< struct ieee80211vap *vap = ni->ni_vap;
< struct ieee80211com *ic = ni->ni_ic;
< const struct ieee80211_txparam *tp;
< struct ieee80211_frame *wh;
< struct ieee80211_key *k;
< uint32_t flags = 0;
< uint16_t dur;
< uint16_t rate;
---
> rssi = (2 * agc) - RT2573_NOISE_FLOOR;
2734c2341,2342
< DPRINTFN(11, "Sending data.\n");
---
> if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
> rssi += sc->rssi_2ghz_corr;
2736c2344,2351
< wh = mtod(m, struct ieee80211_frame *);
---
> if (lna == 1)
> rssi -= 64;
> else if (lna == 2)
> rssi -= 74;
> else if (lna == 3)
> rssi -= 90;
> } else {
> rssi += sc->rssi_5ghz_corr;
2738,2744c2353,2354
< tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
< if (IEEE80211_IS_MULTICAST(wh->i_addr1))
< rate = tp->mcastrate;
< else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
< rate = tp->ucastrate;
< else
< rate = ni->ni_txrate;
---
> if (!sc->ext_5ghz_lna && lna != 1)
> rssi += 4;
2746,2754c2356,2361
< if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
< k = ieee80211_crypto_encap(ni, m);
< if (k == NULL) {
< m_freem(m);
< ieee80211_free_node(ni);
< return;
< }
< /* packet header may have moved, reset our local pointer */
< wh = mtod(m, struct ieee80211_frame *);
---
> if (lna == 1)
> rssi -= 64;
> else if (lna == 2)
> rssi -= 86;
> else if (lna == 3)
> rssi -= 100;
2756,2776c2363
< if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
< uint8_t prot = IEEE80211_PROT_NONE;
<
< if (m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
< prot = IEEE80211_PROT_RTSCTS;
< else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
< ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM)
< prot = ic->ic_protmode;
< if (prot != IEEE80211_PROT_NONE) {
< rum_tx_prot(sc, m, ni, prot, rate);
< flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
< }
< flags |= RT2573_TX_NEED_ACK;
< flags |= RT2573_TX_MORE_FRAG;
<
< dur = ieee80211_ack_duration(sc->sc_rates, rate,
< ic->ic_flags & IEEE80211_F_SHPREAMBLE);
< USETW(wh->i_dur, dur);
< }
< m->m_pkthdr.rcvif = (void *)ni;
< rum_setup_desc_and_tx(sc, m, flags, 0, rate);
---
> return rssi;
2780,2782c2367,2368
< rum_tx_prot(struct rum_softc *sc,
< const struct mbuf *m, struct ieee80211_node *ni,
< uint8_t prot, uint16_t rate)
---
> rum_queue_command(struct rum_softc *sc, usb2_proc_callback_t *fn,
> struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
2784,2792c2370
< struct ieee80211com *ic = ni->ni_ic;
< const struct ieee80211_frame *wh;
< struct mbuf *mprot;
< uint32_t flags;
< uint16_t protrate;
< uint16_t ackrate;
< uint16_t pktlen;
< uint16_t dur;
< uint8_t isshort;
---
> struct rum_task *task;
2794,2796c2372
< KASSERT((prot == IEEE80211_PROT_RTSCTS) ||
< (prot == IEEE80211_PROT_CTSONLY),
< ("protection %u", prot));
---
> RUM_LOCK_ASSERT(sc, MA_OWNED);
2798,2816c2374,2376
< DPRINTFN(11, "Sending protection frame.\n");
<
< wh = mtod(m, const struct ieee80211_frame *);
< pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
<
< protrate = ieee80211_ctl_rate(sc->sc_rates, rate);
< ackrate = ieee80211_ack_rate(sc->sc_rates, rate);
<
< isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
< dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort);
< +ieee80211_ack_duration(sc->sc_rates, rate, isshort);
< flags = RT2573_TX_MORE_FRAG;
< if (prot == IEEE80211_PROT_RTSCTS) {
< /* NB: CTS is the same size as an ACK */
< dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort);
< flags |= RT2573_TX_NEED_ACK;
< mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
< } else {
< mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
---
> if (usb2_proc_is_gone(&sc->sc_tq)) {
> DPRINTF("proc is gone\n");
> return; /* nothing to do */
2818,2823c2378,2384
< if (mprot == NULL) {
< return;
< }
< mprot->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ni);
< rum_setup_desc_and_tx(sc, mprot, flags, 0, protrate);
< }
---
> /*
> * NOTE: The task cannot get executed before we drop the
> * "sc_mtx" mutex. It is safe to update fields in the message
> * structure after that the message got queued.
> */
> task = (struct rum_task *)
> usb2_proc_msignal(&sc->sc_tq, t0, t1);
2825,2830c2386,2388
< static void
< rum_tx_raw(struct rum_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
< const struct ieee80211_bpf_params *params)
< {
< uint32_t flags;
< uint16_t rate;
---
> /* Setup callback and softc pointers */
> task->hdr.pm_callback = fn;
> task->sc = sc;
2832,2853c2390,2394
< DPRINTFN(11, "Sending raw frame.\n");
<
< rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
<
< /* XXX validate */
< if (rate == 0) {
< m_freem(m);
< ieee80211_free_node(ni);
< return;
< }
< flags = 0;
< if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
< flags |= RT2573_TX_NEED_ACK;
< if (params->ibp_flags & (IEEE80211_BPF_RTS | IEEE80211_BPF_CTS)) {
< rum_tx_prot(sc, m, ni,
< params->ibp_flags & IEEE80211_BPF_RTS ?
< IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
< rate);
< flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
< }
< m->m_pkthdr.rcvif = (void *)ni;
< rum_setup_desc_and_tx(sc, m, flags, 0, rate);
---
> /*
> * Init and stop must be synchronous!
> */
> if ((fn == rum_init_task) || (fn == rum_stop_task))
> usb2_proc_mwait(&sc->sc_tq, t0, t1);
2856,2862c2397,2401
< static int
< rum_raw_xmit_cb(struct ieee80211_node *ni, struct mbuf *m,
< const struct ieee80211_bpf_params *params)
< {
< struct ieee80211com *ic = ni->ni_ic;
< struct ifnet *ifp = ic->ic_ifp;
< struct rum_softc *sc = ifp->if_softc;
---
> static device_method_t rum_methods[] = {
> /* Device interface */
> DEVMETHOD(device_probe, rum_match),
> DEVMETHOD(device_attach, rum_attach),
> DEVMETHOD(device_detach, rum_detach),
2864,2880c2403,2404
< mtx_lock(&sc->sc_mtx);
< if (params == NULL) {
< /*
< * Legacy path; interpret frame contents to decide
< * precisely how to send the frame.
< */
< rum_tx_mgt(sc, m, ni);
< } else {
< /*
< * Caller supplied explicit parameters to use in
< * sending the frame.
< */
< rum_tx_raw(sc, m, ni, params);
< }
< mtx_unlock(&sc->sc_mtx);
< return (0);
< }
---
> { 0, 0 }
> };
2882,2886c2406,2410
< static void
< rum_update_mcast_cb(struct ifnet *ifp)
< {
< /* not supported */
< }
---
> static driver_t rum_driver = {
> .name = "rum",
> .methods = rum_methods,
> .size = sizeof(struct rum_softc),
> };
2888,2891c2412
< static void
< rum_update_promisc_cb(struct ifnet *ifp)
< {
< struct rum_softc *sc = ifp->if_softc;
---
> static devclass_t rum_devclass;
2893,2898c2414
< mtx_lock(&sc->sc_mtx);
< usb2_config_td_queue_command
< (&sc->sc_config_td, &rum_config_copy,
< &rum_cfg_update_promisc, 0, 0);
< mtx_unlock(&sc->sc_mtx);
< }
---
> DRIVER_MODULE(rum, ushub, rum_driver, rum_devclass, NULL, 0);