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