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