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