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