if_run.c revision 227309
1169695Skan/*- 2169695Skan * Copyright (c) 2008,2010 Damien Bergamini <damien.bergamini@free.fr> 3169695Skan * ported to FreeBSD by Akinori Furukoshi <moonlightakkiy@yahoo.ca> 4169695Skan * USB Consulting, Hans Petter Selasky <hselasky@freebsd.org> 5169695Skan * 6169695Skan * Permission to use, copy, modify, and distribute this software for any 7169695Skan * purpose with or without fee is hereby granted, provided that the above 8169695Skan * copyright notice and this permission notice appear in all copies. 9169695Skan * 10169695Skan * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11169695Skan * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12169695Skan * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13169695Skan * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14169695Skan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15169695Skan * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16169695Skan * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17169695Skan */ 18169695Skan 19169695Skan#include <sys/cdefs.h> 20169695Skan__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_run.c 227309 2011-11-07 15:43:11Z ed $"); 21169695Skan 22169695Skan/*- 23169695Skan * Ralink Technology RT2700U/RT2800U/RT3000U chipset driver. 24169695Skan * http://www.ralinktech.com/ 25169695Skan */ 26169695Skan 27169695Skan#include <sys/param.h> 28169695Skan#include <sys/sockio.h> 29169695Skan#include <sys/sysctl.h> 30169695Skan#include <sys/lock.h> 31169695Skan#include <sys/mutex.h> 32169695Skan#include <sys/mbuf.h> 33169695Skan#include <sys/kernel.h> 34169695Skan#include <sys/socket.h> 35169695Skan#include <sys/systm.h> 36169695Skan#include <sys/malloc.h> 37169695Skan#include <sys/module.h> 38169695Skan#include <sys/bus.h> 39169695Skan#include <sys/endian.h> 40169695Skan#include <sys/linker.h> 41169695Skan#include <sys/firmware.h> 42169695Skan#include <sys/kdb.h> 43169695Skan 44169695Skan#include <machine/bus.h> 45169695Skan#include <machine/resource.h> 46169695Skan#include <sys/rman.h> 47169695Skan 48169695Skan#include <net/bpf.h> 49169695Skan#include <net/if.h> 50169695Skan#include <net/if_arp.h> 51169695Skan#include <net/ethernet.h> 52169695Skan#include <net/if_dl.h> 53169695Skan#include <net/if_media.h> 54169695Skan#include <net/if_types.h> 55169695Skan 56169695Skan#include <netinet/in.h> 57169695Skan#include <netinet/in_systm.h> 58169695Skan#include <netinet/in_var.h> 59169695Skan#include <netinet/if_ether.h> 60169695Skan#include <netinet/ip.h> 61169695Skan 62169695Skan#include <net80211/ieee80211_var.h> 63169695Skan#include <net80211/ieee80211_regdomain.h> 64169695Skan#include <net80211/ieee80211_radiotap.h> 65169695Skan#include <net80211/ieee80211_ratectl.h> 66169695Skan 67169695Skan#include <dev/usb/usb.h> 68169695Skan#include <dev/usb/usbdi.h> 69169695Skan#include "usbdevs.h" 70169695Skan 71169695Skan#define USB_DEBUG_VAR run_debug 72169695Skan#include <dev/usb/usb_debug.h> 73169695Skan 74169695Skan#include <dev/usb/wlan/if_runreg.h> 75169695Skan#include <dev/usb/wlan/if_runvar.h> 76169695Skan 77169695Skan#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 78169695Skan 79169695Skan#ifdef USB_DEBUG 80169695Skan#define RUN_DEBUG 81169695Skan#endif 82169695Skan 83169695Skan#ifdef RUN_DEBUG 84169695Skanint run_debug = 0; 85169695Skanstatic SYSCTL_NODE(_hw_usb, OID_AUTO, run, CTLFLAG_RW, 0, "USB run"); 86169695SkanSYSCTL_INT(_hw_usb_run, OID_AUTO, debug, CTLFLAG_RW, &run_debug, 0, 87169695Skan "run debug level"); 88169695Skan#endif 89169695Skan 90169695Skan#define IEEE80211_HAS_ADDR4(wh) \ 91169695Skan (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) 92169695Skan 93169695Skan/* 94169695Skan * Because of LOR in run_key_delete(), use atomic instead. 95169695Skan * '& RUN_CMDQ_MASQ' is to loop cmdq[]. 96169695Skan */ 97169695Skan#define RUN_CMDQ_GET(c) (atomic_fetchadd_32((c), 1) & RUN_CMDQ_MASQ) 98169695Skan 99169695Skanstatic const STRUCT_USB_HOST_ID run_devs[] = { 100169695Skan#define RUN_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } 101169695Skan RUN_DEV(ABOCOM, RT2770), 102169695Skan RUN_DEV(ABOCOM, RT2870), 103169695Skan RUN_DEV(ABOCOM, RT3070), 104169695Skan RUN_DEV(ABOCOM, RT3071), 105169695Skan RUN_DEV(ABOCOM, RT3072), 106169695Skan RUN_DEV(ABOCOM2, RT2870_1), 107169695Skan RUN_DEV(ACCTON, RT2770), 108169695Skan RUN_DEV(ACCTON, RT2870_1), 109169695Skan RUN_DEV(ACCTON, RT2870_2), 110169695Skan RUN_DEV(ACCTON, RT2870_3), 111169695Skan RUN_DEV(ACCTON, RT2870_4), 112169695Skan RUN_DEV(ACCTON, RT2870_5), 113169695Skan RUN_DEV(ACCTON, RT3070), 114169695Skan RUN_DEV(ACCTON, RT3070_1), 115169695Skan RUN_DEV(ACCTON, RT3070_2), 116169695Skan RUN_DEV(ACCTON, RT3070_3), 117169695Skan RUN_DEV(ACCTON, RT3070_4), 118169695Skan RUN_DEV(ACCTON, RT3070_5), 119169695Skan RUN_DEV(AIRTIES, RT3070), 120169695Skan RUN_DEV(ALLWIN, RT2070), 121169695Skan RUN_DEV(ALLWIN, RT2770), 122169695Skan RUN_DEV(ALLWIN, RT2870), 123169695Skan RUN_DEV(ALLWIN, RT3070), 124169695Skan RUN_DEV(ALLWIN, RT3071), 125169695Skan RUN_DEV(ALLWIN, RT3072), 126169695Skan RUN_DEV(ALLWIN, RT3572), 127169695Skan RUN_DEV(AMIGO, RT2870_1), 128169695Skan RUN_DEV(AMIGO, RT2870_2), 129169695Skan RUN_DEV(AMIT, CGWLUSB2GNR), 130169695Skan RUN_DEV(AMIT, RT2870_1), 131169695Skan RUN_DEV(AMIT2, RT2870), 132169695Skan RUN_DEV(ASUS, RT2870_1), 133169695Skan RUN_DEV(ASUS, RT2870_2), 134169695Skan RUN_DEV(ASUS, RT2870_3), 135169695Skan RUN_DEV(ASUS, RT2870_4), 136169695Skan RUN_DEV(ASUS, RT2870_5), 137169695Skan RUN_DEV(ASUS, USBN13), 138169695Skan RUN_DEV(ASUS, RT3070_1), 139169695Skan RUN_DEV(ASUS2, USBN11), 140169695Skan RUN_DEV(AZUREWAVE, RT2870_1), 141169695Skan RUN_DEV(AZUREWAVE, RT2870_2), 142169695Skan RUN_DEV(AZUREWAVE, RT3070_1), 143169695Skan RUN_DEV(AZUREWAVE, RT3070_2), 144169695Skan RUN_DEV(AZUREWAVE, RT3070_3), 145169695Skan RUN_DEV(BELKIN, F5D8053V3), 146169695Skan RUN_DEV(BELKIN, F5D8055), 147169695Skan RUN_DEV(BELKIN, F5D8055V2), 148169695Skan RUN_DEV(BELKIN, F6D4050V1), 149169695Skan RUN_DEV(BELKIN, RT2870_1), 150169695Skan RUN_DEV(BELKIN, RT2870_2), 151169695Skan RUN_DEV(CISCOLINKSYS, AE1000), 152169695Skan RUN_DEV(CISCOLINKSYS2, RT3070), 153169695Skan RUN_DEV(CISCOLINKSYS3, RT3070), 154169695Skan RUN_DEV(CONCEPTRONIC2, RT2870_1), 155169695Skan RUN_DEV(CONCEPTRONIC2, RT2870_2), 156169695Skan RUN_DEV(CONCEPTRONIC2, RT2870_3), 157169695Skan RUN_DEV(CONCEPTRONIC2, RT2870_4), 158169695Skan RUN_DEV(CONCEPTRONIC2, RT2870_5), 159169695Skan RUN_DEV(CONCEPTRONIC2, RT2870_6), 160169695Skan RUN_DEV(CONCEPTRONIC2, RT2870_7), 161169695Skan RUN_DEV(CONCEPTRONIC2, RT2870_8), 162169695Skan RUN_DEV(CONCEPTRONIC2, RT3070_1), 163169695Skan RUN_DEV(CONCEPTRONIC2, RT3070_2), 164169695Skan RUN_DEV(CONCEPTRONIC2, VIGORN61), 165169695Skan RUN_DEV(COREGA, CGWLUSB300GNM), 166169695Skan RUN_DEV(COREGA, RT2870_1), 167169695Skan RUN_DEV(COREGA, RT2870_2), 168169695Skan RUN_DEV(COREGA, RT2870_3), 169169695Skan RUN_DEV(COREGA, RT3070), 170169695Skan RUN_DEV(CYBERTAN, RT2870), 171169695Skan RUN_DEV(DLINK, RT2870), 172169695Skan RUN_DEV(DLINK, RT3072), 173169695Skan RUN_DEV(DLINK2, DWA130), 174169695Skan RUN_DEV(DLINK2, RT2870_1), 175169695Skan RUN_DEV(DLINK2, RT2870_2), 176169695Skan RUN_DEV(DLINK2, RT3070_1), 177169695Skan RUN_DEV(DLINK2, RT3070_2), 178169695Skan RUN_DEV(DLINK2, RT3070_3), 179169695Skan RUN_DEV(DLINK2, RT3070_4), 180169695Skan RUN_DEV(DLINK2, RT3070_5), 181169695Skan RUN_DEV(DLINK2, RT3072), 182169695Skan RUN_DEV(DLINK2, RT3072_1), 183169695Skan RUN_DEV(EDIMAX, EW7717), 184169695Skan RUN_DEV(EDIMAX, EW7718), 185169695Skan RUN_DEV(EDIMAX, RT2870_1), 186169695Skan RUN_DEV(ENCORE, RT3070_1), 187169695Skan RUN_DEV(ENCORE, RT3070_2), 188169695Skan RUN_DEV(ENCORE, RT3070_3), 189169695Skan RUN_DEV(GIGABYTE, GNWB31N), 190169695Skan RUN_DEV(GIGABYTE, GNWB32L), 191169695Skan RUN_DEV(GIGABYTE, RT2870_1), 192169695Skan RUN_DEV(GIGASET, RT3070_1), 193169695Skan RUN_DEV(GIGASET, RT3070_2), 194169695Skan RUN_DEV(GUILLEMOT, HWNU300), 195169695Skan RUN_DEV(HAWKING, HWUN2), 196169695Skan RUN_DEV(HAWKING, RT2870_1), 197169695Skan RUN_DEV(HAWKING, RT2870_2), 198169695Skan RUN_DEV(HAWKING, RT3070), 199169695Skan RUN_DEV(IODATA, RT3072_1), 200169695Skan RUN_DEV(IODATA, RT3072_2), 201169695Skan RUN_DEV(IODATA, RT3072_3), 202169695Skan RUN_DEV(IODATA, RT3072_4), 203169695Skan RUN_DEV(LINKSYS4, RT3070), 204169695Skan RUN_DEV(LINKSYS4, WUSB100), 205169695Skan RUN_DEV(LINKSYS4, WUSB54GCV3), 206169695Skan RUN_DEV(LINKSYS4, WUSB600N), 207169695Skan RUN_DEV(LINKSYS4, WUSB600NV2), 208169695Skan RUN_DEV(LOGITEC, RT2870_1), 209169695Skan RUN_DEV(LOGITEC, RT2870_2), 210169695Skan RUN_DEV(LOGITEC, RT2870_3), 211169695Skan RUN_DEV(MELCO, RT2870_1), 212169695Skan RUN_DEV(MELCO, RT2870_2), 213169695Skan RUN_DEV(MELCO, WLIUCAG300N), 214169695Skan RUN_DEV(MELCO, WLIUCG300N), 215169695Skan RUN_DEV(MELCO, WLIUCG301N), 216169695Skan RUN_DEV(MELCO, WLIUCGN), 217169695Skan RUN_DEV(MOTOROLA4, RT2770), 218169695Skan RUN_DEV(MOTOROLA4, RT3070), 219169695Skan RUN_DEV(MSI, RT3070_1), 220169695Skan RUN_DEV(MSI, RT3070_2), 221169695Skan RUN_DEV(MSI, RT3070_3), 222169695Skan RUN_DEV(MSI, RT3070_4), 223169695Skan RUN_DEV(MSI, RT3070_5), 224169695Skan RUN_DEV(MSI, RT3070_6), 225169695Skan RUN_DEV(MSI, RT3070_7), 226169695Skan RUN_DEV(MSI, RT3070_8), 227169695Skan RUN_DEV(MSI, RT3070_9), 228169695Skan RUN_DEV(MSI, RT3070_10), 229169695Skan RUN_DEV(MSI, RT3070_11), 230169695Skan RUN_DEV(OVISLINK, RT3072), 231169695Skan RUN_DEV(PARA, RT3070), 232169695Skan RUN_DEV(PEGATRON, RT2870), 233169695Skan RUN_DEV(PEGATRON, RT3070), 234169695Skan RUN_DEV(PEGATRON, RT3070_2), 235169695Skan RUN_DEV(PEGATRON, RT3070_3), 236169695Skan RUN_DEV(PHILIPS, RT2870), 237169695Skan RUN_DEV(PLANEX2, GWUS300MINIS), 238169695Skan RUN_DEV(PLANEX2, GWUSMICRON), 239169695Skan RUN_DEV(PLANEX2, RT2870), 240169695Skan RUN_DEV(PLANEX2, RT3070), 241169695Skan RUN_DEV(QCOM, RT2870), 242169695Skan RUN_DEV(QUANTA, RT3070), 243169695Skan RUN_DEV(RALINK, RT2070), 244169695Skan RUN_DEV(RALINK, RT2770), 245169695Skan RUN_DEV(RALINK, RT2870), 246169695Skan RUN_DEV(RALINK, RT3070), 247169695Skan RUN_DEV(RALINK, RT3071), 248169695Skan RUN_DEV(RALINK, RT3072), 249169695Skan RUN_DEV(RALINK, RT3370), 250169695Skan RUN_DEV(RALINK, RT3572), 251169695Skan RUN_DEV(RALINK, RT8070), 252169695Skan RUN_DEV(SAMSUNG, WIS09ABGN), 253169695Skan RUN_DEV(SAMSUNG2, RT2870_1), 254169695Skan RUN_DEV(SENAO, RT2870_1), 255169695Skan RUN_DEV(SENAO, RT2870_2), 256169695Skan RUN_DEV(SENAO, RT2870_3), 257169695Skan RUN_DEV(SENAO, RT2870_4), 258169695Skan RUN_DEV(SENAO, RT3070), 259169695Skan RUN_DEV(SENAO, RT3071), 260169695Skan RUN_DEV(SENAO, RT3072_1), 261169695Skan RUN_DEV(SENAO, RT3072_2), 262169695Skan RUN_DEV(SENAO, RT3072_3), 263169695Skan RUN_DEV(SENAO, RT3072_4), 264169695Skan RUN_DEV(SENAO, RT3072_5), 265169695Skan RUN_DEV(SITECOMEU, RT2770), 266169695Skan RUN_DEV(SITECOMEU, RT2870_1), 267169695Skan RUN_DEV(SITECOMEU, RT2870_2), 268169695Skan RUN_DEV(SITECOMEU, RT2870_3), 269169695Skan RUN_DEV(SITECOMEU, RT2870_4), 270169695Skan RUN_DEV(SITECOMEU, RT3070), 271169695Skan RUN_DEV(SITECOMEU, RT3070_2), 272169695Skan RUN_DEV(SITECOMEU, RT3070_3), 273169695Skan RUN_DEV(SITECOMEU, RT3070_4), 274169695Skan RUN_DEV(SITECOMEU, RT3071), 275169695Skan RUN_DEV(SITECOMEU, RT3072_1), 276169695Skan RUN_DEV(SITECOMEU, RT3072_2), 277169695Skan RUN_DEV(SITECOMEU, RT3072_3), 278169695Skan RUN_DEV(SITECOMEU, RT3072_4), 279169695Skan RUN_DEV(SITECOMEU, RT3072_5), 280169695Skan RUN_DEV(SITECOMEU, RT3072_6), 281169695Skan RUN_DEV(SITECOMEU, WL608), 282169695Skan RUN_DEV(SPARKLAN, RT2870_1), 283169695Skan RUN_DEV(SPARKLAN, RT3070), 284169695Skan RUN_DEV(SWEEX2, LW153), 285169695Skan RUN_DEV(SWEEX2, LW303), 286169695Skan RUN_DEV(SWEEX2, LW313), 287169695Skan RUN_DEV(TOSHIBA, RT3070), 288169695Skan RUN_DEV(UMEDIA, RT2870_1), 289169695Skan RUN_DEV(ZCOM, RT2870_1), 290169695Skan RUN_DEV(ZCOM, RT2870_2), 291169695Skan RUN_DEV(ZINWELL, RT2870_1), 292169695Skan RUN_DEV(ZINWELL, RT2870_2), 293169695Skan RUN_DEV(ZINWELL, RT3070), 294169695Skan RUN_DEV(ZINWELL, RT3072_1), 295169695Skan RUN_DEV(ZINWELL, RT3072_2), 296169695Skan RUN_DEV(ZYXEL, RT2870_1), 297169695Skan RUN_DEV(ZYXEL, RT2870_2), 298169695Skan#undef RUN_DEV 299169695Skan}; 300169695Skan 301169695Skanstatic device_probe_t run_match; 302169695Skanstatic device_attach_t run_attach; 303169695Skanstatic device_detach_t run_detach; 304169695Skan 305169695Skanstatic usb_callback_t run_bulk_rx_callback; 306169695Skanstatic usb_callback_t run_bulk_tx_callback0; 307169695Skanstatic usb_callback_t run_bulk_tx_callback1; 308169695Skanstatic usb_callback_t run_bulk_tx_callback2; 309169695Skanstatic usb_callback_t run_bulk_tx_callback3; 310169695Skanstatic usb_callback_t run_bulk_tx_callback4; 311169695Skanstatic usb_callback_t run_bulk_tx_callback5; 312169695Skan 313169695Skanstatic void run_bulk_tx_callbackN(struct usb_xfer *xfer, 314169695Skan usb_error_t error, unsigned int index); 315169695Skanstatic struct ieee80211vap *run_vap_create(struct ieee80211com *, 316169695Skan const char name[IFNAMSIZ], int unit, int opmode, int flags, 317169695Skan const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t 318169695Skan mac[IEEE80211_ADDR_LEN]); 319169695Skanstatic void run_vap_delete(struct ieee80211vap *); 320169695Skanstatic void run_cmdq_cb(void *, int); 321169695Skanstatic void run_setup_tx_list(struct run_softc *, 322169695Skan struct run_endpoint_queue *); 323169695Skanstatic void run_unsetup_tx_list(struct run_softc *, 324169695Skan struct run_endpoint_queue *); 325169695Skanstatic int run_load_microcode(struct run_softc *); 326169695Skanstatic int run_reset(struct run_softc *); 327169695Skanstatic usb_error_t run_do_request(struct run_softc *, 328169695Skan struct usb_device_request *, void *); 329169695Skanstatic int run_read(struct run_softc *, uint16_t, uint32_t *); 330169695Skanstatic int run_read_region_1(struct run_softc *, uint16_t, uint8_t *, int); 331169695Skanstatic int run_write_2(struct run_softc *, uint16_t, uint16_t); 332169695Skanstatic int run_write(struct run_softc *, uint16_t, uint32_t); 333169695Skanstatic int run_write_region_1(struct run_softc *, uint16_t, 334169695Skan const uint8_t *, int); 335169695Skanstatic int run_set_region_4(struct run_softc *, uint16_t, uint32_t, int); 336169695Skanstatic int run_efuse_read_2(struct run_softc *, uint16_t, uint16_t *); 337169695Skanstatic int run_eeprom_read_2(struct run_softc *, uint16_t, uint16_t *); 338169695Skanstatic int run_rt2870_rf_write(struct run_softc *, uint8_t, uint32_t); 339169695Skanstatic int run_rt3070_rf_read(struct run_softc *, uint8_t, uint8_t *); 340169695Skanstatic int run_rt3070_rf_write(struct run_softc *, uint8_t, uint8_t); 341169695Skanstatic int run_bbp_read(struct run_softc *, uint8_t, uint8_t *); 342169695Skanstatic int run_bbp_write(struct run_softc *, uint8_t, uint8_t); 343169695Skanstatic int run_mcu_cmd(struct run_softc *, uint8_t, uint16_t); 344169695Skanstatic const char *run_get_rf(int); 345169695Skanstatic int run_read_eeprom(struct run_softc *); 346169695Skanstatic struct ieee80211_node *run_node_alloc(struct ieee80211vap *, 347169695Skan const uint8_t mac[IEEE80211_ADDR_LEN]); 348169695Skanstatic int run_media_change(struct ifnet *); 349169695Skanstatic int run_newstate(struct ieee80211vap *, enum ieee80211_state, int); 350169695Skanstatic int run_wme_update(struct ieee80211com *); 351169695Skanstatic void run_wme_update_cb(void *); 352169695Skanstatic void run_key_update_begin(struct ieee80211vap *); 353169695Skanstatic void run_key_update_end(struct ieee80211vap *); 354169695Skanstatic void run_key_set_cb(void *); 355169695Skanstatic int run_key_set(struct ieee80211vap *, struct ieee80211_key *, 356169695Skan const uint8_t mac[IEEE80211_ADDR_LEN]); 357169695Skanstatic void run_key_delete_cb(void *); 358169695Skanstatic int run_key_delete(struct ieee80211vap *, struct ieee80211_key *); 359169695Skanstatic void run_ratectl_to(void *); 360169695Skanstatic void run_ratectl_cb(void *, int); 361169695Skanstatic void run_drain_fifo(void *); 362169695Skanstatic void run_iter_func(void *, struct ieee80211_node *); 363169695Skanstatic void run_newassoc_cb(void *); 364169695Skanstatic void run_newassoc(struct ieee80211_node *, int); 365169695Skanstatic void run_rx_frame(struct run_softc *, struct mbuf *, uint32_t); 366169695Skanstatic void run_tx_free(struct run_endpoint_queue *pq, 367169695Skan struct run_tx_data *, int); 368169695Skanstatic void run_set_tx_desc(struct run_softc *, struct run_tx_data *); 369169695Skanstatic int run_tx(struct run_softc *, struct mbuf *, 370169695Skan struct ieee80211_node *); 371169695Skanstatic int run_tx_mgt(struct run_softc *, struct mbuf *, 372169695Skan struct ieee80211_node *); 373169695Skanstatic int run_sendprot(struct run_softc *, const struct mbuf *, 374169695Skan struct ieee80211_node *, int, int); 375169695Skanstatic int run_tx_param(struct run_softc *, struct mbuf *, 376169695Skan struct ieee80211_node *, 377169695Skan const struct ieee80211_bpf_params *); 378169695Skanstatic int run_raw_xmit(struct ieee80211_node *, struct mbuf *, 379169695Skan const struct ieee80211_bpf_params *); 380169695Skanstatic void run_start(struct ifnet *); 381169695Skanstatic int run_ioctl(struct ifnet *, u_long, caddr_t); 382169695Skanstatic void run_set_agc(struct run_softc *, uint8_t); 383169695Skanstatic void run_select_chan_group(struct run_softc *, int); 384169695Skanstatic void run_set_rx_antenna(struct run_softc *, int); 385169695Skanstatic void run_rt2870_set_chan(struct run_softc *, u_int); 386169695Skanstatic void run_rt3070_set_chan(struct run_softc *, u_int); 387169695Skanstatic void run_rt3572_set_chan(struct run_softc *, u_int); 388169695Skanstatic int run_set_chan(struct run_softc *, struct ieee80211_channel *); 389169695Skanstatic void run_set_channel(struct ieee80211com *); 390169695Skanstatic void run_scan_start(struct ieee80211com *); 391169695Skanstatic void run_scan_end(struct ieee80211com *); 392169695Skanstatic void run_update_beacon(struct ieee80211vap *, int); 393169695Skanstatic void run_update_beacon_cb(void *); 394169695Skanstatic void run_updateprot(struct ieee80211com *); 395169695Skanstatic void run_updateprot_cb(void *); 396169695Skanstatic void run_usb_timeout_cb(void *); 397169695Skanstatic void run_reset_livelock(struct run_softc *); 398169695Skanstatic void run_enable_tsf_sync(struct run_softc *); 399169695Skanstatic void run_enable_mrr(struct run_softc *); 400169695Skanstatic void run_set_txpreamble(struct run_softc *); 401169695Skanstatic void run_set_basicrates(struct run_softc *); 402169695Skanstatic void run_set_leds(struct run_softc *, uint16_t); 403169695Skanstatic void run_set_bssid(struct run_softc *, const uint8_t *); 404169695Skanstatic void run_set_macaddr(struct run_softc *, const uint8_t *); 405169695Skanstatic void run_updateslot(struct ifnet *); 406169695Skanstatic void run_updateslot_cb(void *); 407169695Skanstatic void run_update_mcast(struct ifnet *); 408169695Skanstatic int8_t run_rssi2dbm(struct run_softc *, uint8_t, uint8_t); 409169695Skanstatic void run_update_promisc_locked(struct ifnet *); 410169695Skanstatic void run_update_promisc(struct ifnet *); 411169695Skanstatic int run_bbp_init(struct run_softc *); 412169695Skanstatic int run_rt3070_rf_init(struct run_softc *); 413169695Skanstatic int run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t, 414169695Skan uint8_t *); 415169695Skanstatic void run_rt3070_rf_setup(struct run_softc *); 416169695Skanstatic int run_txrx_enable(struct run_softc *); 417169695Skanstatic void run_init(void *); 418169695Skanstatic void run_init_locked(struct run_softc *); 419169695Skanstatic void run_stop(void *); 420169695Skanstatic void run_delay(struct run_softc *, unsigned int); 421169695Skan 422169695Skanstatic const struct { 423169695Skan uint16_t reg; 424169695Skan uint32_t val; 425169695Skan} rt2870_def_mac[] = { 426169695Skan RT2870_DEF_MAC 427169695Skan}; 428169695Skan 429169695Skanstatic const struct { 430169695Skan uint8_t reg; 431169695Skan uint8_t val; 432169695Skan} rt2860_def_bbp[] = { 433169695Skan RT2860_DEF_BBP 434169695Skan}; 435169695Skan 436169695Skanstatic const struct rfprog { 437169695Skan uint8_t chan; 438169695Skan uint32_t r1, r2, r3, r4; 439169695Skan} rt2860_rf2850[] = { 440169695Skan RT2860_RF2850 441169695Skan}; 442169695Skan 443169695Skanstruct { 444169695Skan uint8_t n, r, k; 445169695Skan} rt3070_freqs[] = { 446169695Skan RT3070_RF3052 447169695Skan}; 448169695Skan 449169695Skanstatic const struct { 450169695Skan uint8_t reg; 451169695Skan uint8_t val; 452169695Skan} rt3070_def_rf[] = { 453169695Skan RT3070_DEF_RF 454169695Skan},rt3572_def_rf[] = { 455169695Skan RT3572_DEF_RF 456169695Skan}; 457169695Skan 458169695Skanstatic const struct usb_config run_config[RUN_N_XFER] = { 459169695Skan [RUN_BULK_TX_BE] = { 460169695Skan .type = UE_BULK, 461169695Skan .endpoint = UE_ADDR_ANY, 462169695Skan .ep_index = 0, 463169695Skan .direction = UE_DIR_OUT, 464169695Skan .bufsize = RUN_MAX_TXSZ, 465169695Skan .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 466169695Skan .callback = run_bulk_tx_callback0, 467169695Skan .timeout = 5000, /* ms */ 468169695Skan }, 469169695Skan [RUN_BULK_TX_BK] = { 470169695Skan .type = UE_BULK, 471169695Skan .endpoint = UE_ADDR_ANY, 472169695Skan .direction = UE_DIR_OUT, 473169695Skan .ep_index = 1, 474169695Skan .bufsize = RUN_MAX_TXSZ, 475169695Skan .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 476169695Skan .callback = run_bulk_tx_callback1, 477169695Skan .timeout = 5000, /* ms */ 478169695Skan }, 479169695Skan [RUN_BULK_TX_VI] = { 480169695Skan .type = UE_BULK, 481169695Skan .endpoint = UE_ADDR_ANY, 482169695Skan .direction = UE_DIR_OUT, 483169695Skan .ep_index = 2, 484169695Skan .bufsize = RUN_MAX_TXSZ, 485169695Skan .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 486169695Skan .callback = run_bulk_tx_callback2, 487169695Skan .timeout = 5000, /* ms */ 488169695Skan }, 489169695Skan [RUN_BULK_TX_VO] = { 490169695Skan .type = UE_BULK, 491169695Skan .endpoint = UE_ADDR_ANY, 492169695Skan .direction = UE_DIR_OUT, 493169695Skan .ep_index = 3, 494169695Skan .bufsize = RUN_MAX_TXSZ, 495169695Skan .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 496169695Skan .callback = run_bulk_tx_callback3, 497169695Skan .timeout = 5000, /* ms */ 498169695Skan }, 499169695Skan [RUN_BULK_TX_HCCA] = { 500169695Skan .type = UE_BULK, 501169695Skan .endpoint = UE_ADDR_ANY, 502169695Skan .direction = UE_DIR_OUT, 503169695Skan .ep_index = 4, 504169695Skan .bufsize = RUN_MAX_TXSZ, 505169695Skan .flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,}, 506169695Skan .callback = run_bulk_tx_callback4, 507169695Skan .timeout = 5000, /* ms */ 508169695Skan }, 509169695Skan [RUN_BULK_TX_PRIO] = { 510169695Skan .type = UE_BULK, 511169695Skan .endpoint = UE_ADDR_ANY, 512169695Skan .direction = UE_DIR_OUT, 513169695Skan .ep_index = 5, 514169695Skan .bufsize = RUN_MAX_TXSZ, 515169695Skan .flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,}, 516169695Skan .callback = run_bulk_tx_callback5, 517169695Skan .timeout = 5000, /* ms */ 518169695Skan }, 519169695Skan [RUN_BULK_RX] = { 520169695Skan .type = UE_BULK, 521169695Skan .endpoint = UE_ADDR_ANY, 522169695Skan .direction = UE_DIR_IN, 523169695Skan .bufsize = RUN_MAX_RXSZ, 524169695Skan .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 525169695Skan .callback = run_bulk_rx_callback, 526169695Skan } 527169695Skan}; 528169695Skan 529169695Skanstatic int 530169695Skanrun_match(device_t self) 531169695Skan{ 532169695Skan struct usb_attach_arg *uaa = device_get_ivars(self); 533169695Skan 534169695Skan if (uaa->usb_mode != USB_MODE_HOST) 535169695Skan return (ENXIO); 536169695Skan if (uaa->info.bConfigIndex != 0) 537169695Skan return (ENXIO); 538169695Skan if (uaa->info.bIfaceIndex != RT2860_IFACE_INDEX) 539169695Skan return (ENXIO); 540169695Skan 541169695Skan return (usbd_lookup_id_by_uaa(run_devs, sizeof(run_devs), uaa)); 542169695Skan} 543169695Skan 544169695Skanstatic int 545169695Skanrun_attach(device_t self) 546169695Skan{ 547169695Skan struct run_softc *sc = device_get_softc(self); 548169695Skan struct usb_attach_arg *uaa = device_get_ivars(self); 549169695Skan struct ieee80211com *ic; 550169695Skan struct ifnet *ifp; 551169695Skan uint32_t ver; 552169695Skan int i, ntries, error; 553169695Skan uint8_t iface_index, bands; 554169695Skan 555169695Skan device_set_usb_desc(self); 556169695Skan sc->sc_udev = uaa->device; 557169695Skan sc->sc_dev = self; 558169695Skan 559169695Skan mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), 560169695Skan MTX_NETWORK_LOCK, MTX_DEF); 561169695Skan 562169695Skan iface_index = RT2860_IFACE_INDEX; 563169695Skan 564169695Skan error = usbd_transfer_setup(uaa->device, &iface_index, 565169695Skan sc->sc_xfer, run_config, RUN_N_XFER, sc, &sc->sc_mtx); 566169695Skan if (error) { 567169695Skan device_printf(self, "could not allocate USB transfers, " 568169695Skan "err=%s\n", usbd_errstr(error)); 569169695Skan goto detach; 570169695Skan } 571169695Skan 572169695Skan RUN_LOCK(sc); 573169695Skan 574169695Skan /* wait for the chip to settle */ 575169695Skan for (ntries = 0; ntries < 100; ntries++) { 576169695Skan if (run_read(sc, RT2860_ASIC_VER_ID, &ver) != 0) { 577169695Skan RUN_UNLOCK(sc); 578169695Skan goto detach; 579169695Skan } 580169695Skan if (ver != 0 && ver != 0xffffffff) 581169695Skan break; 582169695Skan run_delay(sc, 10); 583169695Skan } 584169695Skan if (ntries == 100) { 585169695Skan device_printf(sc->sc_dev, 586169695Skan "timeout waiting for NIC to initialize\n"); 587169695Skan RUN_UNLOCK(sc); 588169695Skan goto detach; 589169695Skan } 590169695Skan sc->mac_ver = ver >> 16; 591169695Skan sc->mac_rev = ver & 0xffff; 592169695Skan 593169695Skan /* retrieve RF rev. no and various other things from EEPROM */ 594169695Skan run_read_eeprom(sc); 595169695Skan 596169695Skan device_printf(sc->sc_dev, 597169695Skan "MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), address %s\n", 598169695Skan sc->mac_ver, sc->mac_rev, run_get_rf(sc->rf_rev), 599169695Skan sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid)); 600169695Skan 601169695Skan if ((error = run_load_microcode(sc)) != 0) { 602169695Skan device_printf(sc->sc_dev, "could not load 8051 microcode\n"); 603169695Skan RUN_UNLOCK(sc); 604169695Skan goto detach; 605169695Skan } 606169695Skan 607169695Skan RUN_UNLOCK(sc); 608169695Skan 609169695Skan ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 610169695Skan if (ifp == NULL) { 611169695Skan device_printf(sc->sc_dev, "can not if_alloc()\n"); 612169695Skan goto detach; 613169695Skan } 614169695Skan ic = ifp->if_l2com; 615169695Skan 616169695Skan ifp->if_softc = sc; 617169695Skan if_initname(ifp, "run", device_get_unit(sc->sc_dev)); 618169695Skan ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 619169695Skan ifp->if_init = run_init; 620169695Skan ifp->if_ioctl = run_ioctl; 621169695Skan ifp->if_start = run_start; 622169695Skan IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 623169695Skan ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 624169695Skan IFQ_SET_READY(&ifp->if_snd); 625169695Skan 626169695Skan ic->ic_ifp = ifp; 627169695Skan ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 628169695Skan ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 629169695Skan 630169695Skan /* set device capabilities */ 631169695Skan ic->ic_caps = 632169695Skan IEEE80211_C_STA | /* station mode supported */ 633169695Skan IEEE80211_C_MONITOR | /* monitor mode supported */ 634169695Skan IEEE80211_C_IBSS | 635169695Skan IEEE80211_C_HOSTAP | 636169695Skan IEEE80211_C_WDS | /* 4-address traffic works */ 637169695Skan IEEE80211_C_MBSS | 638169695Skan IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 639169695Skan IEEE80211_C_SHSLOT | /* short slot time supported */ 640169695Skan IEEE80211_C_WME | /* WME */ 641169695Skan IEEE80211_C_WPA; /* WPA1|WPA2(RSN) */ 642169695Skan 643169695Skan ic->ic_cryptocaps = 644169695Skan IEEE80211_CRYPTO_WEP | 645169695Skan IEEE80211_CRYPTO_AES_CCM | 646169695Skan IEEE80211_CRYPTO_TKIPMIC | 647169695Skan IEEE80211_CRYPTO_TKIP; 648169695Skan 649169695Skan ic->ic_flags |= IEEE80211_F_DATAPAD; 650169695Skan ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; 651169695Skan 652169695Skan bands = 0; 653169695Skan setbit(&bands, IEEE80211_MODE_11B); 654169695Skan setbit(&bands, IEEE80211_MODE_11G); 655169695Skan ieee80211_init_channels(ic, NULL, &bands); 656169695Skan 657169695Skan /* 658169695Skan * Do this by own because h/w supports 659169695Skan * more channels than ieee80211_init_channels() 660169695Skan */ 661169695Skan if (sc->rf_rev == RT2860_RF_2750 || 662169695Skan sc->rf_rev == RT2860_RF_2850 || 663169695Skan sc->rf_rev == RT3070_RF_3052) { 664169695Skan /* set supported .11a rates */ 665169695Skan for (i = 14; i < nitems(rt2860_rf2850); i++) { 666169695Skan uint8_t chan = rt2860_rf2850[i].chan; 667169695Skan ic->ic_channels[ic->ic_nchans].ic_freq = 668169695Skan ieee80211_ieee2mhz(chan, IEEE80211_CHAN_A); 669169695Skan ic->ic_channels[ic->ic_nchans].ic_ieee = chan; 670169695Skan ic->ic_channels[ic->ic_nchans].ic_flags = IEEE80211_CHAN_A; 671169695Skan ic->ic_channels[ic->ic_nchans].ic_extieee = 0; 672169695Skan ic->ic_nchans++; 673169695Skan } 674169695Skan } 675169695Skan 676169695Skan ieee80211_ifattach(ic, sc->sc_bssid); 677169695Skan 678169695Skan ic->ic_scan_start = run_scan_start; 679169695Skan ic->ic_scan_end = run_scan_end; 680169695Skan ic->ic_set_channel = run_set_channel; 681169695Skan ic->ic_node_alloc = run_node_alloc; 682169695Skan ic->ic_newassoc = run_newassoc; 683169695Skan ic->ic_updateslot = run_updateslot; 684169695Skan ic->ic_update_mcast = run_update_mcast; 685169695Skan ic->ic_wme.wme_update = run_wme_update; 686169695Skan ic->ic_raw_xmit = run_raw_xmit; 687169695Skan ic->ic_update_promisc = run_update_promisc; 688169695Skan 689169695Skan ic->ic_vap_create = run_vap_create; 690169695Skan ic->ic_vap_delete = run_vap_delete; 691169695Skan 692169695Skan ieee80211_radiotap_attach(ic, 693169695Skan &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), 694169695Skan RUN_TX_RADIOTAP_PRESENT, 695169695Skan &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), 696169695Skan RUN_RX_RADIOTAP_PRESENT); 697169695Skan 698169695Skan TASK_INIT(&sc->cmdq_task, 0, run_cmdq_cb, sc); 699169695Skan TASK_INIT(&sc->ratectl_task, 0, run_ratectl_cb, sc); 700169695Skan callout_init((struct callout *)&sc->ratectl_ch, 1); 701169695Skan 702169695Skan if (bootverbose) 703169695Skan ieee80211_announce(ic); 704169695Skan 705169695Skan return (0); 706169695Skan 707169695Skandetach: 708169695Skan run_detach(self); 709169695Skan return (ENXIO); 710169695Skan} 711169695Skan 712169695Skanstatic int 713169695Skanrun_detach(device_t self) 714169695Skan{ 715169695Skan struct run_softc *sc = device_get_softc(self); 716169695Skan struct ifnet *ifp = sc->sc_ifp; 717169695Skan struct ieee80211com *ic; 718169695Skan int i; 719169695Skan 720169695Skan /* stop all USB transfers */ 721169695Skan usbd_transfer_unsetup(sc->sc_xfer, RUN_N_XFER); 722169695Skan 723169695Skan RUN_LOCK(sc); 724169695Skan 725169695Skan sc->ratectl_run = RUN_RATECTL_OFF; 726169695Skan sc->cmdq_run = sc->cmdq_key_set = RUN_CMDQ_ABORT; 727169695Skan 728169695Skan /* free TX list, if any */ 729169695Skan for (i = 0; i != RUN_EP_QUEUES; i++) 730169695Skan run_unsetup_tx_list(sc, &sc->sc_epq[i]); 731169695Skan RUN_UNLOCK(sc); 732169695Skan 733169695Skan if (ifp) { 734169695Skan ic = ifp->if_l2com; 735169695Skan /* drain tasks */ 736169695Skan usb_callout_drain(&sc->ratectl_ch); 737169695Skan ieee80211_draintask(ic, &sc->cmdq_task); 738169695Skan ieee80211_draintask(ic, &sc->ratectl_task); 739169695Skan ieee80211_ifdetach(ic); 740169695Skan if_free(ifp); 741169695Skan } 742169695Skan 743169695Skan mtx_destroy(&sc->sc_mtx); 744169695Skan 745169695Skan return (0); 746169695Skan} 747169695Skan 748169695Skanstatic struct ieee80211vap * 749169695Skanrun_vap_create(struct ieee80211com *ic, 750169695Skan const char name[IFNAMSIZ], int unit, int opmode, int flags, 751169695Skan const uint8_t bssid[IEEE80211_ADDR_LEN], 752169695Skan const uint8_t mac[IEEE80211_ADDR_LEN]) 753169695Skan{ 754169695Skan struct ifnet *ifp = ic->ic_ifp; 755169695Skan struct run_softc *sc = ifp->if_softc; 756169695Skan struct run_vap *rvp; 757169695Skan struct ieee80211vap *vap; 758169695Skan int i; 759169695Skan 760169695Skan if (sc->rvp_cnt >= RUN_VAP_MAX) { 761169695Skan if_printf(ifp, "number of VAPs maxed out\n"); 762169695Skan return (NULL); 763169695Skan } 764169695Skan 765169695Skan switch (opmode) { 766169695Skan case IEEE80211_M_STA: 767169695Skan /* enable s/w bmiss handling for sta mode */ 768169695Skan flags |= IEEE80211_CLONE_NOBEACONS; 769169695Skan /* fall though */ 770169695Skan case IEEE80211_M_IBSS: 771169695Skan case IEEE80211_M_MONITOR: 772169695Skan case IEEE80211_M_HOSTAP: 773169695Skan case IEEE80211_M_MBSS: 774169695Skan /* other than WDS vaps, only one at a time */ 775169695Skan if (!TAILQ_EMPTY(&ic->ic_vaps)) 776169695Skan return (NULL); 777169695Skan break; 778169695Skan case IEEE80211_M_WDS: 779169695Skan TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next){ 780169695Skan if(vap->iv_opmode != IEEE80211_M_HOSTAP) 781169695Skan continue; 782169695Skan /* WDS vap's always share the local mac address. */ 783169695Skan flags &= ~IEEE80211_CLONE_BSSID; 784169695Skan break; 785169695Skan } 786169695Skan if (vap == NULL) { 787169695Skan if_printf(ifp, "wds only supported in ap mode\n"); 788169695Skan return (NULL); 789169695Skan } 790169695Skan break; 791169695Skan default: 792169695Skan if_printf(ifp, "unknown opmode %d\n", opmode); 793169695Skan return (NULL); 794169695Skan } 795169695Skan 796169695Skan rvp = (struct run_vap *) malloc(sizeof(struct run_vap), 797169695Skan M_80211_VAP, M_NOWAIT | M_ZERO); 798169695Skan if (rvp == NULL) 799169695Skan return (NULL); 800169695Skan vap = &rvp->vap; 801169695Skan ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 802169695Skan 803169695Skan vap->iv_key_update_begin = run_key_update_begin; 804169695Skan vap->iv_key_update_end = run_key_update_end; 805169695Skan vap->iv_update_beacon = run_update_beacon; 806169695Skan vap->iv_max_aid = RT2870_WCID_MAX; 807169695Skan /* 808169695Skan * To delete the right key from h/w, we need wcid. 809169695Skan * Luckily, there is unused space in ieee80211_key{}, wk_pad, 810169695Skan * and matching wcid will be written into there. So, cast 811169695Skan * some spells to remove 'const' from ieee80211_key{} 812169695Skan */ 813169695Skan vap->iv_key_delete = (void *)run_key_delete; 814169695Skan vap->iv_key_set = (void *)run_key_set; 815169695Skan 816169695Skan /* override state transition machine */ 817169695Skan rvp->newstate = vap->iv_newstate; 818169695Skan vap->iv_newstate = run_newstate; 819169695Skan 820169695Skan ieee80211_ratectl_init(vap); 821169695Skan ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */); 822169695Skan 823169695Skan /* complete setup */ 824169695Skan ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status); 825169695Skan 826169695Skan /* make sure id is always unique */ 827169695Skan for (i = 0; i < RUN_VAP_MAX; i++) { 828169695Skan if((sc->rvp_bmap & 1 << i) == 0){ 829169695Skan sc->rvp_bmap |= 1 << i; 830169695Skan rvp->rvp_id = i; 831169695Skan break; 832169695Skan } 833169695Skan } 834169695Skan if (sc->rvp_cnt++ == 0) 835169695Skan ic->ic_opmode = opmode; 836169695Skan 837169695Skan if (opmode == IEEE80211_M_HOSTAP) 838169695Skan sc->cmdq_run = RUN_CMDQ_GO; 839169695Skan 840169695Skan DPRINTF("rvp_id=%d bmap=%x rvp_cnt=%d\n", 841169695Skan rvp->rvp_id, sc->rvp_bmap, sc->rvp_cnt); 842169695Skan 843169695Skan return (vap); 844169695Skan} 845169695Skan 846169695Skanstatic void 847169695Skanrun_vap_delete(struct ieee80211vap *vap) 848169695Skan{ 849169695Skan struct run_vap *rvp = RUN_VAP(vap); 850169695Skan struct ifnet *ifp; 851169695Skan struct ieee80211com *ic; 852169695Skan struct run_softc *sc; 853169695Skan uint8_t rvp_id; 854169695Skan 855169695Skan if (vap == NULL) 856169695Skan return; 857169695Skan 858169695Skan ic = vap->iv_ic; 859169695Skan ifp = ic->ic_ifp; 860169695Skan 861169695Skan sc = ifp->if_softc; 862169695Skan 863169695Skan RUN_LOCK(sc); 864169695Skan 865169695Skan m_freem(rvp->beacon_mbuf); 866169695Skan rvp->beacon_mbuf = NULL; 867169695Skan 868169695Skan rvp_id = rvp->rvp_id; 869169695Skan sc->ratectl_run &= ~(1 << rvp_id); 870169695Skan sc->rvp_bmap &= ~(1 << rvp_id); 871169695Skan run_set_region_4(sc, RT2860_SKEY(rvp_id, 0), 0, 128); 872169695Skan run_set_region_4(sc, RT2860_BCN_BASE(rvp_id), 0, 512); 873169695Skan --sc->rvp_cnt; 874169695Skan 875169695Skan DPRINTF("vap=%p rvp_id=%d bmap=%x rvp_cnt=%d\n", 876169695Skan vap, rvp_id, sc->rvp_bmap, sc->rvp_cnt); 877169695Skan 878169695Skan RUN_UNLOCK(sc); 879169695Skan 880169695Skan ieee80211_ratectl_deinit(vap); 881169695Skan ieee80211_vap_detach(vap); 882169695Skan free(rvp, M_80211_VAP); 883169695Skan} 884169695Skan 885169695Skan/* 886169695Skan * There are numbers of functions need to be called in context thread. 887169695Skan * Rather than creating taskqueue event for each of those functions, 888169695Skan * here is all-for-one taskqueue callback function. This function 889169695Skan * gurantees deferred functions are executed in the same order they 890169695Skan * were enqueued. 891169695Skan * '& RUN_CMDQ_MASQ' is to loop cmdq[]. 892169695Skan */ 893169695Skanstatic void 894169695Skanrun_cmdq_cb(void *arg, int pending) 895169695Skan{ 896169695Skan struct run_softc *sc = arg; 897169695Skan uint8_t i; 898169695Skan 899169695Skan /* call cmdq[].func locked */ 900169695Skan RUN_LOCK(sc); 901169695Skan for (i = sc->cmdq_exec; sc->cmdq[i].func && pending; 902169695Skan i = sc->cmdq_exec, pending--) { 903169695Skan DPRINTFN(6, "cmdq_exec=%d pending=%d\n", i, pending); 904169695Skan if (sc->cmdq_run == RUN_CMDQ_GO) { 905169695Skan /* 906169695Skan * If arg0 is NULL, callback func needs more 907169695Skan * than one arg. So, pass ptr to cmdq struct. 908169695Skan */ 909169695Skan if (sc->cmdq[i].arg0) 910169695Skan sc->cmdq[i].func(sc->cmdq[i].arg0); 911169695Skan else 912169695Skan sc->cmdq[i].func(&sc->cmdq[i]); 913169695Skan } 914169695Skan sc->cmdq[i].arg0 = NULL; 915169695Skan sc->cmdq[i].func = NULL; 916169695Skan sc->cmdq_exec++; 917169695Skan sc->cmdq_exec &= RUN_CMDQ_MASQ; 918169695Skan } 919169695Skan RUN_UNLOCK(sc); 920169695Skan} 921169695Skan 922169695Skanstatic void 923169695Skanrun_setup_tx_list(struct run_softc *sc, struct run_endpoint_queue *pq) 924169695Skan{ 925169695Skan struct run_tx_data *data; 926169695Skan 927169695Skan memset(pq, 0, sizeof(*pq)); 928169695Skan 929169695Skan STAILQ_INIT(&pq->tx_qh); 930169695Skan STAILQ_INIT(&pq->tx_fh); 931169695Skan 932169695Skan for (data = &pq->tx_data[0]; 933169695Skan data < &pq->tx_data[RUN_TX_RING_COUNT]; data++) { 934169695Skan data->sc = sc; 935169695Skan STAILQ_INSERT_TAIL(&pq->tx_fh, data, next); 936169695Skan } 937169695Skan pq->tx_nfree = RUN_TX_RING_COUNT; 938169695Skan} 939169695Skan 940169695Skanstatic void 941169695Skanrun_unsetup_tx_list(struct run_softc *sc, struct run_endpoint_queue *pq) 942169695Skan{ 943169695Skan struct run_tx_data *data; 944169695Skan 945169695Skan /* make sure any subsequent use of the queues will fail */ 946169695Skan pq->tx_nfree = 0; 947169695Skan STAILQ_INIT(&pq->tx_fh); 948169695Skan STAILQ_INIT(&pq->tx_qh); 949169695Skan 950169695Skan /* free up all node references and mbufs */ 951169695Skan for (data = &pq->tx_data[0]; 952169695Skan data < &pq->tx_data[RUN_TX_RING_COUNT]; data++) { 953169695Skan if (data->m != NULL) { 954169695Skan m_freem(data->m); 955169695Skan data->m = NULL; 956169695Skan } 957169695Skan if (data->ni != NULL) { 958169695Skan ieee80211_free_node(data->ni); 959169695Skan data->ni = NULL; 960169695Skan } 961169695Skan } 962169695Skan} 963169695Skan 964169695Skanstatic int 965169695Skanrun_load_microcode(struct run_softc *sc) 966169695Skan{ 967169695Skan usb_device_request_t req; 968169695Skan const struct firmware *fw; 969169695Skan const u_char *base; 970169695Skan uint32_t tmp; 971169695Skan int ntries, error; 972169695Skan const uint64_t *temp; 973169695Skan uint64_t bytes; 974169695Skan 975169695Skan RUN_UNLOCK(sc); 976169695Skan fw = firmware_get("runfw"); 977169695Skan RUN_LOCK(sc); 978169695Skan if (fw == NULL) { 979169695Skan device_printf(sc->sc_dev, 980169695Skan "failed loadfirmware of file %s\n", "runfw"); 981169695Skan return ENOENT; 982169695Skan } 983169695Skan 984169695Skan if (fw->datasize != 8192) { 985169695Skan device_printf(sc->sc_dev, 986169695Skan "invalid firmware size (should be 8KB)\n"); 987169695Skan error = EINVAL; 988169695Skan goto fail; 989169695Skan } 990169695Skan 991169695Skan /* 992169695Skan * RT3071/RT3072 use a different firmware 993169695Skan * run-rt2870 (8KB) contains both, 994169695Skan * first half (4KB) is for rt2870, 995169695Skan * last half is for rt3071. 996169695Skan */ 997169695Skan base = fw->data; 998169695Skan if ((sc->mac_ver) != 0x2860 && 999169695Skan (sc->mac_ver) != 0x2872 && 1000169695Skan (sc->mac_ver) != 0x3070) { 1001169695Skan base += 4096; 1002169695Skan } 1003169695Skan 1004169695Skan /* cheap sanity check */ 1005169695Skan temp = fw->data; 1006169695Skan bytes = *temp; 1007169695Skan if (bytes != be64toh(0xffffff0210280210)) { 1008169695Skan device_printf(sc->sc_dev, "firmware checksum failed\n"); 1009169695Skan error = EINVAL; 1010169695Skan goto fail; 1011169695Skan } 1012169695Skan 1013169695Skan run_read(sc, RT2860_ASIC_VER_ID, &tmp); 1014169695Skan /* write microcode image */ 1015169695Skan run_write_region_1(sc, RT2870_FW_BASE, base, 4096); 1016169695Skan run_write(sc, RT2860_H2M_MAILBOX_CID, 0xffffffff); 1017169695Skan run_write(sc, RT2860_H2M_MAILBOX_STATUS, 0xffffffff); 1018169695Skan 1019169695Skan req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1020169695Skan req.bRequest = RT2870_RESET; 1021169695Skan USETW(req.wValue, 8); 1022169695Skan USETW(req.wIndex, 0); 1023169695Skan USETW(req.wLength, 0); 1024169695Skan if ((error = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL)) 1025169695Skan != 0) { 1026169695Skan device_printf(sc->sc_dev, "firmware reset failed\n"); 1027169695Skan goto fail; 1028169695Skan } 1029169695Skan 1030169695Skan run_delay(sc, 10); 1031169695Skan 1032169695Skan run_write(sc, RT2860_H2M_MAILBOX, 0); 1033169695Skan if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0)) != 0) 1034169695Skan goto fail; 1035169695Skan 1036169695Skan /* wait until microcontroller is ready */ 1037169695Skan for (ntries = 0; ntries < 1000; ntries++) { 1038169695Skan if ((error = run_read(sc, RT2860_SYS_CTRL, &tmp)) != 0) { 1039169695Skan goto fail; 1040169695Skan } 1041169695Skan if (tmp & RT2860_MCU_READY) 1042169695Skan break; 1043169695Skan run_delay(sc, 10); 1044169695Skan } 1045169695Skan if (ntries == 1000) { 1046169695Skan device_printf(sc->sc_dev, 1047169695Skan "timeout waiting for MCU to initialize\n"); 1048169695Skan error = ETIMEDOUT; 1049169695Skan goto fail; 1050169695Skan } 1051169695Skan device_printf(sc->sc_dev, "firmware %s loaded\n", 1052169695Skan (base == fw->data) ? "RT2870" : "RT3071"); 1053169695Skan 1054169695Skanfail: 1055169695Skan firmware_put(fw, FIRMWARE_UNLOAD); 1056169695Skan return (error); 1057169695Skan} 1058169695Skan 1059169695Skanint 1060169695Skanrun_reset(struct run_softc *sc) 1061169695Skan{ 1062169695Skan usb_device_request_t req; 1063169695Skan 1064169695Skan req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1065169695Skan req.bRequest = RT2870_RESET; 1066169695Skan USETW(req.wValue, 1); 1067169695Skan USETW(req.wIndex, 0); 1068169695Skan USETW(req.wLength, 0); 1069169695Skan return (usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL)); 1070169695Skan} 1071169695Skan 1072169695Skanstatic usb_error_t 1073169695Skanrun_do_request(struct run_softc *sc, 1074169695Skan struct usb_device_request *req, void *data) 1075169695Skan{ 1076169695Skan usb_error_t err; 1077169695Skan int ntries = 10; 1078169695Skan 1079169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 1080169695Skan 1081169695Skan while (ntries--) { 1082169695Skan err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx, 1083169695Skan req, data, 0, NULL, 250 /* ms */); 1084169695Skan if (err == 0) 1085169695Skan break; 1086169695Skan DPRINTFN(1, "Control request failed, %s (retrying)\n", 1087169695Skan usbd_errstr(err)); 1088169695Skan run_delay(sc, 10); 1089169695Skan } 1090169695Skan return (err); 1091169695Skan} 1092169695Skan 1093169695Skanstatic int 1094169695Skanrun_read(struct run_softc *sc, uint16_t reg, uint32_t *val) 1095169695Skan{ 1096169695Skan uint32_t tmp; 1097169695Skan int error; 1098169695Skan 1099169695Skan error = run_read_region_1(sc, reg, (uint8_t *)&tmp, sizeof tmp); 1100169695Skan if (error == 0) 1101169695Skan *val = le32toh(tmp); 1102169695Skan else 1103169695Skan *val = 0xffffffff; 1104169695Skan return (error); 1105169695Skan} 1106169695Skan 1107169695Skanstatic int 1108169695Skanrun_read_region_1(struct run_softc *sc, uint16_t reg, uint8_t *buf, int len) 1109169695Skan{ 1110169695Skan usb_device_request_t req; 1111169695Skan 1112169695Skan req.bmRequestType = UT_READ_VENDOR_DEVICE; 1113169695Skan req.bRequest = RT2870_READ_REGION_1; 1114169695Skan USETW(req.wValue, 0); 1115169695Skan USETW(req.wIndex, reg); 1116169695Skan USETW(req.wLength, len); 1117169695Skan 1118169695Skan return (run_do_request(sc, &req, buf)); 1119169695Skan} 1120169695Skan 1121169695Skanstatic int 1122169695Skanrun_write_2(struct run_softc *sc, uint16_t reg, uint16_t val) 1123169695Skan{ 1124169695Skan usb_device_request_t req; 1125169695Skan 1126169695Skan req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1127169695Skan req.bRequest = RT2870_WRITE_2; 1128169695Skan USETW(req.wValue, val); 1129169695Skan USETW(req.wIndex, reg); 1130169695Skan USETW(req.wLength, 0); 1131169695Skan 1132169695Skan return (run_do_request(sc, &req, NULL)); 1133169695Skan} 1134169695Skan 1135169695Skanstatic int 1136169695Skanrun_write(struct run_softc *sc, uint16_t reg, uint32_t val) 1137169695Skan{ 1138169695Skan int error; 1139169695Skan 1140169695Skan if ((error = run_write_2(sc, reg, val & 0xffff)) == 0) 1141169695Skan error = run_write_2(sc, reg + 2, val >> 16); 1142169695Skan return (error); 1143169695Skan} 1144169695Skan 1145169695Skanstatic int 1146169695Skanrun_write_region_1(struct run_softc *sc, uint16_t reg, const uint8_t *buf, 1147169695Skan int len) 1148169695Skan{ 1149169695Skan#if 1 1150169695Skan int i, error = 0; 1151169695Skan /* 1152169695Skan * NB: the WRITE_REGION_1 command is not stable on RT2860. 1153169695Skan * We thus issue multiple WRITE_2 commands instead. 1154169695Skan */ 1155169695Skan KASSERT((len & 1) == 0, ("run_write_region_1: Data too long.\n")); 1156169695Skan for (i = 0; i < len && error == 0; i += 2) 1157169695Skan error = run_write_2(sc, reg + i, buf[i] | buf[i + 1] << 8); 1158169695Skan return (error); 1159169695Skan#else 1160169695Skan usb_device_request_t req; 1161169695Skan 1162169695Skan req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1163169695Skan req.bRequest = RT2870_WRITE_REGION_1; 1164169695Skan USETW(req.wValue, 0); 1165169695Skan USETW(req.wIndex, reg); 1166169695Skan USETW(req.wLength, len); 1167169695Skan return (run_do_request(sc, &req, buf)); 1168169695Skan#endif 1169169695Skan} 1170169695Skan 1171169695Skanstatic int 1172169695Skanrun_set_region_4(struct run_softc *sc, uint16_t reg, uint32_t val, int len) 1173169695Skan{ 1174169695Skan int i, error = 0; 1175169695Skan 1176169695Skan KASSERT((len & 3) == 0, ("run_set_region_4: Invalid data length.\n")); 1177169695Skan for (i = 0; i < len && error == 0; i += 4) 1178169695Skan error = run_write(sc, reg + i, val); 1179169695Skan return (error); 1180169695Skan} 1181169695Skan 1182169695Skan/* Read 16-bit from eFUSE ROM (RT3070 only.) */ 1183169695Skanstatic int 1184169695Skanrun_efuse_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val) 1185169695Skan{ 1186169695Skan uint32_t tmp; 1187169695Skan uint16_t reg; 1188169695Skan int error, ntries; 1189169695Skan 1190169695Skan if ((error = run_read(sc, RT3070_EFUSE_CTRL, &tmp)) != 0) 1191169695Skan return (error); 1192169695Skan 1193169695Skan addr *= 2; 1194169695Skan /*- 1195169695Skan * Read one 16-byte block into registers EFUSE_DATA[0-3]: 1196169695Skan * DATA0: F E D C 1197169695Skan * DATA1: B A 9 8 1198169695Skan * DATA2: 7 6 5 4 1199169695Skan * DATA3: 3 2 1 0 1200169695Skan */ 1201169695Skan tmp &= ~(RT3070_EFSROM_MODE_MASK | RT3070_EFSROM_AIN_MASK); 1202169695Skan tmp |= (addr & ~0xf) << RT3070_EFSROM_AIN_SHIFT | RT3070_EFSROM_KICK; 1203169695Skan run_write(sc, RT3070_EFUSE_CTRL, tmp); 1204169695Skan for (ntries = 0; ntries < 100; ntries++) { 1205169695Skan if ((error = run_read(sc, RT3070_EFUSE_CTRL, &tmp)) != 0) 1206169695Skan return (error); 1207169695Skan if (!(tmp & RT3070_EFSROM_KICK)) 1208169695Skan break; 1209169695Skan run_delay(sc, 2); 1210169695Skan } 1211169695Skan if (ntries == 100) 1212169695Skan return (ETIMEDOUT); 1213169695Skan 1214169695Skan if ((tmp & RT3070_EFUSE_AOUT_MASK) == RT3070_EFUSE_AOUT_MASK) { 1215169695Skan *val = 0xffff; /* address not found */ 1216169695Skan return (0); 1217169695Skan } 1218169695Skan /* determine to which 32-bit register our 16-bit word belongs */ 1219169695Skan reg = RT3070_EFUSE_DATA3 - (addr & 0xc); 1220169695Skan if ((error = run_read(sc, reg, &tmp)) != 0) 1221169695Skan return (error); 1222169695Skan 1223169695Skan *val = (addr & 2) ? tmp >> 16 : tmp & 0xffff; 1224169695Skan return (0); 1225169695Skan} 1226169695Skan 1227169695Skanstatic int 1228169695Skanrun_eeprom_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val) 1229169695Skan{ 1230169695Skan usb_device_request_t req; 1231169695Skan uint16_t tmp; 1232169695Skan int error; 1233169695Skan 1234169695Skan addr *= 2; 1235169695Skan req.bmRequestType = UT_READ_VENDOR_DEVICE; 1236169695Skan req.bRequest = RT2870_EEPROM_READ; 1237169695Skan USETW(req.wValue, 0); 1238169695Skan USETW(req.wIndex, addr); 1239169695Skan USETW(req.wLength, sizeof tmp); 1240169695Skan 1241169695Skan error = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, &tmp); 1242169695Skan if (error == 0) 1243169695Skan *val = le16toh(tmp); 1244169695Skan else 1245169695Skan *val = 0xffff; 1246169695Skan return (error); 1247169695Skan} 1248169695Skan 1249169695Skanstatic __inline int 1250169695Skanrun_srom_read(struct run_softc *sc, uint16_t addr, uint16_t *val) 1251169695Skan{ 1252169695Skan /* either eFUSE ROM or EEPROM */ 1253169695Skan return sc->sc_srom_read(sc, addr, val); 1254169695Skan} 1255169695Skan 1256169695Skanstatic int 1257169695Skanrun_rt2870_rf_write(struct run_softc *sc, uint8_t reg, uint32_t val) 1258169695Skan{ 1259169695Skan uint32_t tmp; 1260169695Skan int error, ntries; 1261169695Skan 1262169695Skan for (ntries = 0; ntries < 10; ntries++) { 1263169695Skan if ((error = run_read(sc, RT2860_RF_CSR_CFG0, &tmp)) != 0) 1264169695Skan return (error); 1265169695Skan if (!(tmp & RT2860_RF_REG_CTRL)) 1266169695Skan break; 1267169695Skan } 1268169695Skan if (ntries == 10) 1269169695Skan return (ETIMEDOUT); 1270169695Skan 1271169695Skan /* RF registers are 24-bit on the RT2860 */ 1272169695Skan tmp = RT2860_RF_REG_CTRL | 24 << RT2860_RF_REG_WIDTH_SHIFT | 1273169695Skan (val & 0x3fffff) << 2 | (reg & 3); 1274169695Skan return (run_write(sc, RT2860_RF_CSR_CFG0, tmp)); 1275169695Skan} 1276169695Skan 1277169695Skanstatic int 1278169695Skanrun_rt3070_rf_read(struct run_softc *sc, uint8_t reg, uint8_t *val) 1279169695Skan{ 1280169695Skan uint32_t tmp; 1281169695Skan int error, ntries; 1282169695Skan 1283169695Skan for (ntries = 0; ntries < 100; ntries++) { 1284169695Skan if ((error = run_read(sc, RT3070_RF_CSR_CFG, &tmp)) != 0) 1285169695Skan return (error); 1286169695Skan if (!(tmp & RT3070_RF_KICK)) 1287169695Skan break; 1288169695Skan } 1289169695Skan if (ntries == 100) 1290169695Skan return (ETIMEDOUT); 1291169695Skan 1292169695Skan tmp = RT3070_RF_KICK | reg << 8; 1293169695Skan if ((error = run_write(sc, RT3070_RF_CSR_CFG, tmp)) != 0) 1294169695Skan return (error); 1295169695Skan 1296169695Skan for (ntries = 0; ntries < 100; ntries++) { 1297169695Skan if ((error = run_read(sc, RT3070_RF_CSR_CFG, &tmp)) != 0) 1298169695Skan return (error); 1299169695Skan if (!(tmp & RT3070_RF_KICK)) 1300169695Skan break; 1301169695Skan } 1302169695Skan if (ntries == 100) 1303169695Skan return (ETIMEDOUT); 1304169695Skan 1305169695Skan *val = tmp & 0xff; 1306169695Skan return (0); 1307169695Skan} 1308169695Skan 1309169695Skanstatic int 1310169695Skanrun_rt3070_rf_write(struct run_softc *sc, uint8_t reg, uint8_t val) 1311169695Skan{ 1312169695Skan uint32_t tmp; 1313169695Skan int error, ntries; 1314169695Skan 1315169695Skan for (ntries = 0; ntries < 10; ntries++) { 1316169695Skan if ((error = run_read(sc, RT3070_RF_CSR_CFG, &tmp)) != 0) 1317169695Skan return (error); 1318169695Skan if (!(tmp & RT3070_RF_KICK)) 1319169695Skan break; 1320169695Skan } 1321169695Skan if (ntries == 10) 1322169695Skan return (ETIMEDOUT); 1323169695Skan 1324169695Skan tmp = RT3070_RF_WRITE | RT3070_RF_KICK | reg << 8 | val; 1325169695Skan return (run_write(sc, RT3070_RF_CSR_CFG, tmp)); 1326169695Skan} 1327169695Skan 1328169695Skanstatic int 1329169695Skanrun_bbp_read(struct run_softc *sc, uint8_t reg, uint8_t *val) 1330169695Skan{ 1331169695Skan uint32_t tmp; 1332169695Skan int ntries, error; 1333169695Skan 1334169695Skan for (ntries = 0; ntries < 10; ntries++) { 1335169695Skan if ((error = run_read(sc, RT2860_BBP_CSR_CFG, &tmp)) != 0) 1336169695Skan return (error); 1337169695Skan if (!(tmp & RT2860_BBP_CSR_KICK)) 1338169695Skan break; 1339169695Skan } 1340169695Skan if (ntries == 10) 1341169695Skan return (ETIMEDOUT); 1342169695Skan 1343169695Skan tmp = RT2860_BBP_CSR_READ | RT2860_BBP_CSR_KICK | reg << 8; 1344169695Skan if ((error = run_write(sc, RT2860_BBP_CSR_CFG, tmp)) != 0) 1345169695Skan return (error); 1346169695Skan 1347169695Skan for (ntries = 0; ntries < 10; ntries++) { 1348169695Skan if ((error = run_read(sc, RT2860_BBP_CSR_CFG, &tmp)) != 0) 1349169695Skan return (error); 1350169695Skan if (!(tmp & RT2860_BBP_CSR_KICK)) 1351169695Skan break; 1352169695Skan } 1353169695Skan if (ntries == 10) 1354169695Skan return (ETIMEDOUT); 1355169695Skan 1356169695Skan *val = tmp & 0xff; 1357169695Skan return (0); 1358169695Skan} 1359169695Skan 1360169695Skanstatic int 1361169695Skanrun_bbp_write(struct run_softc *sc, uint8_t reg, uint8_t val) 1362169695Skan{ 1363169695Skan uint32_t tmp; 1364169695Skan int ntries, error; 1365169695Skan 1366169695Skan for (ntries = 0; ntries < 10; ntries++) { 1367169695Skan if ((error = run_read(sc, RT2860_BBP_CSR_CFG, &tmp)) != 0) 1368169695Skan return (error); 1369169695Skan if (!(tmp & RT2860_BBP_CSR_KICK)) 1370169695Skan break; 1371169695Skan } 1372169695Skan if (ntries == 10) 1373169695Skan return (ETIMEDOUT); 1374169695Skan 1375169695Skan tmp = RT2860_BBP_CSR_KICK | reg << 8 | val; 1376169695Skan return (run_write(sc, RT2860_BBP_CSR_CFG, tmp)); 1377169695Skan} 1378169695Skan 1379169695Skan/* 1380169695Skan * Send a command to the 8051 microcontroller unit. 1381169695Skan */ 1382169695Skanstatic int 1383169695Skanrun_mcu_cmd(struct run_softc *sc, uint8_t cmd, uint16_t arg) 1384169695Skan{ 1385169695Skan uint32_t tmp; 1386169695Skan int error, ntries; 1387169695Skan 1388169695Skan for (ntries = 0; ntries < 100; ntries++) { 1389169695Skan if ((error = run_read(sc, RT2860_H2M_MAILBOX, &tmp)) != 0) 1390169695Skan return error; 1391169695Skan if (!(tmp & RT2860_H2M_BUSY)) 1392169695Skan break; 1393169695Skan } 1394169695Skan if (ntries == 100) 1395169695Skan return ETIMEDOUT; 1396169695Skan 1397169695Skan tmp = RT2860_H2M_BUSY | RT2860_TOKEN_NO_INTR << 16 | arg; 1398169695Skan if ((error = run_write(sc, RT2860_H2M_MAILBOX, tmp)) == 0) 1399169695Skan error = run_write(sc, RT2860_HOST_CMD, cmd); 1400169695Skan return (error); 1401169695Skan} 1402169695Skan 1403169695Skan/* 1404169695Skan * Add `delta' (signed) to each 4-bit sub-word of a 32-bit word. 1405169695Skan * Used to adjust per-rate Tx power registers. 1406169695Skan */ 1407169695Skanstatic __inline uint32_t 1408169695Skanb4inc(uint32_t b32, int8_t delta) 1409169695Skan{ 1410169695Skan int8_t i, b4; 1411169695Skan 1412169695Skan for (i = 0; i < 8; i++) { 1413169695Skan b4 = b32 & 0xf; 1414169695Skan b4 += delta; 1415169695Skan if (b4 < 0) 1416169695Skan b4 = 0; 1417169695Skan else if (b4 > 0xf) 1418169695Skan b4 = 0xf; 1419169695Skan b32 = b32 >> 4 | b4 << 28; 1420169695Skan } 1421169695Skan return (b32); 1422169695Skan} 1423169695Skan 1424169695Skanstatic const char * 1425169695Skanrun_get_rf(int rev) 1426169695Skan{ 1427169695Skan switch (rev) { 1428169695Skan case RT2860_RF_2820: return "RT2820"; 1429169695Skan case RT2860_RF_2850: return "RT2850"; 1430169695Skan case RT2860_RF_2720: return "RT2720"; 1431169695Skan case RT2860_RF_2750: return "RT2750"; 1432169695Skan case RT3070_RF_3020: return "RT3020"; 1433169695Skan case RT3070_RF_2020: return "RT2020"; 1434169695Skan case RT3070_RF_3021: return "RT3021"; 1435169695Skan case RT3070_RF_3022: return "RT3022"; 1436169695Skan case RT3070_RF_3052: return "RT3052"; 1437169695Skan } 1438169695Skan return ("unknown"); 1439169695Skan} 1440169695Skan 1441169695Skanint 1442169695Skanrun_read_eeprom(struct run_softc *sc) 1443169695Skan{ 1444169695Skan int8_t delta_2ghz, delta_5ghz; 1445169695Skan uint32_t tmp; 1446169695Skan uint16_t val; 1447169695Skan int ridx, ant, i; 1448169695Skan 1449169695Skan /* check whether the ROM is eFUSE ROM or EEPROM */ 1450169695Skan sc->sc_srom_read = run_eeprom_read_2; 1451169695Skan if (sc->mac_ver >= 0x3070) { 1452169695Skan run_read(sc, RT3070_EFUSE_CTRL, &tmp); 1453169695Skan DPRINTF("EFUSE_CTRL=0x%08x\n", tmp); 1454169695Skan if (tmp & RT3070_SEL_EFUSE) 1455169695Skan sc->sc_srom_read = run_efuse_read_2; 1456169695Skan } 1457169695Skan 1458169695Skan /* read ROM version */ 1459169695Skan run_srom_read(sc, RT2860_EEPROM_VERSION, &val); 1460169695Skan DPRINTF("EEPROM rev=%d, FAE=%d\n", val & 0xff, val >> 8); 1461169695Skan 1462169695Skan /* read MAC address */ 1463169695Skan run_srom_read(sc, RT2860_EEPROM_MAC01, &val); 1464169695Skan sc->sc_bssid[0] = val & 0xff; 1465169695Skan sc->sc_bssid[1] = val >> 8; 1466169695Skan run_srom_read(sc, RT2860_EEPROM_MAC23, &val); 1467169695Skan sc->sc_bssid[2] = val & 0xff; 1468169695Skan sc->sc_bssid[3] = val >> 8; 1469169695Skan run_srom_read(sc, RT2860_EEPROM_MAC45, &val); 1470169695Skan sc->sc_bssid[4] = val & 0xff; 1471169695Skan sc->sc_bssid[5] = val >> 8; 1472169695Skan 1473169695Skan /* read vender BBP settings */ 1474169695Skan for (i = 0; i < 10; i++) { 1475169695Skan run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val); 1476169695Skan sc->bbp[i].val = val & 0xff; 1477169695Skan sc->bbp[i].reg = val >> 8; 1478169695Skan DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val); 1479169695Skan } 1480169695Skan if (sc->mac_ver >= 0x3071) { 1481169695Skan /* read vendor RF settings */ 1482169695Skan for (i = 0; i < 10; i++) { 1483169695Skan run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, &val); 1484169695Skan sc->rf[i].val = val & 0xff; 1485169695Skan sc->rf[i].reg = val >> 8; 1486169695Skan DPRINTF("RF%d=0x%02x\n", sc->rf[i].reg, 1487169695Skan sc->rf[i].val); 1488169695Skan } 1489169695Skan } 1490169695Skan 1491169695Skan /* read RF frequency offset from EEPROM */ 1492169695Skan run_srom_read(sc, RT2860_EEPROM_FREQ_LEDS, &val); 1493169695Skan sc->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0; 1494169695Skan DPRINTF("EEPROM freq offset %d\n", sc->freq & 0xff); 1495169695Skan 1496169695Skan if (val >> 8 != 0xff) { 1497169695Skan /* read LEDs operating mode */ 1498169695Skan sc->leds = val >> 8; 1499169695Skan run_srom_read(sc, RT2860_EEPROM_LED1, &sc->led[0]); 1500169695Skan run_srom_read(sc, RT2860_EEPROM_LED2, &sc->led[1]); 1501169695Skan run_srom_read(sc, RT2860_EEPROM_LED3, &sc->led[2]); 1502169695Skan } else { 1503169695Skan /* broken EEPROM, use default settings */ 1504169695Skan sc->leds = 0x01; 1505169695Skan sc->led[0] = 0x5555; 1506169695Skan sc->led[1] = 0x2221; 1507169695Skan sc->led[2] = 0x5627; /* differs from RT2860 */ 1508169695Skan } 1509169695Skan DPRINTF("EEPROM LED mode=0x%02x, LEDs=0x%04x/0x%04x/0x%04x\n", 1510169695Skan sc->leds, sc->led[0], sc->led[1], sc->led[2]); 1511169695Skan 1512169695Skan /* read RF information */ 1513169695Skan run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); 1514169695Skan if (val == 0xffff) { 1515169695Skan DPRINTF("invalid EEPROM antenna info, using default\n"); 1516169695Skan if (sc->mac_ver == 0x3572) { 1517169695Skan /* default to RF3052 2T2R */ 1518169695Skan sc->rf_rev = RT3070_RF_3052; 1519169695Skan sc->ntxchains = 2; 1520169695Skan sc->nrxchains = 2; 1521169695Skan } else if (sc->mac_ver >= 0x3070) { 1522169695Skan /* default to RF3020 1T1R */ 1523169695Skan sc->rf_rev = RT3070_RF_3020; 1524169695Skan sc->ntxchains = 1; 1525169695Skan sc->nrxchains = 1; 1526169695Skan } else { 1527169695Skan /* default to RF2820 1T2R */ 1528169695Skan sc->rf_rev = RT2860_RF_2820; 1529169695Skan sc->ntxchains = 1; 1530169695Skan sc->nrxchains = 2; 1531169695Skan } 1532169695Skan } else { 1533169695Skan sc->rf_rev = (val >> 8) & 0xf; 1534169695Skan sc->ntxchains = (val >> 4) & 0xf; 1535169695Skan sc->nrxchains = val & 0xf; 1536169695Skan } 1537169695Skan DPRINTF("EEPROM RF rev=0x%02x chains=%dT%dR\n", 1538169695Skan sc->rf_rev, sc->ntxchains, sc->nrxchains); 1539169695Skan 1540169695Skan /* check if RF supports automatic Tx access gain control */ 1541169695Skan run_srom_read(sc, RT2860_EEPROM_CONFIG, &val); 1542169695Skan DPRINTF("EEPROM CFG 0x%04x\n", val); 1543169695Skan /* check if driver should patch the DAC issue */ 1544169695Skan if ((val >> 8) != 0xff) 1545169695Skan sc->patch_dac = (val >> 15) & 1; 1546169695Skan if ((val & 0xff) != 0xff) { 1547169695Skan sc->ext_5ghz_lna = (val >> 3) & 1; 1548169695Skan sc->ext_2ghz_lna = (val >> 2) & 1; 1549169695Skan /* check if RF supports automatic Tx access gain control */ 1550169695Skan sc->calib_2ghz = sc->calib_5ghz = (val >> 1) & 1; 1551169695Skan /* check if we have a hardware radio switch */ 1552169695Skan sc->rfswitch = val & 1; 1553169695Skan } 1554169695Skan 1555169695Skan /* read power settings for 2GHz channels */ 1556169695Skan for (i = 0; i < 14; i += 2) { 1557169695Skan run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2, &val); 1558169695Skan sc->txpow1[i + 0] = (int8_t)(val & 0xff); 1559169695Skan sc->txpow1[i + 1] = (int8_t)(val >> 8); 1560169695Skan 1561169695Skan run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val); 1562169695Skan sc->txpow2[i + 0] = (int8_t)(val & 0xff); 1563169695Skan sc->txpow2[i + 1] = (int8_t)(val >> 8); 1564169695Skan } 1565169695Skan /* fix broken Tx power entries */ 1566169695Skan for (i = 0; i < 14; i++) { 1567169695Skan if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31) 1568169695Skan sc->txpow1[i] = 5; 1569169695Skan if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31) 1570169695Skan sc->txpow2[i] = 5; 1571169695Skan DPRINTF("chan %d: power1=%d, power2=%d\n", 1572169695Skan rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]); 1573169695Skan } 1574169695Skan /* read power settings for 5GHz channels */ 1575169695Skan for (i = 0; i < 40; i += 2) { 1576169695Skan run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2, &val); 1577169695Skan sc->txpow1[i + 14] = (int8_t)(val & 0xff); 1578169695Skan sc->txpow1[i + 15] = (int8_t)(val >> 8); 1579169695Skan 1580169695Skan run_srom_read(sc, RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2, &val); 1581169695Skan sc->txpow2[i + 14] = (int8_t)(val & 0xff); 1582169695Skan sc->txpow2[i + 15] = (int8_t)(val >> 8); 1583169695Skan } 1584169695Skan /* fix broken Tx power entries */ 1585169695Skan for (i = 0; i < 40; i++) { 1586169695Skan if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15) 1587169695Skan sc->txpow1[14 + i] = 5; 1588169695Skan if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15) 1589169695Skan sc->txpow2[14 + i] = 5; 1590169695Skan DPRINTF("chan %d: power1=%d, power2=%d\n", 1591169695Skan rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i], 1592169695Skan sc->txpow2[14 + i]); 1593169695Skan } 1594169695Skan 1595169695Skan /* read Tx power compensation for each Tx rate */ 1596169695Skan run_srom_read(sc, RT2860_EEPROM_DELTAPWR, &val); 1597169695Skan delta_2ghz = delta_5ghz = 0; 1598169695Skan if ((val & 0xff) != 0xff && (val & 0x80)) { 1599169695Skan delta_2ghz = val & 0xf; 1600169695Skan if (!(val & 0x40)) /* negative number */ 1601169695Skan delta_2ghz = -delta_2ghz; 1602169695Skan } 1603169695Skan val >>= 8; 1604169695Skan if ((val & 0xff) != 0xff && (val & 0x80)) { 1605169695Skan delta_5ghz = val & 0xf; 1606169695Skan if (!(val & 0x40)) /* negative number */ 1607169695Skan delta_5ghz = -delta_5ghz; 1608169695Skan } 1609169695Skan DPRINTF("power compensation=%d (2GHz), %d (5GHz)\n", 1610169695Skan delta_2ghz, delta_5ghz); 1611169695Skan 1612169695Skan for (ridx = 0; ridx < 5; ridx++) { 1613169695Skan uint32_t reg; 1614169695Skan 1615169695Skan run_srom_read(sc, RT2860_EEPROM_RPWR + ridx * 2, &val); 1616169695Skan reg = val; 1617169695Skan run_srom_read(sc, RT2860_EEPROM_RPWR + ridx * 2 + 1, &val); 1618169695Skan reg |= (uint32_t)val << 16; 1619169695Skan 1620169695Skan sc->txpow20mhz[ridx] = reg; 1621169695Skan sc->txpow40mhz_2ghz[ridx] = b4inc(reg, delta_2ghz); 1622169695Skan sc->txpow40mhz_5ghz[ridx] = b4inc(reg, delta_5ghz); 1623169695Skan 1624169695Skan DPRINTF("ridx %d: power 20MHz=0x%08x, 40MHz/2GHz=0x%08x, " 1625169695Skan "40MHz/5GHz=0x%08x\n", ridx, sc->txpow20mhz[ridx], 1626169695Skan sc->txpow40mhz_2ghz[ridx], sc->txpow40mhz_5ghz[ridx]); 1627169695Skan } 1628169695Skan 1629169695Skan /* read RSSI offsets and LNA gains from EEPROM */ 1630169695Skan run_srom_read(sc, RT2860_EEPROM_RSSI1_2GHZ, &val); 1631169695Skan sc->rssi_2ghz[0] = val & 0xff; /* Ant A */ 1632169695Skan sc->rssi_2ghz[1] = val >> 8; /* Ant B */ 1633169695Skan run_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ, &val); 1634169695Skan if (sc->mac_ver >= 0x3070) { 1635169695Skan /* 1636169695Skan * On RT3070 chips (limited to 2 Rx chains), this ROM 1637169695Skan * field contains the Tx mixer gain for the 2GHz band. 1638169695Skan */ 1639169695Skan if ((val & 0xff) != 0xff) 1640169695Skan sc->txmixgain_2ghz = val & 0x7; 1641169695Skan DPRINTF("tx mixer gain=%u (2GHz)\n", sc->txmixgain_2ghz); 1642169695Skan } else 1643169695Skan sc->rssi_2ghz[2] = val & 0xff; /* Ant C */ 1644169695Skan sc->lna[2] = val >> 8; /* channel group 2 */ 1645169695Skan 1646169695Skan run_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ, &val); 1647169695Skan sc->rssi_5ghz[0] = val & 0xff; /* Ant A */ 1648169695Skan sc->rssi_5ghz[1] = val >> 8; /* Ant B */ 1649169695Skan run_srom_read(sc, RT2860_EEPROM_RSSI2_5GHZ, &val); 1650169695Skan if (sc->mac_ver == 0x3572) { 1651169695Skan /* 1652169695Skan * On RT3572 chips (limited to 2 Rx chains), this ROM 1653169695Skan * field contains the Tx mixer gain for the 5GHz band. 1654169695Skan */ 1655169695Skan if ((val & 0xff) != 0xff) 1656169695Skan sc->txmixgain_5ghz = val & 0x7; 1657169695Skan DPRINTF("tx mixer gain=%u (5GHz)\n", sc->txmixgain_5ghz); 1658169695Skan } else 1659169695Skan sc->rssi_5ghz[2] = val & 0xff; /* Ant C */ 1660169695Skan sc->lna[3] = val >> 8; /* channel group 3 */ 1661169695Skan 1662169695Skan run_srom_read(sc, RT2860_EEPROM_LNA, &val); 1663169695Skan sc->lna[0] = val & 0xff; /* channel group 0 */ 1664169695Skan sc->lna[1] = val >> 8; /* channel group 1 */ 1665169695Skan 1666169695Skan /* fix broken 5GHz LNA entries */ 1667169695Skan if (sc->lna[2] == 0 || sc->lna[2] == 0xff) { 1668169695Skan DPRINTF("invalid LNA for channel group %d\n", 2); 1669169695Skan sc->lna[2] = sc->lna[1]; 1670169695Skan } 1671169695Skan if (sc->lna[3] == 0 || sc->lna[3] == 0xff) { 1672169695Skan DPRINTF("invalid LNA for channel group %d\n", 3); 1673169695Skan sc->lna[3] = sc->lna[1]; 1674169695Skan } 1675169695Skan 1676169695Skan /* fix broken RSSI offset entries */ 1677169695Skan for (ant = 0; ant < 3; ant++) { 1678169695Skan if (sc->rssi_2ghz[ant] < -10 || sc->rssi_2ghz[ant] > 10) { 1679169695Skan DPRINTF("invalid RSSI%d offset: %d (2GHz)\n", 1680169695Skan ant + 1, sc->rssi_2ghz[ant]); 1681169695Skan sc->rssi_2ghz[ant] = 0; 1682169695Skan } 1683169695Skan if (sc->rssi_5ghz[ant] < -10 || sc->rssi_5ghz[ant] > 10) { 1684169695Skan DPRINTF("invalid RSSI%d offset: %d (5GHz)\n", 1685169695Skan ant + 1, sc->rssi_5ghz[ant]); 1686169695Skan sc->rssi_5ghz[ant] = 0; 1687169695Skan } 1688169695Skan } 1689169695Skan return (0); 1690169695Skan} 1691169695Skan 1692169695Skanstatic struct ieee80211_node * 1693169695Skanrun_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 1694169695Skan{ 1695169695Skan return malloc(sizeof (struct run_node), M_DEVBUF, M_NOWAIT | M_ZERO); 1696169695Skan} 1697169695Skan 1698169695Skanstatic int 1699169695Skanrun_media_change(struct ifnet *ifp) 1700169695Skan{ 1701169695Skan struct ieee80211vap *vap = ifp->if_softc; 1702169695Skan struct ieee80211com *ic = vap->iv_ic; 1703169695Skan const struct ieee80211_txparam *tp; 1704169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 1705169695Skan uint8_t rate, ridx; 1706169695Skan int error; 1707169695Skan 1708169695Skan RUN_LOCK(sc); 1709169695Skan 1710169695Skan error = ieee80211_media_change(ifp); 1711169695Skan if (error != ENETRESET) { 1712169695Skan RUN_UNLOCK(sc); 1713169695Skan return (error); 1714169695Skan } 1715169695Skan 1716169695Skan tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 1717169695Skan if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { 1718169695Skan struct ieee80211_node *ni; 1719169695Skan struct run_node *rn; 1720169695Skan 1721169695Skan rate = ic->ic_sup_rates[ic->ic_curmode]. 1722169695Skan rs_rates[tp->ucastrate] & IEEE80211_RATE_VAL; 1723169695Skan for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) 1724169695Skan if (rt2860_rates[ridx].rate == rate) 1725169695Skan break; 1726169695Skan ni = ieee80211_ref_node(vap->iv_bss); 1727169695Skan rn = (struct run_node *)ni; 1728169695Skan rn->fix_ridx = ridx; 1729169695Skan DPRINTF("rate=%d, fix_ridx=%d\n", rate, rn->fix_ridx); 1730169695Skan ieee80211_free_node(ni); 1731169695Skan } 1732169695Skan 1733169695Skan#if 0 1734169695Skan if ((ifp->if_flags & IFF_UP) && 1735169695Skan (ifp->if_drv_flags & IFF_DRV_RUNNING)){ 1736169695Skan run_init_locked(sc); 1737169695Skan } 1738169695Skan#endif 1739169695Skan 1740169695Skan RUN_UNLOCK(sc); 1741169695Skan 1742169695Skan return (0); 1743169695Skan} 1744169695Skan 1745169695Skanstatic int 1746169695Skanrun_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1747169695Skan{ 1748169695Skan const struct ieee80211_txparam *tp; 1749169695Skan struct ieee80211com *ic = vap->iv_ic; 1750169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 1751169695Skan struct run_vap *rvp = RUN_VAP(vap); 1752169695Skan enum ieee80211_state ostate; 1753169695Skan uint32_t sta[3]; 1754169695Skan uint32_t tmp; 1755169695Skan uint8_t ratectl; 1756169695Skan uint8_t restart_ratectl = 0; 1757169695Skan uint8_t bid = 1 << rvp->rvp_id; 1758169695Skan 1759169695Skan ostate = vap->iv_state; 1760169695Skan DPRINTF("%s -> %s\n", 1761169695Skan ieee80211_state_name[ostate], 1762169695Skan ieee80211_state_name[nstate]); 1763169695Skan 1764169695Skan IEEE80211_UNLOCK(ic); 1765169695Skan RUN_LOCK(sc); 1766169695Skan 1767169695Skan ratectl = sc->ratectl_run; /* remember current state */ 1768169695Skan sc->ratectl_run = RUN_RATECTL_OFF; 1769169695Skan usb_callout_stop(&sc->ratectl_ch); 1770169695Skan 1771169695Skan if (ostate == IEEE80211_S_RUN) { 1772169695Skan /* turn link LED off */ 1773169695Skan run_set_leds(sc, RT2860_LED_RADIO); 1774169695Skan } 1775169695Skan 1776169695Skan switch (nstate) { 1777169695Skan case IEEE80211_S_INIT: 1778169695Skan restart_ratectl = 1; 1779169695Skan 1780169695Skan if (ostate != IEEE80211_S_RUN) 1781169695Skan break; 1782169695Skan 1783169695Skan ratectl &= ~bid; 1784169695Skan sc->runbmap &= ~bid; 1785169695Skan 1786169695Skan /* abort TSF synchronization if there is no vap running */ 1787169695Skan if (--sc->running == 0) { 1788169695Skan run_read(sc, RT2860_BCN_TIME_CFG, &tmp); 1789169695Skan run_write(sc, RT2860_BCN_TIME_CFG, 1790169695Skan tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | 1791169695Skan RT2860_TBTT_TIMER_EN)); 1792169695Skan } 1793169695Skan break; 1794169695Skan 1795169695Skan case IEEE80211_S_RUN: 1796169695Skan if (!(sc->runbmap & bid)) { 1797169695Skan if(sc->running++) 1798169695Skan restart_ratectl = 1; 1799169695Skan sc->runbmap |= bid; 1800169695Skan } 1801169695Skan 1802169695Skan m_freem(rvp->beacon_mbuf); 1803169695Skan rvp->beacon_mbuf = NULL; 1804169695Skan 1805169695Skan switch (vap->iv_opmode) { 1806169695Skan case IEEE80211_M_HOSTAP: 1807169695Skan case IEEE80211_M_MBSS: 1808169695Skan sc->ap_running |= bid; 1809169695Skan ic->ic_opmode = vap->iv_opmode; 1810169695Skan run_update_beacon_cb(vap); 1811169695Skan break; 1812169695Skan case IEEE80211_M_IBSS: 1813169695Skan sc->adhoc_running |= bid; 1814169695Skan if (!sc->ap_running) 1815169695Skan ic->ic_opmode = vap->iv_opmode; 1816169695Skan run_update_beacon_cb(vap); 1817169695Skan break; 1818169695Skan case IEEE80211_M_STA: 1819169695Skan sc->sta_running |= bid; 1820169695Skan if (!sc->ap_running && !sc->adhoc_running) 1821169695Skan ic->ic_opmode = vap->iv_opmode; 1822169695Skan 1823169695Skan /* read statistic counters (clear on read) */ 1824169695Skan run_read_region_1(sc, RT2860_TX_STA_CNT0, 1825169695Skan (uint8_t *)sta, sizeof sta); 1826169695Skan 1827169695Skan break; 1828169695Skan default: 1829169695Skan ic->ic_opmode = vap->iv_opmode; 1830169695Skan break; 1831169695Skan } 1832169695Skan 1833169695Skan if (vap->iv_opmode != IEEE80211_M_MONITOR) { 1834169695Skan struct ieee80211_node *ni; 1835169695Skan 1836169695Skan run_updateslot(ic->ic_ifp); 1837169695Skan run_enable_mrr(sc); 1838169695Skan run_set_txpreamble(sc); 1839169695Skan run_set_basicrates(sc); 1840169695Skan ni = ieee80211_ref_node(vap->iv_bss); 1841169695Skan IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); 1842169695Skan run_set_bssid(sc, ni->ni_bssid); 1843169695Skan ieee80211_free_node(ni); 1844169695Skan run_enable_tsf_sync(sc); 1845169695Skan 1846169695Skan /* enable automatic rate adaptation */ 1847169695Skan tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 1848169695Skan if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) 1849169695Skan ratectl |= bid; 1850169695Skan } 1851169695Skan 1852169695Skan /* turn link LED on */ 1853169695Skan run_set_leds(sc, RT2860_LED_RADIO | 1854169695Skan (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1855169695Skan RT2860_LED_LINK_2GHZ : RT2860_LED_LINK_5GHZ)); 1856169695Skan 1857169695Skan break; 1858169695Skan default: 1859169695Skan DPRINTFN(6, "undefined case\n"); 1860169695Skan break; 1861169695Skan } 1862169695Skan 1863169695Skan /* restart amrr for running VAPs */ 1864169695Skan if ((sc->ratectl_run = ratectl) && restart_ratectl) 1865169695Skan usb_callout_reset(&sc->ratectl_ch, hz, run_ratectl_to, sc); 1866169695Skan 1867169695Skan RUN_UNLOCK(sc); 1868169695Skan IEEE80211_LOCK(ic); 1869169695Skan 1870169695Skan return(rvp->newstate(vap, nstate, arg)); 1871169695Skan} 1872169695Skan 1873169695Skan/* ARGSUSED */ 1874169695Skanstatic void 1875169695Skanrun_wme_update_cb(void *arg) 1876169695Skan{ 1877169695Skan struct ieee80211com *ic = arg; 1878169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 1879169695Skan struct ieee80211_wme_state *wmesp = &ic->ic_wme; 1880169695Skan int aci, error = 0; 1881169695Skan 1882169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 1883169695Skan 1884169695Skan /* update MAC TX configuration registers */ 1885169695Skan for (aci = 0; aci < WME_NUM_AC; aci++) { 1886169695Skan error = run_write(sc, RT2860_EDCA_AC_CFG(aci), 1887169695Skan wmesp->wme_params[aci].wmep_logcwmax << 16 | 1888169695Skan wmesp->wme_params[aci].wmep_logcwmin << 12 | 1889169695Skan wmesp->wme_params[aci].wmep_aifsn << 8 | 1890169695Skan wmesp->wme_params[aci].wmep_txopLimit); 1891169695Skan if (error) goto err; 1892169695Skan } 1893169695Skan 1894169695Skan /* update SCH/DMA registers too */ 1895169695Skan error = run_write(sc, RT2860_WMM_AIFSN_CFG, 1896169695Skan wmesp->wme_params[WME_AC_VO].wmep_aifsn << 12 | 1897169695Skan wmesp->wme_params[WME_AC_VI].wmep_aifsn << 8 | 1898169695Skan wmesp->wme_params[WME_AC_BK].wmep_aifsn << 4 | 1899169695Skan wmesp->wme_params[WME_AC_BE].wmep_aifsn); 1900169695Skan if (error) goto err; 1901169695Skan error = run_write(sc, RT2860_WMM_CWMIN_CFG, 1902169695Skan wmesp->wme_params[WME_AC_VO].wmep_logcwmin << 12 | 1903169695Skan wmesp->wme_params[WME_AC_VI].wmep_logcwmin << 8 | 1904169695Skan wmesp->wme_params[WME_AC_BK].wmep_logcwmin << 4 | 1905169695Skan wmesp->wme_params[WME_AC_BE].wmep_logcwmin); 1906169695Skan if (error) goto err; 1907169695Skan error = run_write(sc, RT2860_WMM_CWMAX_CFG, 1908169695Skan wmesp->wme_params[WME_AC_VO].wmep_logcwmax << 12 | 1909169695Skan wmesp->wme_params[WME_AC_VI].wmep_logcwmax << 8 | 1910169695Skan wmesp->wme_params[WME_AC_BK].wmep_logcwmax << 4 | 1911169695Skan wmesp->wme_params[WME_AC_BE].wmep_logcwmax); 1912169695Skan if (error) goto err; 1913169695Skan error = run_write(sc, RT2860_WMM_TXOP0_CFG, 1914169695Skan wmesp->wme_params[WME_AC_BK].wmep_txopLimit << 16 | 1915169695Skan wmesp->wme_params[WME_AC_BE].wmep_txopLimit); 1916169695Skan if (error) goto err; 1917169695Skan error = run_write(sc, RT2860_WMM_TXOP1_CFG, 1918169695Skan wmesp->wme_params[WME_AC_VO].wmep_txopLimit << 16 | 1919169695Skan wmesp->wme_params[WME_AC_VI].wmep_txopLimit); 1920169695Skan 1921169695Skanerr: 1922169695Skan if (error) 1923169695Skan DPRINTF("WME update failed\n"); 1924169695Skan 1925169695Skan return; 1926169695Skan} 1927169695Skan 1928169695Skanstatic int 1929169695Skanrun_wme_update(struct ieee80211com *ic) 1930169695Skan{ 1931169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 1932169695Skan 1933169695Skan /* sometime called wothout lock */ 1934169695Skan if (mtx_owned(&ic->ic_comlock.mtx)) { 1935169695Skan uint32_t i = RUN_CMDQ_GET(&sc->cmdq_store); 1936169695Skan DPRINTF("cmdq_store=%d\n", i); 1937169695Skan sc->cmdq[i].func = run_wme_update_cb; 1938169695Skan sc->cmdq[i].arg0 = ic; 1939169695Skan ieee80211_runtask(ic, &sc->cmdq_task); 1940169695Skan return (0); 1941169695Skan } 1942169695Skan 1943169695Skan RUN_LOCK(sc); 1944169695Skan run_wme_update_cb(ic); 1945169695Skan RUN_UNLOCK(sc); 1946169695Skan 1947169695Skan /* return whatever, upper layer desn't care anyway */ 1948169695Skan return (0); 1949169695Skan} 1950169695Skan 1951169695Skanstatic void 1952169695Skanrun_key_update_begin(struct ieee80211vap *vap) 1953169695Skan{ 1954169695Skan /* 1955169695Skan * To avoid out-of-order events, both run_key_set() and 1956169695Skan * _delete() are deferred and handled by run_cmdq_cb(). 1957169695Skan * So, there is nothing we need to do here. 1958169695Skan */ 1959169695Skan} 1960169695Skan 1961169695Skanstatic void 1962169695Skanrun_key_update_end(struct ieee80211vap *vap) 1963169695Skan{ 1964169695Skan /* null */ 1965169695Skan} 1966169695Skan 1967169695Skanstatic void 1968169695Skanrun_key_set_cb(void *arg) 1969169695Skan{ 1970169695Skan struct run_cmdq *cmdq = arg; 1971169695Skan struct ieee80211vap *vap = cmdq->arg1; 1972169695Skan struct ieee80211_key *k = cmdq->k; 1973169695Skan struct ieee80211com *ic = vap->iv_ic; 1974169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 1975169695Skan struct ieee80211_node *ni; 1976169695Skan uint32_t attr; 1977169695Skan uint16_t base, associd; 1978169695Skan uint8_t mode, wcid, iv[8]; 1979169695Skan 1980169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 1981169695Skan 1982169695Skan if (vap->iv_opmode == IEEE80211_M_HOSTAP) 1983169695Skan ni = ieee80211_find_vap_node(&ic->ic_sta, vap, cmdq->mac); 1984169695Skan else 1985169695Skan ni = vap->iv_bss; 1986169695Skan associd = (ni != NULL) ? ni->ni_associd : 0; 1987169695Skan 1988169695Skan /* map net80211 cipher to RT2860 security mode */ 1989169695Skan switch (k->wk_cipher->ic_cipher) { 1990169695Skan case IEEE80211_CIPHER_WEP: 1991169695Skan if(k->wk_keylen < 8) 1992169695Skan mode = RT2860_MODE_WEP40; 1993169695Skan else 1994169695Skan mode = RT2860_MODE_WEP104; 1995169695Skan break; 1996169695Skan case IEEE80211_CIPHER_TKIP: 1997169695Skan mode = RT2860_MODE_TKIP; 1998169695Skan break; 1999169695Skan case IEEE80211_CIPHER_AES_CCM: 2000169695Skan mode = RT2860_MODE_AES_CCMP; 2001169695Skan break; 2002169695Skan default: 2003169695Skan DPRINTF("undefined case\n"); 2004169695Skan return; 2005169695Skan } 2006169695Skan 2007169695Skan DPRINTFN(1, "associd=%x, keyix=%d, mode=%x, type=%s, tx=%s, rx=%s\n", 2008169695Skan associd, k->wk_keyix, mode, 2009169695Skan (k->wk_flags & IEEE80211_KEY_GROUP) ? "group" : "pairwise", 2010169695Skan (k->wk_flags & IEEE80211_KEY_XMIT) ? "on" : "off", 2011169695Skan (k->wk_flags & IEEE80211_KEY_RECV) ? "on" : "off"); 2012169695Skan 2013169695Skan if (k->wk_flags & IEEE80211_KEY_GROUP) { 2014169695Skan wcid = 0; /* NB: update WCID0 for group keys */ 2015169695Skan base = RT2860_SKEY(RUN_VAP(vap)->rvp_id, k->wk_keyix); 2016169695Skan } else { 2017169695Skan wcid = RUN_AID2WCID(associd); 2018169695Skan base = RT2860_PKEY(wcid); 2019169695Skan } 2020169695Skan 2021169695Skan if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP) { 2022169695Skan if(run_write_region_1(sc, base, k->wk_key, 16)) 2023169695Skan return; 2024169695Skan if(run_write_region_1(sc, base + 16, &k->wk_key[16], 8)) /* wk_txmic */ 2025169695Skan return; 2026169695Skan if(run_write_region_1(sc, base + 24, &k->wk_key[24], 8)) /* wk_rxmic */ 2027169695Skan return; 2028169695Skan } else { 2029169695Skan /* roundup len to 16-bit: XXX fix write_region_1() instead */ 2030169695Skan if(run_write_region_1(sc, base, k->wk_key, (k->wk_keylen + 1) & ~1)) 2031169695Skan return; 2032169695Skan } 2033169695Skan 2034169695Skan if (!(k->wk_flags & IEEE80211_KEY_GROUP) || 2035169695Skan (k->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV))) { 2036169695Skan /* set initial packet number in IV+EIV */ 2037169695Skan if (k->wk_cipher == IEEE80211_CIPHER_WEP) { 2038169695Skan memset(iv, 0, sizeof iv); 2039169695Skan iv[3] = vap->iv_def_txkey << 6; 2040169695Skan } else { 2041169695Skan if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP) { 2042169695Skan iv[0] = k->wk_keytsc >> 8; 2043169695Skan iv[1] = (iv[0] | 0x20) & 0x7f; 2044169695Skan iv[2] = k->wk_keytsc; 2045169695Skan } else /* CCMP */ { 2046169695Skan iv[0] = k->wk_keytsc; 2047169695Skan iv[1] = k->wk_keytsc >> 8; 2048169695Skan iv[2] = 0; 2049169695Skan } 2050169695Skan iv[3] = k->wk_keyix << 6 | IEEE80211_WEP_EXTIV; 2051169695Skan iv[4] = k->wk_keytsc >> 16; 2052169695Skan iv[5] = k->wk_keytsc >> 24; 2053169695Skan iv[6] = k->wk_keytsc >> 32; 2054169695Skan iv[7] = k->wk_keytsc >> 40; 2055169695Skan } 2056169695Skan if (run_write_region_1(sc, RT2860_IVEIV(wcid), iv, 8)) 2057169695Skan return; 2058169695Skan } 2059169695Skan 2060169695Skan if (k->wk_flags & IEEE80211_KEY_GROUP) { 2061169695Skan /* install group key */ 2062169695Skan if (run_read(sc, RT2860_SKEY_MODE_0_7, &attr)) 2063169695Skan return; 2064169695Skan attr &= ~(0xf << (k->wk_keyix * 4)); 2065169695Skan attr |= mode << (k->wk_keyix * 4); 2066169695Skan if (run_write(sc, RT2860_SKEY_MODE_0_7, attr)) 2067169695Skan return; 2068169695Skan } else { 2069169695Skan /* install pairwise key */ 2070169695Skan if (run_read(sc, RT2860_WCID_ATTR(wcid), &attr)) 2071169695Skan return; 2072169695Skan attr = (attr & ~0xf) | (mode << 1) | RT2860_RX_PKEY_EN; 2073169695Skan if (run_write(sc, RT2860_WCID_ATTR(wcid), attr)) 2074169695Skan return; 2075169695Skan } 2076169695Skan 2077169695Skan /* TODO create a pass-thru key entry? */ 2078169695Skan 2079169695Skan /* need wcid to delete the right key later */ 2080169695Skan k->wk_pad = wcid; 2081169695Skan} 2082169695Skan 2083169695Skan/* 2084169695Skan * Don't have to be deferred, but in order to keep order of 2085169695Skan * execution, i.e. with run_key_delete(), defer this and let 2086169695Skan * run_cmdq_cb() maintain the order. 2087169695Skan * 2088169695Skan * return 0 on error 2089169695Skan */ 2090169695Skanstatic int 2091169695Skanrun_key_set(struct ieee80211vap *vap, struct ieee80211_key *k, 2092169695Skan const uint8_t mac[IEEE80211_ADDR_LEN]) 2093169695Skan{ 2094169695Skan struct ieee80211com *ic = vap->iv_ic; 2095169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 2096169695Skan uint32_t i; 2097169695Skan 2098169695Skan i = RUN_CMDQ_GET(&sc->cmdq_store); 2099169695Skan DPRINTF("cmdq_store=%d\n", i); 2100169695Skan sc->cmdq[i].func = run_key_set_cb; 2101169695Skan sc->cmdq[i].arg0 = NULL; 2102169695Skan sc->cmdq[i].arg1 = vap; 2103169695Skan sc->cmdq[i].k = k; 2104169695Skan IEEE80211_ADDR_COPY(sc->cmdq[i].mac, mac); 2105169695Skan ieee80211_runtask(ic, &sc->cmdq_task); 2106169695Skan 2107169695Skan /* 2108169695Skan * To make sure key will be set when hostapd 2109169695Skan * calls iv_key_set() before if_init(). 2110169695Skan */ 2111169695Skan if (vap->iv_opmode == IEEE80211_M_HOSTAP) { 2112169695Skan RUN_LOCK(sc); 2113169695Skan sc->cmdq_key_set = RUN_CMDQ_GO; 2114169695Skan RUN_UNLOCK(sc); 2115169695Skan } 2116169695Skan 2117169695Skan return (1); 2118169695Skan} 2119169695Skan 2120169695Skan/* 2121169695Skan * If wlan is destroyed without being brought down i.e. without 2122169695Skan * wlan down or wpa_cli terminate, this function is called after 2123169695Skan * vap is gone. Don't refer it. 2124169695Skan */ 2125169695Skanstatic void 2126169695Skanrun_key_delete_cb(void *arg) 2127169695Skan{ 2128169695Skan struct run_cmdq *cmdq = arg; 2129169695Skan struct run_softc *sc = cmdq->arg1; 2130169695Skan struct ieee80211_key *k = &cmdq->key; 2131169695Skan uint32_t attr; 2132169695Skan uint8_t wcid; 2133169695Skan 2134169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 2135169695Skan 2136169695Skan if (k->wk_flags & IEEE80211_KEY_GROUP) { 2137169695Skan /* remove group key */ 2138169695Skan DPRINTF("removing group key\n"); 2139169695Skan run_read(sc, RT2860_SKEY_MODE_0_7, &attr); 2140169695Skan attr &= ~(0xf << (k->wk_keyix * 4)); 2141169695Skan run_write(sc, RT2860_SKEY_MODE_0_7, attr); 2142169695Skan } else { 2143169695Skan /* remove pairwise key */ 2144169695Skan DPRINTF("removing key for wcid %x\n", k->wk_pad); 2145169695Skan /* matching wcid was written to wk_pad in run_key_set() */ 2146169695Skan wcid = k->wk_pad; 2147169695Skan run_read(sc, RT2860_WCID_ATTR(wcid), &attr); 2148169695Skan attr &= ~0xf; 2149169695Skan run_write(sc, RT2860_WCID_ATTR(wcid), attr); 2150169695Skan run_set_region_4(sc, RT2860_WCID_ENTRY(wcid), 0, 8); 2151169695Skan } 2152169695Skan 2153169695Skan k->wk_pad = 0; 2154169695Skan} 2155169695Skan 2156169695Skan/* 2157169695Skan * return 0 on error 2158169695Skan */ 2159169695Skanstatic int 2160169695Skanrun_key_delete(struct ieee80211vap *vap, struct ieee80211_key *k) 2161169695Skan{ 2162169695Skan struct ieee80211com *ic = vap->iv_ic; 2163169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 2164169695Skan struct ieee80211_key *k0; 2165169695Skan uint32_t i; 2166169695Skan 2167169695Skan /* 2168169695Skan * When called back, key might be gone. So, make a copy 2169169695Skan * of some values need to delete keys before deferring. 2170169695Skan * But, because of LOR with node lock, cannot use lock here. 2171169695Skan * So, use atomic instead. 2172169695Skan */ 2173169695Skan i = RUN_CMDQ_GET(&sc->cmdq_store); 2174169695Skan DPRINTF("cmdq_store=%d\n", i); 2175169695Skan sc->cmdq[i].func = run_key_delete_cb; 2176169695Skan sc->cmdq[i].arg0 = NULL; 2177169695Skan sc->cmdq[i].arg1 = sc; 2178169695Skan k0 = &sc->cmdq[i].key; 2179169695Skan k0->wk_flags = k->wk_flags; 2180169695Skan k0->wk_keyix = k->wk_keyix; 2181169695Skan /* matching wcid was written to wk_pad in run_key_set() */ 2182169695Skan k0->wk_pad = k->wk_pad; 2183169695Skan ieee80211_runtask(ic, &sc->cmdq_task); 2184169695Skan return (1); /* return fake success */ 2185169695Skan 2186169695Skan} 2187169695Skan 2188169695Skanstatic void 2189169695Skanrun_ratectl_to(void *arg) 2190169695Skan{ 2191169695Skan struct run_softc *sc = arg; 2192169695Skan 2193169695Skan /* do it in a process context, so it can go sleep */ 2194169695Skan ieee80211_runtask(sc->sc_ifp->if_l2com, &sc->ratectl_task); 2195169695Skan /* next timeout will be rescheduled in the callback task */ 2196169695Skan} 2197169695Skan 2198169695Skan/* ARGSUSED */ 2199169695Skanstatic void 2200169695Skanrun_ratectl_cb(void *arg, int pending) 2201169695Skan{ 2202169695Skan struct run_softc *sc = arg; 2203169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 2204169695Skan struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 2205169695Skan 2206169695Skan if (vap == NULL) 2207169695Skan return; 2208169695Skan 2209169695Skan if (sc->rvp_cnt <= 1 && vap->iv_opmode == IEEE80211_M_STA) 2210169695Skan run_iter_func(sc, vap->iv_bss); 2211169695Skan else { 2212169695Skan /* 2213169695Skan * run_reset_livelock() doesn't do anything with AMRR, 2214169695Skan * but Ralink wants us to call it every 1 sec. So, we 2215169695Skan * piggyback here rather than creating another callout. 2216169695Skan * Livelock may occur only in HOSTAP or IBSS mode 2217169695Skan * (when h/w is sending beacons). 2218169695Skan */ 2219169695Skan RUN_LOCK(sc); 2220169695Skan run_reset_livelock(sc); 2221169695Skan /* just in case, there are some stats to drain */ 2222169695Skan run_drain_fifo(sc); 2223169695Skan RUN_UNLOCK(sc); 2224169695Skan ieee80211_iterate_nodes(&ic->ic_sta, run_iter_func, sc); 2225169695Skan } 2226169695Skan 2227169695Skan if(sc->ratectl_run != RUN_RATECTL_OFF) 2228169695Skan usb_callout_reset(&sc->ratectl_ch, hz, run_ratectl_to, sc); 2229169695Skan} 2230169695Skan 2231169695Skanstatic void 2232169695Skanrun_drain_fifo(void *arg) 2233169695Skan{ 2234169695Skan struct run_softc *sc = arg; 2235169695Skan struct ifnet *ifp = sc->sc_ifp; 2236169695Skan uint32_t stat; 2237169695Skan uint16_t (*wstat)[3]; 2238169695Skan uint8_t wcid, mcs, pid; 2239169695Skan int8_t retry; 2240169695Skan 2241169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 2242169695Skan 2243169695Skan for (;;) { 2244169695Skan /* drain Tx status FIFO (maxsize = 16) */ 2245169695Skan run_read(sc, RT2860_TX_STAT_FIFO, &stat); 2246169695Skan DPRINTFN(4, "tx stat 0x%08x\n", stat); 2247169695Skan if (!(stat & RT2860_TXQ_VLD)) 2248169695Skan break; 2249169695Skan 2250169695Skan wcid = (stat >> RT2860_TXQ_WCID_SHIFT) & 0xff; 2251169695Skan 2252169695Skan /* if no ACK was requested, no feedback is available */ 2253169695Skan if (!(stat & RT2860_TXQ_ACKREQ) || wcid > RT2870_WCID_MAX || 2254169695Skan wcid == 0) 2255169695Skan continue; 2256169695Skan 2257169695Skan /* 2258169695Skan * Even though each stat is Tx-complete-status like format, 2259169695Skan * the device can poll stats. Because there is no guarantee 2260169695Skan * that the referring node is still around when read the stats. 2261169695Skan * So that, if we use ieee80211_ratectl_tx_update(), we will 2262169695Skan * have hard time not to refer already freed node. 2263169695Skan * 2264169695Skan * To eliminate such page faults, we poll stats in softc. 2265169695Skan * Then, update the rates later with ieee80211_ratectl_tx_update(). 2266169695Skan */ 2267169695Skan wstat = &(sc->wcid_stats[wcid]); 2268169695Skan (*wstat)[RUN_TXCNT]++; 2269169695Skan if (stat & RT2860_TXQ_OK) 2270169695Skan (*wstat)[RUN_SUCCESS]++; 2271169695Skan else 2272169695Skan ifp->if_oerrors++; 2273169695Skan /* 2274169695Skan * Check if there were retries, ie if the Tx success rate is 2275169695Skan * different from the requested rate. Note that it works only 2276169695Skan * because we do not allow rate fallback from OFDM to CCK. 2277169695Skan */ 2278169695Skan mcs = (stat >> RT2860_TXQ_MCS_SHIFT) & 0x7f; 2279169695Skan pid = (stat >> RT2860_TXQ_PID_SHIFT) & 0xf; 2280169695Skan if ((retry = pid -1 - mcs) > 0) { 2281169695Skan (*wstat)[RUN_TXCNT] += retry; 2282169695Skan (*wstat)[RUN_RETRY] += retry; 2283169695Skan } 2284169695Skan } 2285169695Skan DPRINTFN(3, "count=%d\n", sc->fifo_cnt); 2286169695Skan 2287169695Skan sc->fifo_cnt = 0; 2288169695Skan} 2289169695Skan 2290169695Skanstatic void 2291169695Skanrun_iter_func(void *arg, struct ieee80211_node *ni) 2292169695Skan{ 2293169695Skan struct run_softc *sc = arg; 2294169695Skan struct ieee80211vap *vap = ni->ni_vap; 2295169695Skan struct ieee80211com *ic = ni->ni_ic; 2296169695Skan struct ifnet *ifp = ic->ic_ifp; 2297169695Skan struct run_node *rn = (void *)ni; 2298169695Skan union run_stats sta[2]; 2299169695Skan uint16_t (*wstat)[3]; 2300169695Skan int txcnt, success, retrycnt, error; 2301169695Skan 2302169695Skan RUN_LOCK(sc); 2303169695Skan 2304169695Skan if (sc->rvp_cnt <= 1 && (vap->iv_opmode == IEEE80211_M_IBSS || 2305169695Skan vap->iv_opmode == IEEE80211_M_STA)) { 2306169695Skan /* read statistic counters (clear on read) and update AMRR state */ 2307169695Skan error = run_read_region_1(sc, RT2860_TX_STA_CNT0, (uint8_t *)sta, 2308169695Skan sizeof sta); 2309169695Skan if (error != 0) 2310169695Skan goto fail; 2311169695Skan 2312169695Skan /* count failed TX as errors */ 2313169695Skan ifp->if_oerrors += le16toh(sta[0].error.fail); 2314169695Skan 2315169695Skan retrycnt = le16toh(sta[1].tx.retry); 2316169695Skan success = le16toh(sta[1].tx.success); 2317169695Skan txcnt = retrycnt + success + le16toh(sta[0].error.fail); 2318169695Skan 2319169695Skan DPRINTFN(3, "retrycnt=%d success=%d failcnt=%d\n", 2320169695Skan retrycnt, success, le16toh(sta[0].error.fail)); 2321169695Skan } else { 2322169695Skan wstat = &(sc->wcid_stats[RUN_AID2WCID(ni->ni_associd)]); 2323169695Skan 2324169695Skan if (wstat == &(sc->wcid_stats[0]) || 2325169695Skan wstat > &(sc->wcid_stats[RT2870_WCID_MAX])) 2326169695Skan goto fail; 2327169695Skan 2328169695Skan txcnt = (*wstat)[RUN_TXCNT]; 2329169695Skan success = (*wstat)[RUN_SUCCESS]; 2330169695Skan retrycnt = (*wstat)[RUN_RETRY]; 2331169695Skan DPRINTFN(3, "retrycnt=%d txcnt=%d success=%d\n", 2332169695Skan retrycnt, txcnt, success); 2333169695Skan 2334169695Skan memset(wstat, 0, sizeof(*wstat)); 2335169695Skan } 2336169695Skan 2337169695Skan ieee80211_ratectl_tx_update(vap, ni, &txcnt, &success, &retrycnt); 2338169695Skan rn->amrr_ridx = ieee80211_ratectl_rate(ni, NULL, 0); 2339169695Skan 2340169695Skanfail: 2341169695Skan RUN_UNLOCK(sc); 2342169695Skan 2343169695Skan DPRINTFN(3, "ridx=%d\n", rn->amrr_ridx); 2344169695Skan} 2345169695Skan 2346169695Skanstatic void 2347169695Skanrun_newassoc_cb(void *arg) 2348169695Skan{ 2349169695Skan struct run_cmdq *cmdq = arg; 2350169695Skan struct ieee80211_node *ni = cmdq->arg1; 2351169695Skan struct run_softc *sc = ni->ni_vap->iv_ic->ic_ifp->if_softc; 2352169695Skan uint8_t wcid = cmdq->wcid; 2353169695Skan 2354169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 2355169695Skan 2356169695Skan run_write_region_1(sc, RT2860_WCID_ENTRY(wcid), 2357169695Skan ni->ni_macaddr, IEEE80211_ADDR_LEN); 2358169695Skan 2359169695Skan memset(&(sc->wcid_stats[wcid]), 0, sizeof(sc->wcid_stats[wcid])); 2360169695Skan} 2361169695Skan 2362169695Skanstatic void 2363169695Skanrun_newassoc(struct ieee80211_node *ni, int isnew) 2364169695Skan{ 2365169695Skan struct run_node *rn = (void *)ni; 2366169695Skan struct ieee80211_rateset *rs = &ni->ni_rates; 2367169695Skan struct ieee80211vap *vap = ni->ni_vap; 2368169695Skan struct ieee80211com *ic = vap->iv_ic; 2369169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 2370169695Skan uint8_t rate; 2371169695Skan uint8_t ridx; 2372169695Skan uint8_t wcid = RUN_AID2WCID(ni->ni_associd); 2373169695Skan int i, j; 2374169695Skan 2375169695Skan if (wcid > RT2870_WCID_MAX) { 2376169695Skan device_printf(sc->sc_dev, "wcid=%d out of range\n", wcid); 2377169695Skan return; 2378169695Skan } 2379169695Skan 2380169695Skan /* only interested in true associations */ 2381169695Skan if (isnew && ni->ni_associd != 0) { 2382169695Skan 2383169695Skan /* 2384169695Skan * This function could is called though timeout function. 2385169695Skan * Need to defer. 2386169695Skan */ 2387169695Skan uint32_t cnt = RUN_CMDQ_GET(&sc->cmdq_store); 2388169695Skan DPRINTF("cmdq_store=%d\n", cnt); 2389169695Skan sc->cmdq[cnt].func = run_newassoc_cb; 2390169695Skan sc->cmdq[cnt].arg0 = NULL; 2391169695Skan sc->cmdq[cnt].arg1 = ni; 2392169695Skan sc->cmdq[cnt].wcid = wcid; 2393169695Skan ieee80211_runtask(ic, &sc->cmdq_task); 2394169695Skan } 2395169695Skan 2396169695Skan DPRINTF("new assoc isnew=%d associd=%x addr=%s\n", 2397169695Skan isnew, ni->ni_associd, ether_sprintf(ni->ni_macaddr)); 2398169695Skan 2399169695Skan for (i = 0; i < rs->rs_nrates; i++) { 2400169695Skan rate = rs->rs_rates[i] & IEEE80211_RATE_VAL; 2401169695Skan /* convert 802.11 rate to hardware rate index */ 2402169695Skan for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) 2403169695Skan if (rt2860_rates[ridx].rate == rate) 2404169695Skan break; 2405169695Skan rn->ridx[i] = ridx; 2406169695Skan /* determine rate of control response frames */ 2407169695Skan for (j = i; j >= 0; j--) { 2408169695Skan if ((rs->rs_rates[j] & IEEE80211_RATE_BASIC) && 2409169695Skan rt2860_rates[rn->ridx[i]].phy == 2410169695Skan rt2860_rates[rn->ridx[j]].phy) 2411169695Skan break; 2412169695Skan } 2413169695Skan if (j >= 0) { 2414169695Skan rn->ctl_ridx[i] = rn->ridx[j]; 2415169695Skan } else { 2416169695Skan /* no basic rate found, use mandatory one */ 2417169695Skan rn->ctl_ridx[i] = rt2860_rates[ridx].ctl_ridx; 2418169695Skan } 2419169695Skan DPRINTF("rate=0x%02x ridx=%d ctl_ridx=%d\n", 2420169695Skan rs->rs_rates[i], rn->ridx[i], rn->ctl_ridx[i]); 2421169695Skan } 2422169695Skan rate = vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)].mgmtrate; 2423169695Skan for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) 2424169695Skan if (rt2860_rates[ridx].rate == rate) 2425169695Skan break; 2426169695Skan rn->mgt_ridx = ridx; 2427169695Skan DPRINTF("rate=%d, mgmt_ridx=%d\n", rate, rn->mgt_ridx); 2428169695Skan 2429169695Skan usb_callout_reset(&sc->ratectl_ch, hz, run_ratectl_to, sc); 2430169695Skan} 2431169695Skan 2432169695Skan/* 2433169695Skan * Return the Rx chain with the highest RSSI for a given frame. 2434169695Skan */ 2435169695Skanstatic __inline uint8_t 2436169695Skanrun_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi) 2437169695Skan{ 2438169695Skan uint8_t rxchain = 0; 2439169695Skan 2440169695Skan if (sc->nrxchains > 1) { 2441169695Skan if (rxwi->rssi[1] > rxwi->rssi[rxchain]) 2442169695Skan rxchain = 1; 2443169695Skan if (sc->nrxchains > 2) 2444169695Skan if (rxwi->rssi[2] > rxwi->rssi[rxchain]) 2445169695Skan rxchain = 2; 2446169695Skan } 2447169695Skan return (rxchain); 2448169695Skan} 2449169695Skan 2450169695Skanstatic void 2451169695Skanrun_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) 2452169695Skan{ 2453169695Skan struct ifnet *ifp = sc->sc_ifp; 2454169695Skan struct ieee80211com *ic = ifp->if_l2com; 2455169695Skan struct ieee80211_frame *wh; 2456169695Skan struct ieee80211_node *ni; 2457169695Skan struct rt2870_rxd *rxd; 2458169695Skan struct rt2860_rxwi *rxwi; 2459169695Skan uint32_t flags; 2460169695Skan uint16_t len, phy; 2461169695Skan uint8_t ant, rssi; 2462169695Skan int8_t nf; 2463169695Skan 2464169695Skan rxwi = mtod(m, struct rt2860_rxwi *); 2465169695Skan len = le16toh(rxwi->len) & 0xfff; 2466169695Skan if (__predict_false(len > dmalen)) { 2467169695Skan m_freem(m); 2468169695Skan ifp->if_ierrors++; 2469169695Skan DPRINTF("bad RXWI length %u > %u\n", len, dmalen); 2470169695Skan return; 2471169695Skan } 2472169695Skan /* Rx descriptor is located at the end */ 2473169695Skan rxd = (struct rt2870_rxd *)(mtod(m, caddr_t) + dmalen); 2474169695Skan flags = le32toh(rxd->flags); 2475169695Skan 2476169695Skan if (__predict_false(flags & (RT2860_RX_CRCERR | RT2860_RX_ICVERR))) { 2477169695Skan m_freem(m); 2478169695Skan ifp->if_ierrors++; 2479169695Skan DPRINTF("%s error.\n", (flags & RT2860_RX_CRCERR)?"CRC":"ICV"); 2480169695Skan return; 2481169695Skan } 2482169695Skan 2483169695Skan m->m_data += sizeof(struct rt2860_rxwi); 2484169695Skan m->m_pkthdr.len = m->m_len -= sizeof(struct rt2860_rxwi); 2485169695Skan 2486169695Skan wh = mtod(m, struct ieee80211_frame *); 2487169695Skan 2488169695Skan if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2489169695Skan wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 2490169695Skan m->m_flags |= M_WEP; 2491169695Skan } 2492169695Skan 2493169695Skan if (flags & RT2860_RX_L2PAD) { 2494169695Skan DPRINTFN(8, "received RT2860_RX_L2PAD frame\n"); 2495169695Skan len += 2; 2496169695Skan } 2497169695Skan 2498169695Skan ni = ieee80211_find_rxnode(ic, 2499169695Skan mtod(m, struct ieee80211_frame_min *)); 2500169695Skan 2501169695Skan if (__predict_false(flags & RT2860_RX_MICERR)) { 2502169695Skan /* report MIC failures to net80211 for TKIP */ 2503169695Skan if (ni != NULL) 2504169695Skan ieee80211_notify_michael_failure(ni->ni_vap, wh, rxwi->keyidx); 2505169695Skan m_freem(m); 2506169695Skan ifp->if_ierrors++; 2507169695Skan DPRINTF("MIC error. Someone is lying.\n"); 2508169695Skan return; 2509169695Skan } 2510169695Skan 2511169695Skan ant = run_maxrssi_chain(sc, rxwi); 2512169695Skan rssi = rxwi->rssi[ant]; 2513169695Skan nf = run_rssi2dbm(sc, rssi, ant); 2514169695Skan 2515169695Skan m->m_pkthdr.rcvif = ifp; 2516169695Skan m->m_pkthdr.len = m->m_len = len; 2517169695Skan 2518169695Skan if (ni != NULL) { 2519169695Skan (void)ieee80211_input(ni, m, rssi, nf); 2520169695Skan ieee80211_free_node(ni); 2521169695Skan } else { 2522169695Skan (void)ieee80211_input_all(ic, m, rssi, nf); 2523169695Skan } 2524169695Skan 2525169695Skan if (__predict_false(ieee80211_radiotap_active(ic))) { 2526169695Skan struct run_rx_radiotap_header *tap = &sc->sc_rxtap; 2527169695Skan 2528169695Skan tap->wr_flags = 0; 2529169695Skan tap->wr_chan_freq = htole16(ic->ic_bsschan->ic_freq); 2530169695Skan tap->wr_chan_flags = htole16(ic->ic_bsschan->ic_flags); 2531169695Skan tap->wr_antsignal = rssi; 2532169695Skan tap->wr_antenna = ant; 2533169695Skan tap->wr_dbm_antsignal = run_rssi2dbm(sc, rssi, ant); 2534169695Skan tap->wr_rate = 2; /* in case it can't be found below */ 2535169695Skan phy = le16toh(rxwi->phy); 2536169695Skan switch (phy & RT2860_PHY_MODE) { 2537169695Skan case RT2860_PHY_CCK: 2538169695Skan switch ((phy & RT2860_PHY_MCS) & ~RT2860_PHY_SHPRE) { 2539169695Skan case 0: tap->wr_rate = 2; break; 2540169695Skan case 1: tap->wr_rate = 4; break; 2541169695Skan case 2: tap->wr_rate = 11; break; 2542169695Skan case 3: tap->wr_rate = 22; break; 2543169695Skan } 2544169695Skan if (phy & RT2860_PHY_SHPRE) 2545169695Skan tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 2546169695Skan break; 2547169695Skan case RT2860_PHY_OFDM: 2548169695Skan switch (phy & RT2860_PHY_MCS) { 2549169695Skan case 0: tap->wr_rate = 12; break; 2550169695Skan case 1: tap->wr_rate = 18; break; 2551169695Skan case 2: tap->wr_rate = 24; break; 2552169695Skan case 3: tap->wr_rate = 36; break; 2553169695Skan case 4: tap->wr_rate = 48; break; 2554169695Skan case 5: tap->wr_rate = 72; break; 2555169695Skan case 6: tap->wr_rate = 96; break; 2556169695Skan case 7: tap->wr_rate = 108; break; 2557169695Skan } 2558169695Skan break; 2559169695Skan } 2560169695Skan } 2561169695Skan} 2562169695Skan 2563169695Skanstatic void 2564169695Skanrun_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) 2565169695Skan{ 2566169695Skan struct run_softc *sc = usbd_xfer_softc(xfer); 2567169695Skan struct ifnet *ifp = sc->sc_ifp; 2568169695Skan struct mbuf *m = NULL; 2569169695Skan struct mbuf *m0; 2570169695Skan uint32_t dmalen; 2571169695Skan int xferlen; 2572169695Skan 2573169695Skan usbd_xfer_status(xfer, &xferlen, NULL, NULL, NULL); 2574169695Skan 2575169695Skan switch (USB_GET_STATE(xfer)) { 2576169695Skan case USB_ST_TRANSFERRED: 2577169695Skan 2578169695Skan DPRINTFN(15, "rx done, actlen=%d\n", xferlen); 2579169695Skan 2580169695Skan if (xferlen < sizeof (uint32_t) + 2581169695Skan sizeof (struct rt2860_rxwi) + sizeof (struct rt2870_rxd)) { 2582169695Skan DPRINTF("xfer too short %d\n", xferlen); 2583169695Skan goto tr_setup; 2584169695Skan } 2585169695Skan 2586169695Skan m = sc->rx_m; 2587169695Skan sc->rx_m = NULL; 2588169695Skan 2589169695Skan /* FALLTHROUGH */ 2590169695Skan case USB_ST_SETUP: 2591169695Skantr_setup: 2592169695Skan if (sc->rx_m == NULL) { 2593169695Skan sc->rx_m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, 2594169695Skan MJUMPAGESIZE /* xfer can be bigger than MCLBYTES */); 2595169695Skan } 2596169695Skan if (sc->rx_m == NULL) { 2597169695Skan DPRINTF("could not allocate mbuf - idle with stall\n"); 2598169695Skan ifp->if_ierrors++; 2599169695Skan usbd_xfer_set_stall(xfer); 2600169695Skan usbd_xfer_set_frames(xfer, 0); 2601169695Skan } else { 2602169695Skan /* 2603169695Skan * Directly loading a mbuf cluster into DMA to 2604169695Skan * save some data copying. This works because 2605169695Skan * there is only one cluster. 2606169695Skan */ 2607169695Skan usbd_xfer_set_frame_data(xfer, 0, 2608169695Skan mtod(sc->rx_m, caddr_t), RUN_MAX_RXSZ); 2609169695Skan usbd_xfer_set_frames(xfer, 1); 2610169695Skan } 2611169695Skan usbd_transfer_submit(xfer); 2612169695Skan break; 2613169695Skan 2614169695Skan default: /* Error */ 2615169695Skan if (error != USB_ERR_CANCELLED) { 2616169695Skan /* try to clear stall first */ 2617169695Skan usbd_xfer_set_stall(xfer); 2618169695Skan 2619169695Skan if (error == USB_ERR_TIMEOUT) 2620169695Skan device_printf(sc->sc_dev, "device timeout\n"); 2621169695Skan 2622169695Skan ifp->if_ierrors++; 2623169695Skan 2624169695Skan goto tr_setup; 2625169695Skan } 2626169695Skan if (sc->rx_m != NULL) { 2627169695Skan m_freem(sc->rx_m); 2628169695Skan sc->rx_m = NULL; 2629169695Skan } 2630169695Skan break; 2631169695Skan } 2632169695Skan 2633169695Skan if (m == NULL) 2634169695Skan return; 2635169695Skan 2636169695Skan /* inputting all the frames must be last */ 2637169695Skan 2638169695Skan RUN_UNLOCK(sc); 2639169695Skan 2640169695Skan m->m_pkthdr.len = m->m_len = xferlen; 2641169695Skan 2642169695Skan /* HW can aggregate multiple 802.11 frames in a single USB xfer */ 2643169695Skan for(;;) { 2644169695Skan dmalen = le32toh(*mtod(m, uint32_t *)) & 0xffff; 2645169695Skan 2646169695Skan if ((dmalen == 0) || ((dmalen & 3) != 0)) { 2647169695Skan DPRINTF("bad DMA length %u\n", dmalen); 2648169695Skan break; 2649169695Skan } 2650169695Skan if ((dmalen + 8) > xferlen) { 2651169695Skan DPRINTF("bad DMA length %u > %d\n", 2652169695Skan dmalen + 8, xferlen); 2653169695Skan break; 2654169695Skan } 2655169695Skan 2656169695Skan /* If it is the last one or a single frame, we won't copy. */ 2657169695Skan if ((xferlen -= dmalen + 8) <= 8) { 2658169695Skan /* trim 32-bit DMA-len header */ 2659169695Skan m->m_data += 4; 2660169695Skan m->m_pkthdr.len = m->m_len -= 4; 2661169695Skan run_rx_frame(sc, m, dmalen); 2662169695Skan break; 2663169695Skan } 2664169695Skan 2665169695Skan /* copy aggregated frames to another mbuf */ 2666169695Skan m0 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 2667169695Skan if (__predict_false(m0 == NULL)) { 2668169695Skan DPRINTF("could not allocate mbuf\n"); 2669169695Skan ifp->if_ierrors++; 2670169695Skan break; 2671169695Skan } 2672169695Skan m_copydata(m, 4 /* skip 32-bit DMA-len header */, 2673169695Skan dmalen + sizeof(struct rt2870_rxd), mtod(m0, caddr_t)); 2674169695Skan m0->m_pkthdr.len = m0->m_len = 2675169695Skan dmalen + sizeof(struct rt2870_rxd); 2676169695Skan run_rx_frame(sc, m0, dmalen); 2677169695Skan 2678169695Skan /* update data ptr */ 2679169695Skan m->m_data += dmalen + 8; 2680169695Skan m->m_pkthdr.len = m->m_len -= dmalen + 8; 2681169695Skan } 2682169695Skan 2683169695Skan RUN_LOCK(sc); 2684169695Skan} 2685169695Skan 2686169695Skanstatic void 2687169695Skanrun_tx_free(struct run_endpoint_queue *pq, 2688169695Skan struct run_tx_data *data, int txerr) 2689169695Skan{ 2690169695Skan if (data->m != NULL) { 2691169695Skan if (data->m->m_flags & M_TXCB) 2692169695Skan ieee80211_process_callback(data->ni, data->m, 2693169695Skan txerr ? ETIMEDOUT : 0); 2694169695Skan m_freem(data->m); 2695169695Skan data->m = NULL; 2696169695Skan 2697169695Skan if (data->ni == NULL) { 2698169695Skan DPRINTF("no node\n"); 2699169695Skan } else { 2700169695Skan ieee80211_free_node(data->ni); 2701169695Skan data->ni = NULL; 2702169695Skan } 2703169695Skan } 2704169695Skan 2705169695Skan STAILQ_INSERT_TAIL(&pq->tx_fh, data, next); 2706169695Skan pq->tx_nfree++; 2707169695Skan} 2708169695Skan 2709169695Skanstatic void 2710169695Skanrun_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, unsigned int index) 2711169695Skan{ 2712169695Skan struct run_softc *sc = usbd_xfer_softc(xfer); 2713169695Skan struct ifnet *ifp = sc->sc_ifp; 2714169695Skan struct ieee80211com *ic = ifp->if_l2com; 2715169695Skan struct run_tx_data *data; 2716169695Skan struct ieee80211vap *vap = NULL; 2717169695Skan struct usb_page_cache *pc; 2718169695Skan struct run_endpoint_queue *pq = &sc->sc_epq[index]; 2719169695Skan struct mbuf *m; 2720169695Skan usb_frlength_t size; 2721169695Skan unsigned int len; 2722169695Skan int actlen; 2723169695Skan int sumlen; 2724169695Skan 2725169695Skan usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 2726169695Skan 2727169695Skan switch (USB_GET_STATE(xfer)) { 2728169695Skan case USB_ST_TRANSFERRED: 2729169695Skan DPRINTFN(11, "transfer complete: %d " 2730169695Skan "bytes @ index %d\n", actlen, index); 2731169695Skan 2732169695Skan data = usbd_xfer_get_priv(xfer); 2733169695Skan 2734169695Skan run_tx_free(pq, data, 0); 2735169695Skan ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 2736169695Skan 2737169695Skan usbd_xfer_set_priv(xfer, NULL); 2738169695Skan 2739169695Skan ifp->if_opackets++; 2740169695Skan 2741169695Skan /* FALLTHROUGH */ 2742169695Skan case USB_ST_SETUP: 2743169695Skantr_setup: 2744169695Skan data = STAILQ_FIRST(&pq->tx_qh); 2745169695Skan if (data == NULL) 2746169695Skan break; 2747169695Skan 2748169695Skan STAILQ_REMOVE_HEAD(&pq->tx_qh, next); 2749169695Skan 2750169695Skan m = data->m; 2751169695Skan if (m->m_pkthdr.len > RUN_MAX_TXSZ) { 2752169695Skan DPRINTF("data overflow, %u bytes\n", 2753169695Skan m->m_pkthdr.len); 2754169695Skan 2755169695Skan ifp->if_oerrors++; 2756169695Skan 2757169695Skan run_tx_free(pq, data, 1); 2758169695Skan 2759169695Skan goto tr_setup; 2760169695Skan } 2761169695Skan 2762169695Skan pc = usbd_xfer_get_frame(xfer, 0); 2763169695Skan size = sizeof(data->desc); 2764169695Skan usbd_copy_in(pc, 0, &data->desc, size); 2765169695Skan usbd_m_copy_in(pc, size, m, 0, m->m_pkthdr.len); 2766169695Skan 2767169695Skan vap = data->ni->ni_vap; 2768169695Skan if (ieee80211_radiotap_active_vap(vap)) { 2769169695Skan struct run_tx_radiotap_header *tap = &sc->sc_txtap; 2770169695Skan struct rt2860_txwi *txwi = 2771169695Skan (struct rt2860_txwi *)(&data->desc + sizeof(struct rt2870_txd)); 2772169695Skan 2773169695Skan tap->wt_flags = 0; 2774169695Skan tap->wt_rate = rt2860_rates[data->ridx].rate; 2775169695Skan tap->wt_chan_freq = htole16(vap->iv_bss->ni_chan->ic_freq); 2776169695Skan tap->wt_chan_flags = htole16(vap->iv_bss->ni_chan->ic_flags); 2777169695Skan tap->wt_hwqueue = index; 2778169695Skan if (le16toh(txwi->phy) & RT2860_PHY_SHPRE) 2779169695Skan tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 2780169695Skan 2781169695Skan ieee80211_radiotap_tx(vap, m); 2782169695Skan } 2783169695Skan 2784169695Skan /* align end on a 4-bytes boundary */ 2785169695Skan len = (size + IEEE80211_CRC_LEN + m->m_pkthdr.len + 3) & ~3; 2786169695Skan 2787169695Skan DPRINTFN(11, "sending frame len=%u xferlen=%u @ index %d\n", 2788169695Skan m->m_pkthdr.len, len, index); 2789169695Skan 2790169695Skan usbd_xfer_set_frame_len(xfer, 0, len); 2791169695Skan usbd_xfer_set_priv(xfer, data); 2792169695Skan 2793169695Skan usbd_transfer_submit(xfer); 2794169695Skan 2795169695Skan RUN_UNLOCK(sc); 2796169695Skan run_start(ifp); 2797169695Skan RUN_LOCK(sc); 2798169695Skan 2799169695Skan break; 2800169695Skan 2801169695Skan default: 2802169695Skan DPRINTF("USB transfer error, %s\n", 2803169695Skan usbd_errstr(error)); 2804169695Skan 2805169695Skan data = usbd_xfer_get_priv(xfer); 2806169695Skan 2807169695Skan ifp->if_oerrors++; 2808169695Skan 2809169695Skan if (data != NULL) { 2810169695Skan if(data->ni != NULL) 2811169695Skan vap = data->ni->ni_vap; 2812169695Skan run_tx_free(pq, data, error); 2813169695Skan usbd_xfer_set_priv(xfer, NULL); 2814169695Skan } 2815169695Skan if (vap == NULL) 2816169695Skan vap = TAILQ_FIRST(&ic->ic_vaps); 2817169695Skan 2818169695Skan if (error != USB_ERR_CANCELLED) { 2819169695Skan if (error == USB_ERR_TIMEOUT) { 2820169695Skan device_printf(sc->sc_dev, "device timeout\n"); 2821169695Skan uint32_t i = RUN_CMDQ_GET(&sc->cmdq_store); 2822169695Skan DPRINTF("cmdq_store=%d\n", i); 2823169695Skan sc->cmdq[i].func = run_usb_timeout_cb; 2824169695Skan sc->cmdq[i].arg0 = vap; 2825169695Skan ieee80211_runtask(ic, &sc->cmdq_task); 2826169695Skan } 2827169695Skan 2828169695Skan /* 2829169695Skan * Try to clear stall first, also if other 2830169695Skan * errors occur, hence clearing stall 2831169695Skan * introduces a 50 ms delay: 2832169695Skan */ 2833169695Skan usbd_xfer_set_stall(xfer); 2834169695Skan goto tr_setup; 2835169695Skan } 2836169695Skan break; 2837169695Skan } 2838169695Skan} 2839169695Skan 2840169695Skanstatic void 2841169695Skanrun_bulk_tx_callback0(struct usb_xfer *xfer, usb_error_t error) 2842169695Skan{ 2843169695Skan run_bulk_tx_callbackN(xfer, error, 0); 2844169695Skan} 2845169695Skan 2846169695Skanstatic void 2847169695Skanrun_bulk_tx_callback1(struct usb_xfer *xfer, usb_error_t error) 2848169695Skan{ 2849169695Skan run_bulk_tx_callbackN(xfer, error, 1); 2850169695Skan} 2851169695Skan 2852169695Skanstatic void 2853169695Skanrun_bulk_tx_callback2(struct usb_xfer *xfer, usb_error_t error) 2854169695Skan{ 2855169695Skan run_bulk_tx_callbackN(xfer, error, 2); 2856169695Skan} 2857169695Skan 2858169695Skanstatic void 2859169695Skanrun_bulk_tx_callback3(struct usb_xfer *xfer, usb_error_t error) 2860169695Skan{ 2861169695Skan run_bulk_tx_callbackN(xfer, error, 3); 2862169695Skan} 2863169695Skan 2864169695Skanstatic void 2865169695Skanrun_bulk_tx_callback4(struct usb_xfer *xfer, usb_error_t error) 2866169695Skan{ 2867169695Skan run_bulk_tx_callbackN(xfer, error, 4); 2868169695Skan} 2869169695Skan 2870169695Skanstatic void 2871169695Skanrun_bulk_tx_callback5(struct usb_xfer *xfer, usb_error_t error) 2872169695Skan{ 2873169695Skan run_bulk_tx_callbackN(xfer, error, 5); 2874169695Skan} 2875169695Skan 2876169695Skanstatic void 2877169695Skanrun_set_tx_desc(struct run_softc *sc, struct run_tx_data *data) 2878169695Skan{ 2879169695Skan struct mbuf *m = data->m; 2880169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 2881169695Skan struct ieee80211vap *vap = data->ni->ni_vap; 2882169695Skan struct ieee80211_frame *wh; 2883169695Skan struct rt2870_txd *txd; 2884169695Skan struct rt2860_txwi *txwi; 2885169695Skan uint16_t xferlen; 2886169695Skan uint16_t mcs; 2887169695Skan uint8_t ridx = data->ridx; 2888169695Skan uint8_t pad; 2889169695Skan 2890169695Skan /* get MCS code from rate index */ 2891169695Skan mcs = rt2860_rates[ridx].mcs; 2892169695Skan 2893169695Skan xferlen = sizeof(*txwi) + m->m_pkthdr.len; 2894169695Skan 2895169695Skan /* roundup to 32-bit alignment */ 2896169695Skan xferlen = (xferlen + 3) & ~3; 2897169695Skan 2898169695Skan txd = (struct rt2870_txd *)&data->desc; 2899169695Skan txd->len = htole16(xferlen); 2900169695Skan 2901169695Skan wh = mtod(m, struct ieee80211_frame *); 2902169695Skan 2903169695Skan /* 2904169695Skan * Ether both are true or both are false, the header 2905169695Skan * are nicely aligned to 32-bit. So, no L2 padding. 2906169695Skan */ 2907169695Skan if(IEEE80211_HAS_ADDR4(wh) == IEEE80211_QOS_HAS_SEQ(wh)) 2908169695Skan pad = 0; 2909169695Skan else 2910169695Skan pad = 2; 2911169695Skan 2912169695Skan /* setup TX Wireless Information */ 2913169695Skan txwi = (struct rt2860_txwi *)(txd + 1); 2914169695Skan txwi->len = htole16(m->m_pkthdr.len - pad); 2915169695Skan if (rt2860_rates[ridx].phy == IEEE80211_T_DS) { 2916169695Skan txwi->phy = htole16(RT2860_PHY_CCK); 2917169695Skan if (ridx != RT2860_RIDX_CCK1 && 2918169695Skan (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) 2919169695Skan mcs |= RT2860_PHY_SHPRE; 2920169695Skan } else 2921169695Skan txwi->phy = htole16(RT2860_PHY_OFDM); 2922169695Skan txwi->phy |= htole16(mcs); 2923169695Skan 2924169695Skan /* check if RTS/CTS or CTS-to-self protection is required */ 2925169695Skan if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 2926169695Skan (m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold || 2927169695Skan ((ic->ic_flags & IEEE80211_F_USEPROT) && 2928169695Skan rt2860_rates[ridx].phy == IEEE80211_T_OFDM))) 2929169695Skan txwi->txop |= RT2860_TX_TXOP_HT; 2930169695Skan else 2931169695Skan txwi->txop |= RT2860_TX_TXOP_BACKOFF; 2932169695Skan 2933169695Skan if (vap->iv_opmode != IEEE80211_M_STA && !IEEE80211_QOS_HAS_SEQ(wh)) 2934169695Skan txwi->xflags |= RT2860_TX_NSEQ; 2935169695Skan} 2936169695Skan 2937169695Skan/* This function must be called locked */ 2938169695Skanstatic int 2939169695Skanrun_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) 2940169695Skan{ 2941169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 2942169695Skan struct ieee80211vap *vap = ni->ni_vap; 2943169695Skan struct ieee80211_frame *wh; 2944169695Skan struct ieee80211_channel *chan; 2945169695Skan const struct ieee80211_txparam *tp; 2946169695Skan struct run_node *rn = (void *)ni; 2947169695Skan struct run_tx_data *data; 2948169695Skan struct rt2870_txd *txd; 2949169695Skan struct rt2860_txwi *txwi; 2950169695Skan uint16_t qos; 2951169695Skan uint16_t dur; 2952169695Skan uint16_t qid; 2953169695Skan uint8_t type; 2954169695Skan uint8_t tid; 2955169695Skan uint8_t ridx; 2956169695Skan uint8_t ctl_ridx; 2957169695Skan uint8_t qflags; 2958169695Skan uint8_t xflags = 0; 2959169695Skan int hasqos; 2960169695Skan 2961169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 2962169695Skan 2963169695Skan wh = mtod(m, struct ieee80211_frame *); 2964169695Skan 2965169695Skan type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 2966169695Skan 2967169695Skan /* 2968169695Skan * There are 7 bulk endpoints: 1 for RX 2969169695Skan * and 6 for TX (4 EDCAs + HCCA + Prio). 2970169695Skan * Update 03-14-2009: some devices like the Planex GW-US300MiniS 2971169695Skan * seem to have only 4 TX bulk endpoints (Fukaumi Naoki). 2972169695Skan */ 2973169695Skan if ((hasqos = IEEE80211_QOS_HAS_SEQ(wh))) { 2974169695Skan uint8_t *frm; 2975169695Skan 2976169695Skan if(IEEE80211_HAS_ADDR4(wh)) 2977169695Skan frm = ((struct ieee80211_qosframe_addr4 *)wh)->i_qos; 2978169695Skan else 2979169695Skan frm =((struct ieee80211_qosframe *)wh)->i_qos; 2980169695Skan 2981169695Skan qos = le16toh(*(const uint16_t *)frm); 2982169695Skan tid = qos & IEEE80211_QOS_TID; 2983169695Skan qid = TID_TO_WME_AC(tid); 2984169695Skan } else { 2985169695Skan qos = 0; 2986169695Skan tid = 0; 2987169695Skan qid = WME_AC_BE; 2988169695Skan } 2989169695Skan qflags = (qid < 4) ? RT2860_TX_QSEL_EDCA : RT2860_TX_QSEL_HCCA; 2990169695Skan 2991169695Skan DPRINTFN(8, "qos %d\tqid %d\ttid %d\tqflags %x\n", 2992169695Skan qos, qid, tid, qflags); 2993169695Skan 2994169695Skan chan = (ni->ni_chan != IEEE80211_CHAN_ANYC)?ni->ni_chan:ic->ic_curchan; 2995169695Skan tp = &vap->iv_txparms[ieee80211_chan2mode(chan)]; 2996169695Skan 2997169695Skan /* pickup a rate index */ 2998169695Skan if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 2999169695Skan type != IEEE80211_FC0_TYPE_DATA) { 3000169695Skan ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ? 3001169695Skan RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1; 3002169695Skan ctl_ridx = rt2860_rates[ridx].ctl_ridx; 3003169695Skan } else { 3004169695Skan if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 3005169695Skan ridx = rn->fix_ridx; 3006169695Skan else 3007169695Skan ridx = rn->amrr_ridx; 3008169695Skan ctl_ridx = rt2860_rates[ridx].ctl_ridx; 3009169695Skan } 3010169695Skan 3011169695Skan if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 3012169695Skan (!hasqos || (qos & IEEE80211_QOS_ACKPOLICY) != 3013169695Skan IEEE80211_QOS_ACKPOLICY_NOACK)) { 3014169695Skan xflags |= RT2860_TX_ACK; 3015169695Skan if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) 3016169695Skan dur = rt2860_rates[ctl_ridx].sp_ack_dur; 3017169695Skan else 3018169695Skan dur = rt2860_rates[ctl_ridx].lp_ack_dur; 3019169695Skan *(uint16_t *)wh->i_dur = htole16(dur); 3020169695Skan } 3021169695Skan 3022169695Skan /* reserve slots for mgmt packets, just in case */ 3023169695Skan if (sc->sc_epq[qid].tx_nfree < 3) { 3024169695Skan DPRINTFN(10, "tx ring %d is full\n", qid); 3025169695Skan return (-1); 3026169695Skan } 3027169695Skan 3028169695Skan data = STAILQ_FIRST(&sc->sc_epq[qid].tx_fh); 3029169695Skan STAILQ_REMOVE_HEAD(&sc->sc_epq[qid].tx_fh, next); 3030169695Skan sc->sc_epq[qid].tx_nfree--; 3031169695Skan 3032169695Skan txd = (struct rt2870_txd *)&data->desc; 3033169695Skan txd->flags = qflags; 3034169695Skan txwi = (struct rt2860_txwi *)(txd + 1); 3035169695Skan txwi->xflags = xflags; 3036169695Skan txwi->wcid = IEEE80211_IS_MULTICAST(wh->i_addr1) ? 3037169695Skan 0 : RUN_AID2WCID(ni->ni_associd); 3038169695Skan /* clear leftover garbage bits */ 3039169695Skan txwi->flags = 0; 3040169695Skan txwi->txop = 0; 3041169695Skan 3042169695Skan data->m = m; 3043169695Skan data->ni = ni; 3044169695Skan data->ridx = ridx; 3045169695Skan 3046169695Skan run_set_tx_desc(sc, data); 3047169695Skan 3048169695Skan /* 3049169695Skan * The chip keeps track of 2 kind of Tx stats, 3050169695Skan * * TX_STAT_FIFO, for per WCID stats, and 3051169695Skan * * TX_STA_CNT0 for all-TX-in-one stats. 3052169695Skan * 3053169695Skan * To use FIFO stats, we need to store MCS into the driver-private 3054169695Skan * PacketID field. So that, we can tell whose stats when we read them. 3055169695Skan * We add 1 to the MCS because setting the PacketID field to 0 means 3056169695Skan * that we don't want feedback in TX_STAT_FIFO. 3057169695Skan * And, that's what we want for STA mode, since TX_STA_CNT0 does the job. 3058169695Skan * 3059169695Skan * FIFO stats doesn't count Tx with WCID 0xff, so we do this in run_tx(). 3060169695Skan */ 3061169695Skan if (sc->rvp_cnt > 1 || vap->iv_opmode == IEEE80211_M_HOSTAP || 3062169695Skan vap->iv_opmode == IEEE80211_M_MBSS) { 3063169695Skan uint16_t pid = (rt2860_rates[ridx].mcs + 1) & 0xf; 3064169695Skan txwi->len |= htole16(pid << RT2860_TX_PID_SHIFT); 3065169695Skan 3066169695Skan /* 3067169695Skan * Unlike PCI based devices, we don't get any interrupt from 3068169695Skan * USB devices, so we simulate FIFO-is-full interrupt here. 3069169695Skan * Ralink recomends to drain FIFO stats every 100 ms, but 16 slots 3070169695Skan * quickly get fulled. To prevent overflow, increment a counter on 3071169695Skan * every FIFO stat request, so we know how many slots are left. 3072169695Skan * We do this only in HOSTAP or multiple vap mode since FIFO stats 3073169695Skan * are used only in those modes. 3074169695Skan * We just drain stats. AMRR gets updated every 1 sec by 3075169695Skan * run_ratectl_cb() via callout. 3076169695Skan * Call it early. Otherwise overflow. 3077169695Skan */ 3078169695Skan if (sc->fifo_cnt++ == 10) { 3079169695Skan /* 3080169695Skan * With multiple vaps or if_bridge, if_start() is called 3081169695Skan * with a non-sleepable lock, tcpinp. So, need to defer. 3082169695Skan */ 3083169695Skan uint32_t i = RUN_CMDQ_GET(&sc->cmdq_store); 3084169695Skan DPRINTFN(6, "cmdq_store=%d\n", i); 3085169695Skan sc->cmdq[i].func = run_drain_fifo; 3086169695Skan sc->cmdq[i].arg0 = sc; 3087169695Skan ieee80211_runtask(ic, &sc->cmdq_task); 3088169695Skan } 3089169695Skan } 3090169695Skan 3091169695Skan STAILQ_INSERT_TAIL(&sc->sc_epq[qid].tx_qh, data, next); 3092169695Skan 3093169695Skan usbd_transfer_start(sc->sc_xfer[qid]); 3094169695Skan 3095169695Skan DPRINTFN(8, "sending data frame len=%d rate=%d qid=%d\n", m->m_pkthdr.len + 3096169695Skan (int)(sizeof (struct rt2870_txd) + sizeof (struct rt2860_rxwi)), 3097169695Skan rt2860_rates[ridx].rate, qid); 3098169695Skan 3099169695Skan return (0); 3100169695Skan} 3101169695Skan 3102169695Skanstatic int 3103169695Skanrun_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) 3104169695Skan{ 3105169695Skan struct ifnet *ifp = sc->sc_ifp; 3106169695Skan struct ieee80211com *ic = ifp->if_l2com; 3107169695Skan struct run_node *rn = (void *)ni; 3108169695Skan struct run_tx_data *data; 3109169695Skan struct ieee80211_frame *wh; 3110169695Skan struct rt2870_txd *txd; 3111169695Skan struct rt2860_txwi *txwi; 3112169695Skan uint16_t dur; 3113169695Skan uint8_t ridx = rn->mgt_ridx; 3114169695Skan uint8_t type; 3115169695Skan uint8_t xflags = 0; 3116169695Skan uint8_t wflags = 0; 3117169695Skan 3118169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 3119169695Skan 3120169695Skan wh = mtod(m, struct ieee80211_frame *); 3121169695Skan 3122169695Skan type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 3123169695Skan 3124169695Skan /* tell hardware to add timestamp for probe responses */ 3125169695Skan if ((wh->i_fc[0] & 3126169695Skan (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == 3127169695Skan (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) 3128169695Skan wflags |= RT2860_TX_TS; 3129169695Skan else if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 3130169695Skan xflags |= RT2860_TX_ACK; 3131169695Skan 3132169695Skan dur = ieee80211_ack_duration(ic->ic_rt, rt2860_rates[ridx].rate, 3133169695Skan ic->ic_flags & IEEE80211_F_SHPREAMBLE); 3134169695Skan *(uint16_t *)wh->i_dur = htole16(dur); 3135169695Skan } 3136169695Skan 3137169695Skan if (sc->sc_epq[0].tx_nfree == 0) { 3138169695Skan /* let caller free mbuf */ 3139169695Skan ifp->if_drv_flags |= IFF_DRV_OACTIVE; 3140169695Skan return (EIO); 3141169695Skan } 3142169695Skan data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh); 3143169695Skan STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next); 3144169695Skan sc->sc_epq[0].tx_nfree--; 3145169695Skan 3146169695Skan txd = (struct rt2870_txd *)&data->desc; 3147169695Skan txd->flags = RT2860_TX_QSEL_EDCA; 3148169695Skan txwi = (struct rt2860_txwi *)(txd + 1); 3149169695Skan txwi->wcid = 0xff; 3150169695Skan txwi->flags = wflags; 3151169695Skan txwi->xflags = xflags; 3152169695Skan txwi->txop = 0; /* clear leftover garbage bits */ 3153169695Skan 3154169695Skan data->m = m; 3155169695Skan data->ni = ni; 3156169695Skan data->ridx = ridx; 3157169695Skan 3158169695Skan run_set_tx_desc(sc, data); 3159169695Skan 3160169695Skan DPRINTFN(10, "sending mgt frame len=%d rate=%d\n", m->m_pkthdr.len + 3161169695Skan (int)(sizeof (struct rt2870_txd) + sizeof (struct rt2860_rxwi)), 3162169695Skan rt2860_rates[ridx].rate); 3163169695Skan 3164169695Skan STAILQ_INSERT_TAIL(&sc->sc_epq[0].tx_qh, data, next); 3165169695Skan 3166169695Skan usbd_transfer_start(sc->sc_xfer[0]); 3167169695Skan 3168169695Skan return (0); 3169169695Skan} 3170169695Skan 3171169695Skanstatic int 3172169695Skanrun_sendprot(struct run_softc *sc, 3173169695Skan const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) 3174169695Skan{ 3175169695Skan struct ieee80211com *ic = ni->ni_ic; 3176169695Skan struct ieee80211_frame *wh; 3177169695Skan struct run_tx_data *data; 3178169695Skan struct rt2870_txd *txd; 3179169695Skan struct rt2860_txwi *txwi; 3180169695Skan struct mbuf *mprot; 3181169695Skan int ridx; 3182169695Skan int protrate; 3183169695Skan int ackrate; 3184169695Skan int pktlen; 3185169695Skan int isshort; 3186169695Skan uint16_t dur; 3187169695Skan uint8_t type; 3188169695Skan uint8_t wflags = 0; 3189169695Skan uint8_t xflags = 0; 3190169695Skan 3191169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 3192169695Skan 3193169695Skan KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, 3194169695Skan ("protection %d", prot)); 3195169695Skan 3196169695Skan wh = mtod(m, struct ieee80211_frame *); 3197169695Skan pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; 3198169695Skan type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 3199169695Skan 3200169695Skan protrate = ieee80211_ctl_rate(ic->ic_rt, rate); 3201169695Skan ackrate = ieee80211_ack_rate(ic->ic_rt, rate); 3202169695Skan 3203169695Skan isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; 3204169695Skan dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) 3205169695Skan + ieee80211_ack_duration(ic->ic_rt, rate, isshort); 3206169695Skan wflags = RT2860_TX_FRAG; 3207169695Skan 3208169695Skan /* check that there are free slots before allocating the mbuf */ 3209169695Skan if (sc->sc_epq[0].tx_nfree == 0) { 3210169695Skan /* let caller free mbuf */ 3211169695Skan sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE; 3212169695Skan return (ENOBUFS); 3213169695Skan } 3214169695Skan 3215169695Skan if (prot == IEEE80211_PROT_RTSCTS) { 3216169695Skan /* NB: CTS is the same size as an ACK */ 3217169695Skan dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); 3218169695Skan xflags |= RT2860_TX_ACK; 3219169695Skan mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); 3220169695Skan } else { 3221169695Skan mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); 3222169695Skan } 3223169695Skan if (mprot == NULL) { 3224169695Skan sc->sc_ifp->if_oerrors++; 3225169695Skan DPRINTF("could not allocate mbuf\n"); 3226169695Skan return (ENOBUFS); 3227169695Skan } 3228169695Skan 3229169695Skan data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh); 3230169695Skan STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next); 3231169695Skan sc->sc_epq[0].tx_nfree--; 3232169695Skan 3233169695Skan txd = (struct rt2870_txd *)&data->desc; 3234169695Skan txd->flags = RT2860_TX_QSEL_EDCA; 3235169695Skan txwi = (struct rt2860_txwi *)(txd + 1); 3236169695Skan txwi->wcid = 0xff; 3237169695Skan txwi->flags = wflags; 3238169695Skan txwi->xflags = xflags; 3239169695Skan txwi->txop = 0; /* clear leftover garbage bits */ 3240169695Skan 3241169695Skan data->m = mprot; 3242169695Skan data->ni = ieee80211_ref_node(ni); 3243169695Skan 3244169695Skan for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) 3245169695Skan if (rt2860_rates[ridx].rate == protrate) 3246169695Skan break; 3247169695Skan data->ridx = ridx; 3248169695Skan 3249169695Skan run_set_tx_desc(sc, data); 3250169695Skan 3251169695Skan DPRINTFN(1, "sending prot len=%u rate=%u\n", 3252169695Skan m->m_pkthdr.len, rate); 3253169695Skan 3254169695Skan STAILQ_INSERT_TAIL(&sc->sc_epq[0].tx_qh, data, next); 3255169695Skan 3256169695Skan usbd_transfer_start(sc->sc_xfer[0]); 3257169695Skan 3258169695Skan return (0); 3259169695Skan} 3260169695Skan 3261169695Skanstatic int 3262169695Skanrun_tx_param(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 3263169695Skan const struct ieee80211_bpf_params *params) 3264169695Skan{ 3265169695Skan struct ieee80211com *ic = ni->ni_ic; 3266169695Skan struct ieee80211_frame *wh; 3267169695Skan struct run_tx_data *data; 3268169695Skan struct rt2870_txd *txd; 3269169695Skan struct rt2860_txwi *txwi; 3270169695Skan uint8_t type; 3271169695Skan uint8_t ridx; 3272169695Skan uint8_t rate; 3273169695Skan uint8_t opflags = 0; 3274169695Skan uint8_t xflags = 0; 3275169695Skan int error; 3276169695Skan 3277169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 3278169695Skan 3279169695Skan KASSERT(params != NULL, ("no raw xmit params")); 3280169695Skan 3281169695Skan wh = mtod(m, struct ieee80211_frame *); 3282169695Skan type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 3283169695Skan 3284169695Skan rate = params->ibp_rate0; 3285169695Skan if (!ieee80211_isratevalid(ic->ic_rt, rate)) { 3286169695Skan /* let caller free mbuf */ 3287169695Skan return (EINVAL); 3288169695Skan } 3289169695Skan 3290169695Skan if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) 3291169695Skan xflags |= RT2860_TX_ACK; 3292169695Skan if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) { 3293169695Skan error = run_sendprot(sc, m, ni, 3294169695Skan params->ibp_flags & IEEE80211_BPF_RTS ? 3295169695Skan IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, 3296169695Skan rate); 3297169695Skan if (error) { 3298169695Skan /* let caller free mbuf */ 3299169695Skan return error; 3300169695Skan } 3301169695Skan opflags |= /*XXX RT2573_TX_LONG_RETRY |*/ RT2860_TX_TXOP_SIFS; 3302169695Skan } 3303169695Skan 3304169695Skan if (sc->sc_epq[0].tx_nfree == 0) { 3305169695Skan /* let caller free mbuf */ 3306169695Skan sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE; 3307169695Skan DPRINTF("sending raw frame, but tx ring is full\n"); 3308169695Skan return (EIO); 3309169695Skan } 3310169695Skan data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh); 3311169695Skan STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next); 3312169695Skan sc->sc_epq[0].tx_nfree--; 3313169695Skan 3314169695Skan txd = (struct rt2870_txd *)&data->desc; 3315169695Skan txd->flags = RT2860_TX_QSEL_EDCA; 3316169695Skan txwi = (struct rt2860_txwi *)(txd + 1); 3317169695Skan txwi->wcid = 0xff; 3318169695Skan txwi->xflags = xflags; 3319169695Skan txwi->txop = opflags; 3320169695Skan txwi->flags = 0; /* clear leftover garbage bits */ 3321169695Skan 3322169695Skan data->m = m; 3323169695Skan data->ni = ni; 3324169695Skan for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) 3325169695Skan if (rt2860_rates[ridx].rate == rate) 3326169695Skan break; 3327169695Skan data->ridx = ridx; 3328169695Skan 3329169695Skan run_set_tx_desc(sc, data); 3330169695Skan 3331169695Skan DPRINTFN(10, "sending raw frame len=%u rate=%u\n", 3332169695Skan m->m_pkthdr.len, rate); 3333169695Skan 3334169695Skan STAILQ_INSERT_TAIL(&sc->sc_epq[0].tx_qh, data, next); 3335169695Skan 3336169695Skan usbd_transfer_start(sc->sc_xfer[0]); 3337169695Skan 3338169695Skan return (0); 3339169695Skan} 3340169695Skan 3341169695Skanstatic int 3342169695Skanrun_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 3343169695Skan const struct ieee80211_bpf_params *params) 3344169695Skan{ 3345169695Skan struct ifnet *ifp = ni->ni_ic->ic_ifp; 3346169695Skan struct run_softc *sc = ifp->if_softc; 3347169695Skan int error = 0; 3348169695Skan 3349169695Skan RUN_LOCK(sc); 3350169695Skan 3351169695Skan /* prevent management frames from being sent if we're not ready */ 3352169695Skan if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 3353169695Skan error = ENETDOWN; 3354169695Skan goto done; 3355169695Skan } 3356169695Skan 3357169695Skan if (params == NULL) { 3358169695Skan /* tx mgt packet */ 3359169695Skan if ((error = run_tx_mgt(sc, m, ni)) != 0) { 3360169695Skan ifp->if_oerrors++; 3361169695Skan DPRINTF("mgt tx failed\n"); 3362169695Skan goto done; 3363169695Skan } 3364169695Skan } else { 3365169695Skan /* tx raw packet with param */ 3366169695Skan if ((error = run_tx_param(sc, m, ni, params)) != 0) { 3367169695Skan ifp->if_oerrors++; 3368169695Skan DPRINTF("tx with param failed\n"); 3369169695Skan goto done; 3370169695Skan } 3371169695Skan } 3372169695Skan 3373169695Skan ifp->if_opackets++; 3374169695Skan 3375169695Skandone: 3376169695Skan RUN_UNLOCK(sc); 3377169695Skan 3378169695Skan if (error != 0) { 3379169695Skan if(m != NULL) 3380169695Skan m_freem(m); 3381169695Skan ieee80211_free_node(ni); 3382169695Skan } 3383169695Skan 3384169695Skan return (error); 3385169695Skan} 3386169695Skan 3387169695Skanstatic void 3388169695Skanrun_start(struct ifnet *ifp) 3389169695Skan{ 3390169695Skan struct run_softc *sc = ifp->if_softc; 3391169695Skan struct ieee80211_node *ni; 3392169695Skan struct mbuf *m; 3393169695Skan 3394169695Skan RUN_LOCK(sc); 3395169695Skan 3396169695Skan if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 3397169695Skan RUN_UNLOCK(sc); 3398169695Skan return; 3399169695Skan } 3400169695Skan 3401169695Skan for (;;) { 3402169695Skan /* send data frames */ 3403169695Skan IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 3404169695Skan if (m == NULL) 3405169695Skan break; 3406169695Skan 3407169695Skan ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 3408169695Skan if (run_tx(sc, m, ni) != 0) { 3409169695Skan IFQ_DRV_PREPEND(&ifp->if_snd, m); 3410169695Skan ifp->if_drv_flags |= IFF_DRV_OACTIVE; 3411169695Skan break; 3412169695Skan } 3413169695Skan } 3414169695Skan 3415169695Skan RUN_UNLOCK(sc); 3416169695Skan} 3417169695Skan 3418169695Skanstatic int 3419169695Skanrun_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 3420169695Skan{ 3421169695Skan struct run_softc *sc = ifp->if_softc; 3422169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 3423169695Skan struct ifreq *ifr = (struct ifreq *) data; 3424169695Skan int startall = 0; 3425169695Skan int error = 0; 3426169695Skan 3427169695Skan switch (cmd) { 3428169695Skan case SIOCSIFFLAGS: 3429169695Skan RUN_LOCK(sc); 3430169695Skan if (ifp->if_flags & IFF_UP) { 3431169695Skan if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)){ 3432169695Skan startall = 1; 3433169695Skan run_init_locked(sc); 3434169695Skan } else 3435169695Skan run_update_promisc_locked(ifp); 3436169695Skan } else { 3437169695Skan if (ifp->if_drv_flags & IFF_DRV_RUNNING && 3438169695Skan (ic->ic_nrunning == 0 || sc->rvp_cnt <= 1)) { 3439169695Skan run_stop(sc); 3440169695Skan } 3441169695Skan } 3442169695Skan RUN_UNLOCK(sc); 3443169695Skan if (startall) 3444169695Skan ieee80211_start_all(ic); 3445169695Skan break; 3446169695Skan case SIOCGIFMEDIA: 3447169695Skan error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 3448169695Skan break; 3449169695Skan case SIOCGIFADDR: 3450169695Skan error = ether_ioctl(ifp, cmd, data); 3451169695Skan break; 3452169695Skan default: 3453169695Skan error = EINVAL; 3454169695Skan break; 3455169695Skan } 3456169695Skan 3457169695Skan return (error); 3458169695Skan} 3459169695Skan 3460169695Skanstatic void 3461169695Skanrun_set_agc(struct run_softc *sc, uint8_t agc) 3462169695Skan{ 3463169695Skan uint8_t bbp; 3464169695Skan 3465169695Skan if (sc->mac_ver == 0x3572) { 3466169695Skan run_bbp_read(sc, 27, &bbp); 3467169695Skan bbp &= ~(0x3 << 5); 3468169695Skan run_bbp_write(sc, 27, bbp | 0 << 5); /* select Rx0 */ 3469169695Skan run_bbp_write(sc, 66, agc); 3470169695Skan run_bbp_write(sc, 27, bbp | 1 << 5); /* select Rx1 */ 3471169695Skan run_bbp_write(sc, 66, agc); 3472169695Skan } else 3473169695Skan run_bbp_write(sc, 66, agc); 3474169695Skan} 3475169695Skan 3476169695Skanstatic void 3477169695Skanrun_select_chan_group(struct run_softc *sc, int group) 3478169695Skan{ 3479169695Skan uint32_t tmp; 3480169695Skan uint8_t agc; 3481169695Skan 3482169695Skan run_bbp_write(sc, 62, 0x37 - sc->lna[group]); 3483169695Skan run_bbp_write(sc, 63, 0x37 - sc->lna[group]); 3484169695Skan run_bbp_write(sc, 64, 0x37 - sc->lna[group]); 3485169695Skan run_bbp_write(sc, 86, 0x00); 3486169695Skan 3487169695Skan if (group == 0) { 3488169695Skan if (sc->ext_2ghz_lna) { 3489169695Skan run_bbp_write(sc, 82, 0x62); 3490169695Skan run_bbp_write(sc, 75, 0x46); 3491169695Skan } else { 3492169695Skan run_bbp_write(sc, 82, 0x84); 3493169695Skan run_bbp_write(sc, 75, 0x50); 3494169695Skan } 3495169695Skan } else { 3496169695Skan if (sc->mac_ver == 0x3572) 3497169695Skan run_bbp_write(sc, 82, 0x94); 3498169695Skan else 3499169695Skan run_bbp_write(sc, 82, 0xf2); 3500169695Skan if (sc->ext_5ghz_lna) 3501169695Skan run_bbp_write(sc, 75, 0x46); 3502169695Skan else 3503169695Skan run_bbp_write(sc, 75, 0x50); 3504169695Skan } 3505169695Skan 3506169695Skan run_read(sc, RT2860_TX_BAND_CFG, &tmp); 3507169695Skan tmp &= ~(RT2860_5G_BAND_SEL_N | RT2860_5G_BAND_SEL_P); 3508169695Skan tmp |= (group == 0) ? RT2860_5G_BAND_SEL_N : RT2860_5G_BAND_SEL_P; 3509169695Skan run_write(sc, RT2860_TX_BAND_CFG, tmp); 3510169695Skan 3511169695Skan /* enable appropriate Power Amplifiers and Low Noise Amplifiers */ 3512169695Skan tmp = RT2860_RFTR_EN | RT2860_TRSW_EN | RT2860_LNA_PE0_EN; 3513169695Skan if (sc->nrxchains > 1) 3514169695Skan tmp |= RT2860_LNA_PE1_EN; 3515169695Skan if (group == 0) { /* 2GHz */ 3516169695Skan tmp |= RT2860_PA_PE_G0_EN; 3517169695Skan if (sc->ntxchains > 1) 3518169695Skan tmp |= RT2860_PA_PE_G1_EN; 3519169695Skan } else { /* 5GHz */ 3520169695Skan tmp |= RT2860_PA_PE_A0_EN; 3521169695Skan if (sc->ntxchains > 1) 3522169695Skan tmp |= RT2860_PA_PE_A1_EN; 3523169695Skan } 3524169695Skan if (sc->mac_ver == 0x3572) { 3525169695Skan run_rt3070_rf_write(sc, 8, 0x00); 3526169695Skan run_write(sc, RT2860_TX_PIN_CFG, tmp); 3527169695Skan run_rt3070_rf_write(sc, 8, 0x80); 3528169695Skan } else 3529169695Skan run_write(sc, RT2860_TX_PIN_CFG, tmp); 3530169695Skan 3531169695Skan /* set initial AGC value */ 3532169695Skan if (group == 0) { /* 2GHz band */ 3533169695Skan if (sc->mac_ver >= 0x3070) 3534169695Skan agc = 0x1c + sc->lna[0] * 2; 3535169695Skan else 3536169695Skan agc = 0x2e + sc->lna[0]; 3537169695Skan } else { /* 5GHz band */ 3538169695Skan if (sc->mac_ver == 0x3572) 3539169695Skan agc = 0x22 + (sc->lna[group] * 5) / 3; 3540169695Skan else 3541169695Skan agc = 0x32 + (sc->lna[group] * 5) / 3; 3542169695Skan } 3543169695Skan run_set_agc(sc, agc); 3544169695Skan} 3545169695Skan 3546169695Skanstatic void 3547169695Skanrun_rt2870_set_chan(struct run_softc *sc, uint32_t chan) 3548169695Skan{ 3549169695Skan const struct rfprog *rfprog = rt2860_rf2850; 3550169695Skan uint32_t r2, r3, r4; 3551169695Skan int8_t txpow1, txpow2; 3552169695Skan int i; 3553169695Skan 3554169695Skan /* find the settings for this channel (we know it exists) */ 3555169695Skan for (i = 0; rfprog[i].chan != chan; i++); 3556169695Skan 3557169695Skan r2 = rfprog[i].r2; 3558169695Skan if (sc->ntxchains == 1) 3559169695Skan r2 |= 1 << 12; /* 1T: disable Tx chain 2 */ 3560169695Skan if (sc->nrxchains == 1) 3561169695Skan r2 |= 1 << 15 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */ 3562169695Skan else if (sc->nrxchains == 2) 3563169695Skan r2 |= 1 << 4; /* 2R: disable Rx chain 3 */ 3564169695Skan 3565169695Skan /* use Tx power values from EEPROM */ 3566169695Skan txpow1 = sc->txpow1[i]; 3567169695Skan txpow2 = sc->txpow2[i]; 3568169695Skan if (chan > 14) { 3569169695Skan if (txpow1 >= 0) 3570169695Skan txpow1 = txpow1 << 1 | 1; 3571169695Skan else 3572169695Skan txpow1 = (7 + txpow1) << 1; 3573169695Skan if (txpow2 >= 0) 3574169695Skan txpow2 = txpow2 << 1 | 1; 3575169695Skan else 3576169695Skan txpow2 = (7 + txpow2) << 1; 3577169695Skan } 3578169695Skan r3 = rfprog[i].r3 | txpow1 << 7; 3579169695Skan r4 = rfprog[i].r4 | sc->freq << 13 | txpow2 << 4; 3580169695Skan 3581169695Skan run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1); 3582169695Skan run_rt2870_rf_write(sc, RT2860_RF2, r2); 3583169695Skan run_rt2870_rf_write(sc, RT2860_RF3, r3); 3584169695Skan run_rt2870_rf_write(sc, RT2860_RF4, r4); 3585169695Skan 3586169695Skan run_delay(sc, 10); 3587169695Skan 3588169695Skan run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1); 3589169695Skan run_rt2870_rf_write(sc, RT2860_RF2, r2); 3590169695Skan run_rt2870_rf_write(sc, RT2860_RF3, r3 | 1); 3591169695Skan run_rt2870_rf_write(sc, RT2860_RF4, r4); 3592169695Skan 3593169695Skan run_delay(sc, 10); 3594169695Skan 3595169695Skan run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1); 3596169695Skan run_rt2870_rf_write(sc, RT2860_RF2, r2); 3597169695Skan run_rt2870_rf_write(sc, RT2860_RF3, r3); 3598169695Skan run_rt2870_rf_write(sc, RT2860_RF4, r4); 3599169695Skan} 3600169695Skan 3601169695Skanstatic void 3602169695Skanrun_rt3070_set_chan(struct run_softc *sc, uint32_t chan) 3603169695Skan{ 3604169695Skan int8_t txpow1, txpow2; 3605169695Skan uint8_t rf; 3606169695Skan int i; 3607169695Skan 3608169695Skan /* RT3070 is 2GHz only */ 3609169695Skan KASSERT(chan >= 1 && chan <= 14, ("wrong channel selected\n")); 3610169695Skan 3611169695Skan /* find the settings for this channel (we know it exists) */ 3612169695Skan for (i = 0; rt2860_rf2850[i].chan != chan; i++); 3613169695Skan 3614169695Skan /* use Tx power values from EEPROM */ 3615169695Skan txpow1 = sc->txpow1[i]; 3616169695Skan txpow2 = sc->txpow2[i]; 3617169695Skan 3618169695Skan run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n); 3619169695Skan run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k); 3620169695Skan run_rt3070_rf_read(sc, 6, &rf); 3621169695Skan rf = (rf & ~0x03) | rt3070_freqs[i].r; 3622169695Skan run_rt3070_rf_write(sc, 6, rf); 3623169695Skan 3624169695Skan /* set Tx0 power */ 3625169695Skan run_rt3070_rf_read(sc, 12, &rf); 3626169695Skan rf = (rf & ~0x1f) | txpow1; 3627169695Skan run_rt3070_rf_write(sc, 12, rf); 3628169695Skan 3629169695Skan /* set Tx1 power */ 3630169695Skan run_rt3070_rf_read(sc, 13, &rf); 3631169695Skan rf = (rf & ~0x1f) | txpow2; 3632169695Skan run_rt3070_rf_write(sc, 13, rf); 3633169695Skan 3634169695Skan run_rt3070_rf_read(sc, 1, &rf); 3635169695Skan rf &= ~0xfc; 3636169695Skan if (sc->ntxchains == 1) 3637169695Skan rf |= 1 << 7 | 1 << 5; /* 1T: disable Tx chains 2 & 3 */ 3638169695Skan else if (sc->ntxchains == 2) 3639169695Skan rf |= 1 << 7; /* 2T: disable Tx chain 3 */ 3640169695Skan if (sc->nrxchains == 1) 3641169695Skan rf |= 1 << 6 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */ 3642169695Skan else if (sc->nrxchains == 2) 3643169695Skan rf |= 1 << 6; /* 2R: disable Rx chain 3 */ 3644169695Skan run_rt3070_rf_write(sc, 1, rf); 3645169695Skan 3646169695Skan /* set RF offset */ 3647169695Skan run_rt3070_rf_read(sc, 23, &rf); 3648169695Skan rf = (rf & ~0x7f) | sc->freq; 3649169695Skan run_rt3070_rf_write(sc, 23, rf); 3650169695Skan 3651169695Skan /* program RF filter */ 3652169695Skan run_rt3070_rf_read(sc, 24, &rf); /* Tx */ 3653169695Skan rf = (rf & ~0x3f) | sc->rf24_20mhz; 3654169695Skan run_rt3070_rf_write(sc, 24, rf); 3655169695Skan run_rt3070_rf_read(sc, 31, &rf); /* Rx */ 3656169695Skan rf = (rf & ~0x3f) | sc->rf24_20mhz; 3657169695Skan run_rt3070_rf_write(sc, 31, rf); 3658169695Skan 3659169695Skan /* enable RF tuning */ 3660169695Skan run_rt3070_rf_read(sc, 7, &rf); 3661169695Skan run_rt3070_rf_write(sc, 7, rf | 0x01); 3662169695Skan} 3663169695Skan 3664169695Skanstatic void 3665169695Skanrun_rt3572_set_chan(struct run_softc *sc, u_int chan) 3666169695Skan{ 3667169695Skan int8_t txpow1, txpow2; 3668169695Skan uint32_t tmp; 3669169695Skan uint8_t rf; 3670169695Skan int i; 3671169695Skan 3672169695Skan /* find the settings for this channel (we know it exists) */ 3673169695Skan for (i = 0; rt2860_rf2850[i].chan != chan; i++); 3674169695Skan 3675169695Skan /* use Tx power values from EEPROM */ 3676169695Skan txpow1 = sc->txpow1[i]; 3677169695Skan txpow2 = sc->txpow2[i]; 3678169695Skan 3679169695Skan if (chan <= 14) { 3680169695Skan run_bbp_write(sc, 25, sc->bbp25); 3681169695Skan run_bbp_write(sc, 26, sc->bbp26); 3682169695Skan } else { 3683169695Skan /* enable IQ phase correction */ 3684169695Skan run_bbp_write(sc, 25, 0x09); 3685169695Skan run_bbp_write(sc, 26, 0xff); 3686169695Skan } 3687169695Skan 3688169695Skan run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n); 3689169695Skan run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k); 3690169695Skan run_rt3070_rf_read(sc, 6, &rf); 3691169695Skan rf = (rf & ~0x0f) | rt3070_freqs[i].r; 3692169695Skan rf |= (chan <= 14) ? 0x08 : 0x04; 3693169695Skan run_rt3070_rf_write(sc, 6, rf); 3694169695Skan 3695169695Skan /* set PLL mode */ 3696169695Skan run_rt3070_rf_read(sc, 5, &rf); 3697169695Skan rf &= ~(0x08 | 0x04); 3698169695Skan rf |= (chan <= 14) ? 0x04 : 0x08; 3699169695Skan run_rt3070_rf_write(sc, 5, rf); 3700169695Skan 3701169695Skan /* set Tx power for chain 0 */ 3702169695Skan if (chan <= 14) 3703169695Skan rf = 0x60 | txpow1; 3704169695Skan else 3705169695Skan rf = 0xe0 | (txpow1 & 0xc) << 1 | (txpow1 & 0x3); 3706169695Skan run_rt3070_rf_write(sc, 12, rf); 3707169695Skan 3708169695Skan /* set Tx power for chain 1 */ 3709169695Skan if (chan <= 14) 3710169695Skan rf = 0x60 | txpow2; 3711169695Skan else 3712169695Skan rf = 0xe0 | (txpow2 & 0xc) << 1 | (txpow2 & 0x3); 3713169695Skan run_rt3070_rf_write(sc, 13, rf); 3714169695Skan 3715169695Skan /* set Tx/Rx streams */ 3716169695Skan run_rt3070_rf_read(sc, 1, &rf); 3717169695Skan rf &= ~0xfc; 3718169695Skan if (sc->ntxchains == 1) 3719169695Skan rf |= 1 << 7 | 1 << 5; /* 1T: disable Tx chains 2 & 3 */ 3720169695Skan else if (sc->ntxchains == 2) 3721169695Skan rf |= 1 << 7; /* 2T: disable Tx chain 3 */ 3722169695Skan if (sc->nrxchains == 1) 3723169695Skan rf |= 1 << 6 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */ 3724169695Skan else if (sc->nrxchains == 2) 3725169695Skan rf |= 1 << 6; /* 2R: disable Rx chain 3 */ 3726169695Skan run_rt3070_rf_write(sc, 1, rf); 3727169695Skan 3728169695Skan /* set RF offset */ 3729169695Skan run_rt3070_rf_read(sc, 23, &rf); 3730169695Skan rf = (rf & ~0x7f) | sc->freq; 3731169695Skan run_rt3070_rf_write(sc, 23, rf); 3732169695Skan 3733169695Skan /* program RF filter */ 3734169695Skan rf = sc->rf24_20mhz; 3735169695Skan run_rt3070_rf_write(sc, 24, rf); /* Tx */ 3736169695Skan run_rt3070_rf_write(sc, 31, rf); /* Rx */ 3737169695Skan 3738169695Skan /* enable RF tuning */ 3739169695Skan run_rt3070_rf_read(sc, 7, &rf); 3740169695Skan rf = (chan <= 14) ? 0xd8 : ((rf & ~0xc8) | 0x14); 3741169695Skan run_rt3070_rf_write(sc, 7, rf); 3742169695Skan 3743169695Skan /* TSSI */ 3744169695Skan rf = (chan <= 14) ? 0xc3 : 0xc0; 3745169695Skan run_rt3070_rf_write(sc, 9, rf); 3746169695Skan 3747169695Skan /* set loop filter 1 */ 3748169695Skan run_rt3070_rf_write(sc, 10, 0xf1); 3749169695Skan /* set loop filter 2 */ 3750169695Skan run_rt3070_rf_write(sc, 11, (chan <= 14) ? 0xb9 : 0x00); 3751169695Skan 3752169695Skan /* set tx_mx2_ic */ 3753169695Skan run_rt3070_rf_write(sc, 15, (chan <= 14) ? 0x53 : 0x43); 3754169695Skan /* set tx_mx1_ic */ 3755169695Skan if (chan <= 14) 3756169695Skan rf = 0x48 | sc->txmixgain_2ghz; 3757169695Skan else 3758169695Skan rf = 0x78 | sc->txmixgain_5ghz; 3759169695Skan run_rt3070_rf_write(sc, 16, rf); 3760169695Skan 3761169695Skan /* set tx_lo1 */ 3762169695Skan run_rt3070_rf_write(sc, 17, 0x23); 3763169695Skan /* set tx_lo2 */ 3764169695Skan if (chan <= 14) 3765169695Skan rf = 0x93; 3766169695Skan else if (chan <= 64) 3767169695Skan rf = 0xb7; 3768169695Skan else if (chan <= 128) 3769169695Skan rf = 0x74; 3770169695Skan else 3771169695Skan rf = 0x72; 3772169695Skan run_rt3070_rf_write(sc, 19, rf); 3773169695Skan 3774169695Skan /* set rx_lo1 */ 3775169695Skan if (chan <= 14) 3776169695Skan rf = 0xb3; 3777169695Skan else if (chan <= 64) 3778169695Skan rf = 0xf6; 3779169695Skan else if (chan <= 128) 3780169695Skan rf = 0xf4; 3781169695Skan else 3782169695Skan rf = 0xf3; 3783169695Skan run_rt3070_rf_write(sc, 20, rf); 3784169695Skan 3785169695Skan /* set pfd_delay */ 3786169695Skan if (chan <= 14) 3787169695Skan rf = 0x15; 3788169695Skan else if (chan <= 64) 3789169695Skan rf = 0x3d; 3790169695Skan else 3791169695Skan rf = 0x01; 3792169695Skan run_rt3070_rf_write(sc, 25, rf); 3793169695Skan 3794169695Skan /* set rx_lo2 */ 3795169695Skan run_rt3070_rf_write(sc, 26, (chan <= 14) ? 0x85 : 0x87); 3796169695Skan /* set ldo_rf_vc */ 3797169695Skan run_rt3070_rf_write(sc, 27, (chan <= 14) ? 0x00 : 0x01); 3798169695Skan /* set drv_cc */ 3799169695Skan run_rt3070_rf_write(sc, 29, (chan <= 14) ? 0x9b : 0x9f); 3800169695Skan 3801169695Skan run_read(sc, RT2860_GPIO_CTRL, &tmp); 3802169695Skan tmp &= ~0x8080; 3803169695Skan if (chan <= 14) 3804169695Skan tmp |= 0x80; 3805169695Skan run_write(sc, RT2860_GPIO_CTRL, tmp); 3806169695Skan 3807169695Skan /* enable RF tuning */ 3808169695Skan run_rt3070_rf_read(sc, 7, &rf); 3809169695Skan run_rt3070_rf_write(sc, 7, rf | 0x01); 3810169695Skan 3811169695Skan run_delay(sc, 2); 3812169695Skan} 3813169695Skan 3814169695Skanstatic void 3815169695Skanrun_set_rx_antenna(struct run_softc *sc, int aux) 3816169695Skan{ 3817169695Skan uint32_t tmp; 3818169695Skan 3819169695Skan if (aux) { 3820169695Skan run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 0); 3821169695Skan run_read(sc, RT2860_GPIO_CTRL, &tmp); 3822169695Skan run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08); 3823169695Skan } else { 3824169695Skan run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 1); 3825169695Skan run_read(sc, RT2860_GPIO_CTRL, &tmp); 3826169695Skan run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808); 3827169695Skan } 3828169695Skan} 3829169695Skan 3830169695Skanstatic int 3831169695Skanrun_set_chan(struct run_softc *sc, struct ieee80211_channel *c) 3832169695Skan{ 3833169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 3834169695Skan uint32_t chan, group; 3835169695Skan 3836169695Skan chan = ieee80211_chan2ieee(ic, c); 3837169695Skan if (chan == 0 || chan == IEEE80211_CHAN_ANY) 3838169695Skan return (EINVAL); 3839169695Skan 3840169695Skan if (sc->mac_ver == 0x3572) 3841169695Skan run_rt3572_set_chan(sc, chan); 3842169695Skan else if (sc->mac_ver >= 0x3070) 3843169695Skan run_rt3070_set_chan(sc, chan); 3844169695Skan else 3845169695Skan run_rt2870_set_chan(sc, chan); 3846169695Skan 3847169695Skan /* determine channel group */ 3848169695Skan if (chan <= 14) 3849169695Skan group = 0; 3850169695Skan else if (chan <= 64) 3851169695Skan group = 1; 3852169695Skan else if (chan <= 128) 3853169695Skan group = 2; 3854169695Skan else 3855169695Skan group = 3; 3856169695Skan 3857169695Skan /* XXX necessary only when group has changed! */ 3858169695Skan run_select_chan_group(sc, group); 3859169695Skan 3860169695Skan run_delay(sc, 10); 3861169695Skan 3862169695Skan return (0); 3863169695Skan} 3864169695Skan 3865169695Skanstatic void 3866169695Skanrun_set_channel(struct ieee80211com *ic) 3867169695Skan{ 3868169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 3869169695Skan 3870169695Skan RUN_LOCK(sc); 3871169695Skan run_set_chan(sc, ic->ic_curchan); 3872169695Skan RUN_UNLOCK(sc); 3873169695Skan 3874169695Skan return; 3875169695Skan} 3876169695Skan 3877169695Skanstatic void 3878169695Skanrun_scan_start(struct ieee80211com *ic) 3879169695Skan{ 3880169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 3881169695Skan uint32_t tmp; 3882169695Skan 3883169695Skan RUN_LOCK(sc); 3884169695Skan 3885169695Skan /* abort TSF synchronization */ 3886169695Skan run_read(sc, RT2860_BCN_TIME_CFG, &tmp); 3887169695Skan run_write(sc, RT2860_BCN_TIME_CFG, 3888169695Skan tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | 3889169695Skan RT2860_TBTT_TIMER_EN)); 3890169695Skan run_set_bssid(sc, sc->sc_ifp->if_broadcastaddr); 3891169695Skan 3892169695Skan RUN_UNLOCK(sc); 3893169695Skan 3894169695Skan return; 3895169695Skan} 3896169695Skan 3897169695Skanstatic void 3898169695Skanrun_scan_end(struct ieee80211com *ic) 3899169695Skan{ 3900169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 3901169695Skan 3902169695Skan RUN_LOCK(sc); 3903169695Skan 3904169695Skan run_enable_tsf_sync(sc); 3905169695Skan /* XXX keep local copy */ 3906169695Skan run_set_bssid(sc, sc->sc_bssid); 3907169695Skan 3908169695Skan RUN_UNLOCK(sc); 3909169695Skan 3910169695Skan return; 3911169695Skan} 3912169695Skan 3913169695Skan/* 3914169695Skan * Could be called from ieee80211_node_timeout() 3915169695Skan * (non-sleepable thread) 3916169695Skan */ 3917169695Skanstatic void 3918169695Skanrun_update_beacon(struct ieee80211vap *vap, int item) 3919169695Skan{ 3920169695Skan struct ieee80211com *ic = vap->iv_ic; 3921169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 3922169695Skan struct run_vap *rvp = RUN_VAP(vap); 3923169695Skan int mcast = 0; 3924169695Skan uint32_t i; 3925169695Skan 3926169695Skan KASSERT(vap != NULL, ("no beacon")); 3927169695Skan 3928169695Skan switch (item) { 3929169695Skan case IEEE80211_BEACON_ERP: 3930169695Skan run_updateslot(ic->ic_ifp); 3931169695Skan break; 3932169695Skan case IEEE80211_BEACON_HTINFO: 3933169695Skan run_updateprot(ic); 3934169695Skan break; 3935169695Skan case IEEE80211_BEACON_TIM: 3936169695Skan mcast = 1; /*TODO*/ 3937169695Skan break; 3938169695Skan default: 3939169695Skan break; 3940169695Skan } 3941169695Skan 3942169695Skan setbit(rvp->bo.bo_flags, item); 3943169695Skan ieee80211_beacon_update(vap->iv_bss, &rvp->bo, rvp->beacon_mbuf, mcast); 3944169695Skan 3945169695Skan i = RUN_CMDQ_GET(&sc->cmdq_store); 3946169695Skan DPRINTF("cmdq_store=%d\n", i); 3947169695Skan sc->cmdq[i].func = run_update_beacon_cb; 3948169695Skan sc->cmdq[i].arg0 = vap; 3949169695Skan ieee80211_runtask(ic, &sc->cmdq_task); 3950169695Skan 3951169695Skan return; 3952169695Skan} 3953169695Skan 3954169695Skanstatic void 3955169695Skanrun_update_beacon_cb(void *arg) 3956169695Skan{ 3957169695Skan struct ieee80211vap *vap = arg; 3958169695Skan struct run_vap *rvp = RUN_VAP(vap); 3959169695Skan struct ieee80211com *ic = vap->iv_ic; 3960169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 3961169695Skan struct rt2860_txwi txwi; 3962169695Skan struct mbuf *m; 3963169695Skan uint8_t ridx; 3964169695Skan 3965169695Skan if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC) 3966169695Skan return; 3967169695Skan 3968169695Skan /* 3969169695Skan * No need to call ieee80211_beacon_update(), run_update_beacon() 3970169695Skan * is taking care of apropriate calls. 3971169695Skan */ 3972169695Skan if (rvp->beacon_mbuf == NULL) { 3973169695Skan rvp->beacon_mbuf = ieee80211_beacon_alloc(vap->iv_bss, 3974169695Skan &rvp->bo); 3975169695Skan if (rvp->beacon_mbuf == NULL) 3976169695Skan return; 3977169695Skan } 3978169695Skan m = rvp->beacon_mbuf; 3979169695Skan 3980169695Skan memset(&txwi, 0, sizeof txwi); 3981169695Skan txwi.wcid = 0xff; 3982169695Skan txwi.len = htole16(m->m_pkthdr.len); 3983169695Skan /* send beacons at the lowest available rate */ 3984169695Skan ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ? 3985169695Skan RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1; 3986169695Skan txwi.phy = htole16(rt2860_rates[ridx].mcs); 3987169695Skan if (rt2860_rates[ridx].phy == IEEE80211_T_OFDM) 3988169695Skan txwi.phy |= htole16(RT2860_PHY_OFDM); 3989169695Skan txwi.txop = RT2860_TX_TXOP_HT; 3990169695Skan txwi.flags = RT2860_TX_TS; 3991169695Skan txwi.xflags = RT2860_TX_NSEQ; 3992169695Skan 3993169695Skan run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id), 3994169695Skan (uint8_t *)&txwi, sizeof txwi); 3995169695Skan run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id) + sizeof txwi, 3996169695Skan mtod(m, uint8_t *), (m->m_pkthdr.len + 1) & ~1); /* roundup len */ 3997169695Skan 3998169695Skan return; 3999169695Skan} 4000169695Skan 4001169695Skanstatic void 4002169695Skanrun_updateprot(struct ieee80211com *ic) 4003169695Skan{ 4004169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 4005169695Skan uint32_t i; 4006169695Skan 4007169695Skan i = RUN_CMDQ_GET(&sc->cmdq_store); 4008169695Skan DPRINTF("cmdq_store=%d\n", i); 4009169695Skan sc->cmdq[i].func = run_updateprot_cb; 4010169695Skan sc->cmdq[i].arg0 = ic; 4011169695Skan ieee80211_runtask(ic, &sc->cmdq_task); 4012169695Skan} 4013169695Skan 4014169695Skanstatic void 4015169695Skanrun_updateprot_cb(void *arg) 4016169695Skan{ 4017169695Skan struct ieee80211com *ic = arg; 4018169695Skan struct run_softc *sc = ic->ic_ifp->if_softc; 4019169695Skan uint32_t tmp; 4020169695Skan 4021169695Skan tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL; 4022169695Skan /* setup protection frame rate (MCS code) */ 4023169695Skan tmp |= (ic->ic_curmode == IEEE80211_MODE_11A) ? 4024169695Skan rt2860_rates[RT2860_RIDX_OFDM6].mcs : 4025169695Skan rt2860_rates[RT2860_RIDX_CCK11].mcs; 4026169695Skan 4027169695Skan /* CCK frames don't require protection */ 4028169695Skan run_write(sc, RT2860_CCK_PROT_CFG, tmp); 4029169695Skan if (ic->ic_flags & IEEE80211_F_USEPROT) { 4030169695Skan if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 4031169695Skan tmp |= RT2860_PROT_CTRL_RTS_CTS; 4032169695Skan else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 4033169695Skan tmp |= RT2860_PROT_CTRL_CTS; 4034169695Skan } 4035169695Skan run_write(sc, RT2860_OFDM_PROT_CFG, tmp); 4036169695Skan} 4037169695Skan 4038169695Skanstatic void 4039169695Skanrun_usb_timeout_cb(void *arg) 4040169695Skan{ 4041169695Skan struct ieee80211vap *vap = arg; 4042169695Skan struct run_softc *sc = vap->iv_ic->ic_ifp->if_softc; 4043169695Skan 4044169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 4045169695Skan 4046169695Skan if(vap->iv_state == IEEE80211_S_RUN && 4047169695Skan vap->iv_opmode != IEEE80211_M_STA) 4048169695Skan run_reset_livelock(sc); 4049169695Skan else if (vap->iv_state == IEEE80211_S_SCAN) { 4050169695Skan DPRINTF("timeout caused by scan\n"); 4051169695Skan /* cancel bgscan */ 4052169695Skan ieee80211_cancel_scan(vap); 4053169695Skan } else 4054169695Skan DPRINTF("timeout by unknown cause\n"); 4055169695Skan} 4056169695Skan 4057169695Skanstatic void 4058169695Skanrun_reset_livelock(struct run_softc *sc) 4059169695Skan{ 4060169695Skan uint32_t tmp; 4061169695Skan 4062169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 4063169695Skan 4064169695Skan /* 4065169695Skan * In IBSS or HostAP modes (when the hardware sends beacons), the MAC 4066169695Skan * can run into a livelock and start sending CTS-to-self frames like 4067169695Skan * crazy if protection is enabled. Reset MAC/BBP for a while 4068169695Skan */ 4069169695Skan run_read(sc, RT2860_DEBUG, &tmp); 4070169695Skan DPRINTFN(3, "debug reg %08x\n", tmp); 4071169695Skan if ((tmp & (1 << 29)) && (tmp & (1 << 7 | 1 << 5))) { 4072169695Skan DPRINTF("CTS-to-self livelock detected\n"); 4073169695Skan run_write(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_SRST); 4074169695Skan run_delay(sc, 1); 4075169695Skan run_write(sc, RT2860_MAC_SYS_CTRL, 4076169695Skan RT2860_MAC_RX_EN | RT2860_MAC_TX_EN); 4077169695Skan } 4078169695Skan} 4079169695Skan 4080169695Skanstatic void 4081169695Skanrun_update_promisc_locked(struct ifnet *ifp) 4082169695Skan{ 4083169695Skan struct run_softc *sc = ifp->if_softc; 4084169695Skan uint32_t tmp; 4085169695Skan 4086169695Skan run_read(sc, RT2860_RX_FILTR_CFG, &tmp); 4087169695Skan 4088169695Skan tmp |= RT2860_DROP_UC_NOME; 4089169695Skan if (ifp->if_flags & IFF_PROMISC) 4090169695Skan tmp &= ~RT2860_DROP_UC_NOME; 4091169695Skan 4092169695Skan run_write(sc, RT2860_RX_FILTR_CFG, tmp); 4093169695Skan 4094169695Skan DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? 4095169695Skan "entering" : "leaving"); 4096169695Skan} 4097169695Skan 4098169695Skanstatic void 4099169695Skanrun_update_promisc(struct ifnet *ifp) 4100169695Skan{ 4101169695Skan struct run_softc *sc = ifp->if_softc; 4102169695Skan 4103169695Skan if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 4104169695Skan return; 4105169695Skan 4106169695Skan RUN_LOCK(sc); 4107169695Skan run_update_promisc_locked(ifp); 4108169695Skan RUN_UNLOCK(sc); 4109169695Skan} 4110169695Skan 4111169695Skanstatic void 4112169695Skanrun_enable_tsf_sync(struct run_softc *sc) 4113169695Skan{ 4114169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4115169695Skan struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 4116169695Skan uint32_t tmp; 4117169695Skan 4118169695Skan DPRINTF("rvp_id=%d ic_opmode=%d\n", RUN_VAP(vap)->rvp_id, ic->ic_opmode); 4119169695Skan 4120169695Skan run_read(sc, RT2860_BCN_TIME_CFG, &tmp); 4121169695Skan tmp &= ~0x1fffff; 4122169695Skan tmp |= vap->iv_bss->ni_intval * 16; 4123169695Skan tmp |= RT2860_TSF_TIMER_EN | RT2860_TBTT_TIMER_EN; 4124169695Skan 4125169695Skan if (ic->ic_opmode == IEEE80211_M_STA) { 4126169695Skan /* 4127169695Skan * Local TSF is always updated with remote TSF on beacon 4128169695Skan * reception. 4129169695Skan */ 4130169695Skan tmp |= 1 << RT2860_TSF_SYNC_MODE_SHIFT; 4131169695Skan } else if (ic->ic_opmode == IEEE80211_M_IBSS) { 4132169695Skan tmp |= RT2860_BCN_TX_EN; 4133169695Skan /* 4134169695Skan * Local TSF is updated with remote TSF on beacon reception 4135169695Skan * only if the remote TSF is greater than local TSF. 4136169695Skan */ 4137169695Skan tmp |= 2 << RT2860_TSF_SYNC_MODE_SHIFT; 4138169695Skan } else if (ic->ic_opmode == IEEE80211_M_HOSTAP || 4139169695Skan ic->ic_opmode == IEEE80211_M_MBSS) { 4140169695Skan tmp |= RT2860_BCN_TX_EN; 4141169695Skan /* SYNC with nobody */ 4142169695Skan tmp |= 3 << RT2860_TSF_SYNC_MODE_SHIFT; 4143169695Skan } else { 4144169695Skan DPRINTF("Enabling TSF failed. undefined opmode\n"); 4145169695Skan return; 4146169695Skan } 4147169695Skan 4148169695Skan run_write(sc, RT2860_BCN_TIME_CFG, tmp); 4149169695Skan} 4150169695Skan 4151169695Skanstatic void 4152169695Skanrun_enable_mrr(struct run_softc *sc) 4153169695Skan{ 4154169695Skan#define CCK(mcs) (mcs) 4155169695Skan#define OFDM(mcs) (1 << 3 | (mcs)) 4156169695Skan run_write(sc, RT2860_LG_FBK_CFG0, 4157169695Skan OFDM(6) << 28 | /* 54->48 */ 4158169695Skan OFDM(5) << 24 | /* 48->36 */ 4159169695Skan OFDM(4) << 20 | /* 36->24 */ 4160169695Skan OFDM(3) << 16 | /* 24->18 */ 4161169695Skan OFDM(2) << 12 | /* 18->12 */ 4162169695Skan OFDM(1) << 8 | /* 12-> 9 */ 4163169695Skan OFDM(0) << 4 | /* 9-> 6 */ 4164169695Skan OFDM(0)); /* 6-> 6 */ 4165169695Skan 4166169695Skan run_write(sc, RT2860_LG_FBK_CFG1, 4167169695Skan CCK(2) << 12 | /* 11->5.5 */ 4168169695Skan CCK(1) << 8 | /* 5.5-> 2 */ 4169169695Skan CCK(0) << 4 | /* 2-> 1 */ 4170169695Skan CCK(0)); /* 1-> 1 */ 4171169695Skan#undef OFDM 4172169695Skan#undef CCK 4173169695Skan} 4174169695Skan 4175169695Skanstatic void 4176169695Skanrun_set_txpreamble(struct run_softc *sc) 4177169695Skan{ 4178169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4179169695Skan uint32_t tmp; 4180169695Skan 4181169695Skan run_read(sc, RT2860_AUTO_RSP_CFG, &tmp); 4182169695Skan if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) 4183169695Skan tmp |= RT2860_CCK_SHORT_EN; 4184169695Skan else 4185169695Skan tmp &= ~RT2860_CCK_SHORT_EN; 4186169695Skan run_write(sc, RT2860_AUTO_RSP_CFG, tmp); 4187169695Skan} 4188169695Skan 4189169695Skanstatic void 4190169695Skanrun_set_basicrates(struct run_softc *sc) 4191169695Skan{ 4192169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4193169695Skan 4194169695Skan /* set basic rates mask */ 4195169695Skan if (ic->ic_curmode == IEEE80211_MODE_11B) 4196169695Skan run_write(sc, RT2860_LEGACY_BASIC_RATE, 0x003); 4197169695Skan else if (ic->ic_curmode == IEEE80211_MODE_11A) 4198169695Skan run_write(sc, RT2860_LEGACY_BASIC_RATE, 0x150); 4199169695Skan else /* 11g */ 4200169695Skan run_write(sc, RT2860_LEGACY_BASIC_RATE, 0x15f); 4201169695Skan} 4202169695Skan 4203169695Skanstatic void 4204169695Skanrun_set_leds(struct run_softc *sc, uint16_t which) 4205169695Skan{ 4206169695Skan (void)run_mcu_cmd(sc, RT2860_MCU_CMD_LEDS, 4207169695Skan which | (sc->leds & 0x7f)); 4208169695Skan} 4209169695Skan 4210169695Skanstatic void 4211169695Skanrun_set_bssid(struct run_softc *sc, const uint8_t *bssid) 4212169695Skan{ 4213169695Skan run_write(sc, RT2860_MAC_BSSID_DW0, 4214169695Skan bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24); 4215169695Skan run_write(sc, RT2860_MAC_BSSID_DW1, 4216169695Skan bssid[4] | bssid[5] << 8); 4217169695Skan} 4218169695Skan 4219169695Skanstatic void 4220169695Skanrun_set_macaddr(struct run_softc *sc, const uint8_t *addr) 4221169695Skan{ 4222169695Skan run_write(sc, RT2860_MAC_ADDR_DW0, 4223169695Skan addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); 4224169695Skan run_write(sc, RT2860_MAC_ADDR_DW1, 4225169695Skan addr[4] | addr[5] << 8 | 0xff << 16); 4226169695Skan} 4227169695Skan 4228169695Skanstatic void 4229169695Skanrun_updateslot(struct ifnet *ifp) 4230169695Skan{ 4231169695Skan struct run_softc *sc = ifp->if_softc; 4232169695Skan struct ieee80211com *ic = ifp->if_l2com; 4233169695Skan uint32_t i; 4234169695Skan 4235169695Skan i = RUN_CMDQ_GET(&sc->cmdq_store); 4236169695Skan DPRINTF("cmdq_store=%d\n", i); 4237169695Skan sc->cmdq[i].func = run_updateslot_cb; 4238169695Skan sc->cmdq[i].arg0 = ifp; 4239169695Skan ieee80211_runtask(ic, &sc->cmdq_task); 4240169695Skan 4241169695Skan return; 4242169695Skan} 4243169695Skan 4244169695Skan/* ARGSUSED */ 4245169695Skanstatic void 4246169695Skanrun_updateslot_cb(void *arg) 4247169695Skan{ 4248169695Skan struct ifnet *ifp = arg; 4249169695Skan struct run_softc *sc = ifp->if_softc; 4250169695Skan struct ieee80211com *ic = ifp->if_l2com; 4251169695Skan uint32_t tmp; 4252169695Skan 4253169695Skan run_read(sc, RT2860_BKOFF_SLOT_CFG, &tmp); 4254169695Skan tmp &= ~0xff; 4255169695Skan tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; 4256169695Skan run_write(sc, RT2860_BKOFF_SLOT_CFG, tmp); 4257169695Skan} 4258169695Skan 4259169695Skanstatic void 4260169695Skanrun_update_mcast(struct ifnet *ifp) 4261169695Skan{ 4262169695Skan /* h/w filter supports getting everything or nothing */ 4263169695Skan ifp->if_flags |= IFF_ALLMULTI; 4264169695Skan} 4265169695Skan 4266169695Skanstatic int8_t 4267169695Skanrun_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain) 4268169695Skan{ 4269169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4270169695Skan struct ieee80211_channel *c = ic->ic_curchan; 4271169695Skan int delta; 4272169695Skan 4273169695Skan if (IEEE80211_IS_CHAN_5GHZ(c)) { 4274169695Skan uint32_t chan = ieee80211_chan2ieee(ic, c); 4275169695Skan delta = sc->rssi_5ghz[rxchain]; 4276169695Skan 4277169695Skan /* determine channel group */ 4278169695Skan if (chan <= 64) 4279169695Skan delta -= sc->lna[1]; 4280169695Skan else if (chan <= 128) 4281169695Skan delta -= sc->lna[2]; 4282169695Skan else 4283169695Skan delta -= sc->lna[3]; 4284169695Skan } else 4285169695Skan delta = sc->rssi_2ghz[rxchain] - sc->lna[0]; 4286169695Skan 4287169695Skan return (-12 - delta - rssi); 4288169695Skan} 4289169695Skan 4290169695Skanstatic int 4291169695Skanrun_bbp_init(struct run_softc *sc) 4292169695Skan{ 4293169695Skan int i, error, ntries; 4294169695Skan uint8_t bbp0; 4295169695Skan 4296169695Skan /* wait for BBP to wake up */ 4297169695Skan for (ntries = 0; ntries < 20; ntries++) { 4298169695Skan if ((error = run_bbp_read(sc, 0, &bbp0)) != 0) 4299169695Skan return error; 4300169695Skan if (bbp0 != 0 && bbp0 != 0xff) 4301169695Skan break; 4302169695Skan } 4303169695Skan if (ntries == 20) 4304169695Skan return (ETIMEDOUT); 4305169695Skan 4306169695Skan /* initialize BBP registers to default values */ 4307169695Skan for (i = 0; i < nitems(rt2860_def_bbp); i++) { 4308169695Skan run_bbp_write(sc, rt2860_def_bbp[i].reg, 4309169695Skan rt2860_def_bbp[i].val); 4310169695Skan } 4311169695Skan 4312169695Skan /* fix BBP84 for RT2860E */ 4313169695Skan if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101) 4314169695Skan run_bbp_write(sc, 84, 0x19); 4315169695Skan 4316169695Skan if (sc->mac_ver >= 0x3070) { 4317169695Skan run_bbp_write(sc, 79, 0x13); 4318169695Skan run_bbp_write(sc, 80, 0x05); 4319169695Skan run_bbp_write(sc, 81, 0x33); 4320169695Skan } else if (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) { 4321169695Skan run_bbp_write(sc, 69, 0x16); 4322169695Skan run_bbp_write(sc, 73, 0x12); 4323169695Skan } 4324169695Skan return (0); 4325169695Skan} 4326169695Skan 4327169695Skanstatic int 4328169695Skanrun_rt3070_rf_init(struct run_softc *sc) 4329169695Skan{ 4330169695Skan uint32_t tmp; 4331169695Skan uint8_t rf, target, bbp4; 4332169695Skan int i; 4333169695Skan 4334169695Skan run_rt3070_rf_read(sc, 30, &rf); 4335169695Skan /* toggle RF R30 bit 7 */ 4336169695Skan run_rt3070_rf_write(sc, 30, rf | 0x80); 4337169695Skan run_delay(sc, 10); 4338169695Skan run_rt3070_rf_write(sc, 30, rf & ~0x80); 4339169695Skan 4340169695Skan /* initialize RF registers to default value */ 4341169695Skan if (sc->mac_ver == 0x3572) { 4342169695Skan for (i = 0; i < nitems(rt3572_def_rf); i++) { 4343169695Skan run_rt3070_rf_write(sc, rt3572_def_rf[i].reg, 4344169695Skan rt3572_def_rf[i].val); 4345169695Skan } 4346169695Skan } else { 4347169695Skan for (i = 0; i < nitems(rt3070_def_rf); i++) { 4348169695Skan run_rt3070_rf_write(sc, rt3070_def_rf[i].reg, 4349169695Skan rt3070_def_rf[i].val); 4350169695Skan } 4351169695Skan } 4352169695Skan 4353169695Skan if (sc->mac_ver == 0x3070) { 4354169695Skan /* change voltage from 1.2V to 1.35V for RT3070 */ 4355169695Skan run_read(sc, RT3070_LDO_CFG0, &tmp); 4356169695Skan tmp = (tmp & ~0x0f000000) | 0x0d000000; 4357169695Skan run_write(sc, RT3070_LDO_CFG0, tmp); 4358169695Skan 4359169695Skan } else if (sc->mac_ver == 0x3071) { 4360169695Skan run_rt3070_rf_read(sc, 6, &rf); 4361169695Skan run_rt3070_rf_write(sc, 6, rf | 0x40); 4362169695Skan run_rt3070_rf_write(sc, 31, 0x14); 4363169695Skan 4364169695Skan run_read(sc, RT3070_LDO_CFG0, &tmp); 4365169695Skan tmp &= ~0x1f000000; 4366169695Skan if (sc->mac_rev < 0x0211) 4367169695Skan tmp |= 0x0d000000; /* 1.3V */ 4368169695Skan else 4369169695Skan tmp |= 0x01000000; /* 1.2V */ 4370169695Skan run_write(sc, RT3070_LDO_CFG0, tmp); 4371169695Skan 4372169695Skan /* patch LNA_PE_G1 */ 4373169695Skan run_read(sc, RT3070_GPIO_SWITCH, &tmp); 4374169695Skan run_write(sc, RT3070_GPIO_SWITCH, tmp & ~0x20); 4375169695Skan 4376169695Skan } else if (sc->mac_ver == 0x3572) { 4377169695Skan run_rt3070_rf_read(sc, 6, &rf); 4378169695Skan run_rt3070_rf_write(sc, 6, rf | 0x40); 4379169695Skan 4380169695Skan /* increase voltage from 1.2V to 1.35V */ 4381169695Skan run_read(sc, RT3070_LDO_CFG0, &tmp); 4382169695Skan tmp = (tmp & ~0x1f000000) | 0x0d000000; 4383169695Skan run_write(sc, RT3070_LDO_CFG0, tmp); 4384169695Skan 4385169695Skan if (sc->mac_rev < 0x0211 || !sc->patch_dac) { 4386169695Skan run_delay(sc, 1); /* wait for 1msec */ 4387169695Skan /* decrease voltage back to 1.2V */ 4388169695Skan tmp = (tmp & ~0x1f000000) | 0x01000000; 4389169695Skan run_write(sc, RT3070_LDO_CFG0, tmp); 4390169695Skan } 4391169695Skan } 4392169695Skan 4393169695Skan /* select 20MHz bandwidth */ 4394169695Skan run_rt3070_rf_read(sc, 31, &rf); 4395169695Skan run_rt3070_rf_write(sc, 31, rf & ~0x20); 4396169695Skan 4397169695Skan /* calibrate filter for 20MHz bandwidth */ 4398169695Skan sc->rf24_20mhz = 0x1f; /* default value */ 4399169695Skan target = (sc->mac_ver < 0x3071) ? 0x16 : 0x13; 4400169695Skan run_rt3070_filter_calib(sc, 0x07, target, &sc->rf24_20mhz); 4401169695Skan 4402169695Skan /* select 40MHz bandwidth */ 4403169695Skan run_bbp_read(sc, 4, &bbp4); 4404169695Skan run_bbp_write(sc, 4, (bbp4 & ~0x08) | 0x10); 4405169695Skan run_rt3070_rf_read(sc, 31, &rf); 4406169695Skan run_rt3070_rf_write(sc, 31, rf | 0x20); 4407169695Skan 4408169695Skan /* calibrate filter for 40MHz bandwidth */ 4409169695Skan sc->rf24_40mhz = 0x2f; /* default value */ 4410169695Skan target = (sc->mac_ver < 0x3071) ? 0x19 : 0x15; 4411169695Skan run_rt3070_filter_calib(sc, 0x27, target, &sc->rf24_40mhz); 4412169695Skan 4413169695Skan /* go back to 20MHz bandwidth */ 4414169695Skan run_bbp_read(sc, 4, &bbp4); 4415169695Skan run_bbp_write(sc, 4, bbp4 & ~0x18); 4416169695Skan 4417169695Skan if (sc->mac_ver == 0x3572) { 4418169695Skan /* save default BBP registers 25 and 26 values */ 4419169695Skan run_bbp_read(sc, 25, &sc->bbp25); 4420169695Skan run_bbp_read(sc, 26, &sc->bbp26); 4421169695Skan } else if (sc->mac_rev < 0x0211) 4422169695Skan run_rt3070_rf_write(sc, 27, 0x03); 4423169695Skan 4424169695Skan run_read(sc, RT3070_OPT_14, &tmp); 4425169695Skan run_write(sc, RT3070_OPT_14, tmp | 1); 4426169695Skan 4427169695Skan if (sc->mac_ver == 0x3070 || sc->mac_ver == 0x3071) { 4428169695Skan run_rt3070_rf_read(sc, 17, &rf); 4429169695Skan rf &= ~RT3070_TX_LO1; 4430169695Skan if ((sc->mac_ver == 0x3070 || 4431169695Skan (sc->mac_ver == 0x3071 && sc->mac_rev >= 0x0211)) && 4432169695Skan !sc->ext_2ghz_lna) 4433169695Skan rf |= 0x20; /* fix for long range Rx issue */ 4434169695Skan if (sc->txmixgain_2ghz >= 1) 4435169695Skan rf = (rf & ~0x7) | sc->txmixgain_2ghz; 4436169695Skan run_rt3070_rf_write(sc, 17, rf); 4437169695Skan } 4438169695Skan 4439169695Skan if (sc->mac_rev == 0x3071) { 4440169695Skan run_rt3070_rf_read(sc, 1, &rf); 4441169695Skan rf &= ~(RT3070_RX0_PD | RT3070_TX0_PD); 4442169695Skan rf |= RT3070_RF_BLOCK | RT3070_RX1_PD | RT3070_TX1_PD; 4443169695Skan run_rt3070_rf_write(sc, 1, rf); 4444169695Skan 4445169695Skan run_rt3070_rf_read(sc, 15, &rf); 4446169695Skan run_rt3070_rf_write(sc, 15, rf & ~RT3070_TX_LO2); 4447169695Skan 4448169695Skan run_rt3070_rf_read(sc, 20, &rf); 4449169695Skan run_rt3070_rf_write(sc, 20, rf & ~RT3070_RX_LO1); 4450169695Skan 4451169695Skan run_rt3070_rf_read(sc, 21, &rf); 4452169695Skan run_rt3070_rf_write(sc, 21, rf & ~RT3070_RX_LO2); 4453169695Skan } 4454169695Skan 4455169695Skan if (sc->mac_ver == 0x3070 || sc->mac_ver == 0x3071) { 4456169695Skan /* fix Tx to Rx IQ glitch by raising RF voltage */ 4457169695Skan run_rt3070_rf_read(sc, 27, &rf); 4458169695Skan rf &= ~0x77; 4459169695Skan if (sc->mac_rev < 0x0211) 4460169695Skan rf |= 0x03; 4461169695Skan run_rt3070_rf_write(sc, 27, rf); 4462169695Skan } 4463169695Skan return (0); 4464169695Skan} 4465169695Skan 4466169695Skanstatic int 4467169695Skanrun_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target, 4468169695Skan uint8_t *val) 4469169695Skan{ 4470169695Skan uint8_t rf22, rf24; 4471169695Skan uint8_t bbp55_pb, bbp55_sb, delta; 4472169695Skan int ntries; 4473169695Skan 4474169695Skan /* program filter */ 4475169695Skan run_rt3070_rf_read(sc, 24, &rf24); 4476169695Skan rf24 = (rf24 & 0xc0) | init; /* initial filter value */ 4477169695Skan run_rt3070_rf_write(sc, 24, rf24); 4478169695Skan 4479169695Skan /* enable baseband loopback mode */ 4480169695Skan run_rt3070_rf_read(sc, 22, &rf22); 4481169695Skan run_rt3070_rf_write(sc, 22, rf22 | 0x01); 4482169695Skan 4483169695Skan /* set power and frequency of passband test tone */ 4484169695Skan run_bbp_write(sc, 24, 0x00); 4485169695Skan for (ntries = 0; ntries < 100; ntries++) { 4486169695Skan /* transmit test tone */ 4487169695Skan run_bbp_write(sc, 25, 0x90); 4488169695Skan run_delay(sc, 10); 4489169695Skan /* read received power */ 4490169695Skan run_bbp_read(sc, 55, &bbp55_pb); 4491169695Skan if (bbp55_pb != 0) 4492169695Skan break; 4493169695Skan } 4494169695Skan if (ntries == 100) 4495169695Skan return ETIMEDOUT; 4496169695Skan 4497169695Skan /* set power and frequency of stopband test tone */ 4498169695Skan run_bbp_write(sc, 24, 0x06); 4499169695Skan for (ntries = 0; ntries < 100; ntries++) { 4500169695Skan /* transmit test tone */ 4501169695Skan run_bbp_write(sc, 25, 0x90); 4502169695Skan run_delay(sc, 10); 4503169695Skan /* read received power */ 4504169695Skan run_bbp_read(sc, 55, &bbp55_sb); 4505169695Skan 4506169695Skan delta = bbp55_pb - bbp55_sb; 4507169695Skan if (delta > target) 4508169695Skan break; 4509169695Skan 4510169695Skan /* reprogram filter */ 4511169695Skan rf24++; 4512169695Skan run_rt3070_rf_write(sc, 24, rf24); 4513169695Skan } 4514169695Skan if (ntries < 100) { 4515169695Skan if (rf24 != init) 4516169695Skan rf24--; /* backtrack */ 4517169695Skan *val = rf24; 4518169695Skan run_rt3070_rf_write(sc, 24, rf24); 4519169695Skan } 4520169695Skan 4521169695Skan /* restore initial state */ 4522169695Skan run_bbp_write(sc, 24, 0x00); 4523169695Skan 4524169695Skan /* disable baseband loopback mode */ 4525169695Skan run_rt3070_rf_read(sc, 22, &rf22); 4526169695Skan run_rt3070_rf_write(sc, 22, rf22 & ~0x01); 4527169695Skan 4528169695Skan return (0); 4529169695Skan} 4530169695Skan 4531169695Skanstatic void 4532169695Skanrun_rt3070_rf_setup(struct run_softc *sc) 4533169695Skan{ 4534169695Skan uint8_t bbp, rf; 4535169695Skan int i; 4536169695Skan 4537169695Skan if (sc->mac_ver == 0x3572) { 4538169695Skan /* enable DC filter */ 4539169695Skan if (sc->mac_rev >= 0x0201) 4540169695Skan run_bbp_write(sc, 103, 0xc0); 4541169695Skan 4542169695Skan run_bbp_read(sc, 138, &bbp); 4543169695Skan if (sc->ntxchains == 1) 4544169695Skan bbp |= 0x20; /* turn off DAC1 */ 4545169695Skan if (sc->nrxchains == 1) 4546169695Skan bbp &= ~0x02; /* turn off ADC1 */ 4547169695Skan run_bbp_write(sc, 138, bbp); 4548169695Skan 4549169695Skan if (sc->mac_rev >= 0x0211) { 4550169695Skan /* improve power consumption */ 4551169695Skan run_bbp_read(sc, 31, &bbp); 4552169695Skan run_bbp_write(sc, 31, bbp & ~0x03); 4553169695Skan } 4554169695Skan 4555169695Skan run_rt3070_rf_read(sc, 16, &rf); 4556169695Skan rf = (rf & ~0x07) | sc->txmixgain_2ghz; 4557169695Skan run_rt3070_rf_write(sc, 16, rf); 4558169695Skan 4559169695Skan } else if (sc->mac_ver == 0x3071) { 4560169695Skan /* enable DC filter */ 4561169695Skan if (sc->mac_rev >= 0x0201) 4562169695Skan run_bbp_write(sc, 103, 0xc0); 4563169695Skan 4564169695Skan run_bbp_read(sc, 138, &bbp); 4565169695Skan if (sc->ntxchains == 1) 4566169695Skan bbp |= 0x20; /* turn off DAC1 */ 4567169695Skan if (sc->nrxchains == 1) 4568169695Skan bbp &= ~0x02; /* turn off ADC1 */ 4569169695Skan run_bbp_write(sc, 138, bbp); 4570169695Skan 4571169695Skan if (sc->mac_rev >= 0x0211) { 4572169695Skan /* improve power consumption */ 4573169695Skan run_bbp_read(sc, 31, &bbp); 4574169695Skan run_bbp_write(sc, 31, bbp & ~0x03); 4575169695Skan } 4576169695Skan 4577169695Skan run_write(sc, RT2860_TX_SW_CFG1, 0); 4578169695Skan if (sc->mac_rev < 0x0211) { 4579169695Skan run_write(sc, RT2860_TX_SW_CFG2, 4580169695Skan sc->patch_dac ? 0x2c : 0x0f); 4581169695Skan } else 4582169695Skan run_write(sc, RT2860_TX_SW_CFG2, 0); 4583169695Skan 4584169695Skan } else if (sc->mac_ver == 0x3070) { 4585169695Skan if (sc->mac_rev >= 0x0201) { 4586169695Skan /* enable DC filter */ 4587169695Skan run_bbp_write(sc, 103, 0xc0); 4588169695Skan 4589169695Skan /* improve power consumption */ 4590169695Skan run_bbp_read(sc, 31, &bbp); 4591169695Skan run_bbp_write(sc, 31, bbp & ~0x03); 4592169695Skan } 4593169695Skan 4594169695Skan if (sc->mac_rev < 0x0211) { 4595169695Skan run_write(sc, RT2860_TX_SW_CFG1, 0); 4596169695Skan run_write(sc, RT2860_TX_SW_CFG2, 0x2c); 4597169695Skan } else 4598169695Skan run_write(sc, RT2860_TX_SW_CFG2, 0); 4599169695Skan } 4600169695Skan 4601169695Skan /* initialize RF registers from ROM for >=RT3071*/ 4602169695Skan if (sc->mac_ver >= 0x3071) { 4603169695Skan for (i = 0; i < 10; i++) { 4604169695Skan if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff) 4605169695Skan continue; 4606169695Skan run_rt3070_rf_write(sc, sc->rf[i].reg, sc->rf[i].val); 4607169695Skan } 4608169695Skan } 4609169695Skan} 4610169695Skan 4611169695Skanstatic int 4612169695Skanrun_txrx_enable(struct run_softc *sc) 4613169695Skan{ 4614169695Skan struct ieee80211com *ic = sc->sc_ifp->if_l2com; 4615169695Skan uint32_t tmp; 4616169695Skan int error, ntries; 4617169695Skan 4618169695Skan run_write(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_TX_EN); 4619169695Skan for (ntries = 0; ntries < 200; ntries++) { 4620169695Skan if ((error = run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp)) != 0) 4621169695Skan return error; 4622169695Skan if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0) 4623169695Skan break; 4624169695Skan run_delay(sc, 50); 4625169695Skan } 4626169695Skan if (ntries == 200) 4627169695Skan return ETIMEDOUT; 4628169695Skan 4629169695Skan run_delay(sc, 50); 4630169695Skan 4631169695Skan tmp |= RT2860_RX_DMA_EN | RT2860_TX_DMA_EN | RT2860_TX_WB_DDONE; 4632169695Skan run_write(sc, RT2860_WPDMA_GLO_CFG, tmp); 4633169695Skan 4634169695Skan /* enable Rx bulk aggregation (set timeout and limit) */ 4635169695Skan tmp = RT2860_USB_TX_EN | RT2860_USB_RX_EN | RT2860_USB_RX_AGG_EN | 4636169695Skan RT2860_USB_RX_AGG_TO(128) | RT2860_USB_RX_AGG_LMT(2); 4637169695Skan run_write(sc, RT2860_USB_DMA_CFG, tmp); 4638169695Skan 4639169695Skan /* set Rx filter */ 4640169695Skan tmp = RT2860_DROP_CRC_ERR | RT2860_DROP_PHY_ERR; 4641169695Skan if (ic->ic_opmode != IEEE80211_M_MONITOR) { 4642169695Skan tmp |= RT2860_DROP_UC_NOME | RT2860_DROP_DUPL | 4643169695Skan RT2860_DROP_CTS | RT2860_DROP_BA | RT2860_DROP_ACK | 4644169695Skan RT2860_DROP_VER_ERR | RT2860_DROP_CTRL_RSV | 4645169695Skan RT2860_DROP_CFACK | RT2860_DROP_CFEND; 4646169695Skan if (ic->ic_opmode == IEEE80211_M_STA) 4647169695Skan tmp |= RT2860_DROP_RTS | RT2860_DROP_PSPOLL; 4648169695Skan } 4649169695Skan run_write(sc, RT2860_RX_FILTR_CFG, tmp); 4650169695Skan 4651169695Skan run_write(sc, RT2860_MAC_SYS_CTRL, 4652169695Skan RT2860_MAC_RX_EN | RT2860_MAC_TX_EN); 4653169695Skan 4654169695Skan return (0); 4655169695Skan} 4656169695Skan 4657169695Skanstatic void 4658169695Skanrun_init_locked(struct run_softc *sc) 4659169695Skan{ 4660169695Skan struct ifnet *ifp = sc->sc_ifp; 4661169695Skan struct ieee80211com *ic = ifp->if_l2com; 4662169695Skan uint32_t tmp; 4663169695Skan uint8_t bbp1, bbp3; 4664169695Skan int i; 4665169695Skan int ridx; 4666169695Skan int ntries; 4667169695Skan 4668169695Skan if (ic->ic_nrunning > 1) 4669169695Skan return; 4670169695Skan 4671169695Skan run_stop(sc); 4672169695Skan 4673169695Skan for (ntries = 0; ntries < 100; ntries++) { 4674169695Skan if (run_read(sc, RT2860_ASIC_VER_ID, &tmp) != 0) 4675169695Skan goto fail; 4676169695Skan if (tmp != 0 && tmp != 0xffffffff) 4677169695Skan break; 4678169695Skan run_delay(sc, 10); 4679169695Skan } 4680169695Skan if (ntries == 100) 4681169695Skan goto fail; 4682169695Skan 4683169695Skan for (i = 0; i != RUN_EP_QUEUES; i++) 4684169695Skan run_setup_tx_list(sc, &sc->sc_epq[i]); 4685169695Skan 4686169695Skan run_set_macaddr(sc, IF_LLADDR(ifp)); 4687169695Skan 4688169695Skan for (ntries = 0; ntries < 100; ntries++) { 4689169695Skan if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0) 4690169695Skan goto fail; 4691169695Skan if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0) 4692169695Skan break; 4693169695Skan run_delay(sc, 10); 4694169695Skan } 4695169695Skan if (ntries == 100) { 4696169695Skan device_printf(sc->sc_dev, "timeout waiting for DMA engine\n"); 4697169695Skan goto fail; 4698169695Skan } 4699169695Skan tmp &= 0xff0; 4700169695Skan tmp |= RT2860_TX_WB_DDONE; 4701169695Skan run_write(sc, RT2860_WPDMA_GLO_CFG, tmp); 4702169695Skan 4703169695Skan /* turn off PME_OEN to solve high-current issue */ 4704169695Skan run_read(sc, RT2860_SYS_CTRL, &tmp); 4705169695Skan run_write(sc, RT2860_SYS_CTRL, tmp & ~RT2860_PME_OEN); 4706169695Skan 4707169695Skan run_write(sc, RT2860_MAC_SYS_CTRL, 4708169695Skan RT2860_BBP_HRST | RT2860_MAC_SRST); 4709169695Skan run_write(sc, RT2860_USB_DMA_CFG, 0); 4710169695Skan 4711169695Skan if (run_reset(sc) != 0) { 4712169695Skan device_printf(sc->sc_dev, "could not reset chipset\n"); 4713169695Skan goto fail; 4714169695Skan } 4715169695Skan 4716169695Skan run_write(sc, RT2860_MAC_SYS_CTRL, 0); 4717169695Skan 4718169695Skan /* init Tx power for all Tx rates (from EEPROM) */ 4719169695Skan for (ridx = 0; ridx < 5; ridx++) { 4720169695Skan if (sc->txpow20mhz[ridx] == 0xffffffff) 4721169695Skan continue; 4722169695Skan run_write(sc, RT2860_TX_PWR_CFG(ridx), sc->txpow20mhz[ridx]); 4723169695Skan } 4724169695Skan 4725169695Skan for (i = 0; i < nitems(rt2870_def_mac); i++) 4726169695Skan run_write(sc, rt2870_def_mac[i].reg, rt2870_def_mac[i].val); 4727169695Skan run_write(sc, RT2860_WMM_AIFSN_CFG, 0x00002273); 4728169695Skan run_write(sc, RT2860_WMM_CWMIN_CFG, 0x00002344); 4729169695Skan run_write(sc, RT2860_WMM_CWMAX_CFG, 0x000034aa); 4730169695Skan 4731169695Skan if (sc->mac_ver >= 0x3070) { 4732169695Skan /* set delay of PA_PE assertion to 1us (unit of 0.25us) */ 4733169695Skan run_write(sc, RT2860_TX_SW_CFG0, 4734169695Skan 4 << RT2860_DLY_PAPE_EN_SHIFT); 4735169695Skan } 4736169695Skan 4737169695Skan /* wait while MAC is busy */ 4738169695Skan for (ntries = 0; ntries < 100; ntries++) { 4739169695Skan if (run_read(sc, RT2860_MAC_STATUS_REG, &tmp) != 0) 4740169695Skan goto fail; 4741169695Skan if (!(tmp & (RT2860_RX_STATUS_BUSY | RT2860_TX_STATUS_BUSY))) 4742169695Skan break; 4743169695Skan run_delay(sc, 10); 4744169695Skan } 4745169695Skan if (ntries == 100) 4746169695Skan goto fail; 4747169695Skan 4748169695Skan /* clear Host to MCU mailbox */ 4749169695Skan run_write(sc, RT2860_H2M_BBPAGENT, 0); 4750169695Skan run_write(sc, RT2860_H2M_MAILBOX, 0); 4751169695Skan run_delay(sc, 10); 4752169695Skan 4753169695Skan if (run_bbp_init(sc) != 0) { 4754169695Skan device_printf(sc->sc_dev, "could not initialize BBP\n"); 4755169695Skan goto fail; 4756169695Skan } 4757169695Skan 4758169695Skan /* abort TSF synchronization */ 4759169695Skan run_read(sc, RT2860_BCN_TIME_CFG, &tmp); 4760169695Skan tmp &= ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | 4761169695Skan RT2860_TBTT_TIMER_EN); 4762169695Skan run_write(sc, RT2860_BCN_TIME_CFG, tmp); 4763169695Skan 4764169695Skan /* clear RX WCID search table */ 4765169695Skan run_set_region_4(sc, RT2860_WCID_ENTRY(0), 0, 512); 4766169695Skan /* clear WCID attribute table */ 4767169695Skan run_set_region_4(sc, RT2860_WCID_ATTR(0), 0, 8 * 32); 4768169695Skan 4769169695Skan /* hostapd sets a key before init. So, don't clear it. */ 4770169695Skan if (sc->cmdq_key_set != RUN_CMDQ_GO) { 4771169695Skan /* clear shared key table */ 4772169695Skan run_set_region_4(sc, RT2860_SKEY(0, 0), 0, 8 * 32); 4773169695Skan /* clear shared key mode */ 4774169695Skan run_set_region_4(sc, RT2860_SKEY_MODE_0_7, 0, 4); 4775169695Skan } 4776169695Skan 4777169695Skan run_read(sc, RT2860_US_CYC_CNT, &tmp); 4778169695Skan tmp = (tmp & ~0xff) | 0x1e; 4779169695Skan run_write(sc, RT2860_US_CYC_CNT, tmp); 4780169695Skan 4781169695Skan if (sc->mac_rev != 0x0101) 4782169695Skan run_write(sc, RT2860_TXOP_CTRL_CFG, 0x0000583f); 4783169695Skan 4784169695Skan run_write(sc, RT2860_WMM_TXOP0_CFG, 0); 4785169695Skan run_write(sc, RT2860_WMM_TXOP1_CFG, 48 << 16 | 96); 4786169695Skan 4787169695Skan /* write vendor-specific BBP values (from EEPROM) */ 4788169695Skan for (i = 0; i < 10; i++) { 4789169695Skan if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff) 4790169695Skan continue; 4791169695Skan run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val); 4792169695Skan } 4793169695Skan 4794169695Skan /* select Main antenna for 1T1R devices */ 4795169695Skan if (sc->rf_rev == RT3070_RF_3020) 4796169695Skan run_set_rx_antenna(sc, 0); 4797169695Skan 4798169695Skan /* send LEDs operating mode to microcontroller */ 4799169695Skan (void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED1, sc->led[0]); 4800169695Skan (void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1]); 4801169695Skan (void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2]); 4802169695Skan 4803169695Skan if (sc->mac_ver >= 0x3070) 4804169695Skan run_rt3070_rf_init(sc); 4805169695Skan 4806169695Skan /* disable non-existing Rx chains */ 4807169695Skan run_bbp_read(sc, 3, &bbp3); 4808169695Skan bbp3 &= ~(1 << 3 | 1 << 4); 4809169695Skan if (sc->nrxchains == 2) 4810169695Skan bbp3 |= 1 << 3; 4811169695Skan else if (sc->nrxchains == 3) 4812169695Skan bbp3 |= 1 << 4; 4813169695Skan run_bbp_write(sc, 3, bbp3); 4814169695Skan 4815169695Skan /* disable non-existing Tx chains */ 4816169695Skan run_bbp_read(sc, 1, &bbp1); 4817169695Skan if (sc->ntxchains == 1) 4818169695Skan bbp1 &= ~(1 << 3 | 1 << 4); 4819169695Skan run_bbp_write(sc, 1, bbp1); 4820169695Skan 4821169695Skan if (sc->mac_ver >= 0x3070) 4822169695Skan run_rt3070_rf_setup(sc); 4823169695Skan 4824169695Skan /* select default channel */ 4825169695Skan run_set_chan(sc, ic->ic_curchan); 4826169695Skan 4827169695Skan /* setup initial protection mode */ 4828169695Skan run_updateprot_cb(ic); 4829169695Skan 4830169695Skan /* turn radio LED on */ 4831169695Skan run_set_leds(sc, RT2860_LED_RADIO); 4832169695Skan 4833169695Skan ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 4834169695Skan ifp->if_drv_flags |= IFF_DRV_RUNNING; 4835169695Skan sc->cmdq_run = RUN_CMDQ_GO; 4836169695Skan 4837169695Skan for (i = 0; i != RUN_N_XFER; i++) 4838169695Skan usbd_xfer_set_stall(sc->sc_xfer[i]); 4839169695Skan 4840169695Skan usbd_transfer_start(sc->sc_xfer[RUN_BULK_RX]); 4841169695Skan 4842169695Skan if (run_txrx_enable(sc) != 0) 4843169695Skan goto fail; 4844169695Skan 4845169695Skan return; 4846169695Skan 4847169695Skanfail: 4848169695Skan run_stop(sc); 4849169695Skan} 4850169695Skan 4851169695Skanstatic void 4852169695Skanrun_init(void *arg) 4853169695Skan{ 4854169695Skan struct run_softc *sc = arg; 4855169695Skan struct ifnet *ifp = sc->sc_ifp; 4856169695Skan struct ieee80211com *ic = ifp->if_l2com; 4857169695Skan 4858169695Skan RUN_LOCK(sc); 4859169695Skan run_init_locked(sc); 4860169695Skan RUN_UNLOCK(sc); 4861169695Skan 4862169695Skan if (ifp->if_drv_flags & IFF_DRV_RUNNING) 4863169695Skan ieee80211_start_all(ic); 4864169695Skan} 4865169695Skan 4866169695Skanstatic void 4867169695Skanrun_stop(void *arg) 4868169695Skan{ 4869169695Skan struct run_softc *sc = (struct run_softc *)arg; 4870169695Skan struct ifnet *ifp = sc->sc_ifp; 4871169695Skan uint32_t tmp; 4872169695Skan int i; 4873169695Skan int ntries; 4874169695Skan 4875169695Skan RUN_LOCK_ASSERT(sc, MA_OWNED); 4876169695Skan 4877169695Skan if (ifp->if_drv_flags & IFF_DRV_RUNNING) 4878169695Skan run_set_leds(sc, 0); /* turn all LEDs off */ 4879169695Skan 4880169695Skan ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 4881169695Skan 4882169695Skan sc->ratectl_run = RUN_RATECTL_OFF; 4883169695Skan sc->cmdq_run = sc->cmdq_key_set; 4884169695Skan 4885169695Skan RUN_UNLOCK(sc); 4886169695Skan 4887169695Skan for(i = 0; i < RUN_N_XFER; i++) 4888169695Skan usbd_transfer_drain(sc->sc_xfer[i]); 4889169695Skan 4890169695Skan RUN_LOCK(sc); 4891169695Skan 4892169695Skan if (sc->rx_m != NULL) { 4893169695Skan m_free(sc->rx_m); 4894169695Skan sc->rx_m = NULL; 4895169695Skan } 4896169695Skan 4897169695Skan /* disable Tx/Rx */ 4898169695Skan run_read(sc, RT2860_MAC_SYS_CTRL, &tmp); 4899169695Skan tmp &= ~(RT2860_MAC_RX_EN | RT2860_MAC_TX_EN); 4900169695Skan run_write(sc, RT2860_MAC_SYS_CTRL, tmp); 4901169695Skan 4902169695Skan /* wait for pending Tx to complete */ 4903169695Skan for (ntries = 0; ntries < 100; ntries++) { 4904169695Skan if (run_read(sc, RT2860_TXRXQ_PCNT, &tmp) != 0) { 4905169695Skan DPRINTF("Cannot read Tx queue count\n"); 4906169695Skan break; 4907169695Skan } 4908169695Skan if ((tmp & RT2860_TX2Q_PCNT_MASK) == 0) { 4909169695Skan DPRINTF("All Tx cleared\n"); 4910169695Skan break; 4911169695Skan } 4912169695Skan run_delay(sc, 10); 4913169695Skan } 4914169695Skan if (ntries >= 100) 4915169695Skan DPRINTF("There are still pending Tx\n"); 4916169695Skan run_delay(sc, 10); 4917169695Skan run_write(sc, RT2860_USB_DMA_CFG, 0); 4918169695Skan 4919169695Skan run_write(sc, RT2860_MAC_SYS_CTRL, RT2860_BBP_HRST | RT2860_MAC_SRST); 4920169695Skan run_write(sc, RT2860_MAC_SYS_CTRL, 0); 4921169695Skan 4922169695Skan for (i = 0; i != RUN_EP_QUEUES; i++) 4923169695Skan run_unsetup_tx_list(sc, &sc->sc_epq[i]); 4924169695Skan 4925169695Skan return; 4926169695Skan} 4927169695Skan 4928169695Skanstatic void 4929169695Skanrun_delay(struct run_softc *sc, unsigned int ms) 4930169695Skan{ 4931169695Skan usb_pause_mtx(mtx_owned(&sc->sc_mtx) ? 4932169695Skan &sc->sc_mtx : NULL, USB_MS_TO_TICKS(ms)); 4933169695Skan} 4934169695Skan 4935169695Skanstatic device_method_t run_methods[] = { 4936169695Skan /* Device interface */ 4937169695Skan DEVMETHOD(device_probe, run_match), 4938169695Skan DEVMETHOD(device_attach, run_attach), 4939169695Skan DEVMETHOD(device_detach, run_detach), 4940169695Skan 4941169695Skan { 0, 0 } 4942169695Skan}; 4943169695Skan 4944169695Skanstatic driver_t run_driver = { 4945169695Skan "run", 4946169695Skan run_methods, 4947169695Skan sizeof(struct run_softc) 4948169695Skan}; 4949169695Skan 4950169695Skanstatic devclass_t run_devclass; 4951169695Skan 4952169695SkanDRIVER_MODULE(run, uhub, run_driver, run_devclass, NULL, 0); 4953169695SkanMODULE_DEPEND(run, wlan, 1, 1, 1); 4954169695SkanMODULE_DEPEND(run, usb, 1, 1, 1); 4955169695SkanMODULE_DEPEND(run, firmware, 1, 1, 1); 4956169695SkanMODULE_VERSION(run, 1); 4957169695Skan