1 /* $NetBSD: if_otus.c,v 1.30 2016/11/25 12:56:29 skrll 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.30 2016/11/25 12:56:29 skrll 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=0x%x product=0x%x revision=0x%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 mutex_init(&sc->sc_cmd_mtx, MUTEX_DEFAULT, IPL_NONE); 634 mutex_init(&sc->sc_task_mtx, MUTEX_DEFAULT, IPL_NET); 635 mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_NONE); 636 mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE); 637 638 usb_init_task(&sc->sc_task, otus_task, sc, 0); 639 640 callout_init(&sc->sc_scan_to, 0); 641 callout_setfunc(&sc->sc_scan_to, otus_next_scan, sc); 642 callout_init(&sc->sc_calib_to, 0); 643 callout_setfunc(&sc->sc_calib_to, otus_calib_to, sc); 644 645 sc->sc_amrr.amrr_min_success_threshold = 1; 646 sc->sc_amrr.amrr_max_success_threshold = 10; 647 648 if (usbd_set_config_no(sc->sc_udev, 1, 0) != 0) { 649 aprint_error_dev(sc->sc_dev, 650 "could not set configuration no\n"); 651 return; 652 } 653 654 /* Get the first interface handle. */ 655 error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface); 656 if (error != 0) { 657 aprint_error_dev(sc->sc_dev, 658 "could not get interface handle\n"); 659 return; 660 } 661 662 if ((error = otus_open_pipes(sc)) != 0) { 663 aprint_error_dev(sc->sc_dev, "could not open pipes\n"); 664 return; 665 } 666 667 /* 668 * We need the firmware loaded from file system to complete the attach. 669 */ 670 config_mountroot(self, otus_attachhook); 671 672 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 673 } 674 675 Static void 676 otus_wait_async(struct otus_softc *sc) 677 { 678 679 DPRINTFN(DBG_FN, sc, "\n"); 680 681 while (sc->sc_cmdq.queued > 0) 682 tsleep(&sc->sc_cmdq, 0, "sc_cmdq", 0); 683 } 684 685 Static int 686 otus_detach(device_t self, int flags) 687 { 688 struct otus_softc *sc; 689 struct ifnet *ifp; 690 int s; 691 692 sc = device_private(self); 693 694 DPRINTFN(DBG_FN, sc, "\n"); 695 696 s = splusb(); 697 698 sc->sc_dying = 1; 699 700 ifp = sc->sc_ic.ic_ifp; 701 if (ifp != NULL) /* Failed to attach properly */ 702 otus_stop(ifp); 703 704 usb_rem_task(sc->sc_udev, &sc->sc_task); 705 callout_destroy(&sc->sc_scan_to); 706 callout_destroy(&sc->sc_calib_to); 707 708 if (ifp && ifp->if_flags != 0) { /* if_attach() has been called. */ 709 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 710 bpf_detach(ifp); 711 ieee80211_ifdetach(&sc->sc_ic); 712 if_detach(ifp); 713 } 714 otus_close_pipes(sc); 715 splx(s); 716 717 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 718 719 mutex_destroy(&sc->sc_write_mtx); 720 mutex_destroy(&sc->sc_tx_mtx); 721 mutex_destroy(&sc->sc_task_mtx); 722 mutex_destroy(&sc->sc_cmd_mtx); 723 return 0; 724 } 725 726 Static int 727 otus_activate(device_t self, devact_t act) 728 { 729 struct otus_softc *sc; 730 731 sc = device_private(self); 732 733 DPRINTFN(DBG_FN, sc, "%d\n", act); 734 735 switch (act) { 736 case DVACT_DEACTIVATE: 737 sc->sc_dying = 1; 738 if_deactivate(sc->sc_ic.ic_ifp); 739 return 0; 740 default: 741 return EOPNOTSUPP; 742 } 743 } 744 745 Static void 746 otus_attachhook(device_t arg) 747 { 748 struct otus_softc *sc; 749 struct ieee80211com *ic; 750 struct ifnet *ifp; 751 usb_device_request_t req; 752 uint32_t in, out; 753 int error; 754 755 sc = device_private(arg); 756 757 DPRINTFN(DBG_FN, sc, "\n"); 758 759 ic = &sc->sc_ic; 760 ifp = &sc->sc_if; 761 762 error = otus_load_firmware(sc, "otus-init", AR_FW_INIT_ADDR); 763 if (error != 0) { 764 aprint_error_dev(sc->sc_dev, "could not load init firmware\n"); 765 return; 766 } 767 usbd_delay_ms(sc->sc_udev, 1000); 768 769 error = otus_load_firmware(sc, "otus-main", AR_FW_MAIN_ADDR); 770 if (error != 0) { 771 aprint_error_dev(sc->sc_dev, "could not load main firmware\n"); 772 return; 773 } 774 775 /* Tell device that firmware transfer is complete. */ 776 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 777 req.bRequest = AR_FW_DOWNLOAD_COMPLETE; 778 USETW(req.wValue, 0); 779 USETW(req.wIndex, 0); 780 USETW(req.wLength, 0); 781 if (usbd_do_request(sc->sc_udev, &req, NULL) != 0) { 782 aprint_error_dev(sc->sc_dev, 783 "firmware initialization failed\n"); 784 return; 785 } 786 787 /* Send an ECHO command to check that everything is settled. */ 788 in = 0xbadc0ffe; 789 if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof(in), &out) != 0) { 790 aprint_error_dev(sc->sc_dev, "echo command failed\n"); 791 return; 792 } 793 if (in != out) { 794 aprint_error_dev(sc->sc_dev, 795 "echo reply mismatch: 0x%08x!=0x%08x\n", in, out); 796 return; 797 } 798 799 /* Read entire EEPROM. */ 800 if (otus_read_eeprom(sc) != 0) { 801 aprint_error_dev(sc->sc_dev, "could not read EEPROM\n"); 802 return; 803 } 804 805 sc->sc_txmask = sc->sc_eeprom.baseEepHeader.txMask; 806 sc->sc_rxmask = sc->sc_eeprom.baseEepHeader.rxMask; 807 sc->sc_capflags = sc->sc_eeprom.baseEepHeader.opCapFlags; 808 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_eeprom.baseEepHeader.macAddr); 809 sc->sc_led_newstate = otus_led_newstate_type3; /* XXX */ 810 811 aprint_normal_dev(sc->sc_dev, 812 "MAC/BBP AR9170, RF AR%X, MIMO %dT%dR, address %s\n", 813 (sc->sc_capflags & AR5416_OPFLAGS_11A) ? 814 0x9104 : ((sc->sc_txmask == 0x5) ? 0x9102 : 0x9101), 815 (sc->sc_txmask == 0x5) ? 2 : 1, (sc->sc_rxmask == 0x5) ? 2 : 1, 816 ether_sprintf(ic->ic_myaddr)); 817 818 /* 819 * Setup the 802.11 device. 820 */ 821 ic->ic_ifp = ifp; 822 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 823 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 824 ic->ic_state = IEEE80211_S_INIT; 825 826 /* Set device capabilities. */ 827 ic->ic_caps = 828 IEEE80211_C_MONITOR | /* monitor mode supported */ 829 IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 830 IEEE80211_C_SHSLOT | /* short slot time supported */ 831 IEEE80211_C_WPA; /* 802.11i */ 832 833 if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { 834 /* Set supported .11b and .11g rates. */ 835 ic->ic_sup_rates[IEEE80211_MODE_11B] = 836 ieee80211_std_rateset_11b; 837 ic->ic_sup_rates[IEEE80211_MODE_11G] = 838 ieee80211_std_rateset_11g; 839 } 840 if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { 841 /* Set supported .11a rates. */ 842 ic->ic_sup_rates[IEEE80211_MODE_11A] = 843 ieee80211_std_rateset_11a; 844 } 845 846 /* Build the list of supported channels. */ 847 otus_get_chanlist(sc); 848 849 ifp->if_softc = sc; 850 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 851 ifp->if_init = otus_init; 852 ifp->if_ioctl = otus_ioctl; 853 ifp->if_start = otus_start; 854 ifp->if_watchdog = otus_watchdog; 855 IFQ_SET_READY(&ifp->if_snd); 856 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 857 858 if_attach(ifp); 859 860 ieee80211_ifattach(ic); 861 862 ic->ic_node_alloc = otus_node_alloc; 863 ic->ic_newassoc = otus_newassoc; 864 ic->ic_updateslot = otus_updateslot; 865 #ifdef HAVE_EDCA 866 ic->ic_updateedca = otus_updateedca; 867 #endif /* HAVE_EDCA */ 868 #ifdef notyet 869 ic->ic_set_key = otus_set_key; 870 ic->ic_delete_key = otus_delete_key; 871 #endif /* notyet */ 872 873 /* Override state transition machine. */ 874 sc->sc_newstate = ic->ic_newstate; 875 ic->ic_newstate = otus_newstate; 876 ieee80211_media_init(ic, otus_media_change, ieee80211_media_status); 877 878 bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 879 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, 880 &sc->sc_drvbpf); 881 882 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); 883 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 884 sc->sc_rxtap.wr_ihdr.it_present = htole32(OTUS_RX_RADIOTAP_PRESENT); 885 886 sc->sc_txtap_len = sizeof(sc->sc_txtapu); 887 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 888 sc->sc_txtap.wt_ihdr.it_present = htole32(OTUS_TX_RADIOTAP_PRESENT); 889 890 ieee80211_announce(ic); 891 } 892 893 Static void 894 otus_get_chanlist(struct otus_softc *sc) 895 { 896 struct ieee80211com *ic; 897 uint8_t chan; 898 int i; 899 900 #ifdef OTUS_DEBUG 901 /* XXX regulatory domain. */ 902 uint16_t domain = le16toh(sc->sc_eeprom.baseEepHeader.regDmn[0]); 903 904 DPRINTFN(DBG_FN|DBG_INIT, sc, "regdomain=0x%04x\n", domain); 905 #endif 906 907 ic = &sc->sc_ic; 908 if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { 909 for (i = 0; i < 14; i++) { 910 chan = ar_chans[i]; 911 ic->ic_channels[chan].ic_freq = 912 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); 913 ic->ic_channels[chan].ic_flags = 914 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 915 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 916 } 917 } 918 if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { 919 for (i = 14; i < __arraycount(ar_chans); i++) { 920 chan = ar_chans[i]; 921 ic->ic_channels[chan].ic_freq = 922 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ); 923 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A; 924 } 925 } 926 } 927 928 Static int 929 otus_load_firmware(struct otus_softc *sc, const char *name, uint32_t addr) 930 { 931 usb_device_request_t req; 932 firmware_handle_t fh; 933 uint8_t *ptr; 934 uint8_t *fw; 935 size_t size; 936 int mlen, error; 937 938 DPRINTFN(DBG_FN, sc, "\n"); 939 940 if ((error = firmware_open("if_otus", name, &fh)) != 0) 941 return error; 942 943 size = firmware_get_size(fh); 944 if ((fw = firmware_malloc(size)) == NULL) { 945 firmware_close(fh); 946 return ENOMEM; 947 } 948 if ((error = firmware_read(fh, 0, fw, size)) != 0) 949 firmware_free(fw, size); 950 firmware_close(fh); 951 if (error) 952 return error; 953 954 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 955 req.bRequest = AR_FW_DOWNLOAD; 956 USETW(req.wIndex, 0); 957 958 ptr = fw; 959 addr >>= 8; 960 while (size > 0) { 961 mlen = MIN(size, 4096); 962 963 USETW(req.wValue, addr); 964 USETW(req.wLength, mlen); 965 if (usbd_do_request(sc->sc_udev, &req, ptr) != 0) { 966 error = EIO; 967 break; 968 } 969 addr += mlen >> 8; 970 ptr += mlen; 971 size -= mlen; 972 } 973 free(fw, M_DEVBUF); 974 return error; 975 } 976 977 Static int 978 otus_open_pipes(struct otus_softc *sc) 979 { 980 usb_endpoint_descriptor_t *ed; 981 int i, error; 982 983 DPRINTFN(DBG_FN, sc, "\n"); 984 985 error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_RX_NO, 0, 986 &sc->sc_data_rx_pipe); 987 if (error != 0) { 988 aprint_error_dev(sc->sc_dev, "could not open Rx bulk pipe\n"); 989 goto fail; 990 } 991 992 ed = usbd_get_endpoint_descriptor(sc->sc_iface, AR_EPT_INTR_RX_NO); 993 if (ed == NULL) { 994 aprint_error_dev(sc->sc_dev, 995 "could not retrieve Rx intr pipe descriptor\n"); 996 goto fail; 997 } 998 sc->sc_ibuf_size = UGETW(ed->wMaxPacketSize); 999 if (sc->sc_ibuf_size == 0) { 1000 aprint_error_dev(sc->sc_dev, 1001 "invalid Rx intr pipe descriptor\n"); 1002 goto fail; 1003 } 1004 sc->sc_ibuf = kmem_alloc(sc->sc_ibuf_size, KM_SLEEP); 1005 if (sc->sc_ibuf == NULL) { 1006 aprint_error_dev(sc->sc_dev, 1007 "could not allocate Rx intr buffer\n"); 1008 goto fail; 1009 } 1010 error = usbd_open_pipe_intr(sc->sc_iface, AR_EPT_INTR_RX_NO, 1011 USBD_SHORT_XFER_OK, &sc->sc_cmd_rx_pipe, sc, sc->sc_ibuf, 1012 sc->sc_ibuf_size, otus_intr, USBD_DEFAULT_INTERVAL); 1013 if (error != 0) { 1014 aprint_error_dev(sc->sc_dev, "could not open Rx intr pipe\n"); 1015 goto fail; 1016 } 1017 1018 error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_TX_NO, 0, 1019 &sc->sc_data_tx_pipe); 1020 if (error != 0) { 1021 aprint_error_dev(sc->sc_dev, "could not open Tx bulk pipe\n"); 1022 goto fail; 1023 } 1024 1025 error = usbd_open_pipe(sc->sc_iface, AR_EPT_INTR_TX_NO, 0, 1026 &sc->sc_cmd_tx_pipe); 1027 if (error != 0) { 1028 aprint_error_dev(sc->sc_dev, "could not open Tx intr pipe\n"); 1029 goto fail; 1030 } 1031 1032 if (otus_alloc_tx_cmd(sc) != 0) { 1033 aprint_error_dev(sc->sc_dev, 1034 "could not allocate command xfer\n"); 1035 goto fail; 1036 } 1037 1038 if (otus_alloc_tx_data_list(sc)) { 1039 aprint_error_dev(sc->sc_dev, "could not allocate Tx xfers\n"); 1040 goto fail; 1041 } 1042 1043 if (otus_alloc_rx_data_list(sc)) { 1044 aprint_error_dev(sc->sc_dev, "could not allocate Rx xfers\n"); 1045 goto fail; 1046 } 1047 1048 for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) { 1049 struct otus_rx_data *data = &sc->sc_rx_data[i]; 1050 1051 usbd_setup_xfer(data->xfer, data, data->buf, OTUS_RXBUFSZ, 1052 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof); 1053 error = usbd_transfer(data->xfer); 1054 if (error != USBD_IN_PROGRESS && error != 0) { 1055 aprint_error_dev(sc->sc_dev, 1056 "could not queue Rx xfer\n"); 1057 goto fail; 1058 } 1059 } 1060 return 0; 1061 1062 fail: otus_close_pipes(sc); 1063 return error; 1064 } 1065 1066 Static void 1067 otus_close_pipes(struct otus_softc *sc) 1068 { 1069 1070 DPRINTFN(DBG_FN, sc, "\n"); 1071 1072 otus_free_tx_cmd(sc); 1073 otus_free_tx_data_list(sc); 1074 otus_free_rx_data_list(sc); 1075 1076 if (sc->sc_data_rx_pipe != NULL) 1077 usbd_close_pipe(sc->sc_data_rx_pipe); 1078 if (sc->sc_cmd_rx_pipe != NULL) { 1079 usbd_abort_pipe(sc->sc_cmd_rx_pipe); 1080 usbd_close_pipe(sc->sc_cmd_rx_pipe); 1081 } 1082 if (sc->sc_ibuf != NULL) 1083 kmem_free(sc->sc_ibuf, sc->sc_ibuf_size); 1084 if (sc->sc_data_tx_pipe != NULL) 1085 usbd_close_pipe(sc->sc_data_tx_pipe); 1086 if (sc->sc_cmd_tx_pipe != NULL) 1087 usbd_close_pipe(sc->sc_cmd_tx_pipe); 1088 } 1089 1090 Static int 1091 otus_alloc_tx_cmd(struct otus_softc *sc) 1092 { 1093 struct otus_tx_cmd *cmd; 1094 1095 DPRINTFN(DBG_FN, sc, "\n"); 1096 1097 cmd = &sc->sc_tx_cmd; 1098 1099 int error = usbd_create_xfer(sc->sc_cmd_tx_pipe, OTUS_MAX_TXCMDSZ, 1100 USBD_FORCE_SHORT_XFER, 0, &cmd->xfer); 1101 if (error) 1102 return error; 1103 1104 cmd->buf = usbd_get_buffer(cmd->xfer); 1105 1106 return 0; 1107 } 1108 1109 Static void 1110 otus_free_tx_cmd(struct otus_softc *sc) 1111 { 1112 1113 DPRINTFN(DBG_FN, sc, "\n"); 1114 1115 /* Make sure no transfers are pending. */ 1116 usbd_abort_pipe(sc->sc_cmd_tx_pipe); 1117 1118 mutex_enter(&sc->sc_cmd_mtx); 1119 if (sc->sc_tx_cmd.xfer != NULL) 1120 usbd_destroy_xfer(sc->sc_tx_cmd.xfer); 1121 sc->sc_tx_cmd.xfer = NULL; 1122 sc->sc_tx_cmd.buf = NULL; 1123 mutex_exit(&sc->sc_cmd_mtx); 1124 } 1125 1126 Static int 1127 otus_alloc_tx_data_list(struct otus_softc *sc) 1128 { 1129 struct otus_tx_data *data; 1130 int i, error; 1131 1132 DPRINTFN(DBG_FN, sc, "\n"); 1133 1134 mutex_enter(&sc->sc_tx_mtx); 1135 error = 0; 1136 TAILQ_INIT(&sc->sc_tx_free_list); 1137 for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) { 1138 data = &sc->sc_tx_data[i]; 1139 1140 data->sc = sc; /* Backpointer for callbacks. */ 1141 1142 error = usbd_create_xfer(sc->sc_data_tx_pipe, OTUS_TXBUFSZ, 1143 USBD_FORCE_SHORT_XFER, 0, &data->xfer); 1144 if (error) { 1145 aprint_error_dev(sc->sc_dev, 1146 "could not allocate xfer\n"); 1147 break; 1148 } 1149 data->buf = usbd_get_buffer(data->xfer); 1150 /* Append this Tx buffer to our free list. */ 1151 TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next); 1152 } 1153 if (error != 0) 1154 otus_free_tx_data_list(sc); 1155 mutex_exit(&sc->sc_tx_mtx); 1156 return error; 1157 } 1158 1159 Static void 1160 otus_free_tx_data_list(struct otus_softc *sc) 1161 { 1162 int i; 1163 1164 DPRINTFN(DBG_FN, sc, "\n"); 1165 1166 /* Make sure no transfers are pending. */ 1167 usbd_abort_pipe(sc->sc_data_tx_pipe); 1168 1169 for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) { 1170 if (sc->sc_tx_data[i].xfer != NULL) 1171 usbd_destroy_xfer(sc->sc_tx_data[i].xfer); 1172 } 1173 } 1174 1175 Static int 1176 otus_alloc_rx_data_list(struct otus_softc *sc) 1177 { 1178 struct otus_rx_data *data; 1179 int i, error; 1180 1181 DPRINTFN(DBG_FN, sc, "\n"); 1182 1183 for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) { 1184 data = &sc->sc_rx_data[i]; 1185 1186 data->sc = sc; /* Backpointer for callbacks. */ 1187 1188 error = usbd_create_xfer(sc->sc_data_rx_pipe, OTUS_RXBUFSZ, 1189 USBD_SHORT_XFER_OK, 0, &data->xfer); 1190 1191 if (error) { 1192 aprint_error_dev(sc->sc_dev, 1193 "could not allocate xfer\n"); 1194 goto fail; 1195 } 1196 data->buf = usbd_get_buffer(data->xfer); 1197 } 1198 return 0; 1199 1200 fail: otus_free_rx_data_list(sc); 1201 return error; 1202 } 1203 1204 Static void 1205 otus_free_rx_data_list(struct otus_softc *sc) 1206 { 1207 int i; 1208 1209 DPRINTFN(DBG_FN, sc, "\n"); 1210 1211 /* Make sure no transfers are pending. */ 1212 usbd_abort_pipe(sc->sc_data_rx_pipe); 1213 1214 for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) 1215 if (sc->sc_rx_data[i].xfer != NULL) 1216 usbd_destroy_xfer(sc->sc_rx_data[i].xfer); 1217 } 1218 1219 Static void 1220 otus_next_scan(void *arg) 1221 { 1222 struct otus_softc *sc; 1223 1224 sc = arg; 1225 1226 DPRINTFN(DBG_FN, sc, "\n"); 1227 1228 if (sc->sc_dying) 1229 return; 1230 1231 if (sc->sc_ic.ic_state == IEEE80211_S_SCAN) 1232 ieee80211_next_scan(&sc->sc_ic); 1233 } 1234 1235 Static void 1236 otus_task(void *arg) 1237 { 1238 struct otus_softc *sc; 1239 struct otus_host_cmd_ring *ring; 1240 struct otus_host_cmd *cmd; 1241 int s; 1242 1243 sc = arg; 1244 1245 DPRINTFN(DBG_FN, sc, "\n"); 1246 1247 /* Process host commands. */ 1248 s = splusb(); 1249 mutex_spin_enter(&sc->sc_task_mtx); 1250 ring = &sc->sc_cmdq; 1251 while (ring->next != ring->cur) { 1252 cmd = &ring->cmd[ring->next]; 1253 mutex_spin_exit(&sc->sc_task_mtx); 1254 splx(s); 1255 1256 /* Callback. */ 1257 DPRINTFN(DBG_CMD, sc, "cb=%p queued=%d\n", cmd->cb, 1258 ring->queued); 1259 cmd->cb(sc, cmd->data); 1260 1261 s = splusb(); 1262 mutex_spin_enter(&sc->sc_task_mtx); 1263 ring->queued--; 1264 ring->next = (ring->next + 1) % OTUS_HOST_CMD_RING_COUNT; 1265 } 1266 mutex_spin_exit(&sc->sc_task_mtx); 1267 wakeup(ring); 1268 splx(s); 1269 } 1270 1271 Static void 1272 otus_do_async(struct otus_softc *sc, void (*cb)(struct otus_softc *, void *), 1273 void *arg, int len) 1274 { 1275 struct otus_host_cmd_ring *ring; 1276 struct otus_host_cmd *cmd; 1277 int s; 1278 1279 DPRINTFN(DBG_FN, sc, "cb=%p\n", cb); 1280 1281 1282 s = splusb(); 1283 mutex_spin_enter(&sc->sc_task_mtx); 1284 ring = &sc->sc_cmdq; 1285 cmd = &ring->cmd[ring->cur]; 1286 cmd->cb = cb; 1287 KASSERT(len <= sizeof(cmd->data)); 1288 memcpy(cmd->data, arg, len); 1289 ring->cur = (ring->cur + 1) % OTUS_HOST_CMD_RING_COUNT; 1290 1291 /* If there is no pending command already, schedule a task. */ 1292 if (++ring->queued == 1) { 1293 mutex_spin_exit(&sc->sc_task_mtx); 1294 usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); 1295 } 1296 else 1297 mutex_spin_exit(&sc->sc_task_mtx); 1298 wakeup(ring); 1299 splx(s); 1300 } 1301 1302 Static int 1303 otus_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1304 { 1305 struct otus_softc *sc; 1306 struct otus_cmd_newstate cmd; 1307 1308 sc = ic->ic_ifp->if_softc; 1309 1310 DPRINTFN(DBG_FN|DBG_STM, sc, "nstate=%s(%d), arg=%d\n", 1311 ieee80211_state_name[nstate], nstate, arg); 1312 1313 /* Do it in a process context. */ 1314 cmd.state = nstate; 1315 cmd.arg = arg; 1316 otus_do_async(sc, otus_newstate_cb, &cmd, sizeof(cmd)); 1317 return 0; 1318 } 1319 1320 Static void 1321 otus_newstate_cb(struct otus_softc *sc, void *arg) 1322 { 1323 struct otus_cmd_newstate *cmd; 1324 struct ieee80211com *ic; 1325 struct ieee80211_node *ni; 1326 enum ieee80211_state nstate; 1327 int s; 1328 1329 cmd = arg; 1330 ic = &sc->sc_ic; 1331 ni = ic->ic_bss; 1332 nstate = cmd->state; 1333 1334 #ifdef OTUS_DEBUG 1335 enum ieee80211_state ostate = ostate = ic->ic_state; 1336 DPRINTFN(DBG_FN|DBG_STM, sc, "%s(%d)->%s(%d)\n", 1337 ieee80211_state_name[ostate], ostate, 1338 ieee80211_state_name[nstate], nstate); 1339 #endif 1340 1341 s = splnet(); 1342 1343 callout_halt(&sc->sc_scan_to, NULL); 1344 callout_halt(&sc->sc_calib_to, NULL); 1345 1346 mutex_enter(&sc->sc_write_mtx); 1347 1348 switch (nstate) { 1349 case IEEE80211_S_INIT: 1350 break; 1351 1352 case IEEE80211_S_SCAN: 1353 otus_set_chan(sc, ic->ic_curchan, 0); 1354 if (!sc->sc_dying) 1355 callout_schedule(&sc->sc_scan_to, hz / 5); 1356 break; 1357 1358 case IEEE80211_S_AUTH: 1359 case IEEE80211_S_ASSOC: 1360 otus_set_chan(sc, ic->ic_curchan, 0); 1361 break; 1362 1363 case IEEE80211_S_RUN: 1364 otus_set_chan(sc, ic->ic_curchan, 1); 1365 1366 switch (ic->ic_opmode) { 1367 case IEEE80211_M_STA: 1368 otus_updateslot_cb_locked(sc); 1369 otus_set_bssid(sc, ni->ni_bssid); 1370 1371 /* Fake a join to init the Tx rate. */ 1372 otus_newassoc(ni, 1); 1373 1374 /* Start calibration timer. */ 1375 if (!sc->sc_dying) 1376 callout_schedule(&sc->sc_calib_to, hz); 1377 break; 1378 1379 case IEEE80211_M_IBSS: 1380 case IEEE80211_M_AHDEMO: 1381 case IEEE80211_M_HOSTAP: 1382 case IEEE80211_M_MONITOR: 1383 break; 1384 } 1385 break; 1386 } 1387 (void)sc->sc_newstate(ic, nstate, cmd->arg); 1388 sc->sc_led_newstate(sc); 1389 mutex_exit(&sc->sc_write_mtx); 1390 1391 splx(s); 1392 } 1393 1394 Static int 1395 otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen, 1396 void *odata) 1397 { 1398 struct otus_tx_cmd *cmd; 1399 struct ar_cmd_hdr *hdr; 1400 int s, xferlen, error; 1401 1402 DPRINTFN(DBG_FN, sc, "\n"); 1403 1404 cmd = &sc->sc_tx_cmd; 1405 1406 mutex_enter(&sc->sc_cmd_mtx); 1407 1408 /* Always bulk-out a multiple of 4 bytes. */ 1409 xferlen = roundup2(sizeof(*hdr) + ilen, 4); 1410 1411 hdr = (void *)cmd->buf; 1412 if (hdr == NULL) { /* we may have been freed while detaching */ 1413 mutex_exit(&sc->sc_cmd_mtx); 1414 DPRINTFN(DBG_CMD, sc, "tx_cmd freed with commands pending\n"); 1415 return 0; 1416 } 1417 hdr->code = code; 1418 hdr->len = ilen; 1419 hdr->token = ++cmd->token; /* Don't care about endianness. */ 1420 KASSERT(sizeof(hdr) + ilen <= OTUS_MAX_TXCMDSZ); 1421 memcpy(cmd->buf + sizeof(hdr[0]), idata, ilen); 1422 1423 DPRINTFN(DBG_CMD, sc, "sending command code=0x%02x len=%d token=%d\n", 1424 code, ilen, hdr->token); 1425 1426 s = splusb(); 1427 cmd->odata = odata; 1428 cmd->done = 0; 1429 usbd_setup_xfer(cmd->xfer, cmd, cmd->buf, xferlen, 1430 USBD_FORCE_SHORT_XFER, OTUS_CMD_TIMEOUT, NULL); 1431 error = usbd_sync_transfer(cmd->xfer); 1432 if (error != 0) { 1433 splx(s); 1434 mutex_exit(&sc->sc_cmd_mtx); 1435 #if defined(DIAGNOSTIC) || defined(OTUS_DEBUG) /* XXX: kill some noise */ 1436 aprint_error_dev(sc->sc_dev, 1437 "could not send command 0x%x (error=%s)\n", 1438 code, usbd_errstr(error)); 1439 #endif 1440 return EIO; 1441 } 1442 if (!cmd->done) 1443 error = tsleep(cmd, PCATCH, "otuscmd", hz); 1444 cmd->odata = NULL; /* In case answer is received too late. */ 1445 splx(s); 1446 mutex_exit(&sc->sc_cmd_mtx); 1447 if (error != 0) { 1448 aprint_error_dev(sc->sc_dev, 1449 "timeout waiting for command 0x%02x reply\n", code); 1450 } 1451 return error; 1452 } 1453 1454 Static void 1455 otus_write(struct otus_softc *sc, uint32_t reg, uint32_t val) 1456 { 1457 1458 DPRINTFN(DBG_FN|DBG_REG, sc, "reg=0x%x, val=0x%x\n", reg, val); 1459 1460 KASSERT(mutex_owned(&sc->sc_write_mtx)); 1461 KASSERT(sc->sc_write_idx < __arraycount(sc->sc_write_buf)); 1462 1463 sc->sc_write_buf[sc->sc_write_idx].reg = htole32(reg); 1464 sc->sc_write_buf[sc->sc_write_idx].val = htole32(val); 1465 1466 if (++sc->sc_write_idx >= __arraycount(sc->sc_write_buf)) 1467 (void)otus_write_barrier(sc); 1468 } 1469 1470 Static int 1471 otus_write_barrier(struct otus_softc *sc) 1472 { 1473 int error; 1474 1475 DPRINTFN(DBG_FN, sc, "\n"); 1476 1477 KASSERT(mutex_owned(&sc->sc_write_mtx)); 1478 KASSERT(sc->sc_write_idx <= __arraycount(sc->sc_write_buf)); 1479 1480 if (sc->sc_write_idx == 0) 1481 return 0; /* Nothing to flush. */ 1482 1483 error = otus_cmd(sc, AR_CMD_WREG, sc->sc_write_buf, 1484 sizeof(sc->sc_write_buf[0]) * sc->sc_write_idx, NULL); 1485 1486 sc->sc_write_idx = 0; 1487 if (error) 1488 DPRINTFN(DBG_REG, sc, "error=%d\n", error); 1489 return error; 1490 } 1491 1492 Static struct ieee80211_node * 1493 otus_node_alloc(struct ieee80211_node_table *ntp) 1494 { 1495 struct otus_node *on; 1496 1497 DPRINTFN(DBG_FN, DBG_NO_SC, "\n"); 1498 1499 on = malloc(sizeof(*on), M_DEVBUF, M_NOWAIT | M_ZERO); 1500 return &on->ni; 1501 } 1502 1503 Static int 1504 otus_media_change(struct ifnet *ifp) 1505 { 1506 struct otus_softc *sc; 1507 struct ieee80211com *ic; 1508 uint8_t rate, ridx; 1509 int error; 1510 1511 sc = ifp->if_softc; 1512 1513 DPRINTFN(DBG_FN, sc, "\n"); 1514 1515 error = ieee80211_media_change(ifp); 1516 if (error != ENETRESET) 1517 return error; 1518 1519 ic = &sc->sc_ic; 1520 if (ic->ic_fixed_rate != -1) { 1521 rate = ic->ic_sup_rates[ic->ic_curmode]. 1522 rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 1523 for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++) 1524 if (otus_rates[ridx].rate == rate) 1525 break; 1526 sc->sc_fixed_ridx = ridx; 1527 } 1528 1529 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) 1530 error = otus_init(ifp); 1531 1532 return error; 1533 } 1534 1535 Static int 1536 otus_read_eeprom(struct otus_softc *sc) 1537 { 1538 uint32_t regs[8], reg; 1539 uint8_t *eep; 1540 int i, j, error; 1541 1542 DPRINTFN(DBG_FN, sc, "\n"); 1543 1544 KASSERT(sizeof(sc->sc_eeprom) % 32 == 0); 1545 1546 /* Read EEPROM by blocks of 32 bytes. */ 1547 eep = (uint8_t *)&sc->sc_eeprom; 1548 reg = AR_EEPROM_OFFSET; 1549 for (i = 0; i < sizeof(sc->sc_eeprom) / 32; i++) { 1550 for (j = 0; j < 8; j++, reg += 4) 1551 regs[j] = htole32(reg); 1552 error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof(regs), eep); 1553 if (error != 0) 1554 break; 1555 eep += 32; 1556 } 1557 return error; 1558 } 1559 1560 Static void 1561 otus_newassoc(struct ieee80211_node *ni, int isnew) 1562 { 1563 struct ieee80211_rateset *rs; 1564 struct otus_softc *sc; 1565 struct otus_node *on; 1566 uint8_t rate; 1567 int ridx, i; 1568 1569 sc = ni->ni_ic->ic_ifp->if_softc; 1570 1571 DPRINTFN(DBG_FN, sc, "isnew=%d addr=%s\n", 1572 isnew, ether_sprintf(ni->ni_macaddr)); 1573 1574 on = (void *)ni; 1575 ieee80211_amrr_node_init(&sc->sc_amrr, &on->amn); 1576 /* Start at lowest available bit-rate, AMRR will raise. */ 1577 ni->ni_txrate = 0; 1578 rs = &ni->ni_rates; 1579 for (i = 0; i < rs->rs_nrates; i++) { 1580 rate = rs->rs_rates[i] & IEEE80211_RATE_VAL; 1581 /* Convert 802.11 rate to hardware rate index. */ 1582 for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++) 1583 if (otus_rates[ridx].rate == rate) 1584 break; 1585 on->ridx[i] = ridx; 1586 DPRINTFN(DBG_INIT, sc, "rate=0x%02x ridx=%d\n", 1587 rs->rs_rates[i], on->ridx[i]); 1588 } 1589 } 1590 1591 /* ARGSUSED */ 1592 Static void 1593 otus_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) 1594 { 1595 #if 0 1596 struct otus_softc *sc; 1597 int len; 1598 1599 sc = priv; 1600 1601 DPRINTFN(DBG_FN, sc, "\n"); 1602 1603 /* 1604 * The Rx intr pipe is unused with current firmware. Notifications 1605 * and replies to commands are sent through the Rx bulk pipe instead 1606 * (with a magic PLCP header.) 1607 */ 1608 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1609 DPRINTFN(DBG_INTR, sc, "status=%d\n", status); 1610 if (status == USBD_STALLED) 1611 usbd_clear_endpoint_stall_async(sc->sc_cmd_rx_pipe); 1612 return; 1613 } 1614 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1615 1616 otus_cmd_rxeof(sc, sc->sc_ibuf, len); 1617 #endif 1618 } 1619 1620 Static void 1621 otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len) 1622 { 1623 struct ieee80211com *ic; 1624 struct otus_tx_cmd *cmd; 1625 struct ar_cmd_hdr *hdr; 1626 int s; 1627 1628 DPRINTFN(DBG_FN, sc, "\n"); 1629 1630 ic = &sc->sc_ic; 1631 1632 if (__predict_false(len < sizeof(*hdr))) { 1633 DPRINTFN(DBG_RX, sc, "cmd too small %d\n", len); 1634 return; 1635 } 1636 hdr = (void *)buf; 1637 if (__predict_false(sizeof(*hdr) + hdr->len > len || 1638 sizeof(*hdr) + hdr->len > 64)) { 1639 DPRINTFN(DBG_RX, sc, "cmd too large %d\n", hdr->len); 1640 return; 1641 } 1642 1643 if ((hdr->code & 0xc0) != 0xc0) { 1644 DPRINTFN(DBG_RX, sc, "received reply code=0x%02x len=%d token=%d\n", 1645 hdr->code, hdr->len, hdr->token); 1646 cmd = &sc->sc_tx_cmd; 1647 if (__predict_false(hdr->token != cmd->token)) 1648 return; 1649 /* Copy answer into caller's supplied buffer. */ 1650 if (cmd->odata != NULL) 1651 memcpy(cmd->odata, &hdr[1], hdr->len); 1652 cmd->done = 1; 1653 wakeup(cmd); 1654 return; 1655 } 1656 1657 /* Received unsolicited notification. */ 1658 DPRINTFN(DBG_RX, sc, "received notification code=0x%02x len=%d\n", 1659 hdr->code, hdr->len); 1660 switch (hdr->code & 0x3f) { 1661 case AR_EVT_BEACON: 1662 break; 1663 case AR_EVT_TX_COMP: 1664 { 1665 struct ar_evt_tx_comp *tx; 1666 struct ieee80211_node *ni; 1667 struct otus_node *on; 1668 1669 tx = (void *)&hdr[1]; 1670 1671 DPRINTFN(DBG_RX, sc, "tx completed %s status=%d phy=0x%x\n", 1672 ether_sprintf(tx->macaddr), le16toh(tx->status), 1673 le32toh(tx->phy)); 1674 s = splnet(); 1675 #ifdef notyet 1676 #ifndef IEEE80211_STA_ONLY 1677 if (ic->ic_opmode != IEEE80211_M_STA) { 1678 ni = ieee80211_find_node(ic, tx->macaddr); 1679 if (__predict_false(ni == NULL)) { 1680 splx(s); 1681 break; 1682 } 1683 } else 1684 #endif 1685 #endif 1686 ni = ic->ic_bss; 1687 /* Update rate control statistics. */ 1688 on = (void *)ni; 1689 /* NB: we do not set the TX_MAC_RATE_PROBING flag. */ 1690 if (__predict_true(tx->status != 0)) 1691 on->amn.amn_retrycnt++; 1692 splx(s); 1693 break; 1694 } 1695 case AR_EVT_TBTT: 1696 break; 1697 } 1698 } 1699 1700 Static void 1701 otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len) 1702 { 1703 struct ieee80211com *ic; 1704 struct ifnet *ifp; 1705 struct ieee80211_node *ni; 1706 struct ar_rx_tail *tail; 1707 struct ieee80211_frame *wh; 1708 struct mbuf *m; 1709 uint8_t *plcp; 1710 int s, mlen, align; 1711 1712 DPRINTFN(DBG_FN, sc, "\n"); 1713 1714 ic = &sc->sc_ic; 1715 ifp = ic->ic_ifp; 1716 1717 if (__predict_false(len < AR_PLCP_HDR_LEN)) { 1718 DPRINTFN(DBG_RX, sc, "sub-xfer too short %d\n", len); 1719 return; 1720 } 1721 plcp = buf; 1722 1723 /* All bits in the PLCP header are set to 1 for non-MPDU. */ 1724 if (memcmp(plcp, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) { 1725 otus_cmd_rxeof(sc, plcp + AR_PLCP_HDR_LEN, 1726 len - AR_PLCP_HDR_LEN); 1727 return; 1728 } 1729 1730 /* Received MPDU. */ 1731 if (__predict_false(len < AR_PLCP_HDR_LEN + sizeof(*tail))) { 1732 DPRINTFN(DBG_RX, sc, "MPDU too short %d\n", len); 1733 ifp->if_ierrors++; 1734 return; 1735 } 1736 tail = (void *)(plcp + len - sizeof(*tail)); 1737 wh = (void *)(plcp + AR_PLCP_HDR_LEN); 1738 1739 /* Discard error frames. */ 1740 if (__predict_false((tail->error & sc->sc_rx_error_msk) != 0)) { 1741 DPRINTFN(DBG_RX, sc, "error frame 0x%02x\n", tail->error); 1742 if (tail->error & AR_RX_ERROR_FCS) { 1743 DPRINTFN(DBG_RX, sc, "bad FCS\n"); 1744 } else if (tail->error & AR_RX_ERROR_MMIC) { 1745 /* Report Michael MIC failures to net80211. */ 1746 ieee80211_notify_michael_failure(ic, wh, 0 /* XXX: keyix */); 1747 } 1748 ifp->if_ierrors++; 1749 return; 1750 } 1751 /* Compute MPDU's length. */ 1752 mlen = len - AR_PLCP_HDR_LEN - sizeof(*tail); 1753 mlen -= IEEE80211_CRC_LEN; /* strip 802.11 FCS */ 1754 /* Make sure there's room for an 802.11 header. */ 1755 /* 1756 * XXX: This will drop most control packets. Do we really 1757 * want this in IEEE80211_M_MONITOR mode? 1758 */ 1759 if (__predict_false(mlen < sizeof(*wh))) { 1760 ifp->if_ierrors++; 1761 return; 1762 } 1763 1764 /* Provide a 32-bit aligned protocol header to the stack. */ 1765 align = (ieee80211_has_qos(wh) ^ ieee80211_has_addr4(wh)) ? 2 : 0; 1766 1767 MGETHDR(m, M_DONTWAIT, MT_DATA); 1768 if (__predict_false(m == NULL)) { 1769 ifp->if_ierrors++; 1770 return; 1771 } 1772 if (align + mlen > MHLEN) { 1773 MCLGET(m, M_DONTWAIT); 1774 if (__predict_false(!(m->m_flags & M_EXT))) { 1775 ifp->if_ierrors++; 1776 m_freem(m); 1777 return; 1778 } 1779 } 1780 /* Finalize mbuf. */ 1781 m_set_rcvif(m, ifp); 1782 m->m_data += align; 1783 memcpy(mtod(m, void *), wh, mlen); 1784 m->m_pkthdr.len = m->m_len = mlen; 1785 1786 s = splnet(); 1787 if (__predict_false(sc->sc_drvbpf != NULL)) { 1788 struct otus_rx_radiotap_header *tap; 1789 1790 tap = &sc->sc_rxtap; 1791 tap->wr_flags = 0; 1792 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); 1793 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); 1794 tap->wr_antsignal = tail->rssi; 1795 tap->wr_rate = 2; /* In case it can't be found below. */ 1796 switch (tail->status & AR_RX_STATUS_MT_MASK) { 1797 case AR_RX_STATUS_MT_CCK: 1798 switch (plcp[0]) { 1799 case 10: tap->wr_rate = 2; break; 1800 case 20: tap->wr_rate = 4; break; 1801 case 55: tap->wr_rate = 11; break; 1802 case 110: tap->wr_rate = 22; break; 1803 } 1804 if (tail->status & AR_RX_STATUS_SHPREAMBLE) 1805 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 1806 break; 1807 case AR_RX_STATUS_MT_OFDM: 1808 switch (plcp[0] & 0xf) { 1809 case 0xb: tap->wr_rate = 12; break; 1810 case 0xf: tap->wr_rate = 18; break; 1811 case 0xa: tap->wr_rate = 24; break; 1812 case 0xe: tap->wr_rate = 36; break; 1813 case 0x9: tap->wr_rate = 48; break; 1814 case 0xd: tap->wr_rate = 72; break; 1815 case 0x8: tap->wr_rate = 96; break; 1816 case 0xc: tap->wr_rate = 108; break; 1817 } 1818 break; 1819 } 1820 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); 1821 } 1822 1823 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); 1824 1825 /* push the frame up to the 802.11 stack */ 1826 ieee80211_input(ic, m, ni, tail->rssi, 0); 1827 1828 /* Node is no longer needed. */ 1829 ieee80211_free_node(ni); 1830 splx(s); 1831 } 1832 1833 Static void 1834 otus_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1835 { 1836 struct otus_rx_data *data; 1837 struct otus_softc *sc; 1838 uint8_t *buf; 1839 struct ar_rx_head *head; 1840 uint16_t hlen; 1841 int len; 1842 1843 data = priv; 1844 sc = data->sc; 1845 1846 DPRINTFN(DBG_FN, sc, "\n"); 1847 1848 buf = data->buf; 1849 1850 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1851 DPRINTFN(DBG_RX, sc, "RX status=%d\n", status); 1852 if (status == USBD_STALLED) 1853 usbd_clear_endpoint_stall_async(sc->sc_data_rx_pipe); 1854 else if (status != USBD_CANCELLED) { 1855 DPRINTFN(DBG_RX, sc, 1856 "otus_rxeof: goto resubmit: status=%d\n", status); 1857 goto resubmit; 1858 } 1859 return; 1860 } 1861 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1862 1863 while (len >= sizeof(*head)) { 1864 head = (void *)buf; 1865 if (__predict_false(head->tag != htole16(AR_RX_HEAD_TAG))) { 1866 DPRINTFN(DBG_RX, sc, "tag not valid 0x%x\n", 1867 le16toh(head->tag)); 1868 break; 1869 } 1870 hlen = le16toh(head->len); 1871 if (__predict_false(sizeof(*head) + hlen > len)) { 1872 DPRINTFN(DBG_RX, sc, "xfer too short %d/%d\n", 1873 len, hlen); 1874 break; 1875 } 1876 /* Process sub-xfer. */ 1877 otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen); 1878 1879 /* Next sub-xfer is aligned on a 32-bit boundary. */ 1880 hlen = roundup2(sizeof(*head) + hlen, 4); 1881 buf += hlen; 1882 len -= hlen; 1883 } 1884 1885 resubmit: 1886 usbd_setup_xfer(xfer, data, data->buf, OTUS_RXBUFSZ, 1887 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof); 1888 (void)usbd_transfer(data->xfer); 1889 } 1890 1891 Static void 1892 otus_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1893 { 1894 struct otus_tx_data *data; 1895 struct otus_softc *sc; 1896 struct ieee80211com *ic; 1897 struct ifnet *ifp; 1898 int s; 1899 1900 data = priv; 1901 sc = data->sc; 1902 1903 DPRINTFN(DBG_FN, sc, "\n"); 1904 1905 /* Put this Tx buffer back to the free list. */ 1906 mutex_enter(&sc->sc_tx_mtx); 1907 TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next); 1908 mutex_exit(&sc->sc_tx_mtx); 1909 1910 ic = &sc->sc_ic; 1911 ifp = ic->ic_ifp; 1912 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1913 DPRINTFN(DBG_TX, sc, "TX status=%d\n", status); 1914 if (status == USBD_STALLED) 1915 usbd_clear_endpoint_stall_async(sc->sc_data_tx_pipe); 1916 ifp->if_oerrors++; 1917 return; 1918 } 1919 ifp->if_opackets++; 1920 1921 s = splnet(); 1922 sc->sc_tx_timer = 0; 1923 ifp->if_flags &= ~IFF_OACTIVE; /* XXX: do after freeing Tx buffer? */ 1924 otus_start(ifp); 1925 splx(s); 1926 } 1927 1928 Static int 1929 otus_tx(struct otus_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 1930 struct otus_tx_data *data) 1931 { 1932 struct ieee80211com *ic; 1933 struct otus_node *on; 1934 struct ieee80211_frame *wh; 1935 struct ieee80211_key *k; 1936 struct ar_tx_head *head; 1937 uint32_t phyctl; 1938 uint16_t macctl, qos; 1939 uint8_t qid; 1940 int error, ridx, hasqos, xferlen; 1941 1942 DPRINTFN(DBG_FN, sc, "\n"); 1943 1944 ic = &sc->sc_ic; 1945 on = (void *)ni; 1946 1947 wh = mtod(m, struct ieee80211_frame *); 1948 if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) { 1949 /* XXX: derived from upgt_tx_task() and ural_tx_data() */ 1950 k = ieee80211_crypto_encap(ic, ni, m); 1951 if (k == NULL) 1952 return ENOBUFS; 1953 1954 /* Packet header may have moved, reset our local pointer. */ 1955 wh = mtod(m, struct ieee80211_frame *); 1956 } 1957 1958 #ifdef HAVE_EDCA 1959 if ((hasqos = ieee80211_has_qos(wh))) { 1960 qos = ieee80211_get_qos(wh); 1961 qid = ieee80211_up_to_ac(ic, qos & IEEE80211_QOS_TID); 1962 } else { 1963 qos = 0; 1964 qid = WME_AC_BE; 1965 } 1966 #else 1967 hasqos = 0; 1968 qos = 0; 1969 qid = WME_AC_BE; 1970 #endif 1971 1972 /* Pickup a rate index. */ 1973 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 1974 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) 1975 ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ? 1976 OTUS_RIDX_OFDM6 : OTUS_RIDX_CCK1; 1977 else if (ic->ic_fixed_rate != -1) 1978 ridx = sc->sc_fixed_ridx; 1979 else 1980 ridx = on->ridx[ni->ni_txrate]; 1981 1982 phyctl = 0; 1983 macctl = AR_TX_MAC_BACKOFF | AR_TX_MAC_HW_DUR | AR_TX_MAC_QID(qid); 1984 1985 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 1986 (hasqos && ((qos & IEEE80211_QOS_ACKPOLICY_MASK) == 1987 IEEE80211_QOS_ACKPOLICY_NOACK))) 1988 macctl |= AR_TX_MAC_NOACK; 1989 1990 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1991 if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= ic->ic_rtsthreshold) 1992 macctl |= AR_TX_MAC_RTS; 1993 else if ((ic->ic_flags & IEEE80211_F_USEPROT) && 1994 ridx >= OTUS_RIDX_OFDM6) { 1995 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 1996 macctl |= AR_TX_MAC_CTS; 1997 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 1998 macctl |= AR_TX_MAC_RTS; 1999 } 2000 } 2001 2002 phyctl |= AR_TX_PHY_MCS(otus_rates[ridx].mcs); 2003 if (ridx >= OTUS_RIDX_OFDM6) { 2004 phyctl |= AR_TX_PHY_MT_OFDM; 2005 if (ridx <= OTUS_RIDX_OFDM24) 2006 phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask); 2007 else 2008 phyctl |= AR_TX_PHY_ANTMSK(1); 2009 } else { /* CCK */ 2010 phyctl |= AR_TX_PHY_MT_CCK; 2011 phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask); 2012 } 2013 2014 /* Update rate control stats for frames that are ACK'ed. */ 2015 if (!(macctl & AR_TX_MAC_NOACK)) 2016 on->amn.amn_txcnt++; 2017 2018 /* Fill Tx descriptor. */ 2019 head = (void *)data->buf; 2020 head->len = htole16(m->m_pkthdr.len + IEEE80211_CRC_LEN); 2021 head->macctl = htole16(macctl); 2022 head->phyctl = htole32(phyctl); 2023 2024 if (__predict_false(sc->sc_drvbpf != NULL)) { 2025 struct otus_tx_radiotap_header *tap = &sc->sc_txtap; 2026 2027 tap->wt_flags = 0; 2028 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 2029 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; 2030 tap->wt_rate = otus_rates[ridx].rate; 2031 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); 2032 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); 2033 2034 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m); 2035 } 2036 2037 xferlen = sizeof(*head) + m->m_pkthdr.len; 2038 m_copydata(m, 0, m->m_pkthdr.len, (void *)&head[1]); 2039 2040 DPRINTFN(DBG_TX, sc, "queued len=%d mac=0x%04x phy=0x%08x rate=%d\n", 2041 head->len, head->macctl, head->phyctl, otus_rates[ridx].rate); 2042 2043 usbd_setup_xfer(data->xfer, data, data->buf, xferlen, 2044 USBD_FORCE_SHORT_XFER, OTUS_TX_TIMEOUT, otus_txeof); 2045 error = usbd_transfer(data->xfer); 2046 if (__predict_false( 2047 error != USBD_NORMAL_COMPLETION && 2048 error != USBD_IN_PROGRESS)) { 2049 DPRINTFN(DBG_TX, sc, "transfer failed %d\n", error); 2050 return error; 2051 } 2052 return 0; 2053 } 2054 2055 Static void 2056 otus_start(struct ifnet *ifp) 2057 { 2058 struct otus_softc *sc; 2059 struct ieee80211com *ic; 2060 struct otus_tx_data *data; 2061 struct ether_header *eh; 2062 struct ieee80211_node *ni; 2063 struct mbuf *m; 2064 2065 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 2066 return; 2067 2068 sc = ifp->if_softc; 2069 ic = &sc->sc_ic; 2070 2071 DPRINTFN(DBG_FN, sc, "\n"); 2072 2073 data = NULL; 2074 for (;;) { 2075 /* 2076 * Grab a Tx buffer if we don't already have one. If 2077 * one isn't available, bail out. 2078 * NB: We must obtain this Tx buffer _before_ 2079 * dequeueing anything as one may not be available 2080 * later. Both must be done inside a single lock. 2081 */ 2082 mutex_enter(&sc->sc_tx_mtx); 2083 if (data == NULL && !TAILQ_EMPTY(&sc->sc_tx_free_list)) { 2084 data = TAILQ_FIRST(&sc->sc_tx_free_list); 2085 TAILQ_REMOVE(&sc->sc_tx_free_list, data, next); 2086 } 2087 mutex_exit(&sc->sc_tx_mtx); 2088 2089 if (data == NULL) { 2090 ifp->if_flags |= IFF_OACTIVE; 2091 DPRINTFN(DBG_TX, sc, "empty sc_tx_free_list\n"); 2092 return; 2093 } 2094 2095 /* Send pending management frames first. */ 2096 IF_DEQUEUE(&ic->ic_mgtq, m); 2097 if (m != NULL) { 2098 ni = M_GETCTX(m, struct ieee80211_node *); 2099 M_CLEARCTX(m); 2100 goto sendit; 2101 } 2102 2103 if (ic->ic_state != IEEE80211_S_RUN) 2104 break; 2105 2106 /* Encapsulate and send data frames. */ 2107 IFQ_DEQUEUE(&ifp->if_snd, m); 2108 if (m == NULL) 2109 break; 2110 2111 if (m->m_len < (int)sizeof(*eh) && 2112 (m = m_pullup(m, sizeof(*eh))) == NULL) { 2113 ifp->if_oerrors++; 2114 continue; 2115 } 2116 2117 eh = mtod(m, struct ether_header *); 2118 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 2119 if (ni == NULL) { 2120 m_freem(m); 2121 ifp->if_oerrors++; 2122 continue; 2123 } 2124 2125 bpf_mtap(ifp, m); 2126 2127 if ((m = ieee80211_encap(ic, m, ni)) == NULL) { 2128 /* original m was freed by ieee80211_encap() */ 2129 ieee80211_free_node(ni); 2130 ifp->if_oerrors++; 2131 continue; 2132 } 2133 sendit: 2134 bpf_mtap3(ic->ic_rawbpf, m); 2135 2136 if (otus_tx(sc, m, ni, data) != 0) { 2137 m_freem(m); 2138 ieee80211_free_node(ni); 2139 ifp->if_oerrors++; 2140 continue; 2141 } 2142 2143 data = NULL; /* we're finished with this data buffer */ 2144 m_freem(m); 2145 ieee80211_free_node(ni); 2146 sc->sc_tx_timer = 5; 2147 ifp->if_timer = 1; 2148 } 2149 2150 /* 2151 * If here, we have a Tx buffer, but ran out of mbufs to 2152 * transmit. Put the Tx buffer back to the free list. 2153 */ 2154 mutex_enter(&sc->sc_tx_mtx); 2155 TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next); 2156 mutex_exit(&sc->sc_tx_mtx); 2157 } 2158 2159 Static void 2160 otus_watchdog(struct ifnet *ifp) 2161 { 2162 struct otus_softc *sc; 2163 2164 sc = ifp->if_softc; 2165 2166 DPRINTFN(DBG_FN, sc, "\n"); 2167 2168 ifp->if_timer = 0; 2169 2170 if (sc->sc_tx_timer > 0) { 2171 if (--sc->sc_tx_timer == 0) { 2172 aprint_error_dev(sc->sc_dev, "device timeout\n"); 2173 /* otus_init(ifp); XXX needs a process context! */ 2174 ifp->if_oerrors++; 2175 return; 2176 } 2177 ifp->if_timer = 1; 2178 } 2179 ieee80211_watchdog(&sc->sc_ic); 2180 } 2181 2182 Static int 2183 otus_ioctl(struct ifnet *ifp, u_long cmd, void *data) 2184 { 2185 struct otus_softc *sc; 2186 struct ieee80211com *ic; 2187 int s, error = 0; 2188 2189 sc = ifp->if_softc; 2190 2191 DPRINTFN(DBG_FN, sc, "0x%lx\n", cmd); 2192 2193 ic = &sc->sc_ic; 2194 2195 s = splnet(); 2196 2197 switch (cmd) { 2198 case SIOCSIFADDR: 2199 ifp->if_flags |= IFF_UP; 2200 #ifdef INET 2201 struct ifaddr *ifa = data; 2202 if (ifa->ifa_addr->sa_family == AF_INET) 2203 arp_ifinit(&ic->ic_ac, ifa); 2204 #endif 2205 /* FALLTHROUGH */ 2206 case SIOCSIFFLAGS: 2207 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 2208 break; 2209 2210 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 2211 case IFF_UP | IFF_RUNNING: 2212 if (((ifp->if_flags ^ sc->sc_if_flags) & 2213 (IFF_ALLMULTI | IFF_PROMISC)) != 0) 2214 otus_set_multi(sc); 2215 break; 2216 case IFF_UP: 2217 otus_init(ifp); 2218 break; 2219 2220 case IFF_RUNNING: 2221 otus_stop(ifp); 2222 break; 2223 case 0: 2224 default: 2225 break; 2226 } 2227 sc->sc_if_flags = ifp->if_flags; 2228 break; 2229 2230 case SIOCADDMULTI: 2231 case SIOCDELMULTI: 2232 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 2233 /* setup multicast filter, etc */ 2234 /* XXX: ??? */ 2235 error = 0; 2236 } 2237 break; 2238 2239 case SIOCS80211CHANNEL: 2240 /* 2241 * This allows for fast channel switching in monitor mode 2242 * (used by kismet). In IBSS mode, we must explicitly reset 2243 * the interface to generate a new beacon frame. 2244 */ 2245 error = ieee80211_ioctl(ic, cmd, data); 2246 2247 DPRINTFN(DBG_CHAN, sc, 2248 "ic_curchan=%d ic_ibss_chan=%d ic_des_chan=%d ni_chan=%d error=%d\n", 2249 ieee80211_chan2ieee(ic, ic->ic_curchan), 2250 ieee80211_chan2ieee(ic, ic->ic_ibss_chan), 2251 ieee80211_chan2ieee(ic, ic->ic_des_chan), 2252 ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan), 2253 error); 2254 2255 if (error == ENETRESET && 2256 ic->ic_opmode == IEEE80211_M_MONITOR) { 2257 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 2258 (IFF_UP | IFF_RUNNING)) { 2259 mutex_enter(&sc->sc_write_mtx); 2260 otus_set_chan(sc, ic->ic_curchan, 0); 2261 mutex_exit(&sc->sc_write_mtx); 2262 } 2263 error = 0; 2264 } 2265 break; 2266 2267 default: 2268 error = ieee80211_ioctl(ic, cmd, data); 2269 } 2270 if (error == ENETRESET) { 2271 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 2272 (IFF_UP | IFF_RUNNING)) 2273 otus_init(ifp); 2274 error = 0; 2275 } 2276 splx(s); 2277 return error; 2278 } 2279 2280 Static int 2281 otus_set_multi(struct otus_softc *sc) 2282 { 2283 struct ifnet *ifp; 2284 struct ether_multi *enm; 2285 struct ether_multistep step; 2286 uint32_t lo, hi; 2287 uint8_t bit; 2288 int error; 2289 2290 DPRINTFN(DBG_FN, sc, "\n"); 2291 2292 ifp = sc->sc_ic.ic_ifp; 2293 if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) { 2294 lo = hi = 0xffffffff; 2295 goto done; 2296 } 2297 lo = hi = 0; 2298 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm); 2299 while (enm != NULL) { 2300 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 2301 ifp->if_flags |= IFF_ALLMULTI; 2302 lo = hi = 0xffffffff; 2303 goto done; 2304 } 2305 bit = enm->enm_addrlo[5] >> 2; 2306 if (bit < 32) 2307 lo |= 1 << bit; 2308 else 2309 hi |= 1 << (bit - 32); 2310 ETHER_NEXT_MULTI(step, enm); 2311 } 2312 done: 2313 mutex_enter(&sc->sc_write_mtx); 2314 hi |= 1 << 31; /* Make sure the broadcast bit is set. */ 2315 otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, lo); 2316 otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hi); 2317 error = otus_write_barrier(sc); 2318 mutex_exit(&sc->sc_write_mtx); 2319 return error; 2320 } 2321 2322 #ifdef HAVE_EDCA 2323 Static void 2324 otus_updateedca(struct ieee80211com *ic) 2325 { 2326 2327 DPRINTFN(DBG_FN, DBG_NO_SC, "\n"); 2328 2329 /* Do it in a process context. */ 2330 otus_do_async(ic->ic_ifp->if_softc, otus_updateedca_cb, NULL, 0); 2331 } 2332 2333 Static void 2334 otus_updateedca_cb(struct otus_softc *sc, void *arg __used) 2335 { 2336 2337 DPRINTFN(DBG_FN, sc, "\n"); 2338 2339 mutex_enter(&sc->sc_write_mtx); 2340 otus_updateedca_cb_locked(sc); 2341 mutex_exit(&sc->sc_write_mtx); 2342 } 2343 #endif 2344 2345 Static void 2346 otus_updateedca_cb_locked(struct otus_softc *sc) 2347 { 2348 #ifdef HAVE_EDCA 2349 struct ieee80211com *ic; 2350 #endif 2351 const struct ieee80211_edca_ac_params *edca; 2352 int s; 2353 2354 DPRINTFN(DBG_FN, sc, "\n"); 2355 2356 KASSERT(mutex_owned(&sc->sc_write_mtx)); 2357 2358 s = splnet(); 2359 2360 #ifdef HAVE_EDCA 2361 ic = &sc->sc_ic; 2362 edca = (ic->ic_flags & IEEE80211_F_QOS) ? 2363 ic->ic_edca_ac : otus_edca_def; 2364 #else 2365 edca = otus_edca_def; 2366 #endif /* HAVE_EDCA */ 2367 2368 #define EXP2(val) ((1 << (val)) - 1) 2369 #define AIFS(val) ((val) * 9 + 10) 2370 2371 /* Set CWmin/CWmax values. */ 2372 otus_write(sc, AR_MAC_REG_AC0_CW, 2373 EXP2(edca[WME_AC_BE].ac_ecwmax) << 16 | 2374 EXP2(edca[WME_AC_BE].ac_ecwmin)); 2375 otus_write(sc, AR_MAC_REG_AC1_CW, 2376 EXP2(edca[WME_AC_BK].ac_ecwmax) << 16 | 2377 EXP2(edca[WME_AC_BK].ac_ecwmin)); 2378 otus_write(sc, AR_MAC_REG_AC2_CW, 2379 EXP2(edca[WME_AC_VI].ac_ecwmax) << 16 | 2380 EXP2(edca[WME_AC_VI].ac_ecwmin)); 2381 otus_write(sc, AR_MAC_REG_AC3_CW, 2382 EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 | 2383 EXP2(edca[WME_AC_VO].ac_ecwmin)); 2384 otus_write(sc, AR_MAC_REG_AC4_CW, /* Special TXQ. */ 2385 EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 | 2386 EXP2(edca[WME_AC_VO].ac_ecwmin)); 2387 2388 /* Set AIFSN values. */ 2389 otus_write(sc, AR_MAC_REG_AC1_AC0_AIFS, 2390 AIFS(edca[WME_AC_VI].ac_aifsn) << 24 | 2391 AIFS(edca[WME_AC_BK].ac_aifsn) << 12 | 2392 AIFS(edca[WME_AC_BE].ac_aifsn)); 2393 otus_write(sc, AR_MAC_REG_AC3_AC2_AIFS, 2394 AIFS(edca[WME_AC_VO].ac_aifsn) << 16 | /* Special TXQ. */ 2395 AIFS(edca[WME_AC_VO].ac_aifsn) << 4 | 2396 AIFS(edca[WME_AC_VI].ac_aifsn) >> 8); 2397 2398 /* Set TXOP limit. */ 2399 otus_write(sc, AR_MAC_REG_AC1_AC0_TXOP, 2400 edca[WME_AC_BK].ac_txoplimit << 16 | 2401 edca[WME_AC_BE].ac_txoplimit); 2402 otus_write(sc, AR_MAC_REG_AC3_AC2_TXOP, 2403 edca[WME_AC_VO].ac_txoplimit << 16 | 2404 edca[WME_AC_VI].ac_txoplimit); 2405 #undef AIFS 2406 #undef EXP2 2407 2408 splx(s); 2409 2410 (void)otus_write_barrier(sc); 2411 } 2412 2413 Static void 2414 otus_updateslot(struct ifnet *ifp) 2415 { 2416 struct otus_softc *sc; 2417 2418 sc = ifp->if_softc; 2419 2420 DPRINTFN(DBG_FN, sc, "\n"); 2421 2422 /* Do it in a process context. */ 2423 otus_do_async(sc, otus_updateslot_cb, NULL, 0); 2424 } 2425 2426 /* ARGSUSED */ 2427 Static void 2428 otus_updateslot_cb(struct otus_softc *sc, void *arg) 2429 { 2430 2431 DPRINTFN(DBG_FN, sc, "\n"); 2432 2433 mutex_enter(&sc->sc_write_mtx); 2434 otus_updateslot_cb_locked(sc); 2435 mutex_exit(&sc->sc_write_mtx); 2436 } 2437 2438 Static void 2439 otus_updateslot_cb_locked(struct otus_softc *sc) 2440 { 2441 uint32_t slottime; 2442 2443 DPRINTFN(DBG_FN, sc, "\n"); 2444 2445 KASSERT(mutex_owned(&sc->sc_write_mtx)); 2446 2447 slottime = (sc->sc_ic.ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; 2448 otus_write(sc, AR_MAC_REG_SLOT_TIME, slottime << 10); 2449 (void)otus_write_barrier(sc); 2450 } 2451 2452 Static int 2453 otus_init_mac(struct otus_softc *sc) 2454 { 2455 int error; 2456 2457 DPRINTFN(DBG_FN|DBG_INIT, sc, "\n"); 2458 2459 KASSERT(mutex_owned(&sc->sc_write_mtx)); 2460 2461 otus_write(sc, AR_MAC_REG_ACK_EXTENSION, 0x40); 2462 otus_write(sc, AR_MAC_REG_RETRY_MAX, 0); 2463 otus_write(sc, AR_MAC_REG_SNIFFER, AR_MAC_REG_SNIFFER_DEFAULTS); 2464 otus_write(sc, AR_MAC_REG_RX_THRESHOLD, 0xc1f80); 2465 otus_write(sc, AR_MAC_REG_RX_PE_DELAY, 0x70); 2466 otus_write(sc, AR_MAC_REG_EIFS_AND_SIFS, 0xa144000); 2467 otus_write(sc, AR_MAC_REG_SLOT_TIME, 9 << 10); 2468 2469 /* CF-END mode */ 2470 otus_write(sc, 0x1c3b2c, 0x19000000); 2471 2472 /* NAV protects ACK only (in TXOP). */ 2473 otus_write(sc, 0x1c3b38, 0x201); 2474 2475 /* Set beacon PHY CTRL's TPC to 0x7, TA1=1 */ 2476 /* OTUS set AM to 0x1 */ 2477 otus_write(sc, AR_MAC_REG_BCN_HT1, 0x8000170); 2478 2479 otus_write(sc, AR_MAC_REG_BACKOFF_PROTECT, 0x105); 2480 2481 /* AGG test code*/ 2482 /* Aggregation MAX number and timeout */ 2483 otus_write(sc, AR_MAC_REG_AMPDU_FACTOR, 0x10000a); 2484 2485 /* Filter any control frames, BAR is bit 24. */ 2486 otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, AR_MAC_REG_FTF_DEFAULTS); 2487 2488 /* Enable deaggregator, response in sniffer mode */ 2489 otus_write(sc, 0x1c3c40, 0x1 | 1 << 30); /* XXX: was 0x1 */ 2490 2491 /* rate sets */ 2492 otus_write(sc, AR_MAC_REG_BASIC_RATE, 0x150f); 2493 otus_write(sc, AR_MAC_REG_MANDATORY_RATE, 0x150f); 2494 otus_write(sc, AR_MAC_REG_RTS_CTS_RATE, 0x10b01bb); 2495 2496 /* MIMO response control */ 2497 otus_write(sc, 0x1c3694, 0x4003c1e); /* bit 26~28 otus-AM */ 2498 2499 /* Switch MAC to OTUS interface. */ 2500 otus_write(sc, 0x1c3600, 0x3); 2501 2502 otus_write(sc, AR_MAC_REG_AMPDU_RX_THRESH, 0xffff); 2503 2504 /* set PHY register read timeout (??) */ 2505 otus_write(sc, AR_MAC_REG_MISC_680, 0xf00008); 2506 2507 /* Disable Rx TimeOut, workaround for BB. */ 2508 otus_write(sc, AR_MAC_REG_RX_TIMEOUT, 0x0); 2509 2510 /* Set clock frequency to 88/80MHz. */ 2511 otus_write(sc, AR_PWR_REG_CLOCK_SEL, 2512 AR_PWR_CLK_AHB_80_88MHZ | AR_PWR_CLK_DAC_160_INV_DLY); 2513 2514 /* Set WLAN DMA interrupt mode: generate intr per packet. */ 2515 otus_write(sc, AR_MAC_REG_TXRX_MPI, 0x110011); 2516 2517 otus_write(sc, AR_MAC_REG_FCS_SELECT, AR_MAC_FCS_FIFO_PROT); 2518 2519 /* Disables the CF_END frame, undocumented register */ 2520 otus_write(sc, AR_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141e0f48); 2521 2522 /* Disable HW decryption for now. */ 2523 otus_write(sc, AR_MAC_REG_ENCRYPTION, 2524 AR_MAC_REG_ENCRYPTION_DEFAULTS | AR_MAC_REG_ENCRYPTION_RX_SOFTWARE); 2525 2526 /* 2527 * XXX: should these be elsewhere? 2528 */ 2529 /* Enable LED0 and LED1. */ 2530 otus_write(sc, AR_GPIO_REG_PORT_TYPE, 3); 2531 otus_write(sc, AR_GPIO_REG_DATA, 2532 AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON); 2533 2534 /* Set USB Rx stream mode maximum frame number to 2. */ 2535 otus_write(sc, AR_USB_REG_MAX_AGG_UPLOAD, (1 << 2)); 2536 2537 /* Set USB Rx stream mode timeout to 10us. */ 2538 otus_write(sc, AR_USB_REG_UPLOAD_TIME_CTL, 0x80); 2539 2540 if ((error = otus_write_barrier(sc)) != 0) 2541 return error; 2542 2543 /* Set default EDCA parameters. */ 2544 otus_updateedca_cb_locked(sc); 2545 return 0; 2546 } 2547 2548 /* 2549 * Return default value for PHY register based on current operating mode. 2550 */ 2551 Static uint32_t 2552 otus_phy_get_def(struct otus_softc *sc, uint32_t reg) 2553 { 2554 int i; 2555 2556 DPRINTFN(DBG_FN, sc, "\n"); 2557 2558 for (i = 0; i < __arraycount(ar5416_phy_regs); i++) 2559 if (AR_PHY(ar5416_phy_regs[i]) == reg) 2560 return sc->sc_phy_vals[i]; 2561 return 0; /* Register not found. */ 2562 } 2563 2564 /* 2565 * Update PHY's programming based on vendor-specific data stored in EEPROM. 2566 * This is for FEM-type devices only. 2567 */ 2568 Static int 2569 otus_set_board_values(struct otus_softc *sc, struct ieee80211_channel *c) 2570 { 2571 const struct ModalEepHeader *eep; 2572 uint32_t tmp, offset; 2573 2574 DPRINTFN(DBG_FN, sc, "\n"); 2575 2576 if (IEEE80211_IS_CHAN_5GHZ(c)) 2577 eep = &sc->sc_eeprom.modalHeader[0]; 2578 else 2579 eep = &sc->sc_eeprom.modalHeader[1]; 2580 2581 /* Offset of chain 2. */ 2582 offset = 2 * 0x1000; 2583 2584 tmp = le32toh(eep->antCtrlCommon); 2585 otus_write(sc, AR_PHY_SWITCH_COM, tmp); 2586 2587 tmp = le32toh(eep->antCtrlChain[0]); 2588 otus_write(sc, AR_PHY_SWITCH_CHAIN_0, tmp); 2589 2590 tmp = le32toh(eep->antCtrlChain[1]); 2591 otus_write(sc, AR_PHY_SWITCH_CHAIN_0 + offset, tmp); 2592 2593 if (1 /* sc->sc_sco == AR_SCO_SCN */) { 2594 tmp = otus_phy_get_def(sc, AR_PHY_SETTLING); 2595 tmp &= ~(0x7f << 7); 2596 tmp |= (eep->switchSettling & 0x7f) << 7; 2597 otus_write(sc, AR_PHY_SETTLING, tmp); 2598 } 2599 2600 tmp = otus_phy_get_def(sc, AR_PHY_DESIRED_SZ); 2601 tmp &= ~0xffff; 2602 tmp |= eep->pgaDesiredSize << 8 | eep->adcDesiredSize; 2603 otus_write(sc, AR_PHY_DESIRED_SZ, tmp); 2604 2605 tmp = eep->txEndToXpaOff << 24 | eep->txEndToXpaOff << 16 | 2606 eep->txFrameToXpaOn << 8 | eep->txFrameToXpaOn; 2607 otus_write(sc, AR_PHY_RF_CTL4, tmp); 2608 2609 tmp = otus_phy_get_def(sc, AR_PHY_RF_CTL3); 2610 tmp &= ~(0xff << 16); 2611 tmp |= eep->txEndToRxOn << 16; 2612 otus_write(sc, AR_PHY_RF_CTL3, tmp); 2613 2614 tmp = otus_phy_get_def(sc, AR_PHY_CCA); 2615 tmp &= ~(0x7f << 12); 2616 tmp |= (eep->thresh62 & 0x7f) << 12; 2617 otus_write(sc, AR_PHY_CCA, tmp); 2618 2619 tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN); 2620 tmp &= ~(0x3f << 12); 2621 tmp |= (eep->txRxAttenCh[0] & 0x3f) << 12; 2622 otus_write(sc, AR_PHY_RXGAIN, tmp); 2623 2624 tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN + offset); 2625 tmp &= ~(0x3f << 12); 2626 tmp |= (eep->txRxAttenCh[1] & 0x3f) << 12; 2627 otus_write(sc, AR_PHY_RXGAIN + offset, tmp); 2628 2629 tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ); 2630 tmp &= ~(0x3f << 18); 2631 tmp |= (eep->rxTxMarginCh[0] & 0x3f) << 18; 2632 if (IEEE80211_IS_CHAN_5GHZ(c)) { 2633 tmp &= ~(0xf << 10); 2634 tmp |= (eep->bswMargin[0] & 0xf) << 10; 2635 } 2636 otus_write(sc, AR_PHY_GAIN_2GHZ, tmp); 2637 2638 tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ + offset); 2639 tmp &= ~(0x3f << 18); 2640 tmp |= (eep->rxTxMarginCh[1] & 0x3f) << 18; 2641 otus_write(sc, AR_PHY_GAIN_2GHZ + offset, tmp); 2642 2643 tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4); 2644 tmp &= ~(0x3f << 5 | 0x1f); 2645 tmp |= (eep->iqCalICh[0] & 0x3f) << 5 | (eep->iqCalQCh[0] & 0x1f); 2646 otus_write(sc, AR_PHY_TIMING_CTRL4, tmp); 2647 2648 tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4 + offset); 2649 tmp &= ~(0x3f << 5 | 0x1f); 2650 tmp |= (eep->iqCalICh[1] & 0x3f) << 5 | (eep->iqCalQCh[1] & 0x1f); 2651 otus_write(sc, AR_PHY_TIMING_CTRL4 + offset, tmp); 2652 2653 tmp = otus_phy_get_def(sc, AR_PHY_TPCRG1); 2654 tmp &= ~(0xf << 16); 2655 tmp |= (eep->xpd & 0xf) << 16; 2656 otus_write(sc, AR_PHY_TPCRG1, tmp); 2657 2658 return otus_write_barrier(sc); 2659 } 2660 2661 Static int 2662 otus_program_phy(struct otus_softc *sc, struct ieee80211_channel *c) 2663 { 2664 const uint32_t *vals; 2665 int error, i; 2666 2667 DPRINTFN(DBG_FN, sc, "\n"); 2668 2669 /* Select PHY programming based on band and bandwidth. */ 2670 if (IEEE80211_IS_CHAN_2GHZ(c)) 2671 vals = ar5416_phy_vals_2ghz_20mhz; 2672 else 2673 vals = ar5416_phy_vals_5ghz_20mhz; 2674 for (i = 0; i < __arraycount(ar5416_phy_regs); i++) 2675 otus_write(sc, AR_PHY(ar5416_phy_regs[i]), vals[i]); 2676 sc->sc_phy_vals = vals; 2677 2678 if (sc->sc_eeprom.baseEepHeader.deviceType == 0x80) /* FEM */ 2679 if ((error = otus_set_board_values(sc, c)) != 0) 2680 return error; 2681 2682 /* Initial Tx power settings. */ 2683 otus_write(sc, AR_PHY_POWER_TX_RATE_MAX, 0x7f); 2684 otus_write(sc, AR_PHY_POWER_TX_RATE1, 0x3f3f3f3f); 2685 otus_write(sc, AR_PHY_POWER_TX_RATE2, 0x3f3f3f3f); 2686 otus_write(sc, AR_PHY_POWER_TX_RATE3, 0x3f3f3f3f); 2687 otus_write(sc, AR_PHY_POWER_TX_RATE4, 0x3f3f3f3f); 2688 otus_write(sc, AR_PHY_POWER_TX_RATE5, 0x3f3f3f3f); 2689 otus_write(sc, AR_PHY_POWER_TX_RATE6, 0x3f3f3f3f); 2690 otus_write(sc, AR_PHY_POWER_TX_RATE7, 0x3f3f3f3f); 2691 otus_write(sc, AR_PHY_POWER_TX_RATE8, 0x3f3f3f3f); 2692 otus_write(sc, AR_PHY_POWER_TX_RATE9, 0x3f3f3f3f); 2693 2694 if (IEEE80211_IS_CHAN_2GHZ(c)) 2695 otus_write(sc, 0x1d4014, 0x5163); 2696 else 2697 otus_write(sc, 0x1d4014, 0x5143); 2698 2699 return otus_write_barrier(sc); 2700 } 2701 2702 static __inline uint8_t 2703 otus_reverse_bits(uint8_t v) 2704 { 2705 2706 v = ((v >> 1) & 0x55) | ((v & 0x55) << 1); 2707 v = ((v >> 2) & 0x33) | ((v & 0x33) << 2); 2708 v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4); 2709 return v; 2710 } 2711 2712 Static int 2713 otus_set_rf_bank4(struct otus_softc *sc, struct ieee80211_channel *c) 2714 { 2715 uint8_t chansel, d0, d1; 2716 uint16_t data; 2717 int error; 2718 2719 DPRINTFN(DBG_FN, sc, "\n"); 2720 2721 d0 = 0; 2722 if (IEEE80211_IS_CHAN_5GHZ(c)) { 2723 chansel = (c->ic_freq - 4800) / 5; 2724 if (chansel & 1) 2725 d0 |= AR_BANK4_AMODE_REFSEL(2); 2726 else 2727 d0 |= AR_BANK4_AMODE_REFSEL(1); 2728 } else { 2729 d0 |= AR_BANK4_AMODE_REFSEL(2); 2730 if (c->ic_freq == 2484) { /* CH 14 */ 2731 d0 |= AR_BANK4_BMODE_LF_SYNTH_FREQ; 2732 chansel = 10 + (c->ic_freq - 2274) / 5; 2733 } else 2734 chansel = 16 + (c->ic_freq - 2272) / 5; 2735 chansel <<= 2; 2736 } 2737 d0 |= AR_BANK4_ADDR(1) | AR_BANK4_CHUP; 2738 d1 = otus_reverse_bits(chansel); 2739 2740 /* Write bits 0-4 of d0 and d1. */ 2741 data = (d1 & 0x1f) << 5 | (d0 & 0x1f); 2742 otus_write(sc, AR_PHY(44), data); 2743 /* Write bits 5-7 of d0 and d1. */ 2744 data = (d1 >> 5) << 5 | (d0 >> 5); 2745 otus_write(sc, AR_PHY(58), data); 2746 2747 if ((error = otus_write_barrier(sc)) == 0) 2748 usbd_delay_ms(sc->sc_udev, 10); 2749 2750 return error; 2751 } 2752 2753 Static void 2754 otus_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa) 2755 { 2756 #define COEFF_SCALE_SHIFT 24 2757 uint32_t exp, man; 2758 2759 DPRINTFN(DBG_FN, DBG_NO_SC, "\n"); 2760 2761 /* exponent = 14 - floor(log2(coeff)) */ 2762 for (exp = 31; exp > 0; exp--) 2763 if (coeff & (1 << exp)) 2764 break; 2765 KASSERT(exp != 0); 2766 exp = 14 - (exp - COEFF_SCALE_SHIFT); 2767 2768 /* mantissa = floor(coeff * 2^exponent + 0.5) */ 2769 man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1)); 2770 2771 *mantissa = man >> (COEFF_SCALE_SHIFT - exp); 2772 *exponent = exp - 16; 2773 #undef COEFF_SCALE_SHIFT 2774 } 2775 2776 Static int 2777 otus_set_chan(struct otus_softc *sc, struct ieee80211_channel *c, int assoc) 2778 { 2779 struct ar_cmd_frequency cmd; 2780 struct ar_rsp_frequency rsp; 2781 const uint32_t *vals; 2782 uint32_t coeff, exp, man, tmp; 2783 uint8_t code; 2784 int error, i; 2785 2786 DPRINTFN(DBG_FN, sc, "\n"); 2787 2788 2789 #ifdef OTUS_DEBUG 2790 struct ieee80211com *ic = &sc->sc_ic; 2791 int chan = ieee80211_chan2ieee(ic, c); 2792 2793 DPRINTFN(DBG_CHAN, sc, "setting channel %d (%dMHz)\n", 2794 chan, c->ic_freq); 2795 #endif 2796 2797 tmp = IEEE80211_IS_CHAN_2GHZ(c) ? 0x105 : 0x104; 2798 otus_write(sc, AR_MAC_REG_DYNAMIC_SIFS_ACK, tmp); 2799 if ((error = otus_write_barrier(sc)) != 0) 2800 return error; 2801 2802 /* Disable BB Heavy Clip. */ 2803 otus_write(sc, AR_PHY_HEAVY_CLIP_ENABLE, 0x200); 2804 if ((error = otus_write_barrier(sc)) != 0) 2805 return error; 2806 2807 /* XXX Is that FREQ_START ? */ 2808 error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL); 2809 if (error != 0) 2810 return error; 2811 2812 /* Reprogram PHY and RF on channel band or bandwidth changes. */ 2813 if (sc->sc_bb_reset || c->ic_flags != sc->sc_curchan->ic_flags) { 2814 DPRINTFN(DBG_CHAN, sc, "band switch\n"); 2815 2816 /* Cold/Warm reset BB/ADDA. */ 2817 otus_write(sc, 0x1d4004, sc->sc_bb_reset ? 0x800 : 0x400); 2818 if ((error = otus_write_barrier(sc)) != 0) 2819 return error; 2820 2821 otus_write(sc, 0x1d4004, 0); 2822 if ((error = otus_write_barrier(sc)) != 0) 2823 return error; 2824 sc->sc_bb_reset = 0; 2825 2826 if ((error = otus_program_phy(sc, c)) != 0) { 2827 aprint_error_dev(sc->sc_dev, 2828 "could not program PHY\n"); 2829 return error; 2830 } 2831 2832 /* Select RF programming based on band. */ 2833 if (IEEE80211_IS_CHAN_5GHZ(c)) 2834 vals = ar5416_banks_vals_5ghz; 2835 else 2836 vals = ar5416_banks_vals_2ghz; 2837 for (i = 0; i < __arraycount(ar5416_banks_regs); i++) 2838 otus_write(sc, AR_PHY(ar5416_banks_regs[i]), vals[i]); 2839 if ((error = otus_write_barrier(sc)) != 0) { 2840 aprint_error_dev(sc->sc_dev, "could not program RF\n"); 2841 return error; 2842 } 2843 code = AR_CMD_RF_INIT; 2844 } else { 2845 code = AR_CMD_FREQUENCY; 2846 } 2847 2848 if ((error = otus_set_rf_bank4(sc, c)) != 0) 2849 return error; 2850 2851 tmp = (sc->sc_txmask == 0x5) ? 0x340 : 0x240; 2852 otus_write(sc, AR_PHY_TURBO, tmp); 2853 if ((error = otus_write_barrier(sc)) != 0) 2854 return error; 2855 2856 /* Send firmware command to set channel. */ 2857 cmd.freq = htole32((uint32_t)c->ic_freq * 1000); 2858 cmd.dynht2040 = htole32(0); 2859 cmd.htena = htole32(1); 2860 2861 /* Set Delta Slope (exponent and mantissa). */ 2862 coeff = (100 << 24) / c->ic_freq; 2863 otus_get_delta_slope(coeff, &exp, &man); 2864 cmd.dsc_exp = htole32(exp); 2865 cmd.dsc_man = htole32(man); 2866 DPRINTFN(DBG_CHAN, sc, "ds coeff=%u exp=%u man=%u\n", 2867 coeff, exp, man); 2868 2869 /* For Short GI, coeff is 9/10 that of normal coeff. */ 2870 coeff = (9 * coeff) / 10; 2871 otus_get_delta_slope(coeff, &exp, &man); 2872 cmd.dsc_shgi_exp = htole32(exp); 2873 cmd.dsc_shgi_man = htole32(man); 2874 DPRINTFN(DBG_CHAN, sc, "ds shgi coeff=%u exp=%u man=%u\n", 2875 coeff, exp, man); 2876 2877 /* Set wait time for AGC and noise calibration (100 or 200ms). */ 2878 cmd.check_loop_count = assoc ? htole32(2000) : htole32(1000); 2879 DPRINTFN(DBG_CHAN, sc, "%s\n", 2880 code == AR_CMD_RF_INIT ? "RF_INIT" : "FREQUENCY"); 2881 error = otus_cmd(sc, code, &cmd, sizeof(cmd), &rsp); 2882 if (error != 0) 2883 return error; 2884 2885 if ((rsp.status & htole32(AR_CAL_ERR_AGC | AR_CAL_ERR_NF_VAL)) != 0) { 2886 DPRINTFN(DBG_CHAN, sc, "status=0x%x\n", le32toh(rsp.status)); 2887 /* Force cold reset on next channel. */ 2888 sc->sc_bb_reset = 1; 2889 } 2890 2891 #ifdef OTUS_DEBUG 2892 if (otus_debug & DBG_CHAN) { 2893 DPRINTFN(DBG_CHAN, sc, "calibration status=0x%x\n", 2894 le32toh(rsp.status)); 2895 for (i = 0; i < 2; i++) { /* 2 Rx chains */ 2896 /* Sign-extend 9-bit NF values. */ 2897 DPRINTFN(DBG_CHAN, sc, "noisefloor chain %d=%d\n", 2898 i, (((int32_t)le32toh(rsp.nf[i])) << 4) >> 23); 2899 DPRINTFN(DBG_CHAN, sc, "noisefloor ext chain %d=%d\n", 2900 i, ((int32_t)le32toh(rsp.nf_ext[i])) >> 23); 2901 } 2902 } 2903 #endif 2904 sc->sc_curchan = c; 2905 return 0; 2906 } 2907 2908 #ifdef notyet 2909 Static int 2910 otus_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, 2911 struct ieee80211_key *k) 2912 { 2913 struct otus_softc *sc; 2914 struct otus_cmd_key cmd; 2915 2916 sc = ic->ic_ifp->if_softc; 2917 2918 DPRINTFN(DBG_FN, sc, "\n"); 2919 2920 /* Defer setting of WEP keys until interface is brought up. */ 2921 if ((ic->ic_ifp->if_flags & (IFF_UP | IFF_RUNNING)) != 2922 (IFF_UP | IFF_RUNNING)) 2923 return 0; 2924 2925 /* Do it in a process context. */ 2926 cmd.key = *k; 2927 cmd.associd = (ni != NULL) ? ni->ni_associd : 0; 2928 otus_do_async(sc, otus_set_key_cb, &cmd, sizeof(cmd)); 2929 return 0; 2930 } 2931 2932 Static void 2933 otus_set_key_cb(struct otus_softc *sc, void *arg) 2934 { 2935 struct otus_cmd_key *cmd; 2936 struct ieee80211_key *k; 2937 struct ar_cmd_ekey key; 2938 uint16_t cipher; 2939 int error; 2940 2941 DPRINTFN(DBG_FN, sc, "\n"); 2942 2943 cmd = arg; 2944 k = &cmd->key; 2945 2946 memset(&key, 0, sizeof(key)); 2947 if (k->k_flags & IEEE80211_KEY_GROUP) { 2948 key.uid = htole16(k->k_id); 2949 IEEE80211_ADDR_COPY(key.macaddr, sc->sc_ic.ic_myaddr); 2950 key.macaddr[0] |= 0x80; 2951 } else { 2952 key.uid = htole16(OTUS_UID(cmd->associd)); 2953 IEEE80211_ADDR_COPY(key.macaddr, ni->ni_macaddr); 2954 } 2955 key.kix = htole16(0); 2956 /* Map net80211 cipher to hardware. */ 2957 switch (k->k_cipher) { 2958 case IEEE80211_CIPHER_WEP40: 2959 cipher = AR_CIPHER_WEP64; 2960 break; 2961 case IEEE80211_CIPHER_WEP104: 2962 cipher = AR_CIPHER_WEP128; 2963 break; 2964 case IEEE80211_CIPHER_TKIP: 2965 cipher = AR_CIPHER_TKIP; 2966 break; 2967 case IEEE80211_CIPHER_CCMP: 2968 cipher = AR_CIPHER_AES; 2969 break; 2970 default: 2971 return; 2972 } 2973 key.cipher = htole16(cipher); 2974 memcpy(key.key, k->k_key, MIN(k->k_len, 16)); 2975 error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL); 2976 if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP) 2977 return; 2978 2979 /* TKIP: set Tx/Rx MIC Key. */ 2980 key.kix = htole16(1); 2981 memcpy(key.key, k->k_key + 16, 16); 2982 (void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL); 2983 } 2984 2985 Static void 2986 otus_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, 2987 struct ieee80211_key *k) 2988 { 2989 struct otus_softc *sc; 2990 struct otus_cmd_key cmd; 2991 2992 sc = ic->ic_ifp->if_softc; 2993 2994 DPRINTFN(DBG_FN, sc, "\n"); 2995 2996 if (!(ic->ic_ifp->if_flags & IFF_RUNNING) || 2997 ic->ic_state != IEEE80211_S_RUN) 2998 return; /* Nothing to do. */ 2999 3000 /* Do it in a process context. */ 3001 cmd.key = *k; 3002 cmd.associd = (ni != NULL) ? ni->ni_associd : 0; 3003 otus_do_async(sc, otus_delete_key_cb, &cmd, sizeof(cmd)); 3004 } 3005 3006 Static void 3007 otus_delete_key_cb(struct otus_softc *sc, void *arg) 3008 { 3009 struct otus_cmd_key *cmd; 3010 struct ieee80211_key *k; 3011 uint32_t uid; 3012 3013 DPRINTFN(DBG_FN, sc, "\n"); 3014 3015 cmd = arg; 3016 k = &cmd->key; 3017 if (k->k_flags & IEEE80211_KEY_GROUP) 3018 uid = htole32(k->k_id); 3019 else 3020 uid = htole32(OTUS_UID(cmd->associd)); 3021 (void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof(uid), NULL); 3022 } 3023 #endif /* notyet */ 3024 3025 Static void 3026 otus_calib_to(void *arg) 3027 { 3028 struct otus_softc *sc; 3029 struct ieee80211com *ic; 3030 struct ieee80211_node *ni; 3031 struct otus_node *on; 3032 int s; 3033 3034 sc = arg; 3035 3036 DPRINTFN(DBG_FN, sc, "\n"); 3037 3038 if (sc->sc_dying) 3039 return; 3040 3041 s = splnet(); 3042 ic = &sc->sc_ic; 3043 ni = ic->ic_bss; 3044 on = (void *)ni; 3045 ieee80211_amrr_choose(&sc->sc_amrr, ni, &on->amn); 3046 splx(s); 3047 3048 if (!sc->sc_dying) 3049 callout_schedule(&sc->sc_calib_to, hz); 3050 } 3051 3052 Static int 3053 otus_set_bssid(struct otus_softc *sc, const uint8_t *bssid) 3054 { 3055 3056 DPRINTFN(DBG_FN, sc, "\n"); 3057 3058 KASSERT(mutex_owned(&sc->sc_write_mtx)); 3059 3060 otus_write(sc, AR_MAC_REG_BSSID_L, 3061 bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24); 3062 otus_write(sc, AR_MAC_REG_BSSID_H, 3063 bssid[4] | bssid[5] << 8); 3064 return otus_write_barrier(sc); 3065 } 3066 3067 Static int 3068 otus_set_macaddr(struct otus_softc *sc, const uint8_t *addr) 3069 { 3070 3071 DPRINTFN(DBG_FN, sc, "\n"); 3072 3073 KASSERT(mutex_owned(&sc->sc_write_mtx)); 3074 3075 otus_write(sc, AR_MAC_REG_MAC_ADDR_L, 3076 addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); 3077 otus_write(sc, AR_MAC_REG_MAC_ADDR_H, 3078 addr[4] | addr[5] << 8); 3079 return otus_write_barrier(sc); 3080 } 3081 3082 #ifdef notyet 3083 /* Default single-LED. */ 3084 Static void 3085 otus_led_newstate_type1(struct otus_softc *sc) 3086 { 3087 3088 DPRINTFN(DBG_FN, sc, "\n"); 3089 3090 /* TBD */ 3091 } 3092 3093 /* NETGEAR, dual-LED. */ 3094 Static void 3095 otus_led_newstate_type2(struct otus_softc *sc) 3096 { 3097 3098 DPRINTFN(DBG_FN, sc, "\n"); 3099 3100 /* TBD */ 3101 } 3102 #endif /* notyet */ 3103 3104 /* 3105 * NETGEAR, single-LED/3 colors (blue, red, purple.) 3106 */ 3107 Static void 3108 otus_led_newstate_type3(struct otus_softc *sc) 3109 { 3110 struct ieee80211com *ic; 3111 uint32_t led_state; 3112 3113 DPRINTFN(DBG_FN, sc, "\n"); 3114 3115 ic = &sc->sc_ic; 3116 led_state = sc->sc_led_state; 3117 switch(ic->ic_state) { 3118 case IEEE80211_S_INIT: 3119 led_state = 0; 3120 break; 3121 case IEEE80211_S_SCAN: 3122 led_state ^= AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON; 3123 led_state &= ~(IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ? 3124 AR_GPIO_REG_DATA_LED1_ON : AR_GPIO_REG_DATA_LED0_ON); 3125 break; 3126 case IEEE80211_S_AUTH: 3127 case IEEE80211_S_ASSOC: 3128 /* XXX: Turn both LEDs on for AUTH and ASSOC? */ 3129 led_state = AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON; 3130 break; 3131 case IEEE80211_S_RUN: 3132 led_state = IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ? 3133 AR_GPIO_REG_DATA_LED0_ON : AR_GPIO_REG_DATA_LED1_ON; 3134 break; 3135 } 3136 if (led_state != sc->sc_led_state) { 3137 otus_write(sc, AR_GPIO_REG_DATA, led_state); 3138 if (otus_write_barrier(sc) == 0) 3139 sc->sc_led_state = led_state; 3140 } 3141 } 3142 3143 Static int 3144 otus_init(struct ifnet *ifp) 3145 { 3146 struct otus_softc *sc; 3147 struct ieee80211com *ic; 3148 uint32_t filter, pm_mode, sniffer; 3149 int error; 3150 3151 sc = ifp->if_softc; 3152 3153 DPRINTFN(DBG_FN|DBG_INIT, sc, "\n"); 3154 3155 ic = &sc->sc_ic; 3156 3157 mutex_enter(&sc->sc_write_mtx); 3158 3159 /* Init host command ring. */ 3160 mutex_spin_enter(&sc->sc_task_mtx); 3161 sc->sc_cmdq.cur = sc->sc_cmdq.next = sc->sc_cmdq.queued = 0; 3162 mutex_spin_exit(&sc->sc_task_mtx); 3163 3164 if ((error = otus_init_mac(sc)) != 0) { 3165 mutex_exit(&sc->sc_write_mtx); 3166 aprint_error_dev(sc->sc_dev, "could not initialize MAC\n"); 3167 return error; 3168 } 3169 3170 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 3171 (void)otus_set_macaddr(sc, ic->ic_myaddr); 3172 3173 pm_mode = AR_MAC_REG_POWERMGT_DEFAULTS; 3174 sniffer = AR_MAC_REG_SNIFFER_DEFAULTS; 3175 filter = AR_MAC_REG_FTF_DEFAULTS; 3176 sc->sc_rx_error_msk = ~0; 3177 3178 switch (ic->ic_opmode) { 3179 #ifdef notyet 3180 #ifndef IEEE80211_STA_ONLY 3181 case IEEE80211_M_HOSTAP: 3182 pm_mode |= AR_MAC_REG_POWERMGT_AP; 3183 break; 3184 case IEEE80211_M_IBSS: 3185 pm_mode |= AR_MAC_REG_POWERMGT_IBSS; /* XXX: was 0x0 */ 3186 break; 3187 #endif 3188 #endif 3189 case IEEE80211_M_STA: 3190 pm_mode |= AR_MAC_REG_POWERMGT_STA; 3191 break; 3192 case IEEE80211_M_MONITOR: 3193 sc->sc_rx_error_msk = ~AR_RX_ERROR_BAD_RA; 3194 filter = AR_MAC_REG_FTF_MONITOR; 3195 sniffer |= AR_MAC_REG_SNIFFER_ENABLE_PROMISC; 3196 break; 3197 default: 3198 aprint_error_dev(sc->sc_dev, "bad opmode: %d", ic->ic_opmode); 3199 return EOPNOTSUPP; /* XXX: ??? */ 3200 } 3201 otus_write(sc, AR_MAC_REG_POWERMANAGEMENT, pm_mode); 3202 otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, filter); 3203 otus_write(sc, AR_MAC_REG_SNIFFER, sniffer); 3204 (void)otus_write_barrier(sc); 3205 3206 sc->sc_bb_reset = 1; /* Force cold reset. */ 3207 if ((error = otus_set_chan(sc, ic->ic_curchan, 0)) != 0) { 3208 mutex_exit(&sc->sc_write_mtx); 3209 aprint_error_dev(sc->sc_dev, "could not set channel\n"); 3210 return error; 3211 } 3212 3213 /* Start Rx. */ 3214 otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_ENABLE); 3215 (void)otus_write_barrier(sc); 3216 mutex_exit(&sc->sc_write_mtx); 3217 3218 ifp->if_flags &= ~IFF_OACTIVE; 3219 ifp->if_flags |= IFF_RUNNING; 3220 3221 if (ic->ic_opmode == IEEE80211_M_MONITOR) 3222 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 3223 else 3224 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 3225 3226 return 0; 3227 } 3228 3229 Static void 3230 otus_stop(struct ifnet *ifp) 3231 { 3232 struct otus_softc *sc; 3233 struct ieee80211com *ic; 3234 int s; 3235 3236 sc = ifp->if_softc; 3237 3238 DPRINTFN(DBG_FN, sc, "\n"); 3239 3240 ic = &sc->sc_ic; 3241 3242 sc->sc_tx_timer = 0; 3243 ifp->if_timer = 0; 3244 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 3245 3246 callout_halt(&sc->sc_scan_to, NULL); 3247 callout_halt(&sc->sc_calib_to, NULL); 3248 3249 s = splusb(); 3250 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 3251 otus_wait_async(sc); 3252 splx(s); 3253 3254 /* Stop Rx. */ 3255 mutex_enter(&sc->sc_write_mtx); 3256 otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_OFF); 3257 (void)otus_write_barrier(sc); 3258 mutex_exit(&sc->sc_write_mtx); 3259 } 3260