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