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