1 /* $NetBSD: if_otus.c,v 1.44 2020/03/15 23:04:50 thorpej Exp $ */ 2 /* $OpenBSD: if_otus.c,v 1.18 2010/08/27 17:08:00 jsg Exp $ */ 3 4 /*- 5 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /*- 21 * Driver for Atheros AR9001U chipset. 22 * http://www.atheros.com/pt/bulletins/AR9001USBBulletin.pdf 23 */ 24 25 #include <sys/cdefs.h> 26 __KERNEL_RCSID(0, "$NetBSD: if_otus.c,v 1.44 2020/03/15 23:04:50 thorpej Exp $"); 27 28 #ifdef _KERNEL_OPT 29 #include "opt_usb.h" 30 #endif 31 32 #include <sys/param.h> 33 #include <sys/sockio.h> 34 #include <sys/mbuf.h> 35 #include <sys/kernel.h> 36 #include <sys/kmem.h> 37 #include <sys/kthread.h> 38 #include <sys/systm.h> 39 #include <sys/callout.h> 40 #include <sys/device.h> 41 #include <sys/proc.h> 42 #include <sys/bus.h> 43 #include <sys/endian.h> 44 #include <sys/intr.h> 45 46 #include <net/bpf.h> 47 #include <net/if.h> 48 #include <net/if_arp.h> 49 #include <net/if_dl.h> 50 #include <net/if_ether.h> 51 #include <net/if_media.h> 52 #include <net/if_types.h> 53 54 #include <netinet/in.h> 55 #include <netinet/in_systm.h> 56 #include <netinet/in_var.h> 57 #include <netinet/ip.h> 58 59 #include <net80211/ieee80211_var.h> 60 #include <net80211/ieee80211_amrr.h> 61 #include <net80211/ieee80211_radiotap.h> 62 63 #include <dev/firmload.h> 64 65 #include <dev/usb/usb.h> 66 #include <dev/usb/usbdi.h> 67 #include <dev/usb/usbdi_util.h> 68 #include <dev/usb/usbdivar.h> 69 #include <dev/usb/usbdevs.h> 70 71 #include <dev/usb/if_otusreg.h> 72 #include <dev/usb/if_otusvar.h> 73 74 #ifdef OTUS_DEBUG 75 76 #define DBG_INIT __BIT(0) 77 #define DBG_FN __BIT(1) 78 #define DBG_TX __BIT(2) 79 #define DBG_RX __BIT(3) 80 #define DBG_STM __BIT(4) 81 #define DBG_CHAN __BIT(5) 82 #define DBG_REG __BIT(6) 83 #define DBG_CMD __BIT(7) 84 #define DBG_ALL 0xffffffffU 85 #define DBG_NO_SC (struct otus_softc *)NULL 86 87 unsigned int otus_debug = 0; 88 #define DPRINTFN(n, s, ...) do { \ 89 if (otus_debug & (n)) { \ 90 if ((s) != NULL) \ 91 printf("%s: ", device_xname((s)->sc_dev)); \ 92 else \ 93 printf("otus0: "); \ 94 printf("%s: ", __func__); \ 95 printf(__VA_ARGS__); \ 96 } \ 97 } while (0) 98 99 #else /* ! OTUS_DEBUG */ 100 101 #define DPRINTFN(n, ...) \ 102 do { } while (0) 103 104 #endif /* OTUS_DEBUG */ 105 106 Static int otus_match(device_t, cfdata_t, void *); 107 Static void otus_attach(device_t, device_t, void *); 108 Static int otus_detach(device_t, int); 109 Static int otus_activate(device_t, devact_t); 110 Static void otus_attachhook(device_t); 111 Static void otus_get_chanlist(struct otus_softc *); 112 Static int otus_load_firmware(struct otus_softc *, const char *, 113 uint32_t); 114 Static int otus_open_pipes(struct otus_softc *); 115 Static void otus_close_pipes(struct otus_softc *); 116 Static int otus_alloc_tx_cmd(struct otus_softc *); 117 Static void otus_free_tx_cmd(struct otus_softc *); 118 Static int otus_alloc_tx_data_list(struct otus_softc *); 119 Static void otus_free_tx_data_list(struct otus_softc *); 120 Static int otus_alloc_rx_data_list(struct otus_softc *); 121 Static void otus_free_rx_data_list(struct otus_softc *); 122 Static void otus_next_scan(void *); 123 Static void otus_task(void *); 124 Static void otus_do_async(struct otus_softc *, 125 void (*)(struct otus_softc *, void *), void *, int); 126 Static int otus_newstate(struct ieee80211com *, enum ieee80211_state, 127 int); 128 Static void otus_newstate_cb(struct otus_softc *, void *); 129 Static int otus_cmd(struct otus_softc *, uint8_t, const void *, int, 130 void *); 131 Static void otus_write(struct otus_softc *, uint32_t, uint32_t); 132 Static int otus_write_barrier(struct otus_softc *); 133 Static struct ieee80211_node *otus_node_alloc(struct ieee80211_node_table *); 134 Static int otus_media_change(struct ifnet *); 135 Static int otus_read_eeprom(struct otus_softc *); 136 Static void otus_newassoc(struct ieee80211_node *, int); 137 Static void otus_intr(struct usbd_xfer *, void *, usbd_status); 138 Static void otus_cmd_rxeof(struct otus_softc *, uint8_t *, int); 139 Static void otus_sub_rxeof(struct otus_softc *, uint8_t *, int); 140 Static void otus_rxeof(struct usbd_xfer *, void *, usbd_status); 141 Static void otus_txeof(struct usbd_xfer *, void *, usbd_status); 142 Static int otus_tx(struct otus_softc *, struct mbuf *, 143 struct ieee80211_node *, struct otus_tx_data *); 144 Static void otus_start(struct ifnet *); 145 Static void otus_watchdog(struct ifnet *); 146 Static int otus_ioctl(struct ifnet *, u_long, void *); 147 Static int otus_set_multi(struct otus_softc *); 148 #ifdef HAVE_EDCA 149 Static void otus_updateedca(struct ieee80211com *); 150 Static void otus_updateedca_cb(struct otus_softc *, void *); 151 #endif 152 Static void otus_updateedca_cb_locked(struct otus_softc *); 153 Static void otus_updateslot(struct ifnet *); 154 Static void otus_updateslot_cb(struct otus_softc *, void *); 155 Static void otus_updateslot_cb_locked(struct otus_softc *); 156 Static int otus_init_mac(struct otus_softc *); 157 Static uint32_t otus_phy_get_def(struct otus_softc *, uint32_t); 158 Static int otus_set_board_values(struct otus_softc *, 159 struct ieee80211_channel *); 160 Static int otus_program_phy(struct otus_softc *, 161 struct ieee80211_channel *); 162 Static int otus_set_rf_bank4(struct otus_softc *, 163 struct ieee80211_channel *); 164 Static void otus_get_delta_slope(uint32_t, uint32_t *, uint32_t *); 165 Static int otus_set_chan(struct otus_softc *, struct ieee80211_channel *, 166 int); 167 #ifdef notyet 168 Static int otus_set_key(struct ieee80211com *, struct ieee80211_node *, 169 struct ieee80211_key *); 170 Static void otus_set_key_cb(struct otus_softc *, void *); 171 Static void otus_delete_key(struct ieee80211com *, struct ieee80211_node *, 172 struct ieee80211_key *); 173 Static void otus_delete_key_cb(struct otus_softc *, void *); 174 #endif /* notyet */ 175 Static void otus_calib_to(void *); 176 Static int otus_set_bssid(struct otus_softc *, const uint8_t *); 177 Static int otus_set_macaddr(struct otus_softc *, const uint8_t *); 178 #ifdef notyet 179 Static void otus_led_newstate_type1(struct otus_softc *); 180 Static void otus_led_newstate_type2(struct otus_softc *); 181 #endif /* notyet */ 182 Static void otus_led_newstate_type3(struct otus_softc *); 183 Static int otus_init(struct ifnet *); 184 Static void otus_stop(struct ifnet *); 185 Static void otus_wait_async(struct otus_softc *); 186 187 /* List of supported channels. */ 188 static const uint8_t ar_chans[] = { 189 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 190 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 191 128, 132, 136, 140, 149, 153, 157, 161, 165, 34, 38, 42, 46 192 }; 193 194 /* 195 * This data is automatically generated from the "otus.ini" file. 196 * It is stored in a different way though, to reduce kernel's .rodata 197 * section overhead (5.1KB instead of 8.5KB). 198 */ 199 200 /* NB: apply AR_PHY(). */ 201 static const uint16_t ar5416_phy_regs[] = { 202 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 203 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f, 0x010, 0x011, 204 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, 0x018, 0x01a, 0x01b, 205 0x040, 0x041, 0x042, 0x043, 0x045, 0x046, 0x047, 0x048, 0x049, 206 0x04a, 0x04b, 0x04d, 0x04e, 0x04f, 0x051, 0x052, 0x053, 0x055, 207 0x056, 0x058, 0x059, 0x05c, 0x05d, 0x05e, 0x05f, 0x060, 0x061, 208 0x062, 0x063, 0x064, 0x065, 0x066, 0x067, 0x068, 0x069, 0x06a, 209 0x06b, 0x06c, 0x06d, 0x070, 0x071, 0x072, 0x073, 0x074, 0x075, 210 0x076, 0x077, 0x078, 0x079, 0x07a, 0x07b, 0x07c, 0x07f, 0x080, 211 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087, 0x088, 0x089, 212 0x08a, 0x08b, 0x08c, 0x08d, 0x08e, 0x08f, 0x090, 0x091, 0x092, 213 0x093, 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09a, 0x09b, 214 0x09c, 0x09d, 0x09e, 0x09f, 0x0a0, 0x0a1, 0x0a2, 0x0a3, 0x0a4, 215 0x0a5, 0x0a6, 0x0a7, 0x0a8, 0x0a9, 0x0aa, 0x0ab, 0x0ac, 0x0ad, 216 0x0ae, 0x0af, 0x0b0, 0x0b1, 0x0b2, 0x0b3, 0x0b4, 0x0b5, 0x0b6, 217 0x0b7, 0x0b8, 0x0b9, 0x0ba, 0x0bb, 0x0bc, 0x0bd, 0x0be, 0x0bf, 218 0x0c0, 0x0c1, 0x0c2, 0x0c3, 0x0c4, 0x0c5, 0x0c6, 0x0c7, 0x0c8, 219 0x0c9, 0x0ca, 0x0cb, 0x0cc, 0x0cd, 0x0ce, 0x0cf, 0x0d0, 0x0d1, 220 0x0d2, 0x0d3, 0x0d4, 0x0d5, 0x0d6, 0x0d7, 0x0d8, 0x0d9, 0x0da, 221 0x0db, 0x0dc, 0x0dd, 0x0de, 0x0df, 0x0e0, 0x0e1, 0x0e2, 0x0e3, 222 0x0e4, 0x0e5, 0x0e6, 0x0e7, 0x0e8, 0x0e9, 0x0ea, 0x0eb, 0x0ec, 223 0x0ed, 0x0ee, 0x0ef, 0x0f0, 0x0f1, 0x0f2, 0x0f3, 0x0f4, 0x0f5, 224 0x0f6, 0x0f7, 0x0f8, 0x0f9, 0x0fa, 0x0fb, 0x0fc, 0x0fd, 0x0fe, 225 0x0ff, 0x100, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 226 0x10a, 0x10b, 0x10c, 0x10d, 0x10e, 0x10f, 0x13c, 0x13d, 0x13e, 227 0x13f, 0x280, 0x281, 0x282, 0x283, 0x284, 0x285, 0x286, 0x287, 228 0x288, 0x289, 0x28a, 0x28b, 0x28c, 0x28d, 0x28e, 0x28f, 0x290, 229 0x291, 0x292, 0x293, 0x294, 0x295, 0x296, 0x297, 0x298, 0x299, 230 0x29a, 0x29b, 0x29d, 0x29e, 0x29f, 0x2c0, 0x2c1, 0x2c2, 0x2c3, 231 0x2c4, 0x2c5, 0x2c6, 0x2c7, 0x2c8, 0x2c9, 0x2ca, 0x2cb, 0x2cc, 232 0x2cd, 0x2ce, 0x2cf, 0x2d0, 0x2d1, 0x2d2, 0x2d3, 0x2d4, 0x2d5, 233 0x2d6, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e6, 0x2e7, 0x2e8, 0x2e9, 234 0x2ea, 0x2eb, 0x2ec, 0x2ed, 0x2ee, 0x2ef, 0x2f0, 0x2f1, 0x2f2, 235 0x2f3, 0x2f4, 0x2f5, 0x2f6, 0x2f7, 0x2f8, 0x412, 0x448, 0x458, 236 0x683, 0x69b, 0x812, 0x848, 0x858, 0xa83, 0xa9b, 0xc19, 0xc57, 237 0xc5a, 0xc6f, 0xe9c, 0xed7, 0xed8, 0xed9, 0xeda, 0xedb, 0xedc, 238 0xedd, 0xede, 0xedf, 0xee0, 0xee1 239 }; 240 241 static const uint32_t ar5416_phy_vals_5ghz_20mhz[] = { 242 0x00000007, 0x00000300, 0x00000000, 0xad848e19, 0x7d14e000, 243 0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e, 244 0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007, 245 0x00200400, 0x206a002e, 0x1372161e, 0x001a6a65, 0x1284233c, 246 0x6c48b4e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd10, 247 0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000, 248 0x00000000, 0x000007d0, 0x00000118, 0x10000fff, 0x0510081c, 249 0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f, 250 0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188, 251 0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000, 252 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 253 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 254 0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000, 255 0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8, 256 0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200, 257 0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042, 258 0x00000000, 0x00000040, 0x00000080, 0x000001a1, 0x000001e1, 259 0x00000021, 0x00000061, 0x00000168, 0x000001a8, 0x000001e8, 260 0x00000028, 0x00000068, 0x00000189, 0x000001c9, 0x00000009, 261 0x00000049, 0x00000089, 0x00000170, 0x000001b0, 0x000001f0, 262 0x00000030, 0x00000070, 0x00000191, 0x000001d1, 0x00000011, 263 0x00000051, 0x00000091, 0x000001b8, 0x000001f8, 0x00000038, 264 0x00000078, 0x00000199, 0x000001d9, 0x00000019, 0x00000059, 265 0x00000099, 0x000000d9, 0x000000f9, 0x000000f9, 0x000000f9, 266 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 267 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 268 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 269 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 270 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000, 271 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 272 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, 273 0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013, 274 0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a, 275 0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021, 276 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028, 277 0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d, 278 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 279 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 280 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 281 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 282 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 283 0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000, 284 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 285 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 286 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 287 0x00000000, 0x00000008, 0x00000440, 0xd6be4788, 0x012e8160, 288 0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6, 289 0x00000400, 0x000009b5, 0x00000000, 0x00000108, 0x3f3f3f3f, 290 0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, 291 0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, 292 0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a9caa, 293 0x1ce739ce, 0x051701ce, 0x18010000, 0x30032602, 0x48073e06, 294 0x560b4c0a, 0x641a600f, 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf, 295 0xb51fa69f, 0xcb3fbd07, 0x0000d7bf, 0x00000000, 0x00000000, 296 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 297 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f, 298 0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce, 299 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 300 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 301 0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 302 0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a65, 0x0510001c, 303 0x00009b40, 0x012e8160, 0x09249126, 0x00180a65, 0x0510001c, 304 0x00009b40, 0x012e8160, 0x09249126, 0x0001c600, 0x004b6a8e, 305 0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207, 306 0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803, 307 0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0 308 }; 309 310 #ifdef notyet 311 static const uint32_t ar5416_phy_vals_5ghz_40mhz[] = { 312 0x00000007, 0x000003c4, 0x00000000, 0xad848e19, 0x7d14e000, 313 0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e, 314 0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007, 315 0x00200400, 0x206a002e, 0x13721c1e, 0x001a6a65, 0x1284233c, 316 0x6c48b4e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd10, 317 0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000, 318 0x00000000, 0x000007d0, 0x00000230, 0x10000fff, 0x0510081c, 319 0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f, 320 0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188, 321 0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000, 322 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 323 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 324 0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000, 325 0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8, 326 0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200, 327 0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042, 328 0x00000000, 0x00000040, 0x00000080, 0x000001a1, 0x000001e1, 329 0x00000021, 0x00000061, 0x00000168, 0x000001a8, 0x000001e8, 330 0x00000028, 0x00000068, 0x00000189, 0x000001c9, 0x00000009, 331 0x00000049, 0x00000089, 0x00000170, 0x000001b0, 0x000001f0, 332 0x00000030, 0x00000070, 0x00000191, 0x000001d1, 0x00000011, 333 0x00000051, 0x00000091, 0x000001b8, 0x000001f8, 0x00000038, 334 0x00000078, 0x00000199, 0x000001d9, 0x00000019, 0x00000059, 335 0x00000099, 0x000000d9, 0x000000f9, 0x000000f9, 0x000000f9, 336 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 337 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 338 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 339 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 340 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000, 341 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 342 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, 343 0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013, 344 0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a, 345 0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021, 346 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028, 347 0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d, 348 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 349 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 350 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 351 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 352 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 353 0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000, 354 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 355 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 356 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 357 0x00000000, 0x00000008, 0x00000440, 0xd6be4788, 0x012e8160, 358 0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6, 359 0x00000400, 0x000009b5, 0x00000000, 0x00000210, 0x3f3f3f3f, 360 0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, 361 0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, 362 0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a9caa, 363 0x1ce739ce, 0x051701ce, 0x18010000, 0x30032602, 0x48073e06, 364 0x560b4c0a, 0x641a600f, 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf, 365 0xb51fa69f, 0xcb3fbcbf, 0x0000d7bf, 0x00000000, 0x00000000, 366 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 367 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f, 368 0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce, 369 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 370 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 371 0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 372 0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a65, 0x0510001c, 373 0x00009b40, 0x012e8160, 0x09249126, 0x00180a65, 0x0510001c, 374 0x00009b40, 0x012e8160, 0x09249126, 0x0001c600, 0x004b6a8e, 375 0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207, 376 0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803, 377 0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0 378 }; 379 #endif 380 381 #ifdef notyet 382 static const uint32_t ar5416_phy_vals_2ghz_40mhz[] = { 383 0x00000007, 0x000003c4, 0x00000000, 0xad848e19, 0x7d14e000, 384 0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e, 385 0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007, 386 0x00200400, 0x206a002e, 0x13721c24, 0x00197a68, 0x1284233c, 387 0x6c48b0e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd20, 388 0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000, 389 0x00000000, 0x00000898, 0x00000268, 0x10000fff, 0x0510001c, 390 0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f, 391 0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188, 392 0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000, 393 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 394 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 395 0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000, 396 0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8, 397 0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200, 398 0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042, 399 0x00000000, 0x00000040, 0x00000080, 0x00000141, 0x00000181, 400 0x000001c1, 0x00000001, 0x00000041, 0x000001a8, 0x000001e8, 401 0x00000028, 0x00000068, 0x000000a8, 0x00000169, 0x000001a9, 402 0x000001e9, 0x00000029, 0x00000069, 0x00000190, 0x000001d0, 403 0x00000010, 0x00000050, 0x00000090, 0x00000151, 0x00000191, 404 0x000001d1, 0x00000011, 0x00000051, 0x00000198, 0x000001d8, 405 0x00000018, 0x00000058, 0x00000098, 0x00000159, 0x00000199, 406 0x000001d9, 0x00000019, 0x00000059, 0x00000099, 0x000000d9, 407 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 408 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 409 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 410 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 411 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000, 412 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 413 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, 414 0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013, 415 0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a, 416 0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021, 417 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028, 418 0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d, 419 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 420 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 421 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 422 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 423 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 424 0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000, 425 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 426 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 427 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 428 0x00000000, 0x0000000e, 0x00000440, 0xd03e4788, 0x012a8160, 429 0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6, 430 0x00000400, 0x000009b5, 0x00000000, 0x00000210, 0x3f3f3f3f, 431 0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, 432 0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, 433 0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a7caa, 434 0x1ce739ce, 0x051701ce, 0x18010000, 0x2e032402, 0x4a0a3c06, 435 0x621a540b, 0x764f6c1b, 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f, 436 0xbddfaf1f, 0xd1ffc93f, 0x00000000, 0x00000000, 0x00000000, 437 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 438 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f, 439 0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce, 440 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 441 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 442 0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 443 0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a68, 0x0510001c, 444 0x00009b40, 0x012a8160, 0x09249126, 0x00180a68, 0x0510001c, 445 0x00009b40, 0x012a8160, 0x09249126, 0x0001c600, 0x004b6a8e, 446 0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207, 447 0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803, 448 0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0 449 }; 450 #endif 451 452 static const uint32_t ar5416_phy_vals_2ghz_20mhz[] = { 453 0x00000007, 0x00000300, 0x00000000, 0xad848e19, 0x7d14e000, 454 0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e, 455 0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007, 456 0x00200400, 0x206a002e, 0x137216a4, 0x00197a68, 0x1284233c, 457 0x6c48b0e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd20, 458 0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000, 459 0x00000000, 0x00000898, 0x00000134, 0x10000fff, 0x0510001c, 460 0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f, 461 0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188, 462 0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000, 463 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 464 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 465 0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000, 466 0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8, 467 0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200, 468 0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042, 469 0x00000000, 0x00000040, 0x00000080, 0x00000141, 0x00000181, 470 0x000001c1, 0x00000001, 0x00000041, 0x000001a8, 0x000001e8, 471 0x00000028, 0x00000068, 0x000000a8, 0x00000169, 0x000001a9, 472 0x000001e9, 0x00000029, 0x00000069, 0x00000190, 0x000001d0, 473 0x00000010, 0x00000050, 0x00000090, 0x00000151, 0x00000191, 474 0x000001d1, 0x00000011, 0x00000051, 0x00000198, 0x000001d8, 475 0x00000018, 0x00000058, 0x00000098, 0x00000159, 0x00000199, 476 0x000001d9, 0x00000019, 0x00000059, 0x00000099, 0x000000d9, 477 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 478 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 479 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 480 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 481 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000, 482 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 483 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, 484 0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013, 485 0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a, 486 0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021, 487 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028, 488 0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d, 489 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 490 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 491 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 492 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 493 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 494 0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000, 495 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 496 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 497 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 498 0x00000000, 0x0000000e, 0x00000440, 0xd03e4788, 0x012a8160, 499 0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6, 500 0x00000400, 0x000009b5, 0x00000000, 0x00000108, 0x3f3f3f3f, 501 0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, 502 0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, 503 0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a7caa, 504 0x1ce739ce, 0x051701ce, 0x18010000, 0x2e032402, 0x4a0a3c06, 505 0x621a540b, 0x764f6c1b, 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f, 506 0xbddfaf1f, 0xd1ffc93f, 0x00000000, 0x00000000, 0x00000000, 507 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 508 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f, 509 0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce, 510 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 511 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 512 0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 513 0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a68, 0x0510001c, 514 0x00009b40, 0x012a8160, 0x09249126, 0x00180a68, 0x0510001c, 515 0x00009b40, 0x012a8160, 0x09249126, 0x0001c600, 0x004b6a8e, 516 0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207, 517 0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803, 518 0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0 519 }; 520 521 /* NB: apply AR_PHY(). */ 522 static const uint8_t ar5416_banks_regs[] = { 523 0x2c, 0x38, 0x2c, 0x3b, 0x2c, 0x38, 0x3c, 0x2c, 0x3a, 0x2c, 0x39, 524 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 525 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 526 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 527 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 528 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x38, 0x2c, 0x2c, 529 0x2c, 0x3c 530 }; 531 532 static const uint32_t ar5416_banks_vals_5ghz[] = { 533 0x1e5795e5, 0x02008020, 0x02108421, 0x00000008, 0x0e73ff17, 534 0x00000420, 0x01400018, 0x000001a1, 0x00000001, 0x00000013, 535 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 536 0x00000000, 0x00004000, 0x00006c00, 0x00002c00, 0x00004800, 537 0x00004000, 0x00006000, 0x00001000, 0x00004000, 0x00007c00, 538 0x00007c00, 0x00007c00, 0x00007c00, 0x00007c00, 0x00087c00, 539 0x00007c00, 0x00005400, 0x00000c00, 0x00001800, 0x00007c00, 540 0x00006c00, 0x00006c00, 0x00007c00, 0x00002c00, 0x00003c00, 541 0x00003800, 0x00001c00, 0x00000800, 0x00000408, 0x00004c15, 542 0x00004188, 0x0000201e, 0x00010408, 0x00000801, 0x00000c08, 543 0x0000181e, 0x00001016, 0x00002800, 0x00004010, 0x0000081c, 544 0x00000115, 0x00000015, 0x00000066, 0x0000001c, 0x00000000, 545 0x00000004, 0x00000015, 0x0000001f, 0x00000000, 0x000000a0, 546 0x00000000, 0x00000040, 0x0000001c 547 }; 548 549 static const uint32_t ar5416_banks_vals_2ghz[] = { 550 0x1e5795e5, 0x02008020, 0x02108421, 0x00000008, 0x0e73ff17, 551 0x00000420, 0x01c00018, 0x000001a1, 0x00000001, 0x00000013, 552 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 553 0x00000000, 0x00004000, 0x00006c00, 0x00002c00, 0x00004800, 554 0x00004000, 0x00006000, 0x00001000, 0x00004000, 0x00007c00, 555 0x00007c00, 0x00007c00, 0x00007c00, 0x00007c00, 0x00087c00, 556 0x00007c00, 0x00005400, 0x00000c00, 0x00001800, 0x00007c00, 557 0x00006c00, 0x00006c00, 0x00007c00, 0x00002c00, 0x00003c00, 558 0x00003800, 0x00001c00, 0x00000800, 0x00000408, 0x00004c15, 559 0x00004188, 0x0000201e, 0x00010408, 0x00000801, 0x00000c08, 560 0x0000181e, 0x00001016, 0x00002800, 0x00004010, 0x0000081c, 561 0x00000115, 0x00000015, 0x00000066, 0x0000001c, 0x00000000, 562 0x00000004, 0x00000015, 0x0000001f, 0x00000400, 0x000000a0, 563 0x00000000, 0x00000040, 0x0000001c 564 }; 565 566 static const struct usb_devno otus_devs[] = { 567 { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN7512 }, 568 { USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_3CRUSBN275 }, 569 { USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_TG121N }, 570 { USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9170 }, 571 { USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN612 }, 572 { USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN821NV2 }, 573 { USB_VENDOR_AVM, USB_PRODUCT_AVM_FRITZWLAN }, 574 { USB_VENDOR_CACE, USB_PRODUCT_CACE_AIRPCAPNX }, 575 { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA130D1 }, 576 { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A1 }, 577 { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A2 }, 578 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_WNGDNUS2 }, 579 { USB_VENDOR_NEC, USB_PRODUCT_NEC_WL300NUG }, 580 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WN111V2 }, 581 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000 }, 582 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3100 }, 583 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US300 }, 584 { USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_O8494 }, 585 { USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_WNC0600 }, 586 { USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB81 }, 587 { USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB82 }, 588 { USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1221 }, 589 { USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD271N } 590 }; 591 592 CFATTACH_DECL_NEW(otus, sizeof(struct otus_softc), otus_match, otus_attach, 593 otus_detach, otus_activate); 594 595 Static int 596 otus_match(device_t parent, cfdata_t match, void *aux) 597 { 598 struct usb_attach_arg *uaa; 599 600 uaa = aux; 601 602 DPRINTFN(DBG_FN, DBG_NO_SC, 603 "otus_match: vendor=%#x product=%#x revision=%#x\n", 604 uaa->uaa_vendor, uaa->uaa_product, uaa->uaa_release); 605 606 return usb_lookup(otus_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ? 607 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 608 } 609 610 Static void 611 otus_attach(device_t parent, device_t self, void *aux) 612 { 613 struct otus_softc *sc; 614 struct usb_attach_arg *uaa; 615 char *devinfop; 616 int error; 617 618 sc = device_private(self); 619 620 DPRINTFN(DBG_FN, sc, "\n"); 621 622 sc->sc_dev = self; 623 uaa = aux; 624 sc->sc_udev = uaa->uaa_device; 625 626 aprint_naive("\n"); 627 aprint_normal("\n"); 628 629 devinfop = usbd_devinfo_alloc(sc->sc_udev, 0); 630 aprint_normal_dev(sc->sc_dev, "%s\n", devinfop); 631 usbd_devinfo_free(devinfop); 632 633 cv_init(&sc->sc_task_cv, "otustsk"); 634 cv_init(&sc->sc_cmd_cv, "otuscmd"); 635 mutex_init(&sc->sc_cmd_mtx, MUTEX_DEFAULT, IPL_NONE); 636 mutex_init(&sc->sc_task_mtx, MUTEX_DEFAULT, IPL_NET); 637 mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_NONE); 638 mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE); 639 640 usb_init_task(&sc->sc_task, otus_task, sc, 0); 641 642 callout_init(&sc->sc_scan_to, 0); 643 callout_setfunc(&sc->sc_scan_to, otus_next_scan, sc); 644 callout_init(&sc->sc_calib_to, 0); 645 callout_setfunc(&sc->sc_calib_to, otus_calib_to, sc); 646 647 sc->sc_amrr.amrr_min_success_threshold = 1; 648 sc->sc_amrr.amrr_max_success_threshold = 10; 649 650 if (usbd_set_config_no(sc->sc_udev, 1, 0) != 0) { 651 aprint_error_dev(sc->sc_dev, 652 "could not set configuration no\n"); 653 return; 654 } 655 656 /* Get the first interface handle. */ 657 error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface); 658 if (error != 0) { 659 aprint_error_dev(sc->sc_dev, 660 "could not get interface handle\n"); 661 return; 662 } 663 664 if ((error = otus_open_pipes(sc)) != 0) { 665 aprint_error_dev(sc->sc_dev, "could not open pipes\n"); 666 return; 667 } 668 669 /* 670 * We need the firmware loaded from file system to complete the attach. 671 */ 672 config_mountroot(self, otus_attachhook); 673 674 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 675 } 676 677 Static void 678 otus_wait_async(struct otus_softc *sc) 679 { 680 681 DPRINTFN(DBG_FN, sc, "\n"); 682 683 mutex_spin_enter(&sc->sc_task_mtx); 684 while (sc->sc_cmdq.queued > 0) 685 cv_wait(&sc->sc_task_cv, &sc->sc_task_mtx); 686 mutex_spin_exit(&sc->sc_task_mtx); 687 } 688 689 Static int 690 otus_detach(device_t self, int flags) 691 { 692 struct otus_softc *sc; 693 struct ifnet *ifp; 694 int s; 695 696 sc = device_private(self); 697 698 DPRINTFN(DBG_FN, sc, "\n"); 699 700 s = splusb(); 701 702 sc->sc_dying = 1; 703 704 ifp = sc->sc_ic.ic_ifp; 705 if (ifp != NULL) /* Failed to attach properly */ 706 otus_stop(ifp); 707 708 usb_rem_task_wait(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL); 709 callout_destroy(&sc->sc_scan_to); 710 callout_destroy(&sc->sc_calib_to); 711 712 if (ifp && ifp->if_flags != 0) { /* if_attach() has been called. */ 713 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 714 bpf_detach(ifp); 715 ieee80211_ifdetach(&sc->sc_ic); 716 if_detach(ifp); 717 } 718 otus_close_pipes(sc); 719 splx(s); 720 721 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 722 723 mutex_destroy(&sc->sc_write_mtx); 724 mutex_destroy(&sc->sc_tx_mtx); 725 mutex_destroy(&sc->sc_task_mtx); 726 mutex_destroy(&sc->sc_cmd_mtx); 727 cv_destroy(&sc->sc_task_cv); 728 cv_destroy(&sc->sc_cmd_cv); 729 730 return 0; 731 } 732 733 Static int 734 otus_activate(device_t self, devact_t act) 735 { 736 struct otus_softc *sc; 737 738 sc = device_private(self); 739 740 DPRINTFN(DBG_FN, sc, "%d\n", act); 741 742 switch (act) { 743 case DVACT_DEACTIVATE: 744 sc->sc_dying = 1; 745 if_deactivate(sc->sc_ic.ic_ifp); 746 return 0; 747 default: 748 return EOPNOTSUPP; 749 } 750 } 751 752 Static void 753 otus_attachhook(device_t arg) 754 { 755 struct otus_softc *sc; 756 struct ieee80211com *ic; 757 struct ifnet *ifp; 758 usb_device_request_t req; 759 uint32_t in, out; 760 int error; 761 762 sc = device_private(arg); 763 764 DPRINTFN(DBG_FN, sc, "\n"); 765 766 ic = &sc->sc_ic; 767 ifp = &sc->sc_if; 768 769 error = otus_load_firmware(sc, "otus-init", AR_FW_INIT_ADDR); 770 if (error != 0) { 771 aprint_error_dev(sc->sc_dev, "could not load init firmware\n"); 772 return; 773 } 774 usbd_delay_ms(sc->sc_udev, 1000); 775 776 error = otus_load_firmware(sc, "otus-main", AR_FW_MAIN_ADDR); 777 if (error != 0) { 778 aprint_error_dev(sc->sc_dev, "could not load main firmware\n"); 779 return; 780 } 781 782 /* Tell device that firmware transfer is complete. */ 783 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 784 req.bRequest = AR_FW_DOWNLOAD_COMPLETE; 785 USETW(req.wValue, 0); 786 USETW(req.wIndex, 0); 787 USETW(req.wLength, 0); 788 if (usbd_do_request(sc->sc_udev, &req, NULL) != 0) { 789 aprint_error_dev(sc->sc_dev, 790 "firmware initialization failed\n"); 791 return; 792 } 793 794 /* Send an ECHO command to check that everything is settled. */ 795 in = 0xbadc0ffe; 796 if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof(in), &out) != 0) { 797 aprint_error_dev(sc->sc_dev, "echo command failed\n"); 798 return; 799 } 800 if (in != out) { 801 aprint_error_dev(sc->sc_dev, 802 "echo reply mismatch: 0x%08x!=0x%08x\n", in, out); 803 return; 804 } 805 806 /* Read entire EEPROM. */ 807 if (otus_read_eeprom(sc) != 0) { 808 aprint_error_dev(sc->sc_dev, "could not read EEPROM\n"); 809 return; 810 } 811 812 sc->sc_txmask = sc->sc_eeprom.baseEepHeader.txMask; 813 sc->sc_rxmask = sc->sc_eeprom.baseEepHeader.rxMask; 814 sc->sc_capflags = sc->sc_eeprom.baseEepHeader.opCapFlags; 815 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_eeprom.baseEepHeader.macAddr); 816 sc->sc_led_newstate = otus_led_newstate_type3; /* XXX */ 817 818 aprint_normal_dev(sc->sc_dev, 819 "MAC/BBP AR9170, RF AR%X, MIMO %dT%dR, address %s\n", 820 (sc->sc_capflags & AR5416_OPFLAGS_11A) ? 821 0x9104 : ((sc->sc_txmask == 0x5) ? 0x9102 : 0x9101), 822 (sc->sc_txmask == 0x5) ? 2 : 1, (sc->sc_rxmask == 0x5) ? 2 : 1, 823 ether_sprintf(ic->ic_myaddr)); 824 825 /* 826 * Setup the 802.11 device. 827 */ 828 ic->ic_ifp = ifp; 829 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 830 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 831 ic->ic_state = IEEE80211_S_INIT; 832 833 /* Set device capabilities. */ 834 ic->ic_caps = 835 IEEE80211_C_MONITOR | /* monitor mode supported */ 836 IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 837 IEEE80211_C_SHSLOT | /* short slot time supported */ 838 IEEE80211_C_WPA; /* 802.11i */ 839 840 if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { 841 /* Set supported .11b and .11g rates. */ 842 ic->ic_sup_rates[IEEE80211_MODE_11B] = 843 ieee80211_std_rateset_11b; 844 ic->ic_sup_rates[IEEE80211_MODE_11G] = 845 ieee80211_std_rateset_11g; 846 } 847 if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { 848 /* Set supported .11a rates. */ 849 ic->ic_sup_rates[IEEE80211_MODE_11A] = 850 ieee80211_std_rateset_11a; 851 } 852 853 /* Build the list of supported channels. */ 854 otus_get_chanlist(sc); 855 856 ifp->if_softc = sc; 857 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 858 ifp->if_init = otus_init; 859 ifp->if_ioctl = otus_ioctl; 860 ifp->if_start = otus_start; 861 ifp->if_watchdog = otus_watchdog; 862 IFQ_SET_READY(&ifp->if_snd); 863 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 864 865 if_attach(ifp); 866 867 ieee80211_ifattach(ic); 868 869 ic->ic_node_alloc = otus_node_alloc; 870 ic->ic_newassoc = otus_newassoc; 871 ic->ic_updateslot = otus_updateslot; 872 #ifdef HAVE_EDCA 873 ic->ic_updateedca = otus_updateedca; 874 #endif /* HAVE_EDCA */ 875 #ifdef notyet 876 ic->ic_set_key = otus_set_key; 877 ic->ic_delete_key = otus_delete_key; 878 #endif /* notyet */ 879 880 /* Override state transition machine. */ 881 sc->sc_newstate = ic->ic_newstate; 882 ic->ic_newstate = otus_newstate; 883 884 /* XXX media locking needs revisiting */ 885 mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB); 886 ieee80211_media_init_with_lock(ic, 887 otus_media_change, ieee80211_media_status, &sc->sc_media_mtx); 888 889 bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 890 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, 891 &sc->sc_drvbpf); 892 893 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); 894 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 895 sc->sc_rxtap.wr_ihdr.it_present = htole32(OTUS_RX_RADIOTAP_PRESENT); 896 897 sc->sc_txtap_len = sizeof(sc->sc_txtapu); 898 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 899 sc->sc_txtap.wt_ihdr.it_present = htole32(OTUS_TX_RADIOTAP_PRESENT); 900 901 ieee80211_announce(ic); 902 } 903 904 Static void 905 otus_get_chanlist(struct otus_softc *sc) 906 { 907 struct ieee80211com *ic; 908 uint8_t chan; 909 int i; 910 911 #ifdef OTUS_DEBUG 912 /* XXX regulatory domain. */ 913 uint16_t domain = le16toh(sc->sc_eeprom.baseEepHeader.regDmn[0]); 914 915 DPRINTFN(DBG_FN | DBG_INIT, sc, "regdomain=0x%04x\n", domain); 916 #endif 917 918 ic = &sc->sc_ic; 919 if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { 920 for (i = 0; i < 14; i++) { 921 chan = ar_chans[i]; 922 ic->ic_channels[chan].ic_freq = 923 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); 924 ic->ic_channels[chan].ic_flags = 925 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 926 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 927 } 928 } 929 if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { 930 for (i = 14; i < __arraycount(ar_chans); i++) { 931 chan = ar_chans[i]; 932 ic->ic_channels[chan].ic_freq = 933 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ); 934 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A; 935 } 936 } 937 } 938 939 Static int 940 otus_load_firmware(struct otus_softc *sc, const char *name, uint32_t addr) 941 { 942 usb_device_request_t req; 943 firmware_handle_t fh; 944 uint8_t *ptr; 945 uint8_t *fw; 946 size_t size; 947 int mlen, error; 948 949 DPRINTFN(DBG_FN, sc, "\n"); 950 951 if ((error = firmware_open("if_otus", name, &fh)) != 0) 952 return error; 953 954 size = firmware_get_size(fh); 955 if ((fw = firmware_malloc(size)) == NULL) { 956 firmware_close(fh); 957 return ENOMEM; 958 } 959 if ((error = firmware_read(fh, 0, fw, size)) != 0) 960 firmware_free(fw, size); 961 firmware_close(fh); 962 if (error) 963 return error; 964 965 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 966 req.bRequest = AR_FW_DOWNLOAD; 967 USETW(req.wIndex, 0); 968 969 ptr = fw; 970 addr >>= 8; 971 while (size > 0) { 972 mlen = MIN(size, 4096); 973 974 USETW(req.wValue, addr); 975 USETW(req.wLength, mlen); 976 if (usbd_do_request(sc->sc_udev, &req, ptr) != 0) { 977 error = EIO; 978 break; 979 } 980 addr += mlen >> 8; 981 ptr += mlen; 982 size -= mlen; 983 } 984 free(fw, M_DEVBUF); 985 return error; 986 } 987 988 Static int 989 otus_open_pipes(struct otus_softc *sc) 990 { 991 usb_endpoint_descriptor_t *ed; 992 int i, error; 993 994 DPRINTFN(DBG_FN, sc, "\n"); 995 996 error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_RX_NO, 0, 997 &sc->sc_data_rx_pipe); 998 if (error != 0) { 999 aprint_error_dev(sc->sc_dev, "could not open Rx bulk pipe\n"); 1000 goto fail; 1001 } 1002 1003 ed = usbd_get_endpoint_descriptor(sc->sc_iface, AR_EPT_INTR_RX_NO); 1004 if (ed == NULL) { 1005 aprint_error_dev(sc->sc_dev, 1006 "could not retrieve Rx intr pipe descriptor\n"); 1007 goto fail; 1008 } 1009 sc->sc_ibuf_size = UGETW(ed->wMaxPacketSize); 1010 if (sc->sc_ibuf_size == 0) { 1011 aprint_error_dev(sc->sc_dev, 1012 "invalid Rx intr pipe descriptor\n"); 1013 goto fail; 1014 } 1015 sc->sc_ibuf = kmem_alloc(sc->sc_ibuf_size, KM_SLEEP); 1016 error = usbd_open_pipe_intr(sc->sc_iface, AR_EPT_INTR_RX_NO, 1017 USBD_SHORT_XFER_OK, &sc->sc_cmd_rx_pipe, sc, sc->sc_ibuf, 1018 sc->sc_ibuf_size, otus_intr, USBD_DEFAULT_INTERVAL); 1019 if (error != 0) { 1020 aprint_error_dev(sc->sc_dev, "could not open Rx intr pipe\n"); 1021 goto fail; 1022 } 1023 1024 error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_TX_NO, 0, 1025 &sc->sc_data_tx_pipe); 1026 if (error != 0) { 1027 aprint_error_dev(sc->sc_dev, "could not open Tx bulk pipe\n"); 1028 goto fail; 1029 } 1030 1031 error = usbd_open_pipe(sc->sc_iface, AR_EPT_INTR_TX_NO, 0, 1032 &sc->sc_cmd_tx_pipe); 1033 if (error != 0) { 1034 aprint_error_dev(sc->sc_dev, "could not open Tx intr pipe\n"); 1035 goto fail; 1036 } 1037 1038 if (otus_alloc_tx_cmd(sc) != 0) { 1039 aprint_error_dev(sc->sc_dev, 1040 "could not allocate command xfer\n"); 1041 goto fail; 1042 } 1043 1044 if (otus_alloc_tx_data_list(sc)) { 1045 aprint_error_dev(sc->sc_dev, "could not allocate Tx xfers\n"); 1046 goto fail; 1047 } 1048 1049 if (otus_alloc_rx_data_list(sc)) { 1050 aprint_error_dev(sc->sc_dev, "could not allocate Rx xfers\n"); 1051 goto fail; 1052 } 1053 1054 for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) { 1055 struct otus_rx_data *data = &sc->sc_rx_data[i]; 1056 1057 usbd_setup_xfer(data->xfer, data, data->buf, OTUS_RXBUFSZ, 1058 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof); 1059 error = usbd_transfer(data->xfer); 1060 if (error != USBD_IN_PROGRESS && error != 0) { 1061 aprint_error_dev(sc->sc_dev, 1062 "could not queue Rx xfer\n"); 1063 goto fail; 1064 } 1065 } 1066 return 0; 1067 1068 fail: otus_close_pipes(sc); 1069 return error; 1070 } 1071 1072 Static void 1073 otus_close_pipes(struct otus_softc *sc) 1074 { 1075 1076 DPRINTFN(DBG_FN, sc, "\n"); 1077 1078 otus_free_tx_cmd(sc); 1079 otus_free_tx_data_list(sc); 1080 otus_free_rx_data_list(sc); 1081 1082 if (sc->sc_data_rx_pipe != NULL) 1083 usbd_close_pipe(sc->sc_data_rx_pipe); 1084 if (sc->sc_cmd_rx_pipe != NULL) { 1085 usbd_abort_pipe(sc->sc_cmd_rx_pipe); 1086 usbd_close_pipe(sc->sc_cmd_rx_pipe); 1087 } 1088 if (sc->sc_ibuf != NULL) 1089 kmem_free(sc->sc_ibuf, sc->sc_ibuf_size); 1090 if (sc->sc_data_tx_pipe != NULL) 1091 usbd_close_pipe(sc->sc_data_tx_pipe); 1092 if (sc->sc_cmd_tx_pipe != NULL) 1093 usbd_close_pipe(sc->sc_cmd_tx_pipe); 1094 } 1095 1096 Static int 1097 otus_alloc_tx_cmd(struct otus_softc *sc) 1098 { 1099 struct otus_tx_cmd *cmd; 1100 1101 DPRINTFN(DBG_FN, sc, "\n"); 1102 1103 cmd = &sc->sc_tx_cmd; 1104 1105 int error = usbd_create_xfer(sc->sc_cmd_tx_pipe, OTUS_MAX_TXCMDSZ, 1106 USBD_FORCE_SHORT_XFER, 0, &cmd->xfer); 1107 if (error) 1108 return error; 1109 1110 cmd->buf = usbd_get_buffer(cmd->xfer); 1111 1112 return 0; 1113 } 1114 1115 Static void 1116 otus_free_tx_cmd(struct otus_softc *sc) 1117 { 1118 1119 DPRINTFN(DBG_FN, sc, "\n"); 1120 1121 if (sc->sc_cmd_tx_pipe == NULL) 1122 return; 1123 1124 /* Make sure no transfers are pending. */ 1125 usbd_abort_pipe(sc->sc_cmd_tx_pipe); 1126 1127 mutex_enter(&sc->sc_cmd_mtx); 1128 if (sc->sc_tx_cmd.xfer != NULL) 1129 usbd_destroy_xfer(sc->sc_tx_cmd.xfer); 1130 sc->sc_tx_cmd.xfer = NULL; 1131 sc->sc_tx_cmd.buf = NULL; 1132 mutex_exit(&sc->sc_cmd_mtx); 1133 } 1134 1135 Static int 1136 otus_alloc_tx_data_list(struct otus_softc *sc) 1137 { 1138 struct otus_tx_data *data; 1139 int i, error; 1140 1141 DPRINTFN(DBG_FN, sc, "\n"); 1142 1143 mutex_enter(&sc->sc_tx_mtx); 1144 error = 0; 1145 TAILQ_INIT(&sc->sc_tx_free_list); 1146 for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) { 1147 data = &sc->sc_tx_data[i]; 1148 1149 data->sc = sc; /* Backpointer for callbacks. */ 1150 1151 error = usbd_create_xfer(sc->sc_data_tx_pipe, OTUS_TXBUFSZ, 1152 USBD_FORCE_SHORT_XFER, 0, &data->xfer); 1153 if (error) { 1154 aprint_error_dev(sc->sc_dev, 1155 "could not allocate xfer\n"); 1156 break; 1157 } 1158 data->buf = usbd_get_buffer(data->xfer); 1159 /* Append this Tx buffer to our free list. */ 1160 TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next); 1161 } 1162 if (error != 0) 1163 otus_free_tx_data_list(sc); 1164 mutex_exit(&sc->sc_tx_mtx); 1165 return error; 1166 } 1167 1168 Static void 1169 otus_free_tx_data_list(struct otus_softc *sc) 1170 { 1171 int i; 1172 1173 DPRINTFN(DBG_FN, sc, "\n"); 1174 1175 if (sc->sc_data_tx_pipe == NULL) 1176 return; 1177 1178 /* Make sure no transfers are pending. */ 1179 usbd_abort_pipe(sc->sc_data_tx_pipe); 1180 1181 for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) { 1182 if (sc->sc_tx_data[i].xfer != NULL) 1183 usbd_destroy_xfer(sc->sc_tx_data[i].xfer); 1184 } 1185 } 1186 1187 Static int 1188 otus_alloc_rx_data_list(struct otus_softc *sc) 1189 { 1190 struct otus_rx_data *data; 1191 int i, error; 1192 1193 DPRINTFN(DBG_FN, sc, "\n"); 1194 1195 for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) { 1196 data = &sc->sc_rx_data[i]; 1197 1198 data->sc = sc; /* Backpointer for callbacks. */ 1199 1200 error = usbd_create_xfer(sc->sc_data_rx_pipe, OTUS_RXBUFSZ, 1201 0, 0, &data->xfer); 1202 1203 if (error) { 1204 aprint_error_dev(sc->sc_dev, 1205 "could not allocate xfer\n"); 1206 goto fail; 1207 } 1208 data->buf = usbd_get_buffer(data->xfer); 1209 } 1210 return 0; 1211 1212 fail: otus_free_rx_data_list(sc); 1213 return error; 1214 } 1215 1216 Static void 1217 otus_free_rx_data_list(struct otus_softc *sc) 1218 { 1219 int i; 1220 1221 DPRINTFN(DBG_FN, sc, "\n"); 1222 1223 if (sc->sc_data_rx_pipe == NULL) 1224 return; 1225 1226 /* Make sure no transfers are pending. */ 1227 usbd_abort_pipe(sc->sc_data_rx_pipe); 1228 1229 for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) 1230 if (sc->sc_rx_data[i].xfer != NULL) 1231 usbd_destroy_xfer(sc->sc_rx_data[i].xfer); 1232 } 1233 1234 Static void 1235 otus_next_scan(void *arg) 1236 { 1237 struct otus_softc *sc; 1238 1239 sc = arg; 1240 1241 DPRINTFN(DBG_FN, sc, "\n"); 1242 1243 if (sc->sc_dying) 1244 return; 1245 1246 if (sc->sc_ic.ic_state == IEEE80211_S_SCAN) 1247 ieee80211_next_scan(&sc->sc_ic); 1248 } 1249 1250 Static void 1251 otus_task(void *arg) 1252 { 1253 struct otus_softc *sc; 1254 struct otus_host_cmd_ring *ring; 1255 struct otus_host_cmd *cmd; 1256 1257 sc = arg; 1258 1259 DPRINTFN(DBG_FN, sc, "\n"); 1260 1261 /* Process host commands. */ 1262 mutex_spin_enter(&sc->sc_task_mtx); 1263 ring = &sc->sc_cmdq; 1264 while (ring->next != ring->cur) { 1265 cmd = &ring->cmd[ring->next]; 1266 mutex_spin_exit(&sc->sc_task_mtx); 1267 1268 /* Callback. */ 1269 DPRINTFN(DBG_CMD, sc, "cb=%p queued=%d\n", cmd->cb, 1270 ring->queued); 1271 cmd->cb(sc, cmd->data); 1272 1273 mutex_spin_enter(&sc->sc_task_mtx); 1274 ring->queued--; 1275 ring->next = (ring->next + 1) % OTUS_HOST_CMD_RING_COUNT; 1276 } 1277 cv_signal(&sc->sc_task_cv); 1278 mutex_spin_exit(&sc->sc_task_mtx); 1279 } 1280 1281 Static void 1282 otus_do_async(struct otus_softc *sc, void (*cb)(struct otus_softc *, void *), 1283 void *arg, int len) 1284 { 1285 struct otus_host_cmd_ring *ring; 1286 struct otus_host_cmd *cmd; 1287 bool sched = false; 1288 1289 DPRINTFN(DBG_FN, sc, "cb=%p\n", cb); 1290 1291 mutex_spin_enter(&sc->sc_task_mtx); 1292 ring = &sc->sc_cmdq; 1293 cmd = &ring->cmd[ring->cur]; 1294 cmd->cb = cb; 1295 KASSERT(len <= sizeof(cmd->data)); 1296 memcpy(cmd->data, arg, len); 1297 ring->cur = (ring->cur + 1) % OTUS_HOST_CMD_RING_COUNT; 1298 1299 /* If there is no pending command already, schedule a task. */ 1300 if (++ring->queued == 1) { 1301 sched = true; 1302 } 1303 cv_signal(&sc->sc_task_cv); 1304 mutex_spin_exit(&sc->sc_task_mtx); 1305 if (sched) 1306 usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); 1307 } 1308 1309 Static int 1310 otus_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1311 { 1312 struct otus_softc *sc; 1313 struct otus_cmd_newstate cmd; 1314 1315 sc = ic->ic_ifp->if_softc; 1316 1317 DPRINTFN(DBG_FN | DBG_STM, sc, "nstate=%s(%d), arg=%d\n", 1318 ieee80211_state_name[nstate], nstate, arg); 1319 1320 /* Do it in a process context. */ 1321 cmd.state = nstate; 1322 cmd.arg = arg; 1323 otus_do_async(sc, otus_newstate_cb, &cmd, sizeof(cmd)); 1324 return 0; 1325 } 1326 1327 Static void 1328 otus_newstate_cb(struct otus_softc *sc, void *arg) 1329 { 1330 struct otus_cmd_newstate *cmd; 1331 struct ieee80211com *ic; 1332 struct ieee80211_node *ni; 1333 enum ieee80211_state nstate; 1334 int s; 1335 1336 cmd = arg; 1337 ic = &sc->sc_ic; 1338 ni = ic->ic_bss; 1339 nstate = cmd->state; 1340 1341 #ifdef OTUS_DEBUG 1342 enum ieee80211_state ostate = ostate = ic->ic_state; 1343 DPRINTFN(DBG_FN | DBG_STM, sc, "%s(%d)->%s(%d)\n", 1344 ieee80211_state_name[ostate], ostate, 1345 ieee80211_state_name[nstate], nstate); 1346 #endif 1347 1348 s = splnet(); 1349 1350 callout_halt(&sc->sc_scan_to, NULL); 1351 callout_halt(&sc->sc_calib_to, NULL); 1352 1353 mutex_enter(&sc->sc_write_mtx); 1354 1355 switch (nstate) { 1356 case IEEE80211_S_INIT: 1357 break; 1358 1359 case IEEE80211_S_SCAN: 1360 otus_set_chan(sc, ic->ic_curchan, 0); 1361 if (!sc->sc_dying) 1362 callout_schedule(&sc->sc_scan_to, hz / 5); 1363 break; 1364 1365 case IEEE80211_S_AUTH: 1366 case IEEE80211_S_ASSOC: 1367 otus_set_chan(sc, ic->ic_curchan, 0); 1368 break; 1369 1370 case IEEE80211_S_RUN: 1371 otus_set_chan(sc, ic->ic_curchan, 1); 1372 1373 switch (ic->ic_opmode) { 1374 case IEEE80211_M_STA: 1375 otus_updateslot_cb_locked(sc); 1376 otus_set_bssid(sc, ni->ni_bssid); 1377 1378 /* Fake a join to init the Tx rate. */ 1379 otus_newassoc(ni, 1); 1380 1381 /* Start calibration timer. */ 1382 if (!sc->sc_dying) 1383 callout_schedule(&sc->sc_calib_to, hz); 1384 break; 1385 1386 case IEEE80211_M_IBSS: 1387 case IEEE80211_M_AHDEMO: 1388 case IEEE80211_M_HOSTAP: 1389 case IEEE80211_M_MONITOR: 1390 break; 1391 } 1392 break; 1393 } 1394 (void)sc->sc_newstate(ic, nstate, cmd->arg); 1395 sc->sc_led_newstate(sc); 1396 mutex_exit(&sc->sc_write_mtx); 1397 1398 splx(s); 1399 } 1400 1401 Static int 1402 otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen, 1403 void *odata) 1404 { 1405 struct otus_tx_cmd *cmd; 1406 struct ar_cmd_hdr *hdr; 1407 int xferlen, error; 1408 1409 DPRINTFN(DBG_FN, sc, "\n"); 1410 1411 cmd = &sc->sc_tx_cmd; 1412 1413 mutex_enter(&sc->sc_cmd_mtx); 1414 1415 /* Always bulk-out a multiple of 4 bytes. */ 1416 xferlen = roundup2(sizeof(*hdr) + ilen, 4); 1417 1418 hdr = (void *)cmd->buf; 1419 if (hdr == NULL) { /* we may have been freed while detaching */ 1420 mutex_exit(&sc->sc_cmd_mtx); 1421 DPRINTFN(DBG_CMD, sc, "tx_cmd freed with commands pending\n"); 1422 return 0; 1423 } 1424 hdr->code = code; 1425 hdr->len = ilen; 1426 hdr->token = ++cmd->token; /* Don't care about endianness. */ 1427 KASSERT(sizeof(hdr) + ilen <= OTUS_MAX_TXCMDSZ); 1428 memcpy(cmd->buf + sizeof(hdr[0]), idata, ilen); 1429 1430 DPRINTFN(DBG_CMD, sc, "sending command code=0x%02x len=%d token=%d\n", 1431 code, ilen, hdr->token); 1432 1433 cmd->odata = odata; 1434 cmd->done = 0; 1435 usbd_setup_xfer(cmd->xfer, cmd, cmd->buf, xferlen, 1436 USBD_FORCE_SHORT_XFER, OTUS_CMD_TIMEOUT, NULL); 1437 error = usbd_sync_transfer(cmd->xfer); 1438 if (error != 0) { 1439 mutex_exit(&sc->sc_cmd_mtx); 1440 #if defined(DIAGNOSTIC) || defined(OTUS_DEBUG) /* XXX: kill some noise */ 1441 aprint_error_dev(sc->sc_dev, 1442 "could not send command %#x (error=%s)\n", 1443 code, usbd_errstr(error)); 1444 #endif 1445 return EIO; 1446 } 1447 if (!cmd->done) 1448 error = cv_timedwait_sig(&sc->sc_cmd_cv, &sc->sc_cmd_mtx, hz); 1449 cmd->odata = NULL; /* In case answer is received too late. */ 1450 mutex_exit(&sc->sc_cmd_mtx); 1451 if (error != 0) { 1452 aprint_error_dev(sc->sc_dev, 1453 "timeout waiting for command 0x%02x reply\n", code); 1454 } 1455 return error; 1456 } 1457 1458 Static void 1459 otus_write(struct otus_softc *sc, uint32_t reg, uint32_t val) 1460 { 1461 1462 DPRINTFN(DBG_FN | DBG_REG, sc, "reg=%#x, val=%#x\n", reg, val); 1463 1464 KASSERT(mutex_owned(&sc->sc_write_mtx)); 1465 KASSERT(sc->sc_write_idx < __arraycount(sc->sc_write_buf)); 1466 1467 sc->sc_write_buf[sc->sc_write_idx].reg = htole32(reg); 1468 sc->sc_write_buf[sc->sc_write_idx].val = htole32(val); 1469 1470 if (++sc->sc_write_idx >= __arraycount(sc->sc_write_buf)) 1471 (void)otus_write_barrier(sc); 1472 } 1473 1474 Static int 1475 otus_write_barrier(struct otus_softc *sc) 1476 { 1477 int error; 1478 1479 DPRINTFN(DBG_FN, sc, "\n"); 1480 1481 KASSERT(mutex_owned(&sc->sc_write_mtx)); 1482 KASSERT(sc->sc_write_idx <= __arraycount(sc->sc_write_buf)); 1483 1484 if (sc->sc_write_idx == 0) 1485 return 0; /* Nothing to flush. */ 1486 1487 error = otus_cmd(sc, AR_CMD_WREG, sc->sc_write_buf, 1488 sizeof(sc->sc_write_buf[0]) * sc->sc_write_idx, NULL); 1489 1490 sc->sc_write_idx = 0; 1491 if (error) 1492 DPRINTFN(DBG_REG, sc, "error=%d\n", error); 1493 return error; 1494 } 1495 1496 Static struct ieee80211_node * 1497 otus_node_alloc(struct ieee80211_node_table *ntp) 1498 { 1499 struct otus_node *on; 1500 1501 DPRINTFN(DBG_FN, DBG_NO_SC, "\n"); 1502 1503 on = malloc(sizeof(*on), M_DEVBUF, M_NOWAIT | M_ZERO); 1504 return on ? &on->ni : NULL; 1505 } 1506 1507 Static int 1508 otus_media_change(struct ifnet *ifp) 1509 { 1510 struct otus_softc *sc; 1511 struct ieee80211com *ic; 1512 uint8_t rate, ridx; 1513 int error; 1514 1515 sc = ifp->if_softc; 1516 1517 DPRINTFN(DBG_FN, sc, "\n"); 1518 1519 error = ieee80211_media_change(ifp); 1520 if (error != ENETRESET) 1521 return error; 1522 1523 ic = &sc->sc_ic; 1524 if (ic->ic_fixed_rate != -1) { 1525 rate = ic->ic_sup_rates[ic->ic_curmode]. 1526 rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 1527 for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++) 1528 if (otus_rates[ridx].rate == rate) 1529 break; 1530 sc->sc_fixed_ridx = ridx; 1531 } 1532 1533 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) 1534 error = otus_init(ifp); 1535 1536 return error; 1537 } 1538 1539 Static int 1540 otus_read_eeprom(struct otus_softc *sc) 1541 { 1542 uint32_t regs[8], reg; 1543 uint8_t *eep; 1544 int i, j, error; 1545 1546 DPRINTFN(DBG_FN, sc, "\n"); 1547 1548 KASSERT(sizeof(sc->sc_eeprom) % 32 == 0); 1549 1550 /* Read EEPROM by blocks of 32 bytes. */ 1551 eep = (uint8_t *)&sc->sc_eeprom; 1552 reg = AR_EEPROM_OFFSET; 1553 for (i = 0; i < sizeof(sc->sc_eeprom) / 32; i++) { 1554 for (j = 0; j < 8; j++, reg += 4) 1555 regs[j] = htole32(reg); 1556 error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof(regs), eep); 1557 if (error != 0) 1558 break; 1559 eep += 32; 1560 } 1561 return error; 1562 } 1563 1564 Static void 1565 otus_newassoc(struct ieee80211_node *ni, int isnew) 1566 { 1567 struct ieee80211_rateset *rs; 1568 struct otus_softc *sc; 1569 struct otus_node *on; 1570 uint8_t rate; 1571 int ridx, i; 1572 1573 sc = ni->ni_ic->ic_ifp->if_softc; 1574 1575 DPRINTFN(DBG_FN, sc, "isnew=%d addr=%s\n", 1576 isnew, ether_sprintf(ni->ni_macaddr)); 1577 1578 on = (void *)ni; 1579 ieee80211_amrr_node_init(&sc->sc_amrr, &on->amn); 1580 /* Start at lowest available bit-rate, AMRR will raise. */ 1581 ni->ni_txrate = 0; 1582 rs = &ni->ni_rates; 1583 for (i = 0; i < rs->rs_nrates; i++) { 1584 rate = rs->rs_rates[i] & IEEE80211_RATE_VAL; 1585 /* Convert 802.11 rate to hardware rate index. */ 1586 for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++) 1587 if (otus_rates[ridx].rate == rate) 1588 break; 1589 on->ridx[i] = ridx; 1590 DPRINTFN(DBG_INIT, sc, "rate=0x%02x ridx=%d\n", 1591 rs->rs_rates[i], on->ridx[i]); 1592 } 1593 } 1594 1595 /* ARGSUSED */ 1596 Static void 1597 otus_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) 1598 { 1599 #if 0 1600 struct otus_softc *sc; 1601 int len; 1602 1603 sc = priv; 1604 1605 DPRINTFN(DBG_FN, sc, "\n"); 1606 1607 /* 1608 * The Rx intr pipe is unused with current firmware. Notifications 1609 * and replies to commands are sent through the Rx bulk pipe instead 1610 * (with a magic PLCP header.) 1611 */ 1612 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1613 DPRINTFN(DBG_INTR, sc, "status=%d\n", status); 1614 if (status == USBD_STALLED) 1615 usbd_clear_endpoint_stall_async(sc->sc_cmd_rx_pipe); 1616 return; 1617 } 1618 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1619 1620 otus_cmd_rxeof(sc, sc->sc_ibuf, len); 1621 #endif 1622 } 1623 1624 Static void 1625 otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len) 1626 { 1627 struct ieee80211com *ic; 1628 struct otus_tx_cmd *cmd; 1629 struct ar_cmd_hdr *hdr; 1630 int s; 1631 1632 DPRINTFN(DBG_FN, sc, "\n"); 1633 1634 ic = &sc->sc_ic; 1635 1636 if (__predict_false(len < sizeof(*hdr))) { 1637 DPRINTFN(DBG_RX, sc, "cmd too small %d\n", len); 1638 return; 1639 } 1640 hdr = (void *)buf; 1641 if (__predict_false(sizeof(*hdr) + hdr->len > len || 1642 sizeof(*hdr) + hdr->len > 64)) { 1643 DPRINTFN(DBG_RX, sc, "cmd too large %d\n", hdr->len); 1644 return; 1645 } 1646 1647 if ((hdr->code & 0xc0) != 0xc0) { 1648 DPRINTFN(DBG_RX, sc, "received reply code=0x%02x len=%d token=%d\n", 1649 hdr->code, hdr->len, hdr->token); 1650 mutex_enter(&sc->sc_cmd_mtx); 1651 cmd = &sc->sc_tx_cmd; 1652 if (__predict_false(hdr->token != cmd->token)) { 1653 mutex_exit(&sc->sc_cmd_mtx); 1654 return; 1655 } 1656 /* Copy answer into caller's supplied buffer. */ 1657 if (cmd->odata != NULL) 1658 memcpy(cmd->odata, &hdr[1], hdr->len); 1659 cmd->done = 1; 1660 cv_signal(&sc->sc_cmd_cv); 1661 mutex_exit(&sc->sc_cmd_mtx); 1662 return; 1663 } 1664 1665 /* Received unsolicited notification. */ 1666 DPRINTFN(DBG_RX, sc, "received notification code=0x%02x len=%d\n", 1667 hdr->code, hdr->len); 1668 switch (hdr->code & 0x3f) { 1669 case AR_EVT_BEACON: 1670 break; 1671 case AR_EVT_TX_COMP: 1672 { 1673 struct ar_evt_tx_comp *tx; 1674 struct ieee80211_node *ni; 1675 struct otus_node *on; 1676 1677 tx = (void *)&hdr[1]; 1678 1679 DPRINTFN(DBG_RX, sc, "tx completed %s status=%d phy=%#x\n", 1680 ether_sprintf(tx->macaddr), le16toh(tx->status), 1681 le32toh(tx->phy)); 1682 s = splnet(); 1683 #ifdef notyet 1684 #ifndef IEEE80211_STA_ONLY 1685 if (ic->ic_opmode != IEEE80211_M_STA) { 1686 ni = ieee80211_find_node(ic, tx->macaddr); 1687 if (__predict_false(ni == NULL)) { 1688 splx(s); 1689 break; 1690 } 1691 } else 1692 #endif 1693 #endif 1694 ni = ic->ic_bss; 1695 /* Update rate control statistics. */ 1696 on = (void *)ni; 1697 /* NB: we do not set the TX_MAC_RATE_PROBING flag. */ 1698 if (__predict_true(tx->status != 0)) 1699 on->amn.amn_retrycnt++; 1700 splx(s); 1701 break; 1702 } 1703 case AR_EVT_TBTT: 1704 break; 1705 } 1706 } 1707 1708 Static void 1709 otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len) 1710 { 1711 struct ieee80211com *ic; 1712 struct ifnet *ifp; 1713 struct ieee80211_node *ni; 1714 struct ar_rx_tail *tail; 1715 struct ieee80211_frame *wh; 1716 struct mbuf *m; 1717 uint8_t *plcp; 1718 int s, mlen, align; 1719 1720 DPRINTFN(DBG_FN, sc, "\n"); 1721 1722 ic = &sc->sc_ic; 1723 ifp = ic->ic_ifp; 1724 1725 if (__predict_false(len < AR_PLCP_HDR_LEN)) { 1726 DPRINTFN(DBG_RX, sc, "sub-xfer too short %d\n", len); 1727 return; 1728 } 1729 plcp = buf; 1730 1731 /* All bits in the PLCP header are set to 1 for non-MPDU. */ 1732 if (memcmp(plcp, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) { 1733 otus_cmd_rxeof(sc, plcp + AR_PLCP_HDR_LEN, 1734 len - AR_PLCP_HDR_LEN); 1735 return; 1736 } 1737 1738 /* Received MPDU. */ 1739 if (__predict_false(len < AR_PLCP_HDR_LEN + sizeof(*tail))) { 1740 DPRINTFN(DBG_RX, sc, "MPDU too short %d\n", len); 1741 if_statinc(ifp, if_ierrors); 1742 return; 1743 } 1744 tail = (void *)(plcp + len - sizeof(*tail)); 1745 wh = (void *)(plcp + AR_PLCP_HDR_LEN); 1746 1747 /* Discard error frames. */ 1748 if (__predict_false((tail->error & sc->sc_rx_error_msk) != 0)) { 1749 DPRINTFN(DBG_RX, sc, "error frame 0x%02x\n", tail->error); 1750 if (tail->error & AR_RX_ERROR_FCS) { 1751 DPRINTFN(DBG_RX, sc, "bad FCS\n"); 1752 } else if (tail->error & AR_RX_ERROR_MMIC) { 1753 /* Report Michael MIC failures to net80211. */ 1754 ieee80211_notify_michael_failure(ic, wh, 0 /* XXX: keyix */); 1755 } 1756 if_statinc(ifp, if_ierrors); 1757 return; 1758 } 1759 /* Compute MPDU's length. */ 1760 mlen = len - AR_PLCP_HDR_LEN - sizeof(*tail); 1761 mlen -= IEEE80211_CRC_LEN; /* strip 802.11 FCS */ 1762 /* Make sure there's room for an 802.11 header. */ 1763 /* 1764 * XXX: This will drop most control packets. Do we really 1765 * want this in IEEE80211_M_MONITOR mode? 1766 */ 1767 if (__predict_false(mlen < sizeof(*wh))) { 1768 if_statinc(ifp, if_ierrors); 1769 return; 1770 } 1771 1772 /* Provide a 32-bit aligned protocol header to the stack. */ 1773 align = (ieee80211_has_qos(wh) ^ ieee80211_has_addr4(wh)) ? 2 : 0; 1774 1775 MGETHDR(m, M_DONTWAIT, MT_DATA); 1776 if (__predict_false(m == NULL)) { 1777 if_statinc(ifp, if_ierrors); 1778 return; 1779 } 1780 if (align + mlen > MHLEN) { 1781 MCLGET(m, M_DONTWAIT); 1782 if (__predict_false(!(m->m_flags & M_EXT))) { 1783 if_statinc(ifp, if_ierrors); 1784 m_freem(m); 1785 return; 1786 } 1787 } 1788 /* Finalize mbuf. */ 1789 m_set_rcvif(m, ifp); 1790 m->m_data += align; 1791 memcpy(mtod(m, void *), wh, mlen); 1792 m->m_pkthdr.len = m->m_len = mlen; 1793 1794 s = splnet(); 1795 if (__predict_false(sc->sc_drvbpf != NULL)) { 1796 struct otus_rx_radiotap_header *tap; 1797 1798 tap = &sc->sc_rxtap; 1799 tap->wr_flags = 0; 1800 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); 1801 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); 1802 tap->wr_antsignal = tail->rssi; 1803 tap->wr_rate = 2; /* In case it can't be found below. */ 1804 switch (tail->status & AR_RX_STATUS_MT_MASK) { 1805 case AR_RX_STATUS_MT_CCK: 1806 switch (plcp[0]) { 1807 case 10: tap->wr_rate = 2; break; 1808 case 20: tap->wr_rate = 4; break; 1809 case 55: tap->wr_rate = 11; break; 1810 case 110: tap->wr_rate = 22; break; 1811 } 1812 if (tail->status & AR_RX_STATUS_SHPREAMBLE) 1813 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 1814 break; 1815 case AR_RX_STATUS_MT_OFDM: 1816 switch (plcp[0] & 0xf) { 1817 case 0xb: tap->wr_rate = 12; break; 1818 case 0xf: tap->wr_rate = 18; break; 1819 case 0xa: tap->wr_rate = 24; break; 1820 case 0xe: tap->wr_rate = 36; break; 1821 case 0x9: tap->wr_rate = 48; break; 1822 case 0xd: tap->wr_rate = 72; break; 1823 case 0x8: tap->wr_rate = 96; break; 1824 case 0xc: tap->wr_rate = 108; break; 1825 } 1826 break; 1827 } 1828 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_D_IN); 1829 } 1830 1831 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); 1832 1833 /* push the frame up to the 802.11 stack */ 1834 ieee80211_input(ic, m, ni, tail->rssi, 0); 1835 1836 /* Node is no longer needed. */ 1837 ieee80211_free_node(ni); 1838 splx(s); 1839 } 1840 1841 Static void 1842 otus_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1843 { 1844 struct otus_rx_data *data; 1845 struct otus_softc *sc; 1846 uint8_t *buf; 1847 struct ar_rx_head *head; 1848 uint16_t hlen; 1849 int len; 1850 1851 data = priv; 1852 sc = data->sc; 1853 1854 DPRINTFN(DBG_FN, sc, "\n"); 1855 1856 buf = data->buf; 1857 1858 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1859 DPRINTFN(DBG_RX, sc, "RX status=%d\n", status); 1860 if (status == USBD_STALLED) 1861 usbd_clear_endpoint_stall_async(sc->sc_data_rx_pipe); 1862 else if (status != USBD_CANCELLED) { 1863 DPRINTFN(DBG_RX, sc, 1864 "otus_rxeof: goto resubmit: status=%d\n", status); 1865 goto resubmit; 1866 } 1867 return; 1868 } 1869 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1870 1871 while (len >= sizeof(*head)) { 1872 head = (void *)buf; 1873 if (__predict_false(head->tag != htole16(AR_RX_HEAD_TAG))) { 1874 DPRINTFN(DBG_RX, sc, "tag not valid %#x\n", 1875 le16toh(head->tag)); 1876 break; 1877 } 1878 hlen = le16toh(head->len); 1879 if (__predict_false(sizeof(*head) + hlen > len)) { 1880 DPRINTFN(DBG_RX, sc, "xfer too short %d/%d\n", 1881 len, hlen); 1882 break; 1883 } 1884 /* Process sub-xfer. */ 1885 otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen); 1886 1887 /* Next sub-xfer is aligned on a 32-bit boundary. */ 1888 hlen = roundup2(sizeof(*head) + hlen, 4); 1889 buf += hlen; 1890 len -= hlen; 1891 } 1892 1893 resubmit: 1894 usbd_setup_xfer(xfer, data, data->buf, OTUS_RXBUFSZ, 1895 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof); 1896 (void)usbd_transfer(data->xfer); 1897 } 1898 1899 Static void 1900 otus_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1901 { 1902 struct otus_tx_data *data; 1903 struct otus_softc *sc; 1904 struct ieee80211com *ic; 1905 struct ifnet *ifp; 1906 int s; 1907 1908 data = priv; 1909 sc = data->sc; 1910 1911 DPRINTFN(DBG_FN, sc, "\n"); 1912 1913 /* Put this Tx buffer back to the free list. */ 1914 mutex_enter(&sc->sc_tx_mtx); 1915 TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next); 1916 mutex_exit(&sc->sc_tx_mtx); 1917 1918 ic = &sc->sc_ic; 1919 ifp = ic->ic_ifp; 1920 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1921 DPRINTFN(DBG_TX, sc, "TX status=%d\n", status); 1922 if (status == USBD_STALLED) 1923 usbd_clear_endpoint_stall_async(sc->sc_data_tx_pipe); 1924 if_statinc(ifp, if_oerrors); 1925 return; 1926 } 1927 if_statinc(ifp, if_opackets); 1928 1929 s = splnet(); 1930 sc->sc_tx_timer = 0; 1931 ifp->if_flags &= ~IFF_OACTIVE; /* XXX: do after freeing Tx buffer? */ 1932 otus_start(ifp); 1933 splx(s); 1934 } 1935 1936 Static int 1937 otus_tx(struct otus_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 1938 struct otus_tx_data *data) 1939 { 1940 struct ieee80211com *ic; 1941 struct otus_node *on; 1942 struct ieee80211_frame *wh; 1943 struct ieee80211_key *k; 1944 struct ar_tx_head *head; 1945 uint32_t phyctl; 1946 uint16_t macctl, qos; 1947 uint8_t qid; 1948 int error, ridx, hasqos, xferlen; 1949 1950 DPRINTFN(DBG_FN, sc, "\n"); 1951 1952 ic = &sc->sc_ic; 1953 on = (void *)ni; 1954 1955 wh = mtod(m, struct ieee80211_frame *); 1956 if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) { 1957 /* XXX: derived from upgt_tx_task() and ural_tx_data() */ 1958 k = ieee80211_crypto_encap(ic, ni, m); 1959 if (k == NULL) 1960 return ENOBUFS; 1961 1962 /* Packet header may have moved, reset our local pointer. */ 1963 wh = mtod(m, struct ieee80211_frame *); 1964 } 1965 1966 #ifdef HAVE_EDCA 1967 if ((hasqos = ieee80211_has_qos(wh))) { 1968 qos = ieee80211_get_qos(wh); 1969 qid = ieee80211_up_to_ac(ic, qos & IEEE80211_QOS_TID); 1970 } else { 1971 qos = 0; 1972 qid = WME_AC_BE; 1973 } 1974 #else 1975 hasqos = 0; 1976 qos = 0; 1977 qid = WME_AC_BE; 1978 #endif 1979 1980 /* Pickup a rate index. */ 1981 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 1982 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) 1983 ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ? 1984 OTUS_RIDX_OFDM6 : OTUS_RIDX_CCK1; 1985 else if (ic->ic_fixed_rate != -1) 1986 ridx = sc->sc_fixed_ridx; 1987 else 1988 ridx = on->ridx[ni->ni_txrate]; 1989 1990 phyctl = 0; 1991 macctl = AR_TX_MAC_BACKOFF | AR_TX_MAC_HW_DUR | AR_TX_MAC_QID(qid); 1992 1993 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 1994 (hasqos && ((qos & IEEE80211_QOS_ACKPOLICY_MASK) == 1995 IEEE80211_QOS_ACKPOLICY_NOACK))) 1996 macctl |= AR_TX_MAC_NOACK; 1997 1998 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1999 if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= ic->ic_rtsthreshold) 2000 macctl |= AR_TX_MAC_RTS; 2001 else if ((ic->ic_flags & IEEE80211_F_USEPROT) && 2002 ridx >= OTUS_RIDX_OFDM6) { 2003 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 2004 macctl |= AR_TX_MAC_CTS; 2005 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 2006 macctl |= AR_TX_MAC_RTS; 2007 } 2008 } 2009 2010 phyctl |= AR_TX_PHY_MCS(otus_rates[ridx].mcs); 2011 if (ridx >= OTUS_RIDX_OFDM6) { 2012 phyctl |= AR_TX_PHY_MT_OFDM; 2013 if (ridx <= OTUS_RIDX_OFDM24) 2014 phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask); 2015 else 2016 phyctl |= AR_TX_PHY_ANTMSK(1); 2017 } else { /* CCK */ 2018 phyctl |= AR_TX_PHY_MT_CCK; 2019 phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask); 2020 } 2021 2022 /* Update rate control stats for frames that are ACK'ed. */ 2023 if (!(macctl & AR_TX_MAC_NOACK)) 2024 on->amn.amn_txcnt++; 2025 2026 /* Fill Tx descriptor. */ 2027 head = (void *)data->buf; 2028 head->len = htole16(m->m_pkthdr.len + IEEE80211_CRC_LEN); 2029 head->macctl = htole16(macctl); 2030 head->phyctl = htole32(phyctl); 2031 2032 if (__predict_false(sc->sc_drvbpf != NULL)) { 2033 struct otus_tx_radiotap_header *tap = &sc->sc_txtap; 2034 2035 tap->wt_flags = 0; 2036 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 2037 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; 2038 tap->wt_rate = otus_rates[ridx].rate; 2039 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); 2040 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); 2041 2042 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m, BPF_D_OUT); 2043 } 2044 2045 xferlen = sizeof(*head) + m->m_pkthdr.len; 2046 m_copydata(m, 0, m->m_pkthdr.len, (void *)&head[1]); 2047 2048 DPRINTFN(DBG_TX, sc, "queued len=%d mac=0x%04x phy=0x%08x rate=%d\n", 2049 head->len, head->macctl, head->phyctl, otus_rates[ridx].rate); 2050 2051 usbd_setup_xfer(data->xfer, data, data->buf, xferlen, 2052 USBD_FORCE_SHORT_XFER, OTUS_TX_TIMEOUT, otus_txeof); 2053 error = usbd_transfer(data->xfer); 2054 if (__predict_false( 2055 error != USBD_NORMAL_COMPLETION && 2056 error != USBD_IN_PROGRESS)) { 2057 DPRINTFN(DBG_TX, sc, "transfer failed %d\n", error); 2058 return error; 2059 } 2060 return 0; 2061 } 2062 2063 Static void 2064 otus_start(struct ifnet *ifp) 2065 { 2066 struct otus_softc *sc; 2067 struct ieee80211com *ic; 2068 struct otus_tx_data *data; 2069 struct ether_header *eh; 2070 struct ieee80211_node *ni; 2071 struct mbuf *m; 2072 2073 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 2074 return; 2075 2076 sc = ifp->if_softc; 2077 ic = &sc->sc_ic; 2078 2079 DPRINTFN(DBG_FN, sc, "\n"); 2080 2081 data = NULL; 2082 for (;;) { 2083 /* 2084 * Grab a Tx buffer if we don't already have one. If 2085 * one isn't available, bail out. 2086 * NB: We must obtain this Tx buffer _before_ 2087 * dequeueing anything as one may not be available 2088 * later. Both must be done inside a single lock. 2089 */ 2090 mutex_enter(&sc->sc_tx_mtx); 2091 if (data == NULL && !TAILQ_EMPTY(&sc->sc_tx_free_list)) { 2092 data = TAILQ_FIRST(&sc->sc_tx_free_list); 2093 TAILQ_REMOVE(&sc->sc_tx_free_list, data, next); 2094 } 2095 mutex_exit(&sc->sc_tx_mtx); 2096 2097 if (data == NULL) { 2098 ifp->if_flags |= IFF_OACTIVE; 2099 DPRINTFN(DBG_TX, sc, "empty sc_tx_free_list\n"); 2100 return; 2101 } 2102 2103 /* Send pending management frames first. */ 2104 IF_DEQUEUE(&ic->ic_mgtq, m); 2105 if (m != NULL) { 2106 ni = M_GETCTX(m, struct ieee80211_node *); 2107 M_CLEARCTX(m); 2108 goto sendit; 2109 } 2110 2111 if (ic->ic_state != IEEE80211_S_RUN) 2112 break; 2113 2114 /* Encapsulate and send data frames. */ 2115 IFQ_DEQUEUE(&ifp->if_snd, m); 2116 if (m == NULL) 2117 break; 2118 2119 if (m->m_len < (int)sizeof(*eh) && 2120 (m = m_pullup(m, sizeof(*eh))) == NULL) { 2121 if_statinc(ifp, if_oerrors); 2122 continue; 2123 } 2124 2125 eh = mtod(m, struct ether_header *); 2126 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 2127 if (ni == NULL) { 2128 m_freem(m); 2129 if_statinc(ifp, if_oerrors); 2130 continue; 2131 } 2132 2133 bpf_mtap(ifp, m, BPF_D_OUT); 2134 2135 if ((m = ieee80211_encap(ic, m, ni)) == NULL) { 2136 /* original m was freed by ieee80211_encap() */ 2137 ieee80211_free_node(ni); 2138 if_statinc(ifp, if_oerrors); 2139 continue; 2140 } 2141 sendit: 2142 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); 2143 2144 if (otus_tx(sc, m, ni, data) != 0) { 2145 m_freem(m); 2146 ieee80211_free_node(ni); 2147 if_statinc(ifp, if_oerrors); 2148 continue; 2149 } 2150 2151 data = NULL; /* we're finished with this data buffer */ 2152 m_freem(m); 2153 ieee80211_free_node(ni); 2154 sc->sc_tx_timer = 5; 2155 ifp->if_timer = 1; 2156 } 2157 2158 /* 2159 * If here, we have a Tx buffer, but ran out of mbufs to 2160 * transmit. Put the Tx buffer back to the free list. 2161 */ 2162 mutex_enter(&sc->sc_tx_mtx); 2163 TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next); 2164 mutex_exit(&sc->sc_tx_mtx); 2165 } 2166 2167 Static void 2168 otus_watchdog(struct ifnet *ifp) 2169 { 2170 struct otus_softc *sc; 2171 2172 sc = ifp->if_softc; 2173 2174 DPRINTFN(DBG_FN, sc, "\n"); 2175 2176 ifp->if_timer = 0; 2177 2178 if (sc->sc_tx_timer > 0) { 2179 if (--sc->sc_tx_timer == 0) { 2180 aprint_error_dev(sc->sc_dev, "device timeout\n"); 2181 /* otus_init(ifp); XXX needs a process context! */ 2182 if_statinc(ifp, if_oerrors); 2183 return; 2184 } 2185 ifp->if_timer = 1; 2186 } 2187 ieee80211_watchdog(&sc->sc_ic); 2188 } 2189 2190 Static int 2191 otus_ioctl(struct ifnet *ifp, u_long cmd, void *data) 2192 { 2193 struct otus_softc *sc; 2194 struct ieee80211com *ic; 2195 int s, error = 0; 2196 2197 sc = ifp->if_softc; 2198 2199 DPRINTFN(DBG_FN, sc, "%#lx\n", cmd); 2200 2201 ic = &sc->sc_ic; 2202 2203 s = splnet(); 2204 2205 switch (cmd) { 2206 case SIOCSIFADDR: 2207 ifp->if_flags |= IFF_UP; 2208 #ifdef INET 2209 struct ifaddr *ifa = data; 2210 if (ifa->ifa_addr->sa_family == AF_INET) 2211 arp_ifinit(&ic->ic_ac, ifa); 2212 #endif 2213 /* FALLTHROUGH */ 2214 case SIOCSIFFLAGS: 2215 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 2216 break; 2217 2218 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 2219 case IFF_UP | IFF_RUNNING: 2220 if (((ifp->if_flags ^ sc->sc_if_flags) & 2221 (IFF_ALLMULTI | IFF_PROMISC)) != 0) 2222 otus_set_multi(sc); 2223 break; 2224 case IFF_UP: 2225 otus_init(ifp); 2226 break; 2227 2228 case IFF_RUNNING: 2229 otus_stop(ifp); 2230 break; 2231 case 0: 2232 default: 2233 break; 2234 } 2235 sc->sc_if_flags = ifp->if_flags; 2236 break; 2237 2238 case SIOCADDMULTI: 2239 case SIOCDELMULTI: 2240 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 2241 /* setup multicast filter, etc */ 2242 /* XXX: ??? */ 2243 error = 0; 2244 } 2245 break; 2246 2247 case SIOCS80211CHANNEL: 2248 /* 2249 * This allows for fast channel switching in monitor mode 2250 * (used by kismet). In IBSS mode, we must explicitly reset 2251 * the interface to generate a new beacon frame. 2252 */ 2253 error = ieee80211_ioctl(ic, cmd, data); 2254 2255 DPRINTFN(DBG_CHAN, sc, 2256 "ic_curchan=%d ic_ibss_chan=%d ic_des_chan=%d ni_chan=%d error=%d\n", 2257 ieee80211_chan2ieee(ic, ic->ic_curchan), 2258 ieee80211_chan2ieee(ic, ic->ic_ibss_chan), 2259 ieee80211_chan2ieee(ic, ic->ic_des_chan), 2260 ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan), 2261 error); 2262 2263 if (error == ENETRESET && 2264 ic->ic_opmode == IEEE80211_M_MONITOR) { 2265 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 2266 (IFF_UP | IFF_RUNNING)) { 2267 mutex_enter(&sc->sc_write_mtx); 2268 otus_set_chan(sc, ic->ic_curchan, 0); 2269 mutex_exit(&sc->sc_write_mtx); 2270 } 2271 error = 0; 2272 } 2273 break; 2274 2275 default: 2276 error = ieee80211_ioctl(ic, cmd, data); 2277 } 2278 if (error == ENETRESET) { 2279 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 2280 (IFF_UP | IFF_RUNNING)) 2281 otus_init(ifp); 2282 error = 0; 2283 } 2284 splx(s); 2285 return error; 2286 } 2287 2288 Static int 2289 otus_set_multi(struct otus_softc *sc) 2290 { 2291 struct ethercom *ec = &sc->sc_ec; 2292 struct ifnet *ifp; 2293 struct ether_multi *enm; 2294 struct ether_multistep step; 2295 uint32_t lo, hi; 2296 uint8_t bit; 2297 int error; 2298 2299 DPRINTFN(DBG_FN, sc, "\n"); 2300 2301 ifp = sc->sc_ic.ic_ifp; 2302 if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) { 2303 lo = hi = 0xffffffff; 2304 goto done; 2305 } 2306 lo = hi = 0; 2307 ETHER_LOCK(ec); 2308 ETHER_FIRST_MULTI(step, ec, enm); 2309 while (enm != NULL) { 2310 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 2311 ifp->if_flags |= IFF_ALLMULTI; 2312 lo = hi = 0xffffffff; 2313 goto done; 2314 } 2315 bit = enm->enm_addrlo[5] >> 2; 2316 if (bit < 32) 2317 lo |= 1 << bit; 2318 else 2319 hi |= 1 << (bit - 32); 2320 ETHER_NEXT_MULTI(step, enm); 2321 } 2322 done: 2323 ETHER_UNLOCK(ec); 2324 mutex_enter(&sc->sc_write_mtx); 2325 hi |= 1 << 31; /* Make sure the broadcast bit is set. */ 2326 otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, lo); 2327 otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hi); 2328 error = otus_write_barrier(sc); 2329 mutex_exit(&sc->sc_write_mtx); 2330 return error; 2331 } 2332 2333 #ifdef HAVE_EDCA 2334 Static void 2335 otus_updateedca(struct ieee80211com *ic) 2336 { 2337 2338 DPRINTFN(DBG_FN, DBG_NO_SC, "\n"); 2339 2340 /* Do it in a process context. */ 2341 otus_do_async(ic->ic_ifp->if_softc, otus_updateedca_cb, NULL, 0); 2342 } 2343 2344 Static void 2345 otus_updateedca_cb(struct otus_softc *sc, void *arg __used) 2346 { 2347 2348 DPRINTFN(DBG_FN, sc, "\n"); 2349 2350 mutex_enter(&sc->sc_write_mtx); 2351 otus_updateedca_cb_locked(sc); 2352 mutex_exit(&sc->sc_write_mtx); 2353 } 2354 #endif 2355 2356 Static void 2357 otus_updateedca_cb_locked(struct otus_softc *sc) 2358 { 2359 #ifdef HAVE_EDCA 2360 struct ieee80211com *ic; 2361 #endif 2362 const struct ieee80211_edca_ac_params *edca; 2363 int s; 2364 2365 DPRINTFN(DBG_FN, sc, "\n"); 2366 2367 KASSERT(mutex_owned(&sc->sc_write_mtx)); 2368 2369 s = splnet(); 2370 2371 #ifdef HAVE_EDCA 2372 ic = &sc->sc_ic; 2373 edca = (ic->ic_flags & IEEE80211_F_QOS) ? 2374 ic->ic_edca_ac : otus_edca_def; 2375 #else 2376 edca = otus_edca_def; 2377 #endif /* HAVE_EDCA */ 2378 2379 #define EXP2(val) ((1 << (val)) - 1) 2380 #define AIFS(val) ((val) * 9 + 10) 2381 2382 /* Set CWmin/CWmax values. */ 2383 otus_write(sc, AR_MAC_REG_AC0_CW, 2384 EXP2(edca[WME_AC_BE].ac_ecwmax) << 16 | 2385 EXP2(edca[WME_AC_BE].ac_ecwmin)); 2386 otus_write(sc, AR_MAC_REG_AC1_CW, 2387 EXP2(edca[WME_AC_BK].ac_ecwmax) << 16 | 2388 EXP2(edca[WME_AC_BK].ac_ecwmin)); 2389 otus_write(sc, AR_MAC_REG_AC2_CW, 2390 EXP2(edca[WME_AC_VI].ac_ecwmax) << 16 | 2391 EXP2(edca[WME_AC_VI].ac_ecwmin)); 2392 otus_write(sc, AR_MAC_REG_AC3_CW, 2393 EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 | 2394 EXP2(edca[WME_AC_VO].ac_ecwmin)); 2395 otus_write(sc, AR_MAC_REG_AC4_CW, /* Special TXQ. */ 2396 EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 | 2397 EXP2(edca[WME_AC_VO].ac_ecwmin)); 2398 2399 /* Set AIFSN values. */ 2400 otus_write(sc, AR_MAC_REG_AC1_AC0_AIFS, 2401 AIFS(edca[WME_AC_VI].ac_aifsn) << 24 | 2402 AIFS(edca[WME_AC_BK].ac_aifsn) << 12 | 2403 AIFS(edca[WME_AC_BE].ac_aifsn)); 2404 otus_write(sc, AR_MAC_REG_AC3_AC2_AIFS, 2405 AIFS(edca[WME_AC_VO].ac_aifsn) << 16 | /* Special TXQ. */ 2406 AIFS(edca[WME_AC_VO].ac_aifsn) << 4 | 2407 AIFS(edca[WME_AC_VI].ac_aifsn) >> 8); 2408 2409 /* Set TXOP limit. */ 2410 otus_write(sc, AR_MAC_REG_AC1_AC0_TXOP, 2411 edca[WME_AC_BK].ac_txoplimit << 16 | 2412 edca[WME_AC_BE].ac_txoplimit); 2413 otus_write(sc, AR_MAC_REG_AC3_AC2_TXOP, 2414 edca[WME_AC_VO].ac_txoplimit << 16 | 2415 edca[WME_AC_VI].ac_txoplimit); 2416 #undef AIFS 2417 #undef EXP2 2418 2419 splx(s); 2420 2421 (void)otus_write_barrier(sc); 2422 } 2423 2424 Static void 2425 otus_updateslot(struct ifnet *ifp) 2426 { 2427 struct otus_softc *sc; 2428 2429 sc = ifp->if_softc; 2430 2431 DPRINTFN(DBG_FN, sc, "\n"); 2432 2433 /* Do it in a process context. */ 2434 otus_do_async(sc, otus_updateslot_cb, NULL, 0); 2435 } 2436 2437 /* ARGSUSED */ 2438 Static void 2439 otus_updateslot_cb(struct otus_softc *sc, void *arg) 2440 { 2441 2442 DPRINTFN(DBG_FN, sc, "\n"); 2443 2444 mutex_enter(&sc->sc_write_mtx); 2445 otus_updateslot_cb_locked(sc); 2446 mutex_exit(&sc->sc_write_mtx); 2447 } 2448 2449 Static void 2450 otus_updateslot_cb_locked(struct otus_softc *sc) 2451 { 2452 uint32_t slottime; 2453 2454 DPRINTFN(DBG_FN, sc, "\n"); 2455 2456 KASSERT(mutex_owned(&sc->sc_write_mtx)); 2457 2458 slottime = (sc->sc_ic.ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; 2459 otus_write(sc, AR_MAC_REG_SLOT_TIME, slottime << 10); 2460 (void)otus_write_barrier(sc); 2461 } 2462 2463 Static int 2464 otus_init_mac(struct otus_softc *sc) 2465 { 2466 int error; 2467 2468 DPRINTFN(DBG_FN | DBG_INIT, sc, "\n"); 2469 2470 KASSERT(mutex_owned(&sc->sc_write_mtx)); 2471 2472 otus_write(sc, AR_MAC_REG_ACK_EXTENSION, 0x40); 2473 otus_write(sc, AR_MAC_REG_RETRY_MAX, 0); 2474 otus_write(sc, AR_MAC_REG_SNIFFER, AR_MAC_REG_SNIFFER_DEFAULTS); 2475 otus_write(sc, AR_MAC_REG_RX_THRESHOLD, 0xc1f80); 2476 otus_write(sc, AR_MAC_REG_RX_PE_DELAY, 0x70); 2477 otus_write(sc, AR_MAC_REG_EIFS_AND_SIFS, 0xa144000); 2478 otus_write(sc, AR_MAC_REG_SLOT_TIME, 9 << 10); 2479 2480 /* CF-END mode */ 2481 otus_write(sc, 0x1c3b2c, 0x19000000); 2482 2483 /* NAV protects ACK only (in TXOP). */ 2484 otus_write(sc, 0x1c3b38, 0x201); 2485 2486 /* Set beacon PHY CTRL's TPC to 0x7, TA1=1 */ 2487 /* OTUS set AM to 0x1 */ 2488 otus_write(sc, AR_MAC_REG_BCN_HT1, 0x8000170); 2489 2490 otus_write(sc, AR_MAC_REG_BACKOFF_PROTECT, 0x105); 2491 2492 /* AGG test code*/ 2493 /* Aggregation MAX number and timeout */ 2494 otus_write(sc, AR_MAC_REG_AMPDU_FACTOR, 0x10000a); 2495 2496 /* Filter any control frames, BAR is bit 24. */ 2497 otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, AR_MAC_REG_FTF_DEFAULTS); 2498 2499 /* Enable deaggregator, response in sniffer mode */ 2500 otus_write(sc, 0x1c3c40, 0x1 | 1 << 30); /* XXX: was 0x1 */ 2501 2502 /* rate sets */ 2503 otus_write(sc, AR_MAC_REG_BASIC_RATE, 0x150f); 2504 otus_write(sc, AR_MAC_REG_MANDATORY_RATE, 0x150f); 2505 otus_write(sc, AR_MAC_REG_RTS_CTS_RATE, 0x10b01bb); 2506 2507 /* MIMO response control */ 2508 otus_write(sc, 0x1c3694, 0x4003c1e); /* bit 26~28 otus-AM */ 2509 2510 /* Switch MAC to OTUS interface. */ 2511 otus_write(sc, 0x1c3600, 0x3); 2512 2513 otus_write(sc, AR_MAC_REG_AMPDU_RX_THRESH, 0xffff); 2514 2515 /* set PHY register read timeout (??) */ 2516 otus_write(sc, AR_MAC_REG_MISC_680, 0xf00008); 2517 2518 /* Disable Rx TimeOut, workaround for BB. */ 2519 otus_write(sc, AR_MAC_REG_RX_TIMEOUT, 0x0); 2520 2521 /* Set clock frequency to 88/80MHz. */ 2522 otus_write(sc, AR_PWR_REG_CLOCK_SEL, 2523 AR_PWR_CLK_AHB_80_88MHZ | AR_PWR_CLK_DAC_160_INV_DLY); 2524 2525 /* Set WLAN DMA interrupt mode: generate intr per packet. */ 2526 otus_write(sc, AR_MAC_REG_TXRX_MPI, 0x110011); 2527 2528 otus_write(sc, AR_MAC_REG_FCS_SELECT, AR_MAC_FCS_FIFO_PROT); 2529 2530 /* Disables the CF_END frame, undocumented register */ 2531 otus_write(sc, AR_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141e0f48); 2532 2533 /* Disable HW decryption for now. */ 2534 otus_write(sc, AR_MAC_REG_ENCRYPTION, 2535 AR_MAC_REG_ENCRYPTION_DEFAULTS | AR_MAC_REG_ENCRYPTION_RX_SOFTWARE); 2536 2537 /* 2538 * XXX: should these be elsewhere? 2539 */ 2540 /* Enable LED0 and LED1. */ 2541 otus_write(sc, AR_GPIO_REG_PORT_TYPE, 3); 2542 otus_write(sc, AR_GPIO_REG_DATA, 2543 AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON); 2544 2545 /* Set USB Rx stream mode maximum frame number to 2. */ 2546 otus_write(sc, AR_USB_REG_MAX_AGG_UPLOAD, (1 << 2)); 2547 2548 /* Set USB Rx stream mode timeout to 10us. */ 2549 otus_write(sc, AR_USB_REG_UPLOAD_TIME_CTL, 0x80); 2550 2551 if ((error = otus_write_barrier(sc)) != 0) 2552 return error; 2553 2554 /* Set default EDCA parameters. */ 2555 otus_updateedca_cb_locked(sc); 2556 return 0; 2557 } 2558 2559 /* 2560 * Return default value for PHY register based on current operating mode. 2561 */ 2562 Static uint32_t 2563 otus_phy_get_def(struct otus_softc *sc, uint32_t reg) 2564 { 2565 int i; 2566 2567 DPRINTFN(DBG_FN, sc, "\n"); 2568 2569 for (i = 0; i < __arraycount(ar5416_phy_regs); i++) 2570 if (AR_PHY(ar5416_phy_regs[i]) == reg) 2571 return sc->sc_phy_vals[i]; 2572 return 0; /* Register not found. */ 2573 } 2574 2575 /* 2576 * Update PHY's programming based on vendor-specific data stored in EEPROM. 2577 * This is for FEM-type devices only. 2578 */ 2579 Static int 2580 otus_set_board_values(struct otus_softc *sc, struct ieee80211_channel *c) 2581 { 2582 const struct ModalEepHeader *eep; 2583 uint32_t tmp, offset; 2584 2585 DPRINTFN(DBG_FN, sc, "\n"); 2586 2587 if (IEEE80211_IS_CHAN_5GHZ(c)) 2588 eep = &sc->sc_eeprom.modalHeader[0]; 2589 else 2590 eep = &sc->sc_eeprom.modalHeader[1]; 2591 2592 /* Offset of chain 2. */ 2593 offset = 2 * 0x1000; 2594 2595 tmp = le32toh(eep->antCtrlCommon); 2596 otus_write(sc, AR_PHY_SWITCH_COM, tmp); 2597 2598 tmp = le32toh(eep->antCtrlChain[0]); 2599 otus_write(sc, AR_PHY_SWITCH_CHAIN_0, tmp); 2600 2601 tmp = le32toh(eep->antCtrlChain[1]); 2602 otus_write(sc, AR_PHY_SWITCH_CHAIN_0 + offset, tmp); 2603 2604 if (1 /* sc->sc_sco == AR_SCO_SCN */) { 2605 tmp = otus_phy_get_def(sc, AR_PHY_SETTLING); 2606 tmp &= ~(0x7f << 7); 2607 tmp |= (eep->switchSettling & 0x7f) << 7; 2608 otus_write(sc, AR_PHY_SETTLING, tmp); 2609 } 2610 2611 tmp = otus_phy_get_def(sc, AR_PHY_DESIRED_SZ); 2612 tmp &= ~0xffff; 2613 tmp |= eep->pgaDesiredSize << 8 | eep->adcDesiredSize; 2614 otus_write(sc, AR_PHY_DESIRED_SZ, tmp); 2615 2616 tmp = eep->txEndToXpaOff << 24 | eep->txEndToXpaOff << 16 | 2617 eep->txFrameToXpaOn << 8 | eep->txFrameToXpaOn; 2618 otus_write(sc, AR_PHY_RF_CTL4, tmp); 2619 2620 tmp = otus_phy_get_def(sc, AR_PHY_RF_CTL3); 2621 tmp &= ~(0xff << 16); 2622 tmp |= eep->txEndToRxOn << 16; 2623 otus_write(sc, AR_PHY_RF_CTL3, tmp); 2624 2625 tmp = otus_phy_get_def(sc, AR_PHY_CCA); 2626 tmp &= ~(0x7f << 12); 2627 tmp |= (eep->thresh62 & 0x7f) << 12; 2628 otus_write(sc, AR_PHY_CCA, tmp); 2629 2630 tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN); 2631 tmp &= ~(0x3f << 12); 2632 tmp |= (eep->txRxAttenCh[0] & 0x3f) << 12; 2633 otus_write(sc, AR_PHY_RXGAIN, tmp); 2634 2635 tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN + offset); 2636 tmp &= ~(0x3f << 12); 2637 tmp |= (eep->txRxAttenCh[1] & 0x3f) << 12; 2638 otus_write(sc, AR_PHY_RXGAIN + offset, tmp); 2639 2640 tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ); 2641 tmp &= ~(0x3f << 18); 2642 tmp |= (eep->rxTxMarginCh[0] & 0x3f) << 18; 2643 if (IEEE80211_IS_CHAN_5GHZ(c)) { 2644 tmp &= ~(0xf << 10); 2645 tmp |= (eep->bswMargin[0] & 0xf) << 10; 2646 } 2647 otus_write(sc, AR_PHY_GAIN_2GHZ, tmp); 2648 2649 tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ + offset); 2650 tmp &= ~(0x3f << 18); 2651 tmp |= (eep->rxTxMarginCh[1] & 0x3f) << 18; 2652 otus_write(sc, AR_PHY_GAIN_2GHZ + offset, tmp); 2653 2654 tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4); 2655 tmp &= ~(0x3f << 5 | 0x1f); 2656 tmp |= (eep->iqCalICh[0] & 0x3f) << 5 | (eep->iqCalQCh[0] & 0x1f); 2657 otus_write(sc, AR_PHY_TIMING_CTRL4, tmp); 2658 2659 tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4 + offset); 2660 tmp &= ~(0x3f << 5 | 0x1f); 2661 tmp |= (eep->iqCalICh[1] & 0x3f) << 5 | (eep->iqCalQCh[1] & 0x1f); 2662 otus_write(sc, AR_PHY_TIMING_CTRL4 + offset, tmp); 2663 2664 tmp = otus_phy_get_def(sc, AR_PHY_TPCRG1); 2665 tmp &= ~(0xf << 16); 2666 tmp |= (eep->xpd & 0xf) << 16; 2667 otus_write(sc, AR_PHY_TPCRG1, tmp); 2668 2669 return otus_write_barrier(sc); 2670 } 2671 2672 Static int 2673 otus_program_phy(struct otus_softc *sc, struct ieee80211_channel *c) 2674 { 2675 const uint32_t *vals; 2676 int error, i; 2677 2678 DPRINTFN(DBG_FN, sc, "\n"); 2679 2680 /* Select PHY programming based on band and bandwidth. */ 2681 if (IEEE80211_IS_CHAN_2GHZ(c)) 2682 vals = ar5416_phy_vals_2ghz_20mhz; 2683 else 2684 vals = ar5416_phy_vals_5ghz_20mhz; 2685 for (i = 0; i < __arraycount(ar5416_phy_regs); i++) 2686 otus_write(sc, AR_PHY(ar5416_phy_regs[i]), vals[i]); 2687 sc->sc_phy_vals = vals; 2688 2689 if (sc->sc_eeprom.baseEepHeader.deviceType == 0x80) /* FEM */ 2690 if ((error = otus_set_board_values(sc, c)) != 0) 2691 return error; 2692 2693 /* Initial Tx power settings. */ 2694 otus_write(sc, AR_PHY_POWER_TX_RATE_MAX, 0x7f); 2695 otus_write(sc, AR_PHY_POWER_TX_RATE1, 0x3f3f3f3f); 2696 otus_write(sc, AR_PHY_POWER_TX_RATE2, 0x3f3f3f3f); 2697 otus_write(sc, AR_PHY_POWER_TX_RATE3, 0x3f3f3f3f); 2698 otus_write(sc, AR_PHY_POWER_TX_RATE4, 0x3f3f3f3f); 2699 otus_write(sc, AR_PHY_POWER_TX_RATE5, 0x3f3f3f3f); 2700 otus_write(sc, AR_PHY_POWER_TX_RATE6, 0x3f3f3f3f); 2701 otus_write(sc, AR_PHY_POWER_TX_RATE7, 0x3f3f3f3f); 2702 otus_write(sc, AR_PHY_POWER_TX_RATE8, 0x3f3f3f3f); 2703 otus_write(sc, AR_PHY_POWER_TX_RATE9, 0x3f3f3f3f); 2704 2705 if (IEEE80211_IS_CHAN_2GHZ(c)) 2706 otus_write(sc, 0x1d4014, 0x5163); 2707 else 2708 otus_write(sc, 0x1d4014, 0x5143); 2709 2710 return otus_write_barrier(sc); 2711 } 2712 2713 static __inline uint8_t 2714 otus_reverse_bits(uint8_t v) 2715 { 2716 2717 v = ((v >> 1) & 0x55) | ((v & 0x55) << 1); 2718 v = ((v >> 2) & 0x33) | ((v & 0x33) << 2); 2719 v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4); 2720 return v; 2721 } 2722 2723 Static int 2724 otus_set_rf_bank4(struct otus_softc *sc, struct ieee80211_channel *c) 2725 { 2726 uint8_t chansel, d0, d1; 2727 uint16_t data; 2728 int error; 2729 2730 DPRINTFN(DBG_FN, sc, "\n"); 2731 2732 d0 = 0; 2733 if (IEEE80211_IS_CHAN_5GHZ(c)) { 2734 chansel = (c->ic_freq - 4800) / 5; 2735 if (chansel & 1) 2736 d0 |= AR_BANK4_AMODE_REFSEL(2); 2737 else 2738 d0 |= AR_BANK4_AMODE_REFSEL(1); 2739 } else { 2740 d0 |= AR_BANK4_AMODE_REFSEL(2); 2741 if (c->ic_freq == 2484) { /* CH 14 */ 2742 d0 |= AR_BANK4_BMODE_LF_SYNTH_FREQ; 2743 chansel = 10 + (c->ic_freq - 2274) / 5; 2744 } else 2745 chansel = 16 + (c->ic_freq - 2272) / 5; 2746 chansel <<= 2; 2747 } 2748 d0 |= AR_BANK4_ADDR(1) | AR_BANK4_CHUP; 2749 d1 = otus_reverse_bits(chansel); 2750 2751 /* Write bits 0-4 of d0 and d1. */ 2752 data = (d1 & 0x1f) << 5 | (d0 & 0x1f); 2753 otus_write(sc, AR_PHY(44), data); 2754 /* Write bits 5-7 of d0 and d1. */ 2755 data = (d1 >> 5) << 5 | (d0 >> 5); 2756 otus_write(sc, AR_PHY(58), data); 2757 2758 if ((error = otus_write_barrier(sc)) == 0) 2759 usbd_delay_ms(sc->sc_udev, 10); 2760 2761 return error; 2762 } 2763 2764 Static void 2765 otus_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa) 2766 { 2767 #define COEFF_SCALE_SHIFT 24 2768 uint32_t exp, man; 2769 2770 DPRINTFN(DBG_FN, DBG_NO_SC, "\n"); 2771 2772 /* exponent = 14 - floor(log2(coeff)) */ 2773 for (exp = 31; exp > 0; exp--) 2774 if (coeff & (1 << exp)) 2775 break; 2776 KASSERT(exp != 0); 2777 exp = 14 - (exp - COEFF_SCALE_SHIFT); 2778 2779 /* mantissa = floor(coeff * 2^exponent + 0.5) */ 2780 man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1)); 2781 2782 *mantissa = man >> (COEFF_SCALE_SHIFT - exp); 2783 *exponent = exp - 16; 2784 #undef COEFF_SCALE_SHIFT 2785 } 2786 2787 Static int 2788 otus_set_chan(struct otus_softc *sc, struct ieee80211_channel *c, int assoc) 2789 { 2790 struct ar_cmd_frequency cmd; 2791 struct ar_rsp_frequency rsp; 2792 const uint32_t *vals; 2793 uint32_t coeff, exp, man, tmp; 2794 uint8_t code; 2795 int error, i; 2796 2797 DPRINTFN(DBG_FN, sc, "\n"); 2798 2799 2800 #ifdef OTUS_DEBUG 2801 struct ieee80211com *ic = &sc->sc_ic; 2802 int chan = ieee80211_chan2ieee(ic, c); 2803 2804 DPRINTFN(DBG_CHAN, sc, "setting channel %d (%dMHz)\n", 2805 chan, c->ic_freq); 2806 #endif 2807 2808 tmp = IEEE80211_IS_CHAN_2GHZ(c) ? 0x105 : 0x104; 2809 otus_write(sc, AR_MAC_REG_DYNAMIC_SIFS_ACK, tmp); 2810 if ((error = otus_write_barrier(sc)) != 0) 2811 return error; 2812 2813 /* Disable BB Heavy Clip. */ 2814 otus_write(sc, AR_PHY_HEAVY_CLIP_ENABLE, 0x200); 2815 if ((error = otus_write_barrier(sc)) != 0) 2816 return error; 2817 2818 /* XXX Is that FREQ_START ? */ 2819 error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL); 2820 if (error != 0) 2821 return error; 2822 2823 /* Reprogram PHY and RF on channel band or bandwidth changes. */ 2824 if (sc->sc_bb_reset || c->ic_flags != sc->sc_curchan->ic_flags) { 2825 DPRINTFN(DBG_CHAN, sc, "band switch\n"); 2826 2827 /* Cold/Warm reset BB/ADDA. */ 2828 otus_write(sc, 0x1d4004, sc->sc_bb_reset ? 0x800 : 0x400); 2829 if ((error = otus_write_barrier(sc)) != 0) 2830 return error; 2831 2832 otus_write(sc, 0x1d4004, 0); 2833 if ((error = otus_write_barrier(sc)) != 0) 2834 return error; 2835 sc->sc_bb_reset = 0; 2836 2837 if ((error = otus_program_phy(sc, c)) != 0) { 2838 aprint_error_dev(sc->sc_dev, 2839 "could not program PHY\n"); 2840 return error; 2841 } 2842 2843 /* Select RF programming based on band. */ 2844 if (IEEE80211_IS_CHAN_5GHZ(c)) 2845 vals = ar5416_banks_vals_5ghz; 2846 else 2847 vals = ar5416_banks_vals_2ghz; 2848 for (i = 0; i < __arraycount(ar5416_banks_regs); i++) 2849 otus_write(sc, AR_PHY(ar5416_banks_regs[i]), vals[i]); 2850 if ((error = otus_write_barrier(sc)) != 0) { 2851 aprint_error_dev(sc->sc_dev, "could not program RF\n"); 2852 return error; 2853 } 2854 code = AR_CMD_RF_INIT; 2855 } else { 2856 code = AR_CMD_FREQUENCY; 2857 } 2858 2859 if ((error = otus_set_rf_bank4(sc, c)) != 0) 2860 return error; 2861 2862 tmp = (sc->sc_txmask == 0x5) ? 0x340 : 0x240; 2863 otus_write(sc, AR_PHY_TURBO, tmp); 2864 if ((error = otus_write_barrier(sc)) != 0) 2865 return error; 2866 2867 /* Send firmware command to set channel. */ 2868 cmd.freq = htole32((uint32_t)c->ic_freq * 1000); 2869 cmd.dynht2040 = htole32(0); 2870 cmd.htena = htole32(1); 2871 2872 /* Set Delta Slope (exponent and mantissa). */ 2873 coeff = (100 << 24) / c->ic_freq; 2874 otus_get_delta_slope(coeff, &exp, &man); 2875 cmd.dsc_exp = htole32(exp); 2876 cmd.dsc_man = htole32(man); 2877 DPRINTFN(DBG_CHAN, sc, "ds coeff=%u exp=%u man=%u\n", 2878 coeff, exp, man); 2879 2880 /* For Short GI, coeff is 9/10 that of normal coeff. */ 2881 coeff = (9 * coeff) / 10; 2882 otus_get_delta_slope(coeff, &exp, &man); 2883 cmd.dsc_shgi_exp = htole32(exp); 2884 cmd.dsc_shgi_man = htole32(man); 2885 DPRINTFN(DBG_CHAN, sc, "ds shgi coeff=%u exp=%u man=%u\n", 2886 coeff, exp, man); 2887 2888 /* Set wait time for AGC and noise calibration (100 or 200ms). */ 2889 cmd.check_loop_count = assoc ? htole32(2000) : htole32(1000); 2890 DPRINTFN(DBG_CHAN, sc, "%s\n", 2891 code == AR_CMD_RF_INIT ? "RF_INIT" : "FREQUENCY"); 2892 error = otus_cmd(sc, code, &cmd, sizeof(cmd), &rsp); 2893 if (error != 0) 2894 return error; 2895 2896 if ((rsp.status & htole32(AR_CAL_ERR_AGC | AR_CAL_ERR_NF_VAL)) != 0) { 2897 DPRINTFN(DBG_CHAN, sc, "status=%#x\n", le32toh(rsp.status)); 2898 /* Force cold reset on next channel. */ 2899 sc->sc_bb_reset = 1; 2900 } 2901 2902 #ifdef OTUS_DEBUG 2903 if (otus_debug & DBG_CHAN) { 2904 DPRINTFN(DBG_CHAN, sc, "calibration status=%#x\n", 2905 le32toh(rsp.status)); 2906 for (i = 0; i < 2; i++) { /* 2 Rx chains */ 2907 /* Sign-extend 9-bit NF values. */ 2908 DPRINTFN(DBG_CHAN, sc, "noisefloor chain %d=%d\n", 2909 i, (((int32_t)le32toh(rsp.nf[i])) << 4) >> 23); 2910 DPRINTFN(DBG_CHAN, sc, "noisefloor ext chain %d=%d\n", 2911 i, ((int32_t)le32toh(rsp.nf_ext[i])) >> 23); 2912 } 2913 } 2914 #endif 2915 sc->sc_curchan = c; 2916 return 0; 2917 } 2918 2919 #ifdef notyet 2920 Static int 2921 otus_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, 2922 struct ieee80211_key *k) 2923 { 2924 struct otus_softc *sc; 2925 struct otus_cmd_key cmd; 2926 2927 sc = ic->ic_ifp->if_softc; 2928 2929 DPRINTFN(DBG_FN, sc, "\n"); 2930 2931 /* Defer setting of WEP keys until interface is brought up. */ 2932 if ((ic->ic_ifp->if_flags & (IFF_UP | IFF_RUNNING)) != 2933 (IFF_UP | IFF_RUNNING)) 2934 return 0; 2935 2936 /* Do it in a process context. */ 2937 cmd.key = *k; 2938 cmd.associd = (ni != NULL) ? ni->ni_associd : 0; 2939 otus_do_async(sc, otus_set_key_cb, &cmd, sizeof(cmd)); 2940 return 0; 2941 } 2942 2943 Static void 2944 otus_set_key_cb(struct otus_softc *sc, void *arg) 2945 { 2946 struct otus_cmd_key *cmd; 2947 struct ieee80211_key *k; 2948 struct ar_cmd_ekey key; 2949 uint16_t cipher; 2950 int error; 2951 2952 DPRINTFN(DBG_FN, sc, "\n"); 2953 2954 cmd = arg; 2955 k = &cmd->key; 2956 2957 memset(&key, 0, sizeof(key)); 2958 if (k->k_flags & IEEE80211_KEY_GROUP) { 2959 key.uid = htole16(k->k_id); 2960 IEEE80211_ADDR_COPY(key.macaddr, sc->sc_ic.ic_myaddr); 2961 key.macaddr[0] |= 0x80; 2962 } else { 2963 key.uid = htole16(OTUS_UID(cmd->associd)); 2964 IEEE80211_ADDR_COPY(key.macaddr, ni->ni_macaddr); 2965 } 2966 key.kix = htole16(0); 2967 /* Map net80211 cipher to hardware. */ 2968 switch (k->k_cipher) { 2969 case IEEE80211_CIPHER_WEP40: 2970 cipher = AR_CIPHER_WEP64; 2971 break; 2972 case IEEE80211_CIPHER_WEP104: 2973 cipher = AR_CIPHER_WEP128; 2974 break; 2975 case IEEE80211_CIPHER_TKIP: 2976 cipher = AR_CIPHER_TKIP; 2977 break; 2978 case IEEE80211_CIPHER_CCMP: 2979 cipher = AR_CIPHER_AES; 2980 break; 2981 default: 2982 return; 2983 } 2984 key.cipher = htole16(cipher); 2985 memcpy(key.key, k->k_key, MIN(k->k_len, 16)); 2986 error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL); 2987 if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP) 2988 return; 2989 2990 /* TKIP: set Tx/Rx MIC Key. */ 2991 key.kix = htole16(1); 2992 memcpy(key.key, k->k_key + 16, 16); 2993 (void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL); 2994 } 2995 2996 Static void 2997 otus_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, 2998 struct ieee80211_key *k) 2999 { 3000 struct otus_softc *sc; 3001 struct otus_cmd_key cmd; 3002 3003 sc = ic->ic_ifp->if_softc; 3004 3005 DPRINTFN(DBG_FN, sc, "\n"); 3006 3007 if (!(ic->ic_ifp->if_flags & IFF_RUNNING) || 3008 ic->ic_state != IEEE80211_S_RUN) 3009 return; /* Nothing to do. */ 3010 3011 /* Do it in a process context. */ 3012 cmd.key = *k; 3013 cmd.associd = (ni != NULL) ? ni->ni_associd : 0; 3014 otus_do_async(sc, otus_delete_key_cb, &cmd, sizeof(cmd)); 3015 } 3016 3017 Static void 3018 otus_delete_key_cb(struct otus_softc *sc, void *arg) 3019 { 3020 struct otus_cmd_key *cmd; 3021 struct ieee80211_key *k; 3022 uint32_t uid; 3023 3024 DPRINTFN(DBG_FN, sc, "\n"); 3025 3026 cmd = arg; 3027 k = &cmd->key; 3028 if (k->k_flags & IEEE80211_KEY_GROUP) 3029 uid = htole32(k->k_id); 3030 else 3031 uid = htole32(OTUS_UID(cmd->associd)); 3032 (void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof(uid), NULL); 3033 } 3034 #endif /* notyet */ 3035 3036 Static void 3037 otus_calib_to(void *arg) 3038 { 3039 struct otus_softc *sc; 3040 struct ieee80211com *ic; 3041 struct ieee80211_node *ni; 3042 struct otus_node *on; 3043 int s; 3044 3045 sc = arg; 3046 3047 DPRINTFN(DBG_FN, sc, "\n"); 3048 3049 if (sc->sc_dying) 3050 return; 3051 3052 s = splnet(); 3053 ic = &sc->sc_ic; 3054 ni = ic->ic_bss; 3055 on = (void *)ni; 3056 ieee80211_amrr_choose(&sc->sc_amrr, ni, &on->amn); 3057 splx(s); 3058 3059 if (!sc->sc_dying) 3060 callout_schedule(&sc->sc_calib_to, hz); 3061 } 3062 3063 Static int 3064 otus_set_bssid(struct otus_softc *sc, const uint8_t *bssid) 3065 { 3066 3067 DPRINTFN(DBG_FN, sc, "\n"); 3068 3069 KASSERT(mutex_owned(&sc->sc_write_mtx)); 3070 3071 otus_write(sc, AR_MAC_REG_BSSID_L, 3072 bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24); 3073 otus_write(sc, AR_MAC_REG_BSSID_H, 3074 bssid[4] | bssid[5] << 8); 3075 return otus_write_barrier(sc); 3076 } 3077 3078 Static int 3079 otus_set_macaddr(struct otus_softc *sc, const uint8_t *addr) 3080 { 3081 3082 DPRINTFN(DBG_FN, sc, "\n"); 3083 3084 KASSERT(mutex_owned(&sc->sc_write_mtx)); 3085 3086 otus_write(sc, AR_MAC_REG_MAC_ADDR_L, 3087 addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); 3088 otus_write(sc, AR_MAC_REG_MAC_ADDR_H, 3089 addr[4] | addr[5] << 8); 3090 return otus_write_barrier(sc); 3091 } 3092 3093 #ifdef notyet 3094 /* Default single-LED. */ 3095 Static void 3096 otus_led_newstate_type1(struct otus_softc *sc) 3097 { 3098 3099 DPRINTFN(DBG_FN, sc, "\n"); 3100 3101 /* TBD */ 3102 } 3103 3104 /* NETGEAR, dual-LED. */ 3105 Static void 3106 otus_led_newstate_type2(struct otus_softc *sc) 3107 { 3108 3109 DPRINTFN(DBG_FN, sc, "\n"); 3110 3111 /* TBD */ 3112 } 3113 #endif /* notyet */ 3114 3115 /* 3116 * NETGEAR, single-LED/3 colors (blue, red, purple.) 3117 */ 3118 Static void 3119 otus_led_newstate_type3(struct otus_softc *sc) 3120 { 3121 struct ieee80211com *ic; 3122 uint32_t led_state; 3123 3124 DPRINTFN(DBG_FN, sc, "\n"); 3125 3126 ic = &sc->sc_ic; 3127 led_state = sc->sc_led_state; 3128 switch (ic->ic_state) { 3129 case IEEE80211_S_INIT: 3130 led_state = 0; 3131 break; 3132 case IEEE80211_S_SCAN: 3133 led_state ^= AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON; 3134 led_state &= ~(IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ? 3135 AR_GPIO_REG_DATA_LED1_ON : AR_GPIO_REG_DATA_LED0_ON); 3136 break; 3137 case IEEE80211_S_AUTH: 3138 case IEEE80211_S_ASSOC: 3139 /* XXX: Turn both LEDs on for AUTH and ASSOC? */ 3140 led_state = AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON; 3141 break; 3142 case IEEE80211_S_RUN: 3143 led_state = IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ? 3144 AR_GPIO_REG_DATA_LED0_ON : AR_GPIO_REG_DATA_LED1_ON; 3145 break; 3146 } 3147 if (led_state != sc->sc_led_state) { 3148 otus_write(sc, AR_GPIO_REG_DATA, led_state); 3149 if (otus_write_barrier(sc) == 0) 3150 sc->sc_led_state = led_state; 3151 } 3152 } 3153 3154 Static int 3155 otus_init(struct ifnet *ifp) 3156 { 3157 struct otus_softc *sc; 3158 struct ieee80211com *ic; 3159 uint32_t filter, pm_mode, sniffer; 3160 int error; 3161 3162 sc = ifp->if_softc; 3163 3164 DPRINTFN(DBG_FN | DBG_INIT, sc, "\n"); 3165 3166 ic = &sc->sc_ic; 3167 3168 mutex_enter(&sc->sc_write_mtx); 3169 3170 /* Init host command ring. */ 3171 mutex_spin_enter(&sc->sc_task_mtx); 3172 sc->sc_cmdq.cur = sc->sc_cmdq.next = sc->sc_cmdq.queued = 0; 3173 mutex_spin_exit(&sc->sc_task_mtx); 3174 3175 if ((error = otus_init_mac(sc)) != 0) { 3176 mutex_exit(&sc->sc_write_mtx); 3177 aprint_error_dev(sc->sc_dev, "could not initialize MAC\n"); 3178 return error; 3179 } 3180 3181 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 3182 (void)otus_set_macaddr(sc, ic->ic_myaddr); 3183 3184 pm_mode = AR_MAC_REG_POWERMGT_DEFAULTS; 3185 sniffer = AR_MAC_REG_SNIFFER_DEFAULTS; 3186 filter = AR_MAC_REG_FTF_DEFAULTS; 3187 sc->sc_rx_error_msk = ~0; 3188 3189 switch (ic->ic_opmode) { 3190 #ifdef notyet 3191 #ifndef IEEE80211_STA_ONLY 3192 case IEEE80211_M_HOSTAP: 3193 pm_mode |= AR_MAC_REG_POWERMGT_AP; 3194 break; 3195 case IEEE80211_M_IBSS: 3196 pm_mode |= AR_MAC_REG_POWERMGT_IBSS; /* XXX: was 0x0 */ 3197 break; 3198 #endif 3199 #endif 3200 case IEEE80211_M_STA: 3201 pm_mode |= AR_MAC_REG_POWERMGT_STA; 3202 break; 3203 case IEEE80211_M_MONITOR: 3204 sc->sc_rx_error_msk = ~AR_RX_ERROR_BAD_RA; 3205 filter = AR_MAC_REG_FTF_MONITOR; 3206 sniffer |= AR_MAC_REG_SNIFFER_ENABLE_PROMISC; 3207 break; 3208 default: 3209 aprint_error_dev(sc->sc_dev, "bad opmode: %d", ic->ic_opmode); 3210 return EOPNOTSUPP; /* XXX: ??? */ 3211 } 3212 otus_write(sc, AR_MAC_REG_POWERMANAGEMENT, pm_mode); 3213 otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, filter); 3214 otus_write(sc, AR_MAC_REG_SNIFFER, sniffer); 3215 (void)otus_write_barrier(sc); 3216 3217 sc->sc_bb_reset = 1; /* Force cold reset. */ 3218 if ((error = otus_set_chan(sc, ic->ic_curchan, 0)) != 0) { 3219 mutex_exit(&sc->sc_write_mtx); 3220 aprint_error_dev(sc->sc_dev, "could not set channel\n"); 3221 return error; 3222 } 3223 3224 /* Start Rx. */ 3225 otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_ENABLE); 3226 (void)otus_write_barrier(sc); 3227 mutex_exit(&sc->sc_write_mtx); 3228 3229 ifp->if_flags &= ~IFF_OACTIVE; 3230 ifp->if_flags |= IFF_RUNNING; 3231 3232 if (ic->ic_opmode == IEEE80211_M_MONITOR) 3233 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 3234 else 3235 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 3236 3237 return 0; 3238 } 3239 3240 Static void 3241 otus_stop(struct ifnet *ifp) 3242 { 3243 struct otus_softc *sc; 3244 struct ieee80211com *ic; 3245 int s; 3246 3247 sc = ifp->if_softc; 3248 3249 DPRINTFN(DBG_FN, sc, "\n"); 3250 3251 ic = &sc->sc_ic; 3252 3253 sc->sc_tx_timer = 0; 3254 ifp->if_timer = 0; 3255 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 3256 3257 callout_halt(&sc->sc_scan_to, NULL); 3258 callout_halt(&sc->sc_calib_to, NULL); 3259 3260 s = splusb(); 3261 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 3262 otus_wait_async(sc); 3263 splx(s); 3264 3265 /* Stop Rx. */ 3266 mutex_enter(&sc->sc_write_mtx); 3267 otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_OFF); 3268 (void)otus_write_barrier(sc); 3269 mutex_exit(&sc->sc_write_mtx); 3270 } 3271