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