if_ural.c revision 185948
1184610Salfred/* $FreeBSD: head/sys/dev/usb2/wlan/if_ural2.c 185948 2008-12-11 23:13:02Z thompsa $ */ 2184610Salfred 3184610Salfred/*- 4184610Salfred * Copyright (c) 2005, 2006 5184610Salfred * Damien Bergamini <damien.bergamini@free.fr> 6184610Salfred * 7184610Salfred * Copyright (c) 2006, 2008 8184610Salfred * Hans Petter Selasky <hselasky@freebsd.org> 9184610Salfred * 10184610Salfred * Permission to use, copy, modify, and distribute this software for any 11184610Salfred * purpose with or without fee is hereby granted, provided that the above 12184610Salfred * copyright notice and this permission notice appear in all copies. 13184610Salfred * 14184610Salfred * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15184610Salfred * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16184610Salfred * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17184610Salfred * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18184610Salfred * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19184610Salfred * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20184610Salfred * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21184610Salfred * 22184610Salfred */ 23184610Salfred 24184610Salfred/* 25184610Salfred * 26184610Salfred * NOTE: all function names beginning like "ural_cfg_" can only 27184610Salfred * be called from within the config thread function ! 28184610Salfred */ 29184610Salfred 30184610Salfred#include <sys/cdefs.h> 31184610Salfred__FBSDID("$FreeBSD: head/sys/dev/usb2/wlan/if_ural2.c 185948 2008-12-11 23:13:02Z thompsa $"); 32184610Salfred 33184610Salfred/*- 34184610Salfred * Ralink Technology RT2500USB chipset driver 35184610Salfred * http://www.ralinktech.com/ 36184610Salfred */ 37184610Salfred 38184610Salfred#include <dev/usb2/include/usb2_devid.h> 39184610Salfred#include <dev/usb2/include/usb2_standard.h> 40184610Salfred#include <dev/usb2/include/usb2_mfunc.h> 41184610Salfred#include <dev/usb2/include/usb2_error.h> 42184610Salfred 43184610Salfred#define usb2_config_td_cc ural_config_copy 44184610Salfred#define usb2_config_td_softc ural_softc 45184610Salfred 46184610Salfred#define USB_DEBUG_VAR ural_debug 47184610Salfred 48184610Salfred#include <dev/usb2/core/usb2_core.h> 49184610Salfred#include <dev/usb2/core/usb2_lookup.h> 50184610Salfred#include <dev/usb2/core/usb2_process.h> 51184610Salfred#include <dev/usb2/core/usb2_config_td.h> 52184610Salfred#include <dev/usb2/core/usb2_debug.h> 53184610Salfred#include <dev/usb2/core/usb2_request.h> 54184610Salfred#include <dev/usb2/core/usb2_busdma.h> 55184610Salfred#include <dev/usb2/core/usb2_util.h> 56184610Salfred 57184610Salfred#include <dev/usb2/wlan/usb2_wlan.h> 58184610Salfred#include <dev/usb2/wlan/if_ural2_reg.h> 59184610Salfred#include <dev/usb2/wlan/if_ural2_var.h> 60184610Salfred 61184610Salfred#if USB_DEBUG 62184610Salfredstatic int ural_debug = 0; 63184610Salfred 64184610SalfredSYSCTL_NODE(_hw_usb2, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural"); 65184610SalfredSYSCTL_INT(_hw_usb2_ural, OID_AUTO, debug, CTLFLAG_RW, &ural_debug, 0, 66184610Salfred "Debug level"); 67184610Salfred#endif 68184610Salfred 69184610Salfred#define URAL_RSSI(rssi) \ 70184610Salfred ((rssi) > (RAL_NOISE_FLOOR + RAL_RSSI_CORR) ? \ 71184610Salfred ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0) 72184610Salfred 73184610Salfred/* prototypes */ 74184610Salfred 75184610Salfredstatic device_probe_t ural_probe; 76184610Salfredstatic device_attach_t ural_attach; 77184610Salfredstatic device_detach_t ural_detach; 78184610Salfred 79184610Salfredstatic usb2_callback_t ural_bulk_read_callback; 80184610Salfredstatic usb2_callback_t ural_bulk_read_clear_stall_callback; 81184610Salfredstatic usb2_callback_t ural_bulk_write_callback; 82184610Salfredstatic usb2_callback_t ural_bulk_write_clear_stall_callback; 83184610Salfred 84184610Salfredstatic usb2_config_td_command_t ural_cfg_first_time_setup; 85184610Salfredstatic usb2_config_td_command_t ural_config_copy; 86184610Salfredstatic usb2_config_td_command_t ural_cfg_scan_start; 87184610Salfredstatic usb2_config_td_command_t ural_cfg_scan_end; 88184610Salfredstatic usb2_config_td_command_t ural_cfg_set_chan; 89184610Salfredstatic usb2_config_td_command_t ural_cfg_enable_tsf_sync; 90184610Salfredstatic usb2_config_td_command_t ural_cfg_update_slot; 91184610Salfredstatic usb2_config_td_command_t ural_cfg_set_txpreamble; 92184610Salfredstatic usb2_config_td_command_t ural_cfg_update_promisc; 93184610Salfredstatic usb2_config_td_command_t ural_cfg_pre_init; 94184610Salfredstatic usb2_config_td_command_t ural_cfg_init; 95184610Salfredstatic usb2_config_td_command_t ural_cfg_pre_stop; 96184610Salfredstatic usb2_config_td_command_t ural_cfg_stop; 97184610Salfredstatic usb2_config_td_command_t ural_cfg_amrr_timeout; 98184610Salfredstatic usb2_config_td_command_t ural_cfg_newstate; 99184610Salfred 100185948Sthompsastatic void ural_cfg_do_request(struct ural_softc *, 101185948Sthompsa struct usb2_device_request *, void *); 102185948Sthompsastatic void ural_cfg_set_testmode(struct ural_softc *); 103185948Sthompsastatic void ural_cfg_eeprom_read(struct ural_softc *, uint16_t, void *, 104185948Sthompsa uint16_t); 105185948Sthompsastatic uint16_t ural_cfg_read(struct ural_softc *, uint16_t); 106185948Sthompsastatic void ural_cfg_read_multi(struct ural_softc *, uint16_t, void *, 107185948Sthompsa uint16_t); 108185948Sthompsastatic void ural_cfg_write(struct ural_softc *, uint16_t, uint16_t); 109185948Sthompsastatic void ural_cfg_write_multi(struct ural_softc *, uint16_t, void *, 110185948Sthompsa uint16_t); 111185948Sthompsastatic void ural_cfg_bbp_write(struct ural_softc *, uint8_t, uint8_t); 112185948Sthompsastatic uint8_t ural_cfg_bbp_read(struct ural_softc *, uint8_t); 113185948Sthompsastatic void ural_cfg_rf_write(struct ural_softc *, uint8_t, uint32_t); 114185948Sthompsastatic void ural_end_of_commands(struct ural_softc *); 115184610Salfredstatic const char *ural_get_rf(int rev); 116185948Sthompsastatic void ural_watchdog(void *); 117185948Sthompsastatic void ural_init_cb(void *); 118185948Sthompsastatic int ural_ioctl_cb(struct ifnet *, u_long cmd, caddr_t data); 119185948Sthompsastatic void ural_start_cb(struct ifnet *); 120185948Sthompsastatic int ural_newstate_cb(struct ieee80211vap *, 121185948Sthompsa enum ieee80211_state, int); 122185948Sthompsastatic void ural_std_command(struct ieee80211com *, 123185948Sthompsa usb2_config_td_command_t *); 124185948Sthompsastatic void ural_scan_start_cb(struct ieee80211com *); 125185948Sthompsastatic void ural_scan_end_cb(struct ieee80211com *); 126185948Sthompsastatic void ural_set_channel_cb(struct ieee80211com *); 127185948Sthompsastatic void ural_cfg_disable_rf_tune(struct ural_softc *); 128185948Sthompsastatic void ural_cfg_set_bssid(struct ural_softc *, uint8_t *); 129185948Sthompsastatic void ural_cfg_set_macaddr(struct ural_softc *, uint8_t *); 130185948Sthompsastatic void ural_cfg_set_txantenna(struct ural_softc *, uint8_t); 131185948Sthompsastatic void ural_cfg_set_rxantenna(struct ural_softc *, uint8_t); 132185948Sthompsastatic void ural_cfg_read_eeprom(struct ural_softc *); 133185948Sthompsastatic uint8_t ural_cfg_bbp_init(struct ural_softc *); 134185948Sthompsastatic void ural_cfg_amrr_start(struct ural_softc *); 135185948Sthompsastatic struct ieee80211vap *ural_vap_create(struct ieee80211com *, 136185948Sthompsa const char name[IFNAMSIZ], int unit, int opmode, int flags, 137185948Sthompsa const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t 138185948Sthompsa mac[IEEE80211_ADDR_LEN]); 139185948Sthompsastatic void ural_vap_delete(struct ieee80211vap *); 140185948Sthompsastatic struct ieee80211_node *ural_node_alloc(struct ieee80211vap *, 141185948Sthompsa const uint8_t mac[IEEE80211_ADDR_LEN]); 142185948Sthompsastatic void ural_newassoc(struct ieee80211_node *, int); 143185948Sthompsastatic void ural_cfg_disable_tsf_sync(struct ural_softc *); 144185948Sthompsastatic void ural_cfg_set_run(struct ural_softc *, 145185948Sthompsa struct usb2_config_td_cc *); 146185948Sthompsastatic void ural_fill_write_queue(struct ural_softc *); 147185948Sthompsastatic void ural_tx_clean_queue(struct ural_softc *); 148185948Sthompsastatic void ural_tx_freem(struct mbuf *); 149185948Sthompsastatic void ural_tx_mgt(struct ural_softc *, struct mbuf *, 150185948Sthompsa struct ieee80211_node *); 151185948Sthompsastatic struct ieee80211vap *ural_get_vap(struct ural_softc *); 152185948Sthompsastatic void ural_tx_bcn(struct ural_softc *); 153185948Sthompsastatic void ural_tx_data(struct ural_softc *, struct mbuf *, 154185948Sthompsa struct ieee80211_node *); 155185948Sthompsastatic void ural_tx_prot(struct ural_softc *, const struct mbuf *, 156185948Sthompsa struct ieee80211_node *, uint8_t, uint16_t); 157185948Sthompsastatic void ural_tx_raw(struct ural_softc *, struct mbuf *, 158185948Sthompsa struct ieee80211_node *, 159185948Sthompsa const struct ieee80211_bpf_params *); 160185948Sthompsastatic int ural_raw_xmit_cb(struct ieee80211_node *, struct mbuf *, 161185948Sthompsa const struct ieee80211_bpf_params *); 162185948Sthompsastatic void ural_setup_desc_and_tx(struct ural_softc *, struct mbuf *, 163185948Sthompsa uint32_t, uint16_t); 164185948Sthompsastatic void ural_update_mcast_cb(struct ifnet *); 165185948Sthompsastatic void ural_update_promisc_cb(struct ifnet *); 166184610Salfred 167184610Salfred/* various supported device vendors/products */ 168184610Salfredstatic const struct usb2_device_id ural_devs[] = { 169184610Salfred {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL167G, 0)}, 170184610Salfred {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_RALINK_RT2570, 0)}, 171184610Salfred {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050, 0)}, 172184610Salfred {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7051, 0)}, 173184610Salfred {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_HU200TS, 0)}, 174184610Salfred {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54G, 0)}, 175184610Salfred {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GP, 0)}, 176184610Salfred {USB_VPI(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU, 0)}, 177184610Salfred {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122, 0)}, 178184610Salfred {USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GN54G, 0)}, 179184610Salfred {USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWBKG, 0)}, 180184610Salfred {USB_VPI(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254, 0)}, 181184610Salfred {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54, 0)}, 182184610Salfred {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54AI, 0)}, 183184610Salfred {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54YB, 0)}, 184184610Salfred {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_NINWIFI, 0)}, 185184610Salfred {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570, 0)}, 186184610Salfred {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_2, 0)}, 187184610Salfred {USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_3, 0)}, 188184610Salfred {USB_VPI(USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_NV902, 0)}, 189184610Salfred {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570, 0)}, 190184610Salfred {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_2, 0)}, 191184610Salfred {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_3, 0)}, 192184610Salfred {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573, 0)}, 193184610Salfred {USB_VPI(USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WL54G, 0)}, 194184610Salfred {USB_VPI(USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG, 0)}, 195184610Salfred {USB_VPI(USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_UB801R, 0)}, 196184610Salfred {USB_VPI(USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2570, 0)}, 197184610Salfred {USB_VPI(USB_VENDOR_VTECH, USB_PRODUCT_VTECH_RT2570, 0)}, 198184610Salfred {USB_VPI(USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2570, 0)}, 199184610Salfred}; 200184610Salfred 201184610Salfred/* 202184610Salfred * Default values for MAC registers; values taken from 203184610Salfred * the reference driver: 204184610Salfred */ 205184610Salfredstruct ural_def_mac { 206184610Salfred uint16_t reg; 207184610Salfred uint16_t val; 208184610Salfred}; 209184610Salfred 210184610Salfredstatic const struct ural_def_mac ural_def_mac[] = { 211184610Salfred {RAL_TXRX_CSR5, 0x8c8d}, 212184610Salfred {RAL_TXRX_CSR6, 0x8b8a}, 213184610Salfred {RAL_TXRX_CSR7, 0x8687}, 214184610Salfred {RAL_TXRX_CSR8, 0x0085}, 215184610Salfred {RAL_MAC_CSR13, 0x1111}, 216184610Salfred {RAL_MAC_CSR14, 0x1e11}, 217184610Salfred {RAL_TXRX_CSR21, 0xe78f}, 218184610Salfred {RAL_MAC_CSR9, 0xff1d}, 219184610Salfred {RAL_MAC_CSR11, 0x0002}, 220184610Salfred {RAL_MAC_CSR22, 0x0053}, 221184610Salfred {RAL_MAC_CSR15, 0x0000}, 222184610Salfred {RAL_MAC_CSR8, RAL_FRAME_SIZE}, 223184610Salfred {RAL_TXRX_CSR19, 0x0000}, 224184610Salfred {RAL_TXRX_CSR18, 0x005a}, 225184610Salfred {RAL_PHY_CSR2, 0x0000}, 226184610Salfred {RAL_TXRX_CSR0, 0x1ec0}, 227184610Salfred {RAL_PHY_CSR4, 0x000f} 228184610Salfred}; 229184610Salfred 230184610Salfred/* 231184610Salfred * Default values for BBP registers; values taken from the reference driver. 232184610Salfred */ 233184610Salfredstruct ural_def_bbp { 234184610Salfred uint8_t reg; 235184610Salfred uint8_t val; 236184610Salfred}; 237184610Salfred 238184610Salfredstatic const struct ural_def_bbp ural_def_bbp[] = { 239184610Salfred {3, 0x02}, 240184610Salfred {4, 0x19}, 241184610Salfred {14, 0x1c}, 242184610Salfred {15, 0x30}, 243184610Salfred {16, 0xac}, 244184610Salfred {17, 0x48}, 245184610Salfred {18, 0x18}, 246184610Salfred {19, 0xff}, 247184610Salfred {20, 0x1e}, 248184610Salfred {21, 0x08}, 249184610Salfred {22, 0x08}, 250184610Salfred {23, 0x08}, 251184610Salfred {24, 0x80}, 252184610Salfred {25, 0x50}, 253184610Salfred {26, 0x08}, 254184610Salfred {27, 0x23}, 255184610Salfred {30, 0x10}, 256184610Salfred {31, 0x2b}, 257184610Salfred {32, 0xb9}, 258184610Salfred {34, 0x12}, 259184610Salfred {35, 0x50}, 260184610Salfred {39, 0xc4}, 261184610Salfred {40, 0x02}, 262184610Salfred {41, 0x60}, 263184610Salfred {53, 0x10}, 264184610Salfred {54, 0x18}, 265184610Salfred {56, 0x08}, 266184610Salfred {57, 0x10}, 267184610Salfred {58, 0x08}, 268184610Salfred {61, 0x60}, 269184610Salfred {62, 0x10}, 270184610Salfred {75, 0xff} 271184610Salfred}; 272184610Salfred 273184610Salfred/* 274184610Salfred * Default values for RF register R2 indexed by channel numbers. 275184610Salfred */ 276184610Salfredstatic const uint32_t ural_rf2522_r2[] = { 277184610Salfred 0x307f6, 0x307fb, 0x30800, 0x30805, 0x3080a, 0x3080f, 0x30814, 278184610Salfred 0x30819, 0x3081e, 0x30823, 0x30828, 0x3082d, 0x30832, 0x3083e 279184610Salfred}; 280184610Salfred 281184610Salfredstatic const uint32_t ural_rf2523_r2[] = { 282184610Salfred 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d, 283184610Salfred 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346 284184610Salfred}; 285184610Salfred 286184610Salfredstatic const uint32_t ural_rf2524_r2[] = { 287184610Salfred 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d, 288184610Salfred 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346 289184610Salfred}; 290184610Salfred 291184610Salfredstatic const uint32_t ural_rf2525_r2[] = { 292184610Salfred 0x20327, 0x20328, 0x20329, 0x2032a, 0x2032b, 0x2032c, 0x2032d, 293184610Salfred 0x2032e, 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20346 294184610Salfred}; 295184610Salfred 296184610Salfredstatic const uint32_t ural_rf2525_hi_r2[] = { 297184610Salfred 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20344, 0x20345, 298184610Salfred 0x20346, 0x20347, 0x20348, 0x20349, 0x2034a, 0x2034b, 0x2034e 299184610Salfred}; 300184610Salfred 301184610Salfredstatic const uint32_t ural_rf2525e_r2[] = { 302184610Salfred 0x2044d, 0x2044e, 0x2044f, 0x20460, 0x20461, 0x20462, 0x20463, 303184610Salfred 0x20464, 0x20465, 0x20466, 0x20467, 0x20468, 0x20469, 0x2046b 304184610Salfred}; 305184610Salfred 306184610Salfredstatic const uint32_t ural_rf2526_hi_r2[] = { 307184610Salfred 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d, 0x0022d, 308184610Salfred 0x0022e, 0x0022e, 0x0022f, 0x0022d, 0x00240, 0x00240, 0x00241 309184610Salfred}; 310184610Salfred 311184610Salfredstatic const uint32_t ural_rf2526_r2[] = { 312184610Salfred 0x00226, 0x00227, 0x00227, 0x00228, 0x00228, 0x00229, 0x00229, 313184610Salfred 0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d 314184610Salfred}; 315184610Salfred 316184610Salfred/* 317184610Salfred * For dual-band RF, RF registers R1 and R4 also depend on channel number; 318184610Salfred * values taken from the reference driver. 319184610Salfred */ 320184610Salfredstruct ural_rf5222 { 321184610Salfred uint8_t chan; 322184610Salfred uint32_t r1; 323184610Salfred uint32_t r2; 324184610Salfred uint32_t r4; 325184610Salfred}; 326184610Salfred 327184610Salfredstatic const struct ural_rf5222 ural_rf5222[] = { 328184610Salfred {1, 0x08808, 0x0044d, 0x00282}, 329184610Salfred {2, 0x08808, 0x0044e, 0x00282}, 330184610Salfred {3, 0x08808, 0x0044f, 0x00282}, 331184610Salfred {4, 0x08808, 0x00460, 0x00282}, 332184610Salfred {5, 0x08808, 0x00461, 0x00282}, 333184610Salfred {6, 0x08808, 0x00462, 0x00282}, 334184610Salfred {7, 0x08808, 0x00463, 0x00282}, 335184610Salfred {8, 0x08808, 0x00464, 0x00282}, 336184610Salfred {9, 0x08808, 0x00465, 0x00282}, 337184610Salfred {10, 0x08808, 0x00466, 0x00282}, 338184610Salfred {11, 0x08808, 0x00467, 0x00282}, 339184610Salfred {12, 0x08808, 0x00468, 0x00282}, 340184610Salfred {13, 0x08808, 0x00469, 0x00282}, 341184610Salfred {14, 0x08808, 0x0046b, 0x00286}, 342184610Salfred 343184610Salfred {36, 0x08804, 0x06225, 0x00287}, 344184610Salfred {40, 0x08804, 0x06226, 0x00287}, 345184610Salfred {44, 0x08804, 0x06227, 0x00287}, 346184610Salfred {48, 0x08804, 0x06228, 0x00287}, 347184610Salfred {52, 0x08804, 0x06229, 0x00287}, 348184610Salfred {56, 0x08804, 0x0622a, 0x00287}, 349184610Salfred {60, 0x08804, 0x0622b, 0x00287}, 350184610Salfred {64, 0x08804, 0x0622c, 0x00287}, 351184610Salfred 352184610Salfred {100, 0x08804, 0x02200, 0x00283}, 353184610Salfred {104, 0x08804, 0x02201, 0x00283}, 354184610Salfred {108, 0x08804, 0x02202, 0x00283}, 355184610Salfred {112, 0x08804, 0x02203, 0x00283}, 356184610Salfred {116, 0x08804, 0x02204, 0x00283}, 357184610Salfred {120, 0x08804, 0x02205, 0x00283}, 358184610Salfred {124, 0x08804, 0x02206, 0x00283}, 359184610Salfred {128, 0x08804, 0x02207, 0x00283}, 360184610Salfred {132, 0x08804, 0x02208, 0x00283}, 361184610Salfred {136, 0x08804, 0x02209, 0x00283}, 362184610Salfred {140, 0x08804, 0x0220a, 0x00283}, 363184610Salfred 364184610Salfred {149, 0x08808, 0x02429, 0x00281}, 365184610Salfred {153, 0x08808, 0x0242b, 0x00281}, 366184610Salfred {157, 0x08808, 0x0242d, 0x00281}, 367184610Salfred {161, 0x08808, 0x0242f, 0x00281} 368184610Salfred}; 369184610Salfred 370184610Salfredstatic const struct usb2_config ural_config[URAL_N_TRANSFER] = { 371184610Salfred [0] = { 372184610Salfred .type = UE_BULK, 373184610Salfred .endpoint = UE_ADDR_ANY, 374184610Salfred .direction = UE_DIR_OUT, 375184610Salfred .mh.bufsize = (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE + 4), 376184610Salfred .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 377184610Salfred .mh.callback = &ural_bulk_write_callback, 378184610Salfred .mh.timeout = 5000, /* ms */ 379184610Salfred }, 380184610Salfred 381184610Salfred [1] = { 382184610Salfred .type = UE_BULK, 383184610Salfred .endpoint = UE_ADDR_ANY, 384184610Salfred .direction = UE_DIR_IN, 385184610Salfred .mh.bufsize = (RAL_FRAME_SIZE + RAL_RX_DESC_SIZE), 386184610Salfred .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 387184610Salfred .mh.callback = &ural_bulk_read_callback, 388184610Salfred }, 389184610Salfred 390184610Salfred [2] = { 391184610Salfred .type = UE_CONTROL, 392184610Salfred .endpoint = 0x00, /* Control pipe */ 393184610Salfred .direction = UE_DIR_ANY, 394184610Salfred .mh.bufsize = sizeof(struct usb2_device_request), 395184610Salfred .mh.callback = &ural_bulk_write_clear_stall_callback, 396184610Salfred .mh.timeout = 1000, /* 1 second */ 397184610Salfred .mh.interval = 50, /* 50ms */ 398184610Salfred }, 399184610Salfred 400184610Salfred [3] = { 401184610Salfred .type = UE_CONTROL, 402184610Salfred .endpoint = 0x00, /* Control pipe */ 403184610Salfred .direction = UE_DIR_ANY, 404184610Salfred .mh.bufsize = sizeof(struct usb2_device_request), 405184610Salfred .mh.callback = &ural_bulk_read_clear_stall_callback, 406184610Salfred .mh.timeout = 1000, /* 1 second */ 407184610Salfred .mh.interval = 50, /* 50ms */ 408184610Salfred }, 409184610Salfred}; 410184610Salfred 411184610Salfredstatic devclass_t ural_devclass; 412184610Salfred 413184610Salfredstatic device_method_t ural_methods[] = { 414184610Salfred DEVMETHOD(device_probe, ural_probe), 415184610Salfred DEVMETHOD(device_attach, ural_attach), 416184610Salfred DEVMETHOD(device_detach, ural_detach), 417184610Salfred {0, 0} 418184610Salfred}; 419184610Salfred 420184610Salfredstatic driver_t ural_driver = { 421184610Salfred .name = "ural", 422184610Salfred .methods = ural_methods, 423184610Salfred .size = sizeof(struct ural_softc), 424184610Salfred}; 425184610Salfred 426184610SalfredDRIVER_MODULE(ural, ushub, ural_driver, ural_devclass, NULL, 0); 427184610SalfredMODULE_DEPEND(ural, usb2_wlan, 1, 1, 1); 428184610SalfredMODULE_DEPEND(ural, usb2_core, 1, 1, 1); 429184610SalfredMODULE_DEPEND(ural, wlan, 1, 1, 1); 430184610SalfredMODULE_DEPEND(ural, wlan_amrr, 1, 1, 1); 431184610Salfred 432184610Salfredstatic int 433184610Salfredural_probe(device_t dev) 434184610Salfred{ 435184610Salfred struct usb2_attach_arg *uaa = device_get_ivars(dev); 436184610Salfred 437184610Salfred if (uaa->usb2_mode != USB_MODE_HOST) { 438184610Salfred return (ENXIO); 439184610Salfred } 440184610Salfred if (uaa->info.bConfigIndex != 0) { 441184610Salfred return (ENXIO); 442184610Salfred } 443184610Salfred if (uaa->info.bIfaceIndex != RAL_IFACE_INDEX) { 444184610Salfred return (ENXIO); 445184610Salfred } 446184610Salfred return (usb2_lookup_id_by_uaa(ural_devs, sizeof(ural_devs), uaa)); 447184610Salfred} 448184610Salfred 449184610Salfredstatic int 450184610Salfredural_attach(device_t dev) 451184610Salfred{ 452184610Salfred struct usb2_attach_arg *uaa = device_get_ivars(dev); 453184610Salfred struct ural_softc *sc = device_get_softc(dev); 454184610Salfred int error; 455184610Salfred uint8_t iface_index; 456184610Salfred 457184610Salfred if (sc == NULL) { 458184610Salfred return (ENOMEM); 459184610Salfred } 460184610Salfred device_set_usb2_desc(dev); 461184610Salfred 462184610Salfred mtx_init(&sc->sc_mtx, "ural lock", MTX_NETWORK_LOCK, 463184610Salfred MTX_DEF | MTX_RECURSE); 464184610Salfred 465184610Salfred snprintf(sc->sc_name, sizeof(sc->sc_name), "%s", 466184610Salfred device_get_nameunit(dev)); 467184610Salfred 468184610Salfred sc->sc_udev = uaa->device; 469184610Salfred sc->sc_unit = device_get_unit(dev); 470184610Salfred 471184610Salfred usb2_callout_init_mtx(&sc->sc_watchdog, 472184610Salfred &sc->sc_mtx, CALLOUT_RETURNUNLOCKED); 473184610Salfred 474184610Salfred iface_index = RAL_IFACE_INDEX; 475184610Salfred error = usb2_transfer_setup(uaa->device, 476184610Salfred &iface_index, sc->sc_xfer, ural_config, 477184610Salfred URAL_N_TRANSFER, sc, &sc->sc_mtx); 478184610Salfred 479184610Salfred if (error) { 480184610Salfred device_printf(dev, "could not allocate USB transfers, " 481184610Salfred "err=%s\n", usb2_errstr(error)); 482184610Salfred goto detach; 483184610Salfred } 484184610Salfred error = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_mtx, 485184610Salfred &ural_end_of_commands, 486184610Salfred sizeof(struct usb2_config_td_cc), 24); 487184610Salfred if (error) { 488184610Salfred device_printf(dev, "could not setup config " 489184610Salfred "thread!\n"); 490184610Salfred goto detach; 491184610Salfred } 492184610Salfred mtx_lock(&sc->sc_mtx); 493184610Salfred 494184610Salfred /* start setup */ 495184610Salfred 496184610Salfred usb2_config_td_queue_command 497184610Salfred (&sc->sc_config_td, NULL, &ural_cfg_first_time_setup, 0, 0); 498184610Salfred 499184610Salfred /* start watchdog (will exit mutex) */ 500184610Salfred 501184610Salfred ural_watchdog(sc); 502184610Salfred 503184610Salfred return (0); /* success */ 504184610Salfred 505184610Salfreddetach: 506184610Salfred ural_detach(dev); 507184610Salfred return (ENXIO); /* failure */ 508184610Salfred} 509184610Salfred 510184610Salfredstatic int 511184610Salfredural_detach(device_t dev) 512184610Salfred{ 513184610Salfred struct ural_softc *sc = device_get_softc(dev); 514184610Salfred struct ieee80211com *ic; 515184610Salfred struct ifnet *ifp; 516184610Salfred 517184610Salfred usb2_config_td_drain(&sc->sc_config_td); 518184610Salfred 519184610Salfred mtx_lock(&sc->sc_mtx); 520184610Salfred 521184610Salfred usb2_callout_stop(&sc->sc_watchdog); 522184610Salfred 523184610Salfred ural_cfg_pre_stop(sc, NULL, 0); 524184610Salfred 525184610Salfred ifp = sc->sc_ifp; 526184610Salfred ic = ifp->if_l2com; 527184610Salfred 528184610Salfred mtx_unlock(&sc->sc_mtx); 529184610Salfred 530184610Salfred /* stop all USB transfers first */ 531184610Salfred usb2_transfer_unsetup(sc->sc_xfer, URAL_N_TRANSFER); 532184610Salfred 533184610Salfred /* get rid of any late children */ 534184610Salfred bus_generic_detach(dev); 535184610Salfred 536184610Salfred if (ifp) { 537184610Salfred bpfdetach(ifp); 538184610Salfred ieee80211_ifdetach(ic); 539184610Salfred if_free(ifp); 540184610Salfred } 541184610Salfred usb2_config_td_unsetup(&sc->sc_config_td); 542184610Salfred 543184610Salfred usb2_callout_drain(&sc->sc_watchdog); 544184610Salfred 545184610Salfred mtx_destroy(&sc->sc_mtx); 546184610Salfred 547184610Salfred return (0); 548184610Salfred} 549184610Salfred 550184610Salfred/*========================================================================* 551184610Salfred * REGISTER READ / WRITE WRAPPER ROUTINES 552184610Salfred *========================================================================*/ 553184610Salfred 554184610Salfredstatic void 555184610Salfredural_cfg_do_request(struct ural_softc *sc, struct usb2_device_request *req, 556184610Salfred void *data) 557184610Salfred{ 558184610Salfred uint16_t length; 559184610Salfred usb2_error_t err; 560184610Salfred 561184610Salfredrepeat: 562184610Salfred 563184610Salfred if (usb2_config_td_is_gone(&sc->sc_config_td)) { 564184610Salfred goto error; 565184610Salfred } 566184610Salfred err = usb2_do_request_flags 567184610Salfred (sc->sc_udev, &sc->sc_mtx, req, data, 0, NULL, 1000); 568184610Salfred 569184610Salfred if (err) { 570184610Salfred 571184610Salfred DPRINTF("device request failed, err=%s " 572184610Salfred "(ignored)\n", usb2_errstr(err)); 573184610Salfred 574184610Salfred /* wait a little before next try */ 575184610Salfred if (usb2_config_td_sleep(&sc->sc_config_td, hz / 4)) { 576184610Salfred goto error; 577184610Salfred } 578184610Salfred /* try until we are detached */ 579184610Salfred goto repeat; 580184610Salfred 581184610Salfrederror: 582184610Salfred /* the device has been detached */ 583184610Salfred length = UGETW(req->wLength); 584184610Salfred 585184610Salfred if ((req->bmRequestType & UT_READ) && length) { 586184610Salfred bzero(data, length); 587184610Salfred } 588184610Salfred } 589184610Salfred return; 590184610Salfred} 591184610Salfred 592184610Salfredstatic void 593184610Salfredural_cfg_set_testmode(struct ural_softc *sc) 594184610Salfred{ 595184610Salfred struct usb2_device_request req; 596184610Salfred 597184610Salfred req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 598184610Salfred req.bRequest = RAL_VENDOR_REQUEST; 599184610Salfred USETW(req.wValue, 4); 600184610Salfred USETW(req.wIndex, 1); 601184610Salfred USETW(req.wLength, 0); 602184610Salfred 603184610Salfred ural_cfg_do_request(sc, &req, NULL); 604184610Salfred return; 605184610Salfred} 606184610Salfred 607184610Salfredstatic void 608184610Salfredural_cfg_eeprom_read(struct ural_softc *sc, uint16_t addr, 609184610Salfred void *buf, uint16_t len) 610184610Salfred{ 611184610Salfred struct usb2_device_request req; 612184610Salfred 613184610Salfred req.bmRequestType = UT_READ_VENDOR_DEVICE; 614184610Salfred req.bRequest = RAL_READ_EEPROM; 615184610Salfred USETW(req.wValue, 0); 616184610Salfred USETW(req.wIndex, addr); 617184610Salfred USETW(req.wLength, len); 618184610Salfred 619184610Salfred ural_cfg_do_request(sc, &req, buf); 620184610Salfred return; 621184610Salfred} 622184610Salfred 623184610Salfredstatic uint16_t 624184610Salfredural_cfg_read(struct ural_softc *sc, uint16_t reg) 625184610Salfred{ 626184610Salfred struct usb2_device_request req; 627184610Salfred uint16_t val; 628184610Salfred 629184610Salfred req.bmRequestType = UT_READ_VENDOR_DEVICE; 630184610Salfred req.bRequest = RAL_READ_MAC; 631184610Salfred USETW(req.wValue, 0); 632184610Salfred USETW(req.wIndex, reg); 633184610Salfred USETW(req.wLength, sizeof(val)); 634184610Salfred 635184610Salfred ural_cfg_do_request(sc, &req, &val); 636184610Salfred 637184610Salfred return (le16toh(val)); 638184610Salfred} 639184610Salfred 640184610Salfredstatic void 641184610Salfredural_cfg_read_multi(struct ural_softc *sc, uint16_t reg, 642184610Salfred void *buf, uint16_t len) 643184610Salfred{ 644184610Salfred struct usb2_device_request req; 645184610Salfred 646184610Salfred req.bmRequestType = UT_READ_VENDOR_DEVICE; 647184610Salfred req.bRequest = RAL_READ_MULTI_MAC; 648184610Salfred USETW(req.wValue, 0); 649184610Salfred USETW(req.wIndex, reg); 650184610Salfred USETW(req.wLength, len); 651184610Salfred 652184610Salfred ural_cfg_do_request(sc, &req, buf); 653184610Salfred return; 654184610Salfred} 655184610Salfred 656184610Salfredstatic void 657184610Salfredural_cfg_write(struct ural_softc *sc, uint16_t reg, uint16_t val) 658184610Salfred{ 659184610Salfred struct usb2_device_request req; 660184610Salfred 661184610Salfred req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 662184610Salfred req.bRequest = RAL_WRITE_MAC; 663184610Salfred USETW(req.wValue, val); 664184610Salfred USETW(req.wIndex, reg); 665184610Salfred USETW(req.wLength, 0); 666184610Salfred 667184610Salfred ural_cfg_do_request(sc, &req, NULL); 668184610Salfred return; 669184610Salfred} 670184610Salfred 671184610Salfredstatic void 672184610Salfredural_cfg_write_multi(struct ural_softc *sc, uint16_t reg, 673184610Salfred void *buf, uint16_t len) 674184610Salfred{ 675184610Salfred struct usb2_device_request req; 676184610Salfred 677184610Salfred req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 678184610Salfred req.bRequest = RAL_WRITE_MULTI_MAC; 679184610Salfred USETW(req.wValue, 0); 680184610Salfred USETW(req.wIndex, reg); 681184610Salfred USETW(req.wLength, len); 682184610Salfred 683184610Salfred ural_cfg_do_request(sc, &req, buf); 684184610Salfred return; 685184610Salfred} 686184610Salfred 687184610Salfredstatic uint8_t 688184610Salfredural_cfg_bbp_disbusy(struct ural_softc *sc) 689184610Salfred{ 690184610Salfred uint16_t tmp; 691184610Salfred uint8_t to; 692184610Salfred 693184610Salfred for (to = 0;; to++) { 694184610Salfred if (to < 100) { 695184610Salfred tmp = ural_cfg_read(sc, RAL_PHY_CSR8); 696184610Salfred tmp &= RAL_BBP_BUSY; 697184610Salfred 698184610Salfred if (tmp == 0) { 699184610Salfred return (0); 700184610Salfred } 701184610Salfred if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 702184610Salfred break; 703184610Salfred } 704184610Salfred } else { 705184610Salfred break; 706184610Salfred } 707184610Salfred } 708184610Salfred DPRINTF("could not disbusy BBP\n"); 709184610Salfred return (1); /* failure */ 710184610Salfred} 711184610Salfred 712184610Salfredstatic void 713184610Salfredural_cfg_bbp_write(struct ural_softc *sc, uint8_t reg, uint8_t val) 714184610Salfred{ 715184610Salfred uint16_t tmp; 716184610Salfred 717184610Salfred if (ural_cfg_bbp_disbusy(sc)) { 718184610Salfred return; 719184610Salfred } 720184610Salfred tmp = (reg << 8) | val; 721184610Salfred ural_cfg_write(sc, RAL_PHY_CSR7, tmp); 722184610Salfred return; 723184610Salfred} 724184610Salfred 725184610Salfredstatic uint8_t 726184610Salfredural_cfg_bbp_read(struct ural_softc *sc, uint8_t reg) 727184610Salfred{ 728184610Salfred uint16_t val; 729184610Salfred 730184610Salfred if (ural_cfg_bbp_disbusy(sc)) { 731184610Salfred return (0); 732184610Salfred } 733184610Salfred val = RAL_BBP_WRITE | (reg << 8); 734184610Salfred ural_cfg_write(sc, RAL_PHY_CSR7, val); 735184610Salfred 736184610Salfred if (ural_cfg_bbp_disbusy(sc)) { 737184610Salfred return (0); 738184610Salfred } 739184610Salfred return (ural_cfg_read(sc, RAL_PHY_CSR7) & 0xff); 740184610Salfred} 741184610Salfred 742184610Salfredstatic void 743184610Salfredural_cfg_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val) 744184610Salfred{ 745184610Salfred uint32_t tmp; 746184610Salfred uint8_t to; 747184610Salfred 748184610Salfred reg &= 3; 749184610Salfred 750184610Salfred /* remember last written value */ 751184610Salfred sc->sc_rf_regs[reg] = val; 752184610Salfred 753184610Salfred for (to = 0;; to++) { 754184610Salfred if (to < 100) { 755184610Salfred tmp = ural_cfg_read(sc, RAL_PHY_CSR10); 756184610Salfred 757184610Salfred if (!(tmp & RAL_RF_LOBUSY)) { 758184610Salfred break; 759184610Salfred } 760184610Salfred if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 761184610Salfred return; 762184610Salfred } 763184610Salfred } else { 764184610Salfred DPRINTF("could not write to RF\n"); 765184610Salfred return; 766184610Salfred } 767184610Salfred } 768184610Salfred 769184610Salfred tmp = RAL_RF_BUSY | RAL_RF_20BIT | ((val & 0xfffff) << 2) | reg; 770184610Salfred ural_cfg_write(sc, RAL_PHY_CSR9, tmp & 0xffff); 771184610Salfred ural_cfg_write(sc, RAL_PHY_CSR10, tmp >> 16); 772184610Salfred 773184610Salfred DPRINTFN(16, "RF R[%u] <- 0x%05x\n", reg, val & 0xfffff); 774184610Salfred return; 775184610Salfred} 776184610Salfred 777184610Salfredstatic void 778184610Salfredural_cfg_first_time_setup(struct ural_softc *sc, 779184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 780184610Salfred{ 781184610Salfred struct ieee80211com *ic; 782184610Salfred struct ifnet *ifp; 783184610Salfred uint8_t bands; 784184610Salfred 785184610Salfred /* setup RX tap header */ 786184610Salfred sc->sc_rxtap_len = sizeof(sc->sc_rxtap); 787184610Salfred sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 788184610Salfred sc->sc_rxtap.wr_ihdr.it_present = htole32(RAL_RX_RADIOTAP_PRESENT); 789184610Salfred 790184610Salfred /* setup TX tap header */ 791184610Salfred sc->sc_txtap_len = sizeof(sc->sc_txtap); 792184610Salfred sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 793184610Salfred sc->sc_txtap.wt_ihdr.it_present = htole32(RAL_TX_RADIOTAP_PRESENT); 794184610Salfred 795184610Salfred /* retrieve RT2570 rev. no */ 796184610Salfred sc->sc_asic_rev = ural_cfg_read(sc, RAL_MAC_CSR0); 797184610Salfred 798184610Salfred /* retrieve MAC address and various other things from EEPROM */ 799184610Salfred ural_cfg_read_eeprom(sc); 800184610Salfred 801184610Salfred printf("%s: MAC/BBP RT2570 (rev 0x%02x), RF %s\n", 802184610Salfred sc->sc_name, sc->sc_asic_rev, ural_get_rf(sc->sc_rf_rev)); 803184610Salfred 804184610Salfred mtx_unlock(&sc->sc_mtx); 805184610Salfred 806184610Salfred ifp = if_alloc(IFT_IEEE80211); 807184610Salfred 808184610Salfred mtx_lock(&sc->sc_mtx); 809184610Salfred 810184610Salfred if (ifp == NULL) { 811184610Salfred DPRINTFN(0, "could not if_alloc()!\n"); 812184610Salfred goto done; 813184610Salfred } 814184610Salfred sc->sc_evilhack = ifp; 815184610Salfred sc->sc_ifp = ifp; 816184610Salfred ic = ifp->if_l2com; 817184610Salfred 818184610Salfred ifp->if_softc = sc; 819184610Salfred if_initname(ifp, "ural", sc->sc_unit); 820184610Salfred ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 821184610Salfred ifp->if_init = &ural_init_cb; 822184610Salfred ifp->if_ioctl = &ural_ioctl_cb; 823184610Salfred ifp->if_start = &ural_start_cb; 824184610Salfred ifp->if_watchdog = NULL; 825184610Salfred IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 826184610Salfred ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 827184610Salfred IFQ_SET_READY(&ifp->if_snd); 828184610Salfred 829184610Salfred bcopy(sc->sc_myaddr, ic->ic_myaddr, sizeof(ic->ic_myaddr)); 830184610Salfred 831184610Salfred ic->ic_ifp = ifp; 832184610Salfred ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 833184610Salfred ic->ic_opmode = IEEE80211_M_STA; 834184610Salfred 835184610Salfred /* set device capabilities */ 836184610Salfred ic->ic_caps = 837184610Salfred IEEE80211_C_STA /* station mode supported */ 838184610Salfred | IEEE80211_C_IBSS /* IBSS mode supported */ 839184610Salfred | IEEE80211_C_MONITOR /* monitor mode supported */ 840184610Salfred | IEEE80211_C_HOSTAP /* HostAp mode supported */ 841184610Salfred | IEEE80211_C_TXPMGT /* tx power management */ 842184610Salfred | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 843184610Salfred | IEEE80211_C_SHSLOT /* short slot time supported */ 844184610Salfred | IEEE80211_C_BGSCAN /* bg scanning supported */ 845184610Salfred | IEEE80211_C_WPA /* 802.11i */ 846184610Salfred ; 847184610Salfred 848184610Salfred bands = 0; 849184610Salfred setbit(&bands, IEEE80211_MODE_11B); 850184610Salfred setbit(&bands, IEEE80211_MODE_11G); 851184610Salfred 852184610Salfred if (sc->sc_rf_rev == RAL_RF_5222) { 853184610Salfred setbit(&bands, IEEE80211_MODE_11A); 854184610Salfred } 855184610Salfred ieee80211_init_channels(ic, NULL, &bands); 856184610Salfred 857184610Salfred mtx_unlock(&sc->sc_mtx); 858184610Salfred 859184610Salfred ieee80211_ifattach(ic); 860184610Salfred 861184610Salfred mtx_lock(&sc->sc_mtx); 862184610Salfred 863184610Salfred ic->ic_newassoc = &ural_newassoc; 864184610Salfred ic->ic_raw_xmit = &ural_raw_xmit_cb; 865184610Salfred ic->ic_node_alloc = &ural_node_alloc; 866184610Salfred ic->ic_update_mcast = &ural_update_mcast_cb; 867184610Salfred ic->ic_update_promisc = &ural_update_promisc_cb; 868184610Salfred ic->ic_scan_start = &ural_scan_start_cb; 869184610Salfred ic->ic_scan_end = &ural_scan_end_cb; 870184610Salfred ic->ic_set_channel = &ural_set_channel_cb; 871184610Salfred ic->ic_vap_create = &ural_vap_create; 872184610Salfred ic->ic_vap_delete = &ural_vap_delete; 873184610Salfred 874184610Salfred sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); 875184610Salfred 876184610Salfred mtx_unlock(&sc->sc_mtx); 877184610Salfred 878184610Salfred bpfattach(ifp, DLT_IEEE802_11_RADIO, 879184610Salfred sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap)); 880184610Salfred 881184610Salfred if (bootverbose) { 882184610Salfred ieee80211_announce(ic); 883184610Salfred } 884184610Salfred mtx_lock(&sc->sc_mtx); 885184610Salfreddone: 886184610Salfred return; 887184610Salfred} 888184610Salfred 889184610Salfredstatic void 890184610Salfredural_end_of_commands(struct ural_softc *sc) 891184610Salfred{ 892184610Salfred sc->sc_flags &= ~URAL_FLAG_WAIT_COMMAND; 893184610Salfred 894184610Salfred /* start write transfer, if not started */ 895184610Salfred usb2_transfer_start(sc->sc_xfer[0]); 896184610Salfred return; 897184610Salfred} 898184610Salfred 899184610Salfredstatic void 900184610Salfredural_config_copy_chan(struct ural_config_copy_chan *cc, 901184610Salfred struct ieee80211com *ic, struct ieee80211_channel *c) 902184610Salfred{ 903184610Salfred if (!c) 904184610Salfred return; 905184610Salfred cc->chan_to_ieee = 906184610Salfred ieee80211_chan2ieee(ic, c); 907184610Salfred if (c != IEEE80211_CHAN_ANYC) { 908184610Salfred cc->chan_to_mode = 909184610Salfred ieee80211_chan2mode(c); 910184610Salfred if (IEEE80211_IS_CHAN_B(c)) 911184610Salfred cc->chan_is_b = 1; 912184610Salfred if (IEEE80211_IS_CHAN_A(c)) 913184610Salfred cc->chan_is_a = 1; 914184610Salfred if (IEEE80211_IS_CHAN_2GHZ(c)) 915184610Salfred cc->chan_is_2ghz = 1; 916184610Salfred if (IEEE80211_IS_CHAN_5GHZ(c)) 917184610Salfred cc->chan_is_5ghz = 1; 918184610Salfred if (IEEE80211_IS_CHAN_ANYG(c)) 919184610Salfred cc->chan_is_g = 1; 920184610Salfred } 921184610Salfred return; 922184610Salfred} 923184610Salfred 924184610Salfredstatic void 925184610Salfredural_config_copy(struct ural_softc *sc, 926184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 927184610Salfred{ 928184610Salfred struct ifnet *ifp; 929184610Salfred struct ieee80211com *ic; 930184610Salfred struct ieee80211_node *ni; 931184610Salfred struct ieee80211vap *vap; 932184610Salfred const struct ieee80211_txparam *tp; 933184610Salfred 934184610Salfred bzero(cc, sizeof(*cc)); 935184610Salfred 936184610Salfred ifp = sc->sc_ifp; 937184610Salfred if (ifp) { 938184610Salfred cc->if_flags = ifp->if_flags; 939184610Salfred bcopy(ifp->if_broadcastaddr, cc->if_broadcastaddr, 940184610Salfred sizeof(cc->if_broadcastaddr)); 941184610Salfred 942184610Salfred ic = ifp->if_l2com; 943184610Salfred if (ic) { 944184610Salfred ural_config_copy_chan(&cc->ic_curchan, ic, ic->ic_curchan); 945184610Salfred ural_config_copy_chan(&cc->ic_bsschan, ic, ic->ic_bsschan); 946184610Salfred vap = TAILQ_FIRST(&ic->ic_vaps); 947184610Salfred if (vap) { 948184610Salfred ni = vap->iv_bss; 949184610Salfred if (ni) { 950184610Salfred cc->iv_bss.ni_intval = ni->ni_intval; 951184610Salfred bcopy(ni->ni_bssid, cc->iv_bss.ni_bssid, 952184610Salfred sizeof(cc->iv_bss.ni_bssid)); 953184610Salfred } 954184610Salfred tp = vap->iv_txparms + cc->ic_bsschan.chan_to_mode; 955184610Salfred if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { 956184610Salfred cc->iv_bss.fixed_rate_none = 1; 957184610Salfred } 958184610Salfred } 959184610Salfred cc->ic_opmode = ic->ic_opmode; 960184610Salfred cc->ic_flags = ic->ic_flags; 961184610Salfred cc->ic_txpowlimit = ic->ic_txpowlimit; 962184610Salfred cc->ic_curmode = ic->ic_curmode; 963184610Salfred 964184610Salfred bcopy(ic->ic_myaddr, cc->ic_myaddr, 965184610Salfred sizeof(cc->ic_myaddr)); 966184610Salfred } 967184610Salfred } 968184610Salfred sc->sc_flags |= URAL_FLAG_WAIT_COMMAND; 969184610Salfred return; 970184610Salfred} 971184610Salfred 972184610Salfredstatic const char * 973184610Salfredural_get_rf(int rev) 974184610Salfred{ 975184610Salfred switch (rev) { 976184610Salfred case RAL_RF_2522:return "RT2522"; 977184610Salfred case RAL_RF_2523: 978184610Salfred return "RT2523"; 979184610Salfred case RAL_RF_2524: 980184610Salfred return "RT2524"; 981184610Salfred case RAL_RF_2525: 982184610Salfred return "RT2525"; 983184610Salfred case RAL_RF_2525E: 984184610Salfred return "RT2525e"; 985184610Salfred case RAL_RF_2526: 986184610Salfred return "RT2526"; 987184610Salfred case RAL_RF_5222: 988184610Salfred return "RT5222"; 989184610Salfred default: 990184610Salfred return "unknown"; 991184610Salfred } 992184610Salfred} 993184610Salfred 994184610Salfred/*------------------------------------------------------------------------* 995184610Salfred * ural_bulk_read_callback - data read "thread" 996184610Salfred *------------------------------------------------------------------------*/ 997184610Salfredstatic void 998184610Salfredural_bulk_read_callback(struct usb2_xfer *xfer) 999184610Salfred{ 1000184610Salfred struct ural_softc *sc = xfer->priv_sc; 1001184610Salfred struct ifnet *ifp = sc->sc_ifp; 1002184610Salfred struct ieee80211com *ic = ifp->if_l2com; 1003184610Salfred struct ieee80211_node *ni; 1004184610Salfred struct mbuf *m = NULL; 1005184610Salfred uint32_t flags; 1006184610Salfred uint32_t max_len; 1007184610Salfred uint32_t real_len; 1008184610Salfred uint8_t rssi = 0; 1009184610Salfred 1010184610Salfred switch (USB_GET_STATE(xfer)) { 1011184610Salfred case USB_ST_TRANSFERRED: 1012184610Salfred 1013184610Salfred DPRINTFN(15, "rx done, actlen=%d\n", xfer->actlen); 1014184610Salfred 1015184610Salfred if (xfer->actlen < RAL_RX_DESC_SIZE) { 1016184610Salfred DPRINTF("too short transfer, " 1017184610Salfred "%d bytes\n", xfer->actlen); 1018184610Salfred ifp->if_ierrors++; 1019184610Salfred goto tr_setup; 1020184610Salfred } 1021184610Salfred max_len = (xfer->actlen - RAL_RX_DESC_SIZE); 1022184610Salfred 1023184610Salfred usb2_copy_out(xfer->frbuffers, max_len, 1024184610Salfred &sc->sc_rx_desc, RAL_RX_DESC_SIZE); 1025184610Salfred 1026184610Salfred flags = le32toh(sc->sc_rx_desc.flags); 1027184610Salfred 1028184610Salfred if (flags & (RAL_RX_PHY_ERROR | RAL_RX_CRC_ERROR)) { 1029184610Salfred /* 1030184610Salfred * This should not happen since we did not 1031184610Salfred * request to receive those frames when we 1032184610Salfred * filled RAL_TXRX_CSR2: 1033184610Salfred */ 1034184610Salfred DPRINTFN(6, "PHY or CRC error\n"); 1035184610Salfred ifp->if_ierrors++; 1036184610Salfred goto tr_setup; 1037184610Salfred } 1038184610Salfred if (max_len > MCLBYTES) { 1039184610Salfred max_len = MCLBYTES; 1040184610Salfred } 1041184610Salfred real_len = (flags >> 16) & 0xfff; 1042184610Salfred 1043184610Salfred if (real_len > max_len) { 1044184610Salfred DPRINTF("invalid length in RX " 1045184610Salfred "descriptor, %u bytes, received %u bytes\n", 1046184610Salfred real_len, max_len); 1047184610Salfred ifp->if_ierrors++; 1048184610Salfred goto tr_setup; 1049184610Salfred } 1050184610Salfred /* ieee80211_input() will check if the mbuf is too short */ 1051184610Salfred 1052184610Salfred m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 1053184610Salfred 1054184610Salfred if (m == NULL) { 1055184610Salfred DPRINTF("could not allocate mbuf\n"); 1056184610Salfred ifp->if_ierrors++; 1057184610Salfred goto tr_setup; 1058184610Salfred } 1059184610Salfred usb2_copy_out(xfer->frbuffers, 0, m->m_data, max_len); 1060184610Salfred 1061184610Salfred /* finalize mbuf */ 1062184610Salfred m->m_pkthdr.rcvif = ifp; 1063184610Salfred m->m_pkthdr.len = m->m_len = real_len; 1064184610Salfred 1065184610Salfred DPRINTF("real length=%d bytes\n", real_len); 1066184610Salfred 1067184610Salfred rssi = URAL_RSSI(sc->sc_rx_desc.rssi); 1068184610Salfred 1069184610Salfred if (bpf_peers_present(ifp->if_bpf)) { 1070184610Salfred struct ural_rx_radiotap_header *tap = &sc->sc_rxtap; 1071184610Salfred 1072184610Salfred tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; 1073184610Salfred tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate, 1074184610Salfred (sc->sc_rx_desc.flags & htole32(RAL_RX_OFDM)) ? 1075184610Salfred IEEE80211_T_OFDM : IEEE80211_T_CCK); 1076184610Salfred 1077184610Salfred tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); 1078184610Salfred tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); 1079184610Salfred tap->wr_antenna = sc->sc_rx_ant; 1080184610Salfred tap->wr_antsignal = rssi; 1081184610Salfred 1082184610Salfred bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); 1083184610Salfred } 1084184610Salfred /* Strip trailing 802.11 MAC FCS. */ 1085184610Salfred m_adj(m, -IEEE80211_CRC_LEN); 1086184610Salfred 1087184610Salfred case USB_ST_SETUP: 1088184610Salfredtr_setup: 1089184610Salfred 1090184610Salfred if (sc->sc_flags & URAL_FLAG_READ_STALL) { 1091184610Salfred usb2_transfer_start(sc->sc_xfer[3]); 1092184610Salfred } else { 1093184610Salfred xfer->frlengths[0] = xfer->max_data_length; 1094184610Salfred usb2_start_hardware(xfer); 1095184610Salfred } 1096184610Salfred 1097184610Salfred /* 1098184610Salfred * At the end of a USB callback it is always safe to unlock 1099184610Salfred * the private mutex of a device! That is why we do the 1100184610Salfred * "ieee80211_input" here, and not some lines up! 1101184610Salfred */ 1102184610Salfred if (m) { 1103184610Salfred mtx_unlock(&sc->sc_mtx); 1104184610Salfred 1105184610Salfred ni = ieee80211_find_rxnode(ic, (void *)(m->m_data)); 1106184610Salfred 1107184610Salfred if (ni) { 1108184610Salfred /* send the frame to the 802.11 layer */ 1109184610Salfred if (ieee80211_input(ni, m, rssi, RAL_NOISE_FLOOR, 0)) { 1110184610Salfred /* ignore */ 1111184610Salfred } 1112184610Salfred /* node is no longer needed */ 1113184610Salfred ieee80211_free_node(ni); 1114184610Salfred } else { 1115184610Salfred /* broadcast */ 1116184610Salfred if (ieee80211_input_all(ic, m, rssi, RAL_NOISE_FLOOR, 0)) { 1117184610Salfred /* ignore */ 1118184610Salfred } 1119184610Salfred } 1120184610Salfred 1121184610Salfred mtx_lock(&sc->sc_mtx); 1122184610Salfred } 1123184610Salfred return; 1124184610Salfred 1125184610Salfred default: /* Error */ 1126184610Salfred if (xfer->error != USB_ERR_CANCELLED) { 1127184610Salfred /* try to clear stall first */ 1128184610Salfred sc->sc_flags |= URAL_FLAG_READ_STALL; 1129184610Salfred usb2_transfer_start(sc->sc_xfer[3]); 1130184610Salfred } 1131184610Salfred return; 1132184610Salfred 1133184610Salfred } 1134184610Salfred} 1135184610Salfred 1136184610Salfredstatic void 1137184610Salfredural_bulk_read_clear_stall_callback(struct usb2_xfer *xfer) 1138184610Salfred{ 1139184610Salfred struct ural_softc *sc = xfer->priv_sc; 1140184610Salfred struct usb2_xfer *xfer_other = sc->sc_xfer[1]; 1141184610Salfred 1142184610Salfred if (usb2_clear_stall_callback(xfer, xfer_other)) { 1143184610Salfred DPRINTF("stall cleared\n"); 1144184610Salfred sc->sc_flags &= ~URAL_FLAG_READ_STALL; 1145184610Salfred usb2_transfer_start(xfer_other); 1146184610Salfred } 1147184610Salfred return; 1148184610Salfred} 1149184610Salfred 1150184610Salfredstatic uint8_t 1151184610Salfredural_plcp_signal(uint16_t rate) 1152184610Salfred{ 1153184610Salfred ; /* indent fix */ 1154184610Salfred switch (rate) { 1155184610Salfred /* CCK rates (NB: not IEEE std, device-specific) */ 1156184610Salfred case 2: 1157184610Salfred return (0x0); 1158184610Salfred case 4: 1159184610Salfred return (0x1); 1160184610Salfred case 11: 1161184610Salfred return (0x2); 1162184610Salfred case 22: 1163184610Salfred return (0x3); 1164184610Salfred 1165184610Salfred /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 1166184610Salfred case 12: 1167184610Salfred return (0xb); 1168184610Salfred case 18: 1169184610Salfred return (0xf); 1170184610Salfred case 24: 1171184610Salfred return (0xa); 1172184610Salfred case 36: 1173184610Salfred return (0xe); 1174184610Salfred case 48: 1175184610Salfred return (0x9); 1176184610Salfred case 72: 1177184610Salfred return (0xd); 1178184610Salfred case 96: 1179184610Salfred return (0x8); 1180184610Salfred case 108: 1181184610Salfred return (0xc); 1182184610Salfred 1183184610Salfred /* XXX unsupported/unknown rate */ 1184184610Salfred default: 1185184610Salfred return (0xff); 1186184610Salfred } 1187184610Salfred} 1188184610Salfred 1189184610Salfred/* 1190184610Salfred * We assume that "m->m_pkthdr.rcvif" is pointing to the "ni" that 1191184610Salfred * should be freed, when "ural_setup_desc_and_tx" is called. 1192184610Salfred */ 1193184610Salfredstatic void 1194184610Salfredural_setup_desc_and_tx(struct ural_softc *sc, struct mbuf *m, 1195184610Salfred uint32_t flags, uint16_t rate) 1196184610Salfred{ 1197184610Salfred struct ifnet *ifp = sc->sc_ifp; 1198184610Salfred struct ieee80211com *ic = ifp->if_l2com; 1199184610Salfred struct mbuf *mm; 1200184610Salfred enum ieee80211_phytype phytype; 1201184610Salfred uint16_t plcp_length; 1202184610Salfred uint16_t len; 1203184610Salfred uint8_t remainder; 1204184610Salfred 1205184610Salfred DPRINTF("in\n"); 1206184610Salfred 1207184610Salfred if (sc->sc_tx_queue.ifq_len >= IFQ_MAXLEN) { 1208184610Salfred /* free packet */ 1209184610Salfred ural_tx_freem(m); 1210184610Salfred ifp->if_oerrors++; 1211184610Salfred return; 1212184610Salfred } 1213184610Salfred if (!((sc->sc_flags & URAL_FLAG_LL_READY) && 1214184610Salfred (sc->sc_flags & URAL_FLAG_HL_READY))) { 1215184610Salfred /* free packet */ 1216184610Salfred ural_tx_freem(m); 1217184610Salfred ifp->if_oerrors++; 1218184610Salfred return; 1219184610Salfred } 1220184610Salfred if (rate < 2) { 1221184610Salfred DPRINTF("rate < 2!\n"); 1222184610Salfred 1223184610Salfred /* avoid division by zero */ 1224184610Salfred rate = 2; 1225184610Salfred } 1226184610Salfred ic->ic_lastdata = ticks; 1227184610Salfred 1228184610Salfred if (bpf_peers_present(ifp->if_bpf)) { 1229184610Salfred struct ural_tx_radiotap_header *tap = &sc->sc_txtap; 1230184610Salfred 1231184610Salfred tap->wt_flags = 0; 1232184610Salfred tap->wt_rate = rate; 1233184610Salfred tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); 1234184610Salfred tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); 1235184610Salfred tap->wt_antenna = sc->sc_tx_ant; 1236184610Salfred 1237184610Salfred bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); 1238184610Salfred } 1239184610Salfred len = m->m_pkthdr.len; 1240184610Salfred 1241184610Salfred sc->sc_tx_desc.flags = htole32(flags); 1242184610Salfred sc->sc_tx_desc.flags |= htole32(RAL_TX_NEWSEQ); 1243184610Salfred sc->sc_tx_desc.flags |= htole32(len << 16); 1244184610Salfred 1245184610Salfred sc->sc_tx_desc.wme = htole16(RAL_AIFSN(2) | 1246184610Salfred RAL_LOGCWMIN(3) | 1247184610Salfred RAL_LOGCWMAX(5) | 1248184610Salfred RAL_IVOFFSET(sizeof(struct ieee80211_frame))); 1249184610Salfred 1250184610Salfred /* setup PLCP fields */ 1251184610Salfred sc->sc_tx_desc.plcp_signal = ural_plcp_signal(rate); 1252184610Salfred sc->sc_tx_desc.plcp_service = 4; 1253184610Salfred 1254184610Salfred len += IEEE80211_CRC_LEN; 1255184610Salfred 1256184610Salfred phytype = ieee80211_rate2phytype(sc->sc_rates, rate); 1257184610Salfred 1258184610Salfred if (phytype == IEEE80211_T_OFDM) { 1259184610Salfred sc->sc_tx_desc.flags |= htole32(RAL_TX_OFDM); 1260184610Salfred 1261184610Salfred plcp_length = len & 0xfff; 1262184610Salfred sc->sc_tx_desc.plcp_length_hi = plcp_length >> 6; 1263184610Salfred sc->sc_tx_desc.plcp_length_lo = plcp_length & 0x3f; 1264184610Salfred 1265184610Salfred } else { 1266184610Salfred plcp_length = ((16 * len) + rate - 1) / rate; 1267184610Salfred if (rate == 22) { 1268184610Salfred remainder = (16 * len) % 22; 1269184610Salfred if ((remainder != 0) && (remainder < 7)) { 1270184610Salfred sc->sc_tx_desc.plcp_service |= 1271184610Salfred RAL_PLCP_LENGEXT; 1272184610Salfred } 1273184610Salfred } 1274184610Salfred sc->sc_tx_desc.plcp_length_hi = plcp_length >> 8; 1275184610Salfred sc->sc_tx_desc.plcp_length_lo = plcp_length & 0xff; 1276184610Salfred 1277184610Salfred if ((rate != 2) && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) { 1278184610Salfred sc->sc_tx_desc.plcp_signal |= 0x08; 1279184610Salfred } 1280184610Salfred } 1281184610Salfred 1282184610Salfred sc->sc_tx_desc.iv = 0; 1283184610Salfred sc->sc_tx_desc.eiv = 0; 1284184610Salfred 1285184610Salfred if (sizeof(sc->sc_tx_desc) > MHLEN) { 1286184610Salfred DPRINTF("No room for header structure!\n"); 1287184610Salfred ural_tx_freem(m); 1288184610Salfred return; 1289184610Salfred } 1290184610Salfred mm = m_gethdr(M_NOWAIT, MT_DATA); 1291184610Salfred if (mm == NULL) { 1292184610Salfred DPRINTF("Could not allocate header mbuf!\n"); 1293184610Salfred ural_tx_freem(m); 1294184610Salfred return; 1295184610Salfred } 1296184610Salfred DPRINTF(" %zu %u (out)\n", sizeof(sc->sc_tx_desc), m->m_pkthdr.len); 1297184610Salfred 1298184610Salfred bcopy(&sc->sc_tx_desc, mm->m_data, sizeof(sc->sc_tx_desc)); 1299184610Salfred mm->m_len = sizeof(sc->sc_tx_desc); 1300184610Salfred 1301184610Salfred mm->m_next = m; 1302184610Salfred mm->m_pkthdr.len = mm->m_len + m->m_pkthdr.len; 1303184610Salfred mm->m_pkthdr.rcvif = NULL; 1304184610Salfred 1305184610Salfred /* start write transfer, if not started */ 1306184610Salfred _IF_ENQUEUE(&sc->sc_tx_queue, mm); 1307184610Salfred 1308184610Salfred usb2_transfer_start(sc->sc_xfer[0]); 1309184610Salfred return; 1310184610Salfred} 1311184610Salfred 1312184610Salfredstatic void 1313184610Salfredural_bulk_write_callback(struct usb2_xfer *xfer) 1314184610Salfred{ 1315184610Salfred struct ural_softc *sc = xfer->priv_sc; 1316184610Salfred struct ifnet *ifp = sc->sc_ifp; 1317184610Salfred struct mbuf *m; 1318184610Salfred uint16_t temp_len; 1319184610Salfred uint8_t align; 1320184610Salfred 1321184610Salfred switch (USB_GET_STATE(xfer)) { 1322184610Salfred case USB_ST_TRANSFERRED: 1323184610Salfred DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen); 1324184610Salfred 1325184610Salfred ifp->if_opackets++; 1326184610Salfred 1327184610Salfred case USB_ST_SETUP: 1328184610Salfred if (sc->sc_flags & URAL_FLAG_WRITE_STALL) { 1329184610Salfred usb2_transfer_start(sc->sc_xfer[2]); 1330184610Salfred break; 1331184610Salfred } 1332184610Salfred if (sc->sc_flags & URAL_FLAG_WAIT_COMMAND) { 1333184610Salfred /* 1334184610Salfred * don't send anything while a command is pending ! 1335184610Salfred */ 1336184610Salfred break; 1337184610Salfred } 1338184610Salfred ural_fill_write_queue(sc); 1339184610Salfred 1340184610Salfred _IF_DEQUEUE(&sc->sc_tx_queue, m); 1341184610Salfred 1342184610Salfred if (m) { 1343184610Salfred 1344184610Salfred if (m->m_pkthdr.len > (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE)) { 1345184610Salfred DPRINTFN(0, "data overflow, %u bytes\n", 1346184610Salfred m->m_pkthdr.len); 1347184610Salfred m->m_pkthdr.len = (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE); 1348184610Salfred } 1349184610Salfred usb2_m_copy_in(xfer->frbuffers, 0, 1350184610Salfred m, 0, m->m_pkthdr.len); 1351184610Salfred 1352184610Salfred /* compute transfer length */ 1353184610Salfred temp_len = m->m_pkthdr.len; 1354184610Salfred 1355184610Salfred /* make transfer length 16-bit aligned */ 1356184610Salfred align = (temp_len & 1); 1357184610Salfred 1358184610Salfred /* check if we need to add two extra bytes */ 1359184610Salfred if (((temp_len + align) % 64) == 0) { 1360184610Salfred align += 2; 1361184610Salfred } 1362184610Salfred /* check if we need to align length */ 1363184610Salfred if (align != 0) { 1364184610Salfred /* zero the extra bytes */ 1365184610Salfred usb2_bzero(xfer->frbuffers, temp_len, align); 1366184610Salfred temp_len += align; 1367184610Salfred } 1368184610Salfred DPRINTFN(11, "sending frame len=%u xferlen=%u\n", 1369184610Salfred m->m_pkthdr.len, temp_len); 1370184610Salfred 1371184610Salfred xfer->frlengths[0] = temp_len; 1372184610Salfred 1373184610Salfred usb2_start_hardware(xfer); 1374184610Salfred 1375184610Salfred /* free mbuf and node */ 1376184610Salfred ural_tx_freem(m); 1377184610Salfred } 1378184610Salfred break; 1379184610Salfred 1380184610Salfred default: /* Error */ 1381184610Salfred DPRINTFN(11, "transfer error, %s\n", 1382184610Salfred usb2_errstr(xfer->error)); 1383184610Salfred 1384184610Salfred if (xfer->error != USB_ERR_CANCELLED) { 1385184610Salfred /* try to clear stall first */ 1386184610Salfred sc->sc_flags |= URAL_FLAG_WRITE_STALL; 1387184610Salfred usb2_transfer_start(sc->sc_xfer[2]); 1388184610Salfred } 1389184610Salfred ifp->if_oerrors++; 1390184610Salfred break; 1391184610Salfred } 1392184610Salfred return; 1393184610Salfred} 1394184610Salfred 1395184610Salfredstatic void 1396184610Salfredural_bulk_write_clear_stall_callback(struct usb2_xfer *xfer) 1397184610Salfred{ 1398184610Salfred struct ural_softc *sc = xfer->priv_sc; 1399184610Salfred struct usb2_xfer *xfer_other = sc->sc_xfer[0]; 1400184610Salfred 1401184610Salfred if (usb2_clear_stall_callback(xfer, xfer_other)) { 1402184610Salfred DPRINTF("stall cleared\n"); 1403184610Salfred sc->sc_flags &= ~URAL_FLAG_WRITE_STALL; 1404184610Salfred usb2_transfer_start(xfer_other); 1405184610Salfred } 1406184610Salfred return; 1407184610Salfred} 1408184610Salfred 1409184610Salfredstatic void 1410184610Salfredural_watchdog(void *arg) 1411184610Salfred{ 1412184610Salfred struct ural_softc *sc = arg; 1413184610Salfred 1414184610Salfred mtx_assert(&sc->sc_mtx, MA_OWNED); 1415184610Salfred 1416184610Salfred if (sc->sc_amrr_timer) { 1417184610Salfred usb2_config_td_queue_command 1418184610Salfred (&sc->sc_config_td, NULL, 1419184610Salfred &ural_cfg_amrr_timeout, 0, 0); 1420184610Salfred } 1421184610Salfred usb2_callout_reset(&sc->sc_watchdog, 1422184610Salfred hz, &ural_watchdog, sc); 1423184610Salfred 1424184610Salfred mtx_unlock(&sc->sc_mtx); 1425184610Salfred 1426184610Salfred return; 1427184610Salfred} 1428184610Salfred 1429184610Salfred/*========================================================================* 1430184610Salfred * IF-net callbacks 1431184610Salfred *========================================================================*/ 1432184610Salfred 1433184610Salfredstatic void 1434184610Salfredural_init_cb(void *arg) 1435184610Salfred{ 1436184610Salfred struct ural_softc *sc = arg; 1437184610Salfred 1438184610Salfred mtx_lock(&sc->sc_mtx); 1439184610Salfred usb2_config_td_queue_command 1440184610Salfred (&sc->sc_config_td, &ural_cfg_pre_init, 1441184610Salfred &ural_cfg_init, 0, 0); 1442184610Salfred mtx_unlock(&sc->sc_mtx); 1443184610Salfred 1444184610Salfred return; 1445184610Salfred} 1446184610Salfred 1447184610Salfredstatic int 1448184610Salfredural_ioctl_cb(struct ifnet *ifp, u_long cmd, caddr_t data) 1449184610Salfred{ 1450184610Salfred struct ural_softc *sc = ifp->if_softc; 1451184610Salfred struct ieee80211com *ic = ifp->if_l2com; 1452184610Salfred int error; 1453184610Salfred 1454184610Salfred switch (cmd) { 1455184610Salfred case SIOCSIFFLAGS: 1456184610Salfred mtx_lock(&sc->sc_mtx); 1457184610Salfred if (ifp->if_flags & IFF_UP) { 1458184610Salfred if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 1459184610Salfred usb2_config_td_queue_command 1460184610Salfred (&sc->sc_config_td, &ural_cfg_pre_init, 1461184610Salfred &ural_cfg_init, 0, 0); 1462184610Salfred } 1463184610Salfred } else { 1464184610Salfred if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1465184610Salfred usb2_config_td_queue_command 1466184610Salfred (&sc->sc_config_td, &ural_cfg_pre_stop, 1467184610Salfred &ural_cfg_stop, 0, 0); 1468184610Salfred } 1469184610Salfred } 1470184610Salfred mtx_unlock(&sc->sc_mtx); 1471184610Salfred error = 0; 1472184610Salfred break; 1473184610Salfred 1474184610Salfred case SIOCGIFMEDIA: 1475184610Salfred case SIOCSIFMEDIA: 1476184610Salfred error = ifmedia_ioctl(ifp, (void *)data, &ic->ic_media, cmd); 1477184610Salfred break; 1478184610Salfred 1479184610Salfred default: 1480184610Salfred error = ether_ioctl(ifp, cmd, data); 1481184610Salfred } 1482184610Salfred return (error); 1483184610Salfred} 1484184610Salfred 1485184610Salfredstatic void 1486184610Salfredural_start_cb(struct ifnet *ifp) 1487184610Salfred{ 1488184610Salfred struct ural_softc *sc = ifp->if_softc; 1489184610Salfred 1490184610Salfred mtx_lock(&sc->sc_mtx); 1491184610Salfred /* start write transfer, if not started */ 1492184610Salfred usb2_transfer_start(sc->sc_xfer[0]); 1493184610Salfred mtx_unlock(&sc->sc_mtx); 1494184610Salfred 1495184610Salfred return; 1496184610Salfred} 1497184610Salfred 1498184610Salfredstatic void 1499184610Salfredural_cfg_newstate(struct ural_softc *sc, 1500184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 1501184610Salfred{ 1502184610Salfred struct ifnet *ifp = sc->sc_ifp; 1503184610Salfred struct ieee80211com *ic = ifp->if_l2com; 1504184610Salfred struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1505184610Salfred struct ural_vap *uvp = URAL_VAP(vap); 1506184610Salfred enum ieee80211_state ostate; 1507184610Salfred enum ieee80211_state nstate; 1508184610Salfred int arg; 1509184610Salfred 1510184610Salfred ostate = vap->iv_state; 1511184610Salfred nstate = sc->sc_ns_state; 1512184610Salfred arg = sc->sc_ns_arg; 1513184610Salfred 1514184610Salfred if (ostate == IEEE80211_S_INIT) { 1515184610Salfred /* We are leaving INIT. TSF sync should be off. */ 1516184610Salfred ural_cfg_disable_tsf_sync(sc); 1517184610Salfred } 1518184610Salfred switch (nstate) { 1519184610Salfred case IEEE80211_S_INIT: 1520184610Salfred break; 1521184610Salfred 1522184610Salfred case IEEE80211_S_RUN: 1523184610Salfred ural_cfg_set_run(sc, cc); 1524184610Salfred break; 1525184610Salfred 1526184610Salfred default: 1527184610Salfred break; 1528184610Salfred } 1529184610Salfred 1530184610Salfred mtx_unlock(&sc->sc_mtx); 1531184610Salfred IEEE80211_LOCK(ic); 1532184610Salfred uvp->newstate(vap, nstate, arg); 1533184610Salfred if (vap->iv_newstate_cb != NULL) 1534184610Salfred vap->iv_newstate_cb(vap, nstate, arg); 1535184610Salfred IEEE80211_UNLOCK(ic); 1536184610Salfred mtx_lock(&sc->sc_mtx); 1537184610Salfred return; 1538184610Salfred} 1539184610Salfred 1540184610Salfredstatic int 1541184610Salfredural_newstate_cb(struct ieee80211vap *vap, 1542184610Salfred enum ieee80211_state nstate, int arg) 1543184610Salfred{ 1544184610Salfred struct ural_vap *uvp = URAL_VAP(vap); 1545184610Salfred struct ieee80211com *ic = vap->iv_ic; 1546184610Salfred struct ural_softc *sc = ic->ic_ifp->if_softc; 1547184610Salfred 1548184610Salfred DPRINTF("setting new state: %d\n", nstate); 1549184610Salfred 1550184610Salfred /* Special case - cannot defer this call and cannot block ! */ 1551184610Salfred if (nstate == IEEE80211_S_INIT) { 1552184610Salfred /* stop timers */ 1553184610Salfred mtx_lock(&sc->sc_mtx); 1554184610Salfred sc->sc_amrr_timer = 0; 1555184610Salfred mtx_unlock(&sc->sc_mtx); 1556184610Salfred return (uvp->newstate(vap, nstate, arg)); 1557184610Salfred } 1558184610Salfred mtx_lock(&sc->sc_mtx); 1559184610Salfred if (usb2_config_td_is_gone(&sc->sc_config_td)) { 1560184610Salfred mtx_unlock(&sc->sc_mtx); 1561184610Salfred return (0); /* nothing to do */ 1562184610Salfred } 1563184610Salfred /* store next state */ 1564184610Salfred sc->sc_ns_state = nstate; 1565184610Salfred sc->sc_ns_arg = arg; 1566184610Salfred 1567184610Salfred /* stop timers */ 1568184610Salfred sc->sc_amrr_timer = 0; 1569184610Salfred 1570184610Salfred /* 1571184610Salfred * USB configuration can only be done from the USB configuration 1572184610Salfred * thread: 1573184610Salfred */ 1574184610Salfred usb2_config_td_queue_command 1575184610Salfred (&sc->sc_config_td, &ural_config_copy, 1576184610Salfred &ural_cfg_newstate, 0, 0); 1577184610Salfred 1578184610Salfred mtx_unlock(&sc->sc_mtx); 1579184610Salfred 1580184610Salfred return (EINPROGRESS); 1581184610Salfred} 1582184610Salfred 1583184610Salfredstatic void 1584184610Salfredural_std_command(struct ieee80211com *ic, usb2_config_td_command_t *func) 1585184610Salfred{ 1586184610Salfred struct ural_softc *sc = ic->ic_ifp->if_softc; 1587184610Salfred 1588184610Salfred mtx_lock(&sc->sc_mtx); 1589184610Salfred 1590184610Salfred sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); 1591184610Salfred 1592184610Salfred usb2_config_td_queue_command 1593184610Salfred (&sc->sc_config_td, &ural_config_copy, func, 0, 0); 1594184610Salfred 1595184610Salfred mtx_unlock(&sc->sc_mtx); 1596184610Salfred 1597184610Salfred return; 1598184610Salfred} 1599184610Salfred 1600184610Salfredstatic void 1601184610Salfredural_scan_start_cb(struct ieee80211com *ic) 1602184610Salfred{ 1603184610Salfred ural_std_command(ic, &ural_cfg_scan_start); 1604184610Salfred return; 1605184610Salfred} 1606184610Salfred 1607184610Salfredstatic void 1608184610Salfredural_scan_end_cb(struct ieee80211com *ic) 1609184610Salfred{ 1610184610Salfred ural_std_command(ic, &ural_cfg_scan_end); 1611184610Salfred return; 1612184610Salfred} 1613184610Salfred 1614184610Salfredstatic void 1615184610Salfredural_set_channel_cb(struct ieee80211com *ic) 1616184610Salfred{ 1617184610Salfred ural_std_command(ic, &ural_cfg_set_chan); 1618184610Salfred return; 1619184610Salfred} 1620184610Salfred 1621184610Salfred/*========================================================================* 1622184610Salfred * configure sub-routines, ural_cfg_xxx 1623184610Salfred *========================================================================*/ 1624184610Salfred 1625184610Salfredstatic void 1626184610Salfredural_cfg_scan_start(struct ural_softc *sc, 1627184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 1628184610Salfred{ 1629184610Salfred /* abort TSF synchronization */ 1630184610Salfred ural_cfg_disable_tsf_sync(sc); 1631184610Salfred ural_cfg_set_bssid(sc, cc->if_broadcastaddr); 1632184610Salfred return; 1633184610Salfred} 1634184610Salfred 1635184610Salfredstatic void 1636184610Salfredural_cfg_scan_end(struct ural_softc *sc, 1637184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 1638184610Salfred{ 1639184610Salfred /* enable TSF synchronization */ 1640184610Salfred ural_cfg_enable_tsf_sync(sc, cc, 0); 1641184610Salfred ural_cfg_set_bssid(sc, cc->iv_bss.ni_bssid); 1642184610Salfred return; 1643184610Salfred} 1644184610Salfred 1645184610Salfredstatic void 1646184610Salfredural_cfg_set_chan(struct ural_softc *sc, 1647184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 1648184610Salfred{ 1649184610Salfred enum { 1650184610Salfred N_RF5222 = (sizeof(ural_rf5222) / sizeof(ural_rf5222[0])), 1651184610Salfred }; 1652184610Salfred uint32_t i; 1653184610Salfred uint32_t chan; 1654184610Salfred uint8_t power; 1655184610Salfred uint8_t tmp; 1656184610Salfred 1657184610Salfred chan = cc->ic_curchan.chan_to_ieee; 1658184610Salfred 1659184610Salfred if ((chan == 0) || 1660184610Salfred (chan == IEEE80211_CHAN_ANY)) { 1661184610Salfred /* nothing to do */ 1662184610Salfred return; 1663184610Salfred } 1664184610Salfred if (cc->ic_curchan.chan_is_2ghz) 1665184610Salfred power = min(sc->sc_txpow[chan - 1], 31); 1666184610Salfred else 1667184610Salfred power = 31; 1668184610Salfred 1669184610Salfred /* adjust txpower using ifconfig settings */ 1670184610Salfred power -= (100 - cc->ic_txpowlimit) / 8; 1671184610Salfred 1672184610Salfred DPRINTFN(3, "setting channel to %u, " 1673184610Salfred "tx-power to %u\n", chan, power); 1674184610Salfred 1675184610Salfred switch (sc->sc_rf_rev) { 1676184610Salfred case RAL_RF_2522: 1677184610Salfred ural_cfg_rf_write(sc, RAL_RF1, 0x00814); 1678184610Salfred ural_cfg_rf_write(sc, RAL_RF2, ural_rf2522_r2[chan - 1]); 1679184610Salfred ural_cfg_rf_write(sc, RAL_RF3, (power << 7) | 0x00040); 1680184610Salfred break; 1681184610Salfred 1682184610Salfred case RAL_RF_2523: 1683184610Salfred ural_cfg_rf_write(sc, RAL_RF1, 0x08804); 1684184610Salfred ural_cfg_rf_write(sc, RAL_RF2, ural_rf2523_r2[chan - 1]); 1685184610Salfred ural_cfg_rf_write(sc, RAL_RF3, (power << 7) | 0x38044); 1686184610Salfred ural_cfg_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); 1687184610Salfred break; 1688184610Salfred 1689184610Salfred case RAL_RF_2524: 1690184610Salfred ural_cfg_rf_write(sc, RAL_RF1, 0x0c808); 1691184610Salfred ural_cfg_rf_write(sc, RAL_RF2, ural_rf2524_r2[chan - 1]); 1692184610Salfred ural_cfg_rf_write(sc, RAL_RF3, (power << 7) | 0x00040); 1693184610Salfred ural_cfg_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); 1694184610Salfred break; 1695184610Salfred 1696184610Salfred case RAL_RF_2525: 1697184610Salfred ural_cfg_rf_write(sc, RAL_RF1, 0x08808); 1698184610Salfred ural_cfg_rf_write(sc, RAL_RF2, ural_rf2525_hi_r2[chan - 1]); 1699184610Salfred ural_cfg_rf_write(sc, RAL_RF3, (power << 7) | 0x18044); 1700184610Salfred ural_cfg_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); 1701184610Salfred 1702184610Salfred ural_cfg_rf_write(sc, RAL_RF1, 0x08808); 1703184610Salfred ural_cfg_rf_write(sc, RAL_RF2, ural_rf2525_r2[chan - 1]); 1704184610Salfred ural_cfg_rf_write(sc, RAL_RF3, (power << 7) | 0x18044); 1705184610Salfred ural_cfg_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); 1706184610Salfred break; 1707184610Salfred 1708184610Salfred case RAL_RF_2525E: 1709184610Salfred ural_cfg_rf_write(sc, RAL_RF1, 0x08808); 1710184610Salfred ural_cfg_rf_write(sc, RAL_RF2, ural_rf2525e_r2[chan - 1]); 1711184610Salfred ural_cfg_rf_write(sc, RAL_RF3, (power << 7) | 0x18044); 1712184610Salfred ural_cfg_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00286 : 0x00282); 1713184610Salfred break; 1714184610Salfred 1715184610Salfred case RAL_RF_2526: 1716184610Salfred ural_cfg_rf_write(sc, RAL_RF2, ural_rf2526_hi_r2[chan - 1]); 1717184610Salfred ural_cfg_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381); 1718184610Salfred ural_cfg_rf_write(sc, RAL_RF1, 0x08804); 1719184610Salfred 1720184610Salfred ural_cfg_rf_write(sc, RAL_RF2, ural_rf2526_r2[chan - 1]); 1721184610Salfred ural_cfg_rf_write(sc, RAL_RF3, (power << 7) | 0x18044); 1722184610Salfred ural_cfg_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381); 1723184610Salfred break; 1724184610Salfred 1725184610Salfred /* dual-band RF */ 1726184610Salfred case RAL_RF_5222: 1727184610Salfred for (i = 0; i < N_RF5222; i++) { 1728184610Salfred if (ural_rf5222[i].chan == chan) { 1729184610Salfred ural_cfg_rf_write(sc, RAL_RF1, ural_rf5222[i].r1); 1730184610Salfred ural_cfg_rf_write(sc, RAL_RF2, ural_rf5222[i].r2); 1731184610Salfred ural_cfg_rf_write(sc, RAL_RF3, (power << 7) | 0x00040); 1732184610Salfred ural_cfg_rf_write(sc, RAL_RF4, ural_rf5222[i].r4); 1733184610Salfred break; 1734184610Salfred } 1735184610Salfred } 1736184610Salfred break; 1737184610Salfred } 1738184610Salfred 1739184610Salfred if ((cc->ic_opmode != IEEE80211_M_MONITOR) && 1740184610Salfred (!(cc->ic_flags & IEEE80211_F_SCAN))) { 1741184610Salfred 1742184610Salfred /* set Japan filter bit for channel 14 */ 1743184610Salfred tmp = ural_cfg_bbp_read(sc, 70); 1744184610Salfred 1745184610Salfred if (chan == 14) { 1746184610Salfred tmp |= RAL_JAPAN_FILTER; 1747184610Salfred } else { 1748184610Salfred tmp &= ~RAL_JAPAN_FILTER; 1749184610Salfred } 1750184610Salfred 1751184610Salfred ural_cfg_bbp_write(sc, 70, tmp); 1752184610Salfred 1753184610Salfred /* clear CRC errors */ 1754184610Salfred ural_cfg_read(sc, RAL_STA_CSR0); 1755184610Salfred 1756184610Salfred ural_cfg_disable_rf_tune(sc); 1757184610Salfred } 1758184610Salfred /* update basic rate set */ 1759184610Salfred if (cc->ic_curchan.chan_is_b) { 1760184610Salfred /* 11b basic rates: 1, 2Mbps */ 1761184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR11, 0x3); 1762184610Salfred } else if (cc->ic_curchan.chan_is_a) { 1763184610Salfred /* 11a basic rates: 6, 12, 24Mbps */ 1764184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR11, 0x150); 1765184610Salfred } else { 1766184610Salfred /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ 1767184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR11, 0x15f); 1768184610Salfred } 1769184610Salfred 1770184610Salfred /* wait a little */ 1771184610Salfred if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 1772184610Salfred return; 1773184610Salfred } 1774184610Salfred return; 1775184610Salfred} 1776184610Salfred 1777184610Salfredstatic void 1778184610Salfredural_cfg_set_run(struct ural_softc *sc, 1779184610Salfred struct usb2_config_td_cc *cc) 1780184610Salfred{ 1781184610Salfred if (cc->ic_opmode != IEEE80211_M_MONITOR) { 1782184610Salfred ural_cfg_update_slot(sc, cc, 0); 1783184610Salfred ural_cfg_set_txpreamble(sc, cc, 0); 1784184610Salfred 1785184610Salfred /* update basic rate set */ 1786184610Salfred 1787184610Salfred if (cc->ic_bsschan.chan_is_5ghz) { 1788184610Salfred /* 11a basic rates: 6, 12, 24Mbps */ 1789184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR11, 0x150); 1790184610Salfred } else if (cc->ic_bsschan.chan_is_g) { 1791184610Salfred /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ 1792184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR11, 0x15f); 1793184610Salfred } else { 1794184610Salfred /* 11b basic rates: 1, 2Mbps */ 1795184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR11, 0x3); 1796184610Salfred } 1797184610Salfred ural_cfg_set_bssid(sc, cc->iv_bss.ni_bssid); 1798184610Salfred } 1799184610Salfred if ((cc->ic_opmode == IEEE80211_M_HOSTAP) || 1800184610Salfred (cc->ic_opmode == IEEE80211_M_IBSS)) { 1801184610Salfred ural_tx_bcn(sc); 1802184610Salfred } 1803184610Salfred /* make tx led blink on tx (controlled by ASIC) */ 1804184610Salfred ural_cfg_write(sc, RAL_MAC_CSR20, 1); 1805184610Salfred 1806184610Salfred if (cc->ic_opmode != IEEE80211_M_MONITOR) { 1807184610Salfred ural_cfg_enable_tsf_sync(sc, cc, 0); 1808184610Salfred } 1809184610Salfred /* clear statistic registers (STA_CSR0 to STA_CSR10) */ 1810184610Salfred ural_cfg_read_multi(sc, RAL_STA_CSR0, sc->sc_sta, sizeof(sc->sc_sta)); 1811184610Salfred 1812184610Salfred if (cc->iv_bss.fixed_rate_none) { 1813184610Salfred /* enable automatic rate adaptation */ 1814184610Salfred ural_cfg_amrr_start(sc); 1815184610Salfred } 1816184610Salfred return; 1817184610Salfred} 1818184610Salfred 1819184610Salfred/*------------------------------------------------------------------------* 1820184610Salfred * ural_cfg_disable_rf_tune - disable RF auto-tuning 1821184610Salfred *------------------------------------------------------------------------*/ 1822184610Salfredstatic void 1823184610Salfredural_cfg_disable_rf_tune(struct ural_softc *sc) 1824184610Salfred{ 1825184610Salfred uint32_t tmp; 1826184610Salfred 1827184610Salfred if (sc->sc_rf_rev != RAL_RF_2523) { 1828184610Salfred tmp = sc->sc_rf_regs[RAL_RF1] & ~RAL_RF1_AUTOTUNE; 1829184610Salfred ural_cfg_rf_write(sc, RAL_RF1, tmp); 1830184610Salfred } 1831184610Salfred tmp = sc->sc_rf_regs[RAL_RF3] & ~RAL_RF3_AUTOTUNE; 1832184610Salfred ural_cfg_rf_write(sc, RAL_RF3, tmp); 1833184610Salfred 1834184610Salfred DPRINTFN(3, "disabling RF autotune\n"); 1835184610Salfred 1836184610Salfred return; 1837184610Salfred} 1838184610Salfred 1839184610Salfred/*------------------------------------------------------------------------* 1840184610Salfred * ural_cfg_enable_tsf_sync - refer to IEEE Std 802.11-1999 pp. 123 1841184610Salfred * for more information on TSF synchronization 1842184610Salfred *------------------------------------------------------------------------*/ 1843184610Salfredstatic void 1844184610Salfredural_cfg_enable_tsf_sync(struct ural_softc *sc, 1845184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 1846184610Salfred{ 1847184610Salfred uint16_t logcwmin; 1848184610Salfred uint16_t preload; 1849184610Salfred uint16_t tmp; 1850184610Salfred 1851184610Salfred /* first, disable TSF synchronization */ 1852184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR19, 0); 1853184610Salfred 1854184610Salfred tmp = (16 * cc->iv_bss.ni_intval) << 4; 1855184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR18, tmp); 1856184610Salfred 1857184610Salfred logcwmin = (cc->ic_opmode == IEEE80211_M_IBSS) ? 2 : 0; 1858184610Salfred preload = (cc->ic_opmode == IEEE80211_M_IBSS) ? 320 : 6; 1859184610Salfred tmp = (logcwmin << 12) | preload; 1860184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR20, tmp); 1861184610Salfred 1862184610Salfred /* finally, enable TSF synchronization */ 1863184610Salfred tmp = RAL_ENABLE_TSF | RAL_ENABLE_TBCN; 1864184610Salfred if (cc->ic_opmode == IEEE80211_M_STA) 1865184610Salfred tmp |= RAL_ENABLE_TSF_SYNC(1); 1866184610Salfred else 1867184610Salfred tmp |= RAL_ENABLE_TSF_SYNC(2) | RAL_ENABLE_BEACON_GENERATOR; 1868184610Salfred 1869184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR19, tmp); 1870184610Salfred 1871184610Salfred DPRINTF("enabling TSF synchronization\n"); 1872184610Salfred 1873184610Salfred return; 1874184610Salfred} 1875184610Salfred 1876184610Salfredstatic void 1877184610Salfredural_cfg_disable_tsf_sync(struct ural_softc *sc) 1878184610Salfred{ 1879184610Salfred /* abort TSF synchronization */ 1880184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR19, 0); 1881184610Salfred 1882184610Salfred /* force tx led to stop blinking */ 1883184610Salfred ural_cfg_write(sc, RAL_MAC_CSR20, 0); 1884184610Salfred 1885184610Salfred return; 1886184610Salfred} 1887184610Salfred 1888184610Salfred#define RAL_RXTX_TURNAROUND 5 /* us */ 1889184610Salfred 1890184610Salfredstatic void 1891184610Salfredural_cfg_update_slot(struct ural_softc *sc, 1892184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 1893184610Salfred{ 1894184610Salfred uint16_t slottime; 1895184610Salfred uint16_t sifs; 1896184610Salfred uint16_t eifs; 1897184610Salfred 1898184610Salfred slottime = (cc->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; 1899184610Salfred 1900184610Salfred /* 1901184610Salfred * These settings may sound a bit inconsistent but this is what the 1902184610Salfred * reference driver does. 1903184610Salfred */ 1904184610Salfred if (cc->ic_curmode == IEEE80211_MODE_11B) { 1905184610Salfred sifs = 16 - RAL_RXTX_TURNAROUND; 1906184610Salfred eifs = 364; 1907184610Salfred } else { 1908184610Salfred sifs = 10 - RAL_RXTX_TURNAROUND; 1909184610Salfred eifs = 64; 1910184610Salfred } 1911184610Salfred 1912184610Salfred ural_cfg_write(sc, RAL_MAC_CSR10, slottime); 1913184610Salfred ural_cfg_write(sc, RAL_MAC_CSR11, sifs); 1914184610Salfred ural_cfg_write(sc, RAL_MAC_CSR12, eifs); 1915184610Salfred return; 1916184610Salfred} 1917184610Salfred 1918184610Salfredstatic void 1919184610Salfredural_cfg_set_txpreamble(struct ural_softc *sc, 1920184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 1921184610Salfred{ 1922184610Salfred uint16_t tmp; 1923184610Salfred 1924184610Salfred tmp = ural_cfg_read(sc, RAL_TXRX_CSR10); 1925184610Salfred 1926184610Salfred if (cc->ic_flags & IEEE80211_F_SHPREAMBLE) { 1927184610Salfred tmp |= RAL_SHORT_PREAMBLE; 1928184610Salfred } else { 1929184610Salfred tmp &= ~RAL_SHORT_PREAMBLE; 1930184610Salfred } 1931184610Salfred 1932184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR10, tmp); 1933184610Salfred return; 1934184610Salfred} 1935184610Salfred 1936184610Salfredstatic void 1937184610Salfredural_cfg_set_bssid(struct ural_softc *sc, uint8_t *bssid) 1938184610Salfred{ 1939184610Salfred ural_cfg_write_multi(sc, RAL_MAC_CSR5, bssid, IEEE80211_ADDR_LEN); 1940184610Salfred 1941184610Salfred DPRINTF("setting BSSID to 0x%02x%02x%02x%02x%02x%02x\n", 1942184610Salfred bssid[5], bssid[4], bssid[3], 1943184610Salfred bssid[2], bssid[1], bssid[0]); 1944184610Salfred return; 1945184610Salfred} 1946184610Salfred 1947184610Salfredstatic void 1948184610Salfredural_cfg_set_macaddr(struct ural_softc *sc, uint8_t *addr) 1949184610Salfred{ 1950184610Salfred ural_cfg_write_multi(sc, RAL_MAC_CSR2, addr, IEEE80211_ADDR_LEN); 1951184610Salfred 1952184610Salfred DPRINTF("setting MAC to 0x%02x%02x%02x%02x%02x%02x\n", 1953184610Salfred addr[5], addr[4], addr[3], 1954184610Salfred addr[2], addr[1], addr[0]); 1955184610Salfred return; 1956184610Salfred} 1957184610Salfred 1958184610Salfredstatic void 1959184610Salfredural_cfg_update_promisc(struct ural_softc *sc, 1960184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 1961184610Salfred{ 1962184610Salfred uint16_t tmp; 1963184610Salfred 1964184610Salfred tmp = ural_cfg_read(sc, RAL_TXRX_CSR2); 1965184610Salfred 1966184610Salfred if (cc->if_flags & IFF_PROMISC) { 1967184610Salfred tmp &= ~RAL_DROP_NOT_TO_ME; 1968184610Salfred } else { 1969184610Salfred tmp |= RAL_DROP_NOT_TO_ME; 1970184610Salfred } 1971184610Salfred 1972184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR2, tmp); 1973184610Salfred 1974184610Salfred DPRINTF("%s promiscuous mode\n", 1975184610Salfred (cc->if_flags & IFF_PROMISC) ? 1976184610Salfred "entering" : "leaving"); 1977184610Salfred return; 1978184610Salfred} 1979184610Salfred 1980184610Salfredstatic void 1981184610Salfredural_cfg_set_txantenna(struct ural_softc *sc, uint8_t antenna) 1982184610Salfred{ 1983184610Salfred uint16_t tmp; 1984184610Salfred uint8_t tx; 1985184610Salfred 1986184610Salfred tx = ural_cfg_bbp_read(sc, RAL_BBP_TX) & ~RAL_BBP_ANTMASK; 1987184610Salfred if (antenna == 1) 1988184610Salfred tx |= RAL_BBP_ANTA; 1989184610Salfred else if (antenna == 2) 1990184610Salfred tx |= RAL_BBP_ANTB; 1991184610Salfred else 1992184610Salfred tx |= RAL_BBP_DIVERSITY; 1993184610Salfred 1994184610Salfred /* need to force I/Q flip for RF 2525e, 2526 and 5222 */ 1995184610Salfred if ((sc->sc_rf_rev == RAL_RF_2525E) || 1996184610Salfred (sc->sc_rf_rev == RAL_RF_2526) || 1997184610Salfred (sc->sc_rf_rev == RAL_RF_5222)) { 1998184610Salfred tx |= RAL_BBP_FLIPIQ; 1999184610Salfred } 2000184610Salfred ural_cfg_bbp_write(sc, RAL_BBP_TX, tx); 2001184610Salfred 2002184610Salfred /* update values in PHY_CSR5 and PHY_CSR6 */ 2003184610Salfred tmp = ural_cfg_read(sc, RAL_PHY_CSR5) & ~0x7; 2004184610Salfred ural_cfg_write(sc, RAL_PHY_CSR5, tmp | (tx & 0x7)); 2005184610Salfred 2006184610Salfred tmp = ural_cfg_read(sc, RAL_PHY_CSR6) & ~0x7; 2007184610Salfred ural_cfg_write(sc, RAL_PHY_CSR6, tmp | (tx & 0x7)); 2008184610Salfred 2009184610Salfred return; 2010184610Salfred} 2011184610Salfred 2012184610Salfredstatic void 2013184610Salfredural_cfg_set_rxantenna(struct ural_softc *sc, uint8_t antenna) 2014184610Salfred{ 2015184610Salfred uint8_t rx; 2016184610Salfred 2017184610Salfred rx = ural_cfg_bbp_read(sc, RAL_BBP_RX) & ~RAL_BBP_ANTMASK; 2018184610Salfred if (antenna == 1) 2019184610Salfred rx |= RAL_BBP_ANTA; 2020184610Salfred else if (antenna == 2) 2021184610Salfred rx |= RAL_BBP_ANTB; 2022184610Salfred else 2023184610Salfred rx |= RAL_BBP_DIVERSITY; 2024184610Salfred 2025184610Salfred /* need to force no I/Q flip for RF 2525e and 2526 */ 2026184610Salfred 2027184610Salfred if ((sc->sc_rf_rev == RAL_RF_2525E) || 2028184610Salfred (sc->sc_rf_rev == RAL_RF_2526)) { 2029184610Salfred rx &= ~RAL_BBP_FLIPIQ; 2030184610Salfred } 2031184610Salfred ural_cfg_bbp_write(sc, RAL_BBP_RX, rx); 2032184610Salfred return; 2033184610Salfred} 2034184610Salfred 2035184610Salfredstatic void 2036184610Salfredural_cfg_read_eeprom(struct ural_softc *sc) 2037184610Salfred{ 2038184610Salfred uint16_t val; 2039184610Salfred 2040184610Salfred ural_cfg_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2); 2041184610Salfred 2042184610Salfred val = le16toh(val); 2043184610Salfred 2044184610Salfred sc->sc_rf_rev = (val >> 11) & 0x7; 2045184610Salfred sc->sc_hw_radio = (val >> 10) & 0x1; 2046184610Salfred sc->sc_led_mode = (val >> 6) & 0x7; 2047184610Salfred sc->sc_rx_ant = (val >> 4) & 0x3; 2048184610Salfred sc->sc_tx_ant = (val >> 2) & 0x3; 2049184610Salfred sc->sc_nb_ant = (val & 0x3); 2050184610Salfred 2051184610Salfred DPRINTF("val = 0x%04x\n", val); 2052184610Salfred 2053184610Salfred /* read MAC address */ 2054184610Salfred ural_cfg_eeprom_read(sc, RAL_EEPROM_ADDRESS, sc->sc_myaddr, 2055184610Salfred sizeof(sc->sc_myaddr)); 2056184610Salfred 2057184610Salfred /* read default values for BBP registers */ 2058184610Salfred ural_cfg_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->sc_bbp_prom, 2059184610Salfred sizeof(sc->sc_bbp_prom)); 2060184610Salfred 2061184610Salfred /* read Tx power for all b/g channels */ 2062184610Salfred ural_cfg_eeprom_read(sc, RAL_EEPROM_TXPOWER, sc->sc_txpow, 2063184610Salfred sizeof(sc->sc_txpow)); 2064184610Salfred return; 2065184610Salfred} 2066184610Salfred 2067184610Salfredstatic uint8_t 2068184610Salfredural_cfg_bbp_init(struct ural_softc *sc) 2069184610Salfred{ 2070184610Salfred enum { 2071184610Salfred N_DEF_BBP = (sizeof(ural_def_bbp) / sizeof(ural_def_bbp[0])), 2072184610Salfred }; 2073184610Salfred uint16_t i; 2074184610Salfred uint8_t to; 2075184610Salfred 2076184610Salfred /* wait for BBP to become ready */ 2077184610Salfred for (to = 0;; to++) { 2078184610Salfred if (to < 100) { 2079184610Salfred if (ural_cfg_bbp_read(sc, RAL_BBP_VERSION) != 0) { 2080184610Salfred break; 2081184610Salfred } 2082184610Salfred if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 2083184610Salfred return (1); /* failure */ 2084184610Salfred } 2085184610Salfred } else { 2086184610Salfred DPRINTF("timeout waiting for BBP\n"); 2087184610Salfred return (1); /* failure */ 2088184610Salfred } 2089184610Salfred } 2090184610Salfred 2091184610Salfred /* initialize BBP registers to default values */ 2092184610Salfred for (i = 0; i < N_DEF_BBP; i++) { 2093184610Salfred ural_cfg_bbp_write(sc, ural_def_bbp[i].reg, 2094184610Salfred ural_def_bbp[i].val); 2095184610Salfred } 2096184610Salfred 2097184610Salfred#if 0 2098184610Salfred /* initialize BBP registers to values stored in EEPROM */ 2099184610Salfred for (i = 0; i < 16; i++) { 2100184610Salfred if (sc->sc_bbp_prom[i].reg == 0xff) { 2101184610Salfred continue; 2102184610Salfred } 2103184610Salfred ural_cfg_bbp_write(sc, sc->sc_bbp_prom[i].reg, 2104184610Salfred sc->sc_bbp_prom[i].val); 2105184610Salfred } 2106184610Salfred#endif 2107184610Salfred return (0); /* success */ 2108184610Salfred} 2109184610Salfred 2110184610Salfredstatic void 2111184610Salfredural_cfg_pre_init(struct ural_softc *sc, 2112184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 2113184610Salfred{ 2114184610Salfred struct ifnet *ifp = sc->sc_ifp; 2115184610Salfred struct ieee80211com *ic = ifp->if_l2com; 2116184610Salfred 2117184610Salfred /* immediate configuration */ 2118184610Salfred 2119184610Salfred ural_cfg_pre_stop(sc, cc, 0); 2120184610Salfred 2121184610Salfred ifp->if_drv_flags |= IFF_DRV_RUNNING; 2122184610Salfred 2123184610Salfred sc->sc_flags |= URAL_FLAG_HL_READY; 2124184610Salfred 2125184610Salfred IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); 2126184610Salfred 2127184610Salfred return; 2128184610Salfred} 2129184610Salfred 2130184610Salfredstatic void 2131184610Salfredural_cfg_init(struct ural_softc *sc, 2132184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 2133184610Salfred{ 2134184610Salfred enum { 2135184610Salfred N_DEF_MAC = (sizeof(ural_def_mac) / sizeof(ural_def_mac[0])), 2136184610Salfred }; 2137184610Salfred uint16_t tmp; 2138184610Salfred uint16_t i; 2139184610Salfred uint8_t to; 2140184610Salfred 2141184610Salfred /* delayed configuration */ 2142184610Salfred 2143184610Salfred ural_cfg_set_testmode(sc); 2144184610Salfred 2145184610Salfred ural_cfg_write(sc, 0x308, 0x00f0); /* XXX magic */ 2146184610Salfred 2147184610Salfred ural_cfg_stop(sc, cc, 0); 2148184610Salfred 2149184610Salfred /* initialize MAC registers to default values */ 2150184610Salfred for (i = 0; i < N_DEF_MAC; i++) { 2151184610Salfred ural_cfg_write(sc, ural_def_mac[i].reg, 2152184610Salfred ural_def_mac[i].val); 2153184610Salfred } 2154184610Salfred 2155184610Salfred /* wait for BBP and RF to wake up (this can take a long time!) */ 2156184610Salfred for (to = 0;; to++) { 2157184610Salfred if (to < 100) { 2158184610Salfred tmp = ural_cfg_read(sc, RAL_MAC_CSR17); 2159184610Salfred if ((tmp & (RAL_BBP_AWAKE | RAL_RF_AWAKE)) == 2160184610Salfred (RAL_BBP_AWAKE | RAL_RF_AWAKE)) { 2161184610Salfred break; 2162184610Salfred } 2163184610Salfred if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) { 2164184610Salfred goto fail; 2165184610Salfred } 2166184610Salfred } else { 2167184610Salfred DPRINTF("timeout waiting for " 2168184610Salfred "BBP/RF to wakeup\n"); 2169184610Salfred goto fail; 2170184610Salfred } 2171184610Salfred } 2172184610Salfred 2173184610Salfred /* we're ready! */ 2174184610Salfred ural_cfg_write(sc, RAL_MAC_CSR1, RAL_HOST_READY); 2175184610Salfred 2176184610Salfred /* set basic rate set (will be updated later) */ 2177184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR11, 0x15f); 2178184610Salfred 2179184610Salfred if (ural_cfg_bbp_init(sc)) { 2180184610Salfred goto fail; 2181184610Salfred } 2182184610Salfred /* set default BSS channel */ 2183184610Salfred ural_cfg_set_chan(sc, cc, 0); 2184184610Salfred 2185184610Salfred /* clear statistic registers (STA_CSR0 to STA_CSR10) */ 2186184610Salfred ural_cfg_read_multi(sc, RAL_STA_CSR0, sc->sc_sta, 2187184610Salfred sizeof(sc->sc_sta)); 2188184610Salfred 2189184610Salfred DPRINTF("rx_ant=%d, tx_ant=%d\n", 2190184610Salfred sc->sc_rx_ant, sc->sc_tx_ant); 2191184610Salfred 2192184610Salfred ural_cfg_set_txantenna(sc, sc->sc_tx_ant); 2193184610Salfred ural_cfg_set_rxantenna(sc, sc->sc_rx_ant); 2194184610Salfred 2195184610Salfred ural_cfg_set_macaddr(sc, cc->ic_myaddr); 2196184610Salfred 2197184610Salfred /* 2198184610Salfred * make sure that the first transaction 2199184610Salfred * clears the stall: 2200184610Salfred */ 2201184610Salfred sc->sc_flags |= (URAL_FLAG_READ_STALL | 2202184610Salfred URAL_FLAG_WRITE_STALL | 2203184610Salfred URAL_FLAG_LL_READY); 2204184610Salfred 2205184610Salfred if ((sc->sc_flags & URAL_FLAG_LL_READY) && 2206184610Salfred (sc->sc_flags & URAL_FLAG_HL_READY)) { 2207184610Salfred struct ifnet *ifp = sc->sc_ifp; 2208184610Salfred struct ieee80211com *ic = ifp->if_l2com; 2209184610Salfred 2210184610Salfred /* 2211184610Salfred * start the USB transfers, if not already started: 2212184610Salfred */ 2213184610Salfred usb2_transfer_start(sc->sc_xfer[1]); 2214184610Salfred usb2_transfer_start(sc->sc_xfer[0]); 2215184610Salfred 2216184610Salfred /* 2217184610Salfred * start IEEE802.11 layer 2218184610Salfred */ 2219184610Salfred mtx_unlock(&sc->sc_mtx); 2220184610Salfred ieee80211_start_all(ic); 2221184610Salfred mtx_lock(&sc->sc_mtx); 2222184610Salfred } 2223184610Salfred /* 2224184610Salfred * start Rx 2225184610Salfred */ 2226184610Salfred tmp = RAL_DROP_PHY | RAL_DROP_CRC; 2227184610Salfred if (cc->ic_opmode != IEEE80211_M_MONITOR) { 2228184610Salfred 2229184610Salfred tmp |= (RAL_DROP_CTL | RAL_DROP_BAD_VERSION); 2230184610Salfred 2231184610Salfred if (cc->ic_opmode != IEEE80211_M_HOSTAP) { 2232184610Salfred tmp |= RAL_DROP_TODS; 2233184610Salfred } 2234184610Salfred if (!(cc->if_flags & IFF_PROMISC)) { 2235184610Salfred tmp |= RAL_DROP_NOT_TO_ME; 2236184610Salfred } 2237184610Salfred } 2238184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR2, tmp); 2239184610Salfred 2240184610Salfred return; 2241184610Salfred 2242184610Salfredfail: 2243184610Salfred ural_cfg_pre_stop(sc, NULL, 0); 2244184610Salfred 2245184610Salfred if (cc) { 2246184610Salfred ural_cfg_stop(sc, cc, 0); 2247184610Salfred } 2248184610Salfred return; 2249184610Salfred} 2250184610Salfred 2251184610Salfredstatic void 2252184610Salfredural_cfg_pre_stop(struct ural_softc *sc, 2253184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 2254184610Salfred{ 2255184610Salfred struct ifnet *ifp = sc->sc_ifp; 2256184610Salfred 2257184610Salfred if (cc) { 2258184610Salfred /* copy the needed configuration */ 2259184610Salfred ural_config_copy(sc, cc, refcount); 2260184610Salfred } 2261184610Salfred /* immediate configuration */ 2262184610Salfred 2263184610Salfred if (ifp) { 2264184610Salfred /* clear flags */ 2265184610Salfred ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 2266184610Salfred } 2267184610Salfred sc->sc_flags &= ~(URAL_FLAG_HL_READY | 2268184610Salfred URAL_FLAG_LL_READY); 2269184610Salfred 2270184610Salfred /* 2271184610Salfred * stop all the transfers, if not already stopped: 2272184610Salfred */ 2273184610Salfred usb2_transfer_stop(sc->sc_xfer[0]); 2274184610Salfred usb2_transfer_stop(sc->sc_xfer[1]); 2275184610Salfred usb2_transfer_stop(sc->sc_xfer[2]); 2276184610Salfred usb2_transfer_stop(sc->sc_xfer[3]); 2277184610Salfred 2278184610Salfred /* clean up transmission */ 2279184610Salfred ural_tx_clean_queue(sc); 2280184610Salfred return; 2281184610Salfred} 2282184610Salfred 2283184610Salfredstatic void 2284184610Salfredural_cfg_stop(struct ural_softc *sc, 2285184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 2286184610Salfred{ 2287184610Salfred /* disable Rx */ 2288184610Salfred ural_cfg_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX); 2289184610Salfred 2290184610Salfred /* reset ASIC and BBP (but won't reset MAC registers!) */ 2291184610Salfred ural_cfg_write(sc, RAL_MAC_CSR1, RAL_RESET_ASIC | RAL_RESET_BBP); 2292184610Salfred 2293184610Salfred /* wait a little */ 2294184610Salfred usb2_config_td_sleep(&sc->sc_config_td, hz / 10); 2295184610Salfred 2296184610Salfred /* clear reset */ 2297184610Salfred ural_cfg_write(sc, RAL_MAC_CSR1, 0); 2298184610Salfred 2299184610Salfred /* wait a little */ 2300184610Salfred usb2_config_td_sleep(&sc->sc_config_td, hz / 10); 2301184610Salfred 2302184610Salfred return; 2303184610Salfred} 2304184610Salfred 2305184610Salfredstatic void 2306184610Salfredural_cfg_amrr_start(struct ural_softc *sc) 2307184610Salfred{ 2308184610Salfred struct ieee80211vap *vap; 2309184610Salfred struct ieee80211_node *ni; 2310184610Salfred 2311184610Salfred vap = ural_get_vap(sc); 2312184610Salfred 2313184610Salfred if (vap == NULL) { 2314184610Salfred return; 2315184610Salfred } 2316184610Salfred ni = vap->iv_bss; 2317184610Salfred if (ni == NULL) { 2318184610Salfred return; 2319184610Salfred } 2320184610Salfred /* init AMRR */ 2321184610Salfred 2322184610Salfred ieee80211_amrr_node_init(&URAL_VAP(vap)->amrr, &URAL_NODE(ni)->amn, ni); 2323184610Salfred /* enable AMRR timer */ 2324184610Salfred 2325184610Salfred sc->sc_amrr_timer = 1; 2326184610Salfred return; 2327184610Salfred} 2328184610Salfred 2329184610Salfredstatic void 2330184610Salfredural_cfg_amrr_timeout(struct ural_softc *sc, 2331184610Salfred struct usb2_config_td_cc *cc, uint16_t refcount) 2332184610Salfred{ 2333184610Salfred struct ifnet *ifp = sc->sc_ifp; 2334184610Salfred struct ieee80211vap *vap; 2335184610Salfred struct ieee80211_node *ni; 2336184610Salfred uint32_t ok; 2337184610Salfred uint32_t fail; 2338184610Salfred 2339184610Salfred /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */ 2340184610Salfred ural_cfg_read_multi(sc, RAL_STA_CSR0, sc->sc_sta, sizeof(sc->sc_sta)); 2341184610Salfred 2342184610Salfred vap = ural_get_vap(sc); 2343184610Salfred if (vap == NULL) { 2344184610Salfred return; 2345184610Salfred } 2346184610Salfred ni = vap->iv_bss; 2347184610Salfred if (ni == NULL) { 2348184610Salfred return; 2349184610Salfred } 2350184610Salfred if ((sc->sc_flags & URAL_FLAG_LL_READY) && 2351184610Salfred (sc->sc_flags & URAL_FLAG_HL_READY)) { 2352184610Salfred 2353184610Salfred ok = sc->sc_sta[7] + /* TX ok w/o retry */ 2354184610Salfred sc->sc_sta[8]; /* TX ok w/ retry */ 2355184610Salfred fail = sc->sc_sta[9]; /* TX retry-fail count */ 2356184610Salfred 2357184610Salfred if (sc->sc_amrr_timer) { 2358184610Salfred 2359184610Salfred ieee80211_amrr_tx_update(&URAL_NODE(ni)->amn, 2360184610Salfred ok + fail, ok, sc->sc_sta[8] + fail); 2361184610Salfred 2362184610Salfred if (ieee80211_amrr_choose(ni, &URAL_NODE(ni)->amn)) { 2363184610Salfred /* ignore */ 2364184610Salfred } 2365184610Salfred } 2366184610Salfred ifp->if_oerrors += fail; 2367184610Salfred } 2368184610Salfred return; 2369184610Salfred} 2370184610Salfred 2371184610Salfredstatic struct ieee80211vap * 2372184610Salfredural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 2373184610Salfred int opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], 2374184610Salfred const uint8_t mac[IEEE80211_ADDR_LEN]) 2375184610Salfred{ 2376184610Salfred struct ural_vap *uvp; 2377184610Salfred struct ieee80211vap *vap; 2378184610Salfred struct ural_softc *sc = ic->ic_ifp->if_softc; 2379184610Salfred 2380184610Salfred /* Need to sync with config thread: */ 2381184610Salfred mtx_lock(&sc->sc_mtx); 2382184610Salfred if (usb2_config_td_sync(&sc->sc_config_td)) { 2383184610Salfred mtx_unlock(&sc->sc_mtx); 2384184610Salfred /* config thread is gone */ 2385184610Salfred return (NULL); 2386184610Salfred } 2387184610Salfred mtx_unlock(&sc->sc_mtx); 2388184610Salfred 2389184610Salfred if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 2390184610Salfred return NULL; 2391184610Salfred uvp = (struct ural_vap *)malloc(sizeof(struct ural_vap), 2392184610Salfred M_80211_VAP, M_NOWAIT | M_ZERO); 2393184610Salfred if (uvp == NULL) 2394184610Salfred return NULL; 2395184610Salfred 2396184610Salfred vap = &uvp->vap; 2397184610Salfred /* enable s/w bmiss handling for sta mode */ 2398184610Salfred ieee80211_vap_setup(ic, vap, name, unit, opmode, 2399184610Salfred flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); 2400184610Salfred 2401184610Salfred /* override state transition machine */ 2402184610Salfred uvp->newstate = vap->iv_newstate; 2403184610Salfred vap->iv_newstate = &ural_newstate_cb; 2404184610Salfred 2405184610Salfred ieee80211_amrr_init(&uvp->amrr, vap, 2406184610Salfred IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, 2407184610Salfred IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, 2408184610Salfred 1000 /* 1 sec */ ); 2409184610Salfred 2410184610Salfred /* complete setup */ 2411184610Salfred ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); 2412184610Salfred 2413184610Salfred /* store current operation mode */ 2414184610Salfred ic->ic_opmode = opmode; 2415184610Salfred 2416184610Salfred return (vap); 2417184610Salfred} 2418184610Salfred 2419184610Salfredstatic void 2420184610Salfredural_vap_delete(struct ieee80211vap *vap) 2421184610Salfred{ 2422184610Salfred struct ural_vap *uvp = URAL_VAP(vap); 2423184610Salfred struct ural_softc *sc = vap->iv_ic->ic_ifp->if_softc; 2424184610Salfred 2425184610Salfred /* Need to sync with config thread: */ 2426184610Salfred mtx_lock(&sc->sc_mtx); 2427184610Salfred if (usb2_config_td_sync(&sc->sc_config_td)) { 2428184610Salfred /* ignore */ 2429184610Salfred } 2430184610Salfred mtx_unlock(&sc->sc_mtx); 2431184610Salfred 2432184610Salfred ieee80211_amrr_cleanup(&uvp->amrr); 2433184610Salfred ieee80211_vap_detach(vap); 2434184610Salfred free(uvp, M_80211_VAP); 2435184610Salfred return; 2436184610Salfred} 2437184610Salfred 2438184610Salfred/* ARGUSED */ 2439184610Salfredstatic struct ieee80211_node * 2440184610Salfredural_node_alloc(struct ieee80211vap *vap __unused, 2441184610Salfred const uint8_t mac[IEEE80211_ADDR_LEN] __unused) 2442184610Salfred{ 2443184610Salfred struct ural_node *un; 2444184610Salfred 2445184610Salfred un = malloc(sizeof(struct ural_node), M_80211_NODE, M_NOWAIT | M_ZERO); 2446184610Salfred return ((un != NULL) ? &un->ni : NULL); 2447184610Salfred} 2448184610Salfred 2449184610Salfredstatic void 2450184610Salfredural_newassoc(struct ieee80211_node *ni, int isnew) 2451184610Salfred{ 2452184610Salfred struct ieee80211vap *vap = ni->ni_vap; 2453184610Salfred 2454184610Salfred ieee80211_amrr_node_init(&URAL_VAP(vap)->amrr, &URAL_NODE(ni)->amn, ni); 2455184610Salfred return; 2456184610Salfred} 2457184610Salfred 2458184610Salfredstatic void 2459184610Salfredural_fill_write_queue(struct ural_softc *sc) 2460184610Salfred{ 2461184610Salfred struct ifnet *ifp = sc->sc_ifp; 2462184610Salfred struct ieee80211_node *ni; 2463184610Salfred struct mbuf *m; 2464184610Salfred 2465184610Salfred /* 2466184610Salfred * We only fill up half of the queue with data frames. The rest is 2467184610Salfred * reserved for other kinds of frames. 2468184610Salfred */ 2469184610Salfred 2470184610Salfred while (sc->sc_tx_queue.ifq_len < (IFQ_MAXLEN / 2)) { 2471184610Salfred 2472184610Salfred IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 2473184610Salfred if (m == NULL) 2474184610Salfred break; 2475184610Salfred 2476184610Salfred ni = (void *)(m->m_pkthdr.rcvif); 2477184610Salfred m = ieee80211_encap(ni, m); 2478184610Salfred if (m == NULL) { 2479184610Salfred ieee80211_free_node(ni); 2480184610Salfred continue; 2481184610Salfred } 2482184610Salfred ural_tx_data(sc, m, ni); 2483184610Salfred } 2484184610Salfred return; 2485184610Salfred} 2486184610Salfred 2487184610Salfredstatic void 2488184610Salfredural_tx_clean_queue(struct ural_softc *sc) 2489184610Salfred{ 2490184610Salfred struct mbuf *m; 2491184610Salfred 2492184610Salfred for (;;) { 2493184610Salfred _IF_DEQUEUE(&sc->sc_tx_queue, m); 2494184610Salfred 2495184610Salfred if (!m) { 2496184610Salfred break; 2497184610Salfred } 2498184610Salfred ural_tx_freem(m); 2499184610Salfred } 2500184610Salfred 2501184610Salfred return; 2502184610Salfred} 2503184610Salfred 2504184610Salfredstatic void 2505184610Salfredural_tx_freem(struct mbuf *m) 2506184610Salfred{ 2507184610Salfred struct ieee80211_node *ni; 2508184610Salfred 2509184610Salfred while (m) { 2510184610Salfred ni = (void *)(m->m_pkthdr.rcvif); 2511184610Salfred if (!ni) { 2512184610Salfred m = m_free(m); 2513184610Salfred continue; 2514184610Salfred } 2515184610Salfred if (m->m_flags & M_TXCB) { 2516184610Salfred ieee80211_process_callback(ni, m, 0); 2517184610Salfred } 2518184610Salfred m_freem(m); 2519184610Salfred ieee80211_free_node(ni); 2520184610Salfred 2521184610Salfred break; 2522184610Salfred } 2523184610Salfred return; 2524184610Salfred} 2525184610Salfred 2526184610Salfredstatic void 2527184610Salfredural_tx_mgt(struct ural_softc *sc, struct mbuf *m, struct ieee80211_node *ni) 2528184610Salfred{ 2529184610Salfred struct ieee80211vap *vap = ni->ni_vap; 2530184610Salfred struct ieee80211com *ic = ni->ni_ic; 2531184610Salfred const struct ieee80211_txparam *tp; 2532184610Salfred struct ieee80211_frame *wh; 2533184610Salfred struct ieee80211_key *k; 2534184610Salfred uint32_t flags; 2535184610Salfred uint16_t dur; 2536184610Salfred 2537184610Salfred tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 2538184610Salfred 2539184610Salfred wh = mtod(m, struct ieee80211_frame *); 2540184610Salfred if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2541184610Salfred k = ieee80211_crypto_encap(ni, m); 2542184610Salfred if (k == NULL) { 2543184610Salfred m_freem(m); 2544184610Salfred ieee80211_free_node(ni); 2545184610Salfred return; 2546184610Salfred } 2547184610Salfred wh = mtod(m, struct ieee80211_frame *); 2548184610Salfred } 2549184610Salfred flags = 0; 2550184610Salfred if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 2551184610Salfred flags |= RAL_TX_ACK; 2552184610Salfred 2553184610Salfred dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate, 2554184610Salfred ic->ic_flags & IEEE80211_F_SHPREAMBLE); 2555184610Salfred USETW(wh->i_dur, dur); 2556184610Salfred 2557184610Salfred /* tell hardware to add timestamp for probe responses */ 2558184610Salfred if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 2559184610Salfred IEEE80211_FC0_TYPE_MGT && 2560184610Salfred (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 2561184610Salfred IEEE80211_FC0_SUBTYPE_PROBE_RESP) 2562184610Salfred flags |= RAL_TX_TIMESTAMP; 2563184610Salfred } 2564184610Salfred m->m_pkthdr.rcvif = (void *)ni; 2565184610Salfred ural_setup_desc_and_tx(sc, m, flags, tp->mgmtrate); 2566184610Salfred return; 2567184610Salfred} 2568184610Salfred 2569184610Salfredstatic struct ieee80211vap * 2570184610Salfredural_get_vap(struct ural_softc *sc) 2571184610Salfred{ 2572184610Salfred struct ifnet *ifp; 2573184610Salfred struct ieee80211com *ic; 2574184610Salfred 2575184610Salfred if (sc == NULL) { 2576184610Salfred return NULL; 2577184610Salfred } 2578184610Salfred ifp = sc->sc_ifp; 2579184610Salfred if (ifp == NULL) { 2580184610Salfred return NULL; 2581184610Salfred } 2582184610Salfred ic = ifp->if_l2com; 2583184610Salfred if (ic == NULL) { 2584184610Salfred return NULL; 2585184610Salfred } 2586184610Salfred return TAILQ_FIRST(&ic->ic_vaps); 2587184610Salfred} 2588184610Salfred 2589184610Salfredstatic void 2590184610Salfredural_tx_bcn(struct ural_softc *sc) 2591184610Salfred{ 2592184610Salfred struct ieee80211_node *ni; 2593184610Salfred struct ieee80211vap *vap; 2594184610Salfred struct ieee80211com *ic; 2595184610Salfred const struct ieee80211_txparam *tp; 2596184610Salfred struct mbuf *m; 2597184610Salfred 2598184610Salfred vap = ural_get_vap(sc); 2599184610Salfred if (vap == NULL) { 2600184610Salfred return; 2601184610Salfred } 2602184610Salfred ni = vap->iv_bss; 2603184610Salfred if (ni == NULL) { 2604184610Salfred return; 2605184610Salfred } 2606184610Salfred ic = vap->iv_ic; 2607184610Salfred if (ic == NULL) { 2608184610Salfred return; 2609184610Salfred } 2610184610Salfred DPRINTFN(11, "Sending beacon frame.\n"); 2611184610Salfred 2612184610Salfred m = ieee80211_beacon_alloc(ni, &URAL_VAP(vap)->bo); 2613184610Salfred if (m == NULL) { 2614184610Salfred DPRINTFN(0, "could not allocate beacon\n"); 2615184610Salfred return; 2616184610Salfred } 2617184610Salfred tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; 2618184610Salfred 2619184610Salfred m->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ni); 2620184610Salfred ural_setup_desc_and_tx(sc, m, RAL_TX_IFS_NEWBACKOFF | RAL_TX_TIMESTAMP, 2621184610Salfred tp->mgmtrate); 2622184610Salfred return; 2623184610Salfred} 2624184610Salfred 2625184610Salfredstatic void 2626184610Salfredural_tx_data(struct ural_softc *sc, struct mbuf *m, struct ieee80211_node *ni) 2627184610Salfred{ 2628184610Salfred struct ieee80211vap *vap = ni->ni_vap; 2629184610Salfred struct ieee80211com *ic = ni->ni_ic; 2630184610Salfred const struct ieee80211_txparam *tp; 2631184610Salfred struct ieee80211_frame *wh; 2632184610Salfred struct ieee80211_key *k; 2633184610Salfred uint32_t flags = 0; 2634184610Salfred uint16_t dur; 2635184610Salfred uint16_t rate; 2636184610Salfred 2637184610Salfred DPRINTFN(11, "Sending data.\n"); 2638184610Salfred 2639184610Salfred wh = mtod(m, struct ieee80211_frame *); 2640184610Salfred 2641184610Salfred tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; 2642184610Salfred if (IEEE80211_IS_MULTICAST(wh->i_addr1)) 2643184610Salfred rate = tp->mcastrate; 2644184610Salfred else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 2645184610Salfred rate = tp->ucastrate; 2646184610Salfred else 2647184610Salfred rate = ni->ni_txrate; 2648184610Salfred 2649184610Salfred if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2650184610Salfred k = ieee80211_crypto_encap(ni, m); 2651184610Salfred if (k == NULL) { 2652184610Salfred m_freem(m); 2653184610Salfred ieee80211_free_node(ni); 2654184610Salfred return; 2655184610Salfred } 2656184610Salfred /* packet header may have moved, reset our local pointer */ 2657184610Salfred wh = mtod(m, struct ieee80211_frame *); 2658184610Salfred } 2659184610Salfred if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 2660184610Salfred uint8_t prot = IEEE80211_PROT_NONE; 2661184610Salfred 2662184610Salfred if (m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 2663184610Salfred prot = IEEE80211_PROT_RTSCTS; 2664184610Salfred else if ((ic->ic_flags & IEEE80211_F_USEPROT) && 2665184610Salfred ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) 2666184610Salfred prot = ic->ic_protmode; 2667184610Salfred if (prot != IEEE80211_PROT_NONE) { 2668184610Salfred ural_tx_prot(sc, m, ni, prot, rate); 2669184610Salfred flags |= RAL_TX_IFS_SIFS; 2670184610Salfred } 2671184610Salfred flags |= RAL_TX_ACK; 2672184610Salfred flags |= RAL_TX_RETRY(7); 2673184610Salfred 2674184610Salfred dur = ieee80211_ack_duration(sc->sc_rates, rate, 2675184610Salfred ic->ic_flags & IEEE80211_F_SHPREAMBLE); 2676184610Salfred USETW(wh->i_dur, dur); 2677184610Salfred } 2678184610Salfred m->m_pkthdr.rcvif = (void *)ni; 2679184610Salfred ural_setup_desc_and_tx(sc, m, flags, rate); 2680184610Salfred return; 2681184610Salfred} 2682184610Salfred 2683184610Salfredstatic void 2684184610Salfredural_tx_prot(struct ural_softc *sc, 2685184610Salfred const struct mbuf *m, struct ieee80211_node *ni, 2686184610Salfred uint8_t prot, uint16_t rate) 2687184610Salfred{ 2688184610Salfred struct ieee80211com *ic = ni->ni_ic; 2689184610Salfred const struct ieee80211_frame *wh; 2690184610Salfred struct mbuf *mprot; 2691184610Salfred uint32_t flags; 2692184610Salfred uint16_t protrate; 2693184610Salfred uint16_t ackrate; 2694184610Salfred uint16_t pktlen; 2695184610Salfred uint16_t dur; 2696184610Salfred uint8_t isshort; 2697184610Salfred 2698184610Salfred KASSERT((prot == IEEE80211_PROT_RTSCTS) || 2699184610Salfred (prot == IEEE80211_PROT_CTSONLY), 2700184610Salfred ("protection %u", prot)); 2701184610Salfred 2702184610Salfred DPRINTFN(16, "Sending protection frame.\n"); 2703184610Salfred 2704184610Salfred wh = mtod(m, const struct ieee80211_frame *); 2705184610Salfred pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; 2706184610Salfred 2707184610Salfred protrate = ieee80211_ctl_rate(sc->sc_rates, rate); 2708184610Salfred ackrate = ieee80211_ack_rate(sc->sc_rates, rate); 2709184610Salfred 2710184610Salfred isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 2711184610Salfred dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); 2712184610Salfred +ieee80211_ack_duration(sc->sc_rates, rate, isshort); 2713184610Salfred flags = RAL_TX_RETRY(7); 2714184610Salfred if (prot == IEEE80211_PROT_RTSCTS) { 2715184610Salfred /* NB: CTS is the same size as an ACK */ 2716184610Salfred dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); 2717184610Salfred flags |= RAL_TX_ACK; 2718184610Salfred mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); 2719184610Salfred } else { 2720184610Salfred mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); 2721184610Salfred } 2722184610Salfred if (mprot == NULL) { 2723184610Salfred return; 2724184610Salfred } 2725184610Salfred mprot->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ni); 2726184610Salfred ural_setup_desc_and_tx(sc, mprot, flags, protrate); 2727184610Salfred return; 2728184610Salfred} 2729184610Salfred 2730184610Salfredstatic void 2731184610Salfredural_tx_raw(struct ural_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2732184610Salfred const struct ieee80211_bpf_params *params) 2733184610Salfred{ 2734184610Salfred uint32_t flags; 2735184610Salfred uint16_t rate; 2736184610Salfred 2737184610Salfred DPRINTFN(11, "Sending raw frame.\n"); 2738184610Salfred 2739184610Salfred rate = params->ibp_rate0 & IEEE80211_RATE_VAL; 2740184610Salfred 2741184610Salfred /* XXX validate */ 2742184610Salfred if (rate == 0) { 2743184610Salfred m_freem(m); 2744184610Salfred ieee80211_free_node(ni); 2745184610Salfred return; 2746184610Salfred } 2747184610Salfred flags = 0; 2748184610Salfred if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) 2749184610Salfred flags |= RAL_TX_ACK; 2750184610Salfred if (params->ibp_flags & (IEEE80211_BPF_RTS | IEEE80211_BPF_CTS)) { 2751184610Salfred ural_tx_prot(sc, m, ni, 2752184610Salfred (params->ibp_flags & IEEE80211_BPF_RTS) ? 2753184610Salfred IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, 2754184610Salfred rate); 2755184610Salfred flags |= RAL_TX_IFS_SIFS; 2756184610Salfred } 2757184610Salfred m->m_pkthdr.rcvif = (void *)ni; 2758184610Salfred ural_setup_desc_and_tx(sc, m, flags, rate); 2759184610Salfred return; 2760184610Salfred} 2761184610Salfred 2762184610Salfredstatic int 2763184610Salfredural_raw_xmit_cb(struct ieee80211_node *ni, struct mbuf *m, 2764184610Salfred const struct ieee80211_bpf_params *params) 2765184610Salfred{ 2766184610Salfred struct ieee80211com *ic = ni->ni_ic; 2767184610Salfred struct ifnet *ifp = ic->ic_ifp; 2768184610Salfred struct ural_softc *sc = ifp->if_softc; 2769184610Salfred 2770184610Salfred mtx_lock(&sc->sc_mtx); 2771184610Salfred if (params == NULL) { 2772184610Salfred /* 2773184610Salfred * Legacy path; interpret frame contents to decide 2774184610Salfred * precisely how to send the frame. 2775184610Salfred */ 2776184610Salfred ural_tx_mgt(sc, m, ni); 2777184610Salfred } else { 2778184610Salfred /* 2779184610Salfred * Caller supplied explicit parameters to use in 2780184610Salfred * sending the frame. 2781184610Salfred */ 2782184610Salfred ural_tx_raw(sc, m, ni, params); 2783184610Salfred } 2784184610Salfred mtx_unlock(&sc->sc_mtx); 2785184610Salfred return (0); 2786184610Salfred} 2787184610Salfred 2788184610Salfredstatic void 2789184610Salfredural_update_mcast_cb(struct ifnet *ifp) 2790184610Salfred{ 2791184610Salfred /* not supported */ 2792184610Salfred return; 2793184610Salfred} 2794184610Salfred 2795184610Salfredstatic void 2796184610Salfredural_update_promisc_cb(struct ifnet *ifp) 2797184610Salfred{ 2798184610Salfred struct ural_softc *sc = ifp->if_softc; 2799184610Salfred 2800184610Salfred mtx_lock(&sc->sc_mtx); 2801184610Salfred usb2_config_td_queue_command 2802184610Salfred (&sc->sc_config_td, &ural_config_copy, 2803184610Salfred &ural_cfg_update_promisc, 0, 0); 2804184610Salfred mtx_unlock(&sc->sc_mtx); 2805184610Salfred return; 2806184610Salfred} 2807