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