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