1 /* $OpenBSD: if_atu.c,v 1.101 2012/02/24 06:19:00 guenther Exp $ */ 2 /* 3 * Copyright (c) 2003, 2004 4 * Daan Vreeken <Danovitsch@Vitsch.net>. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Daan Vreeken. 17 * 4. Neither the name of the author nor the names of any co-contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Daan Vreeken AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL Daan Vreeken OR THE VOICES IN HIS HEAD 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Atmel AT76c503 / AT76c503a / AT76c505 / AT76c505a USB WLAN driver 36 * version 0.5 - 2004-08-03 37 * 38 * Originally written by Daan Vreeken <Danovitsch @ Vitsch . net> 39 * http://vitsch.net/bsd/atuwi 40 * 41 * Contributed to by : 42 * Chris Whitehouse, Alistair Phillips, Peter Pilka, Martijn van Buul, 43 * Suihong Liang, Arjan van Leeuwen, Stuart Walsh 44 * 45 * Ported to OpenBSD by Theo de Raadt and David Gwynne. 46 */ 47 48 #include "bpfilter.h" 49 50 #include <sys/param.h> 51 #include <sys/sockio.h> 52 #include <sys/mbuf.h> 53 #include <sys/kernel.h> 54 #include <sys/socket.h> 55 #include <sys/systm.h> 56 #include <sys/timeout.h> 57 #include <sys/queue.h> 58 #include <sys/device.h> 59 60 #include <machine/bus.h> 61 62 #include <dev/usb/usb.h> 63 #include <dev/usb/usbdi.h> 64 #include <dev/usb/usbdi_util.h> 65 #include <dev/usb/usbdivar.h> 66 67 #include <dev/usb/usbdevs.h> 68 69 #if NBPFILTER > 0 70 #include <net/bpf.h> 71 #endif 72 73 #include <net/if.h> 74 #include <net/if_dl.h> 75 #include <net/if_media.h> 76 77 #ifdef INET 78 #include <netinet/in.h> 79 #include <netinet/if_ether.h> 80 #endif 81 82 #include <net80211/ieee80211_var.h> 83 #include <net80211/ieee80211_radiotap.h> 84 85 #ifdef USB_DEBUG 86 #define ATU_DEBUG 87 #endif 88 89 #include <dev/usb/if_atureg.h> 90 91 #ifdef ATU_DEBUG 92 #define DPRINTF(x) do { if (atudebug) printf x; } while (0) 93 #define DPRINTFN(n,x) do { if (atudebug>(n)) printf x; } while (0) 94 int atudebug = 1; 95 #else 96 #define DPRINTF(x) 97 #define DPRINTFN(n,x) 98 #endif 99 100 int atu_match(struct device *, void *, void *); 101 void atu_attach(struct device *, struct device *, void *); 102 int atu_detach(struct device *, int); 103 int atu_activate(struct device *, int); 104 105 struct cfdriver atu_cd = { 106 NULL, "atu", DV_IFNET 107 }; 108 109 const struct cfattach atu_ca = { 110 sizeof(struct atu_softc), 111 atu_match, 112 atu_attach, 113 atu_detach, 114 atu_activate, 115 }; 116 117 /* 118 * Various supported device vendors/products/radio type. 119 */ 120 struct atu_type atu_devs[] = { 121 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3CRSHEW696, 122 RadioRFMD, ATU_NO_QUIRK }, 123 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_BWU613, 124 RadioRFMD, ATU_NO_QUIRK }, 125 { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_2664W, 126 AT76C503_rfmd_acc, ATU_NO_QUIRK }, 127 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL300, 128 RadioIntersil, ATU_NO_QUIRK }, 129 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL400, 130 RadioRFMD, ATU_NO_QUIRK }, 131 { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_802UAT1, 132 RadioRFMD, ATU_NO_QUIRK }, 133 { USB_VENDOR_ADDTRON, USB_PRODUCT_ADDTRON_AWU120, 134 RadioIntersil, ATU_NO_QUIRK }, 135 { USB_VENDOR_AINCOMM, USB_PRODUCT_AINCOMM_AWU2000B, 136 RadioRFMD2958, ATU_NO_QUIRK }, 137 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_VOYAGER1010, 138 RadioIntersil, ATU_NO_QUIRK }, 139 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013I, 140 RadioIntersil, ATU_NO_QUIRK }, 141 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013, 142 RadioRFMD, ATU_NO_QUIRK }, 143 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I1, 144 RadioIntersil, ATU_NO_QUIRK }, 145 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I2, 146 AT76C503_i3863, ATU_NO_QUIRK }, 147 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503RFMD, 148 RadioRFMD, ATU_NO_QUIRK }, 149 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD, 150 AT76C505_rfmd, ATU_NO_QUIRK }, 151 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD2958, 152 RadioRFMD2958, ATU_NO_QUIRK }, 153 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505A, /* SMC2662 V.4 */ 154 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 155 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505AS, /* quirk? */ 156 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 157 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_WN210, 158 RadioRFMD, ATU_NO_QUIRK }, 159 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D6050, 160 RadioRFMD, ATU_NO_QUIRK }, 161 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U, 162 RadioIntersil, ATU_NO_QUIRK }, 163 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210, 164 RadioIntersil, ATU_NO_QUIRK }, 165 { USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQWLAN, 166 RadioRFMD, ATU_NO_QUIRK }, 167 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK, 168 RadioRFMD2958, ATU_NO_QUIRK }, 169 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CHUSB611G, 170 RadioRFMD2958, ATU_NO_QUIRK }, 171 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL200U, 172 RadioRFMD, ATU_NO_QUIRK }, 173 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL240U, 174 RadioRFMD2958, ATU_NO_QUIRK }, 175 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_XH1153, 176 RadioRFMD, ATU_NO_QUIRK }, 177 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120E, 178 RadioRFMD, ATU_NO_QUIRK }, 179 { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWLBM101, 180 RadioRFMD, ATU_NO_QUIRK }, 181 { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_WLAN, /* quirk? */ 182 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 183 { USB_VENDOR_HP, USB_PRODUCT_HP_HN210W, 184 RadioIntersil, ATU_NO_QUIRK }, 185 { USB_VENDOR_INTEL, USB_PRODUCT_INTEL_AP310, 186 RadioIntersil, ATU_NO_QUIRK }, 187 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11A, 188 RadioIntersil, ATU_NO_QUIRK }, 189 { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_2662WAR, 190 RadioRFMD, ATU_NO_QUIRK }, 191 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11, 192 RadioIntersil, ATU_NO_QUIRK }, 193 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_WUSB11, 194 RadioRFMD, ATU_NO_QUIRK }, 195 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_NWU11B, 196 RadioRFMD, ATU_NO_QUIRK }, 197 { USB_VENDOR_LINKSYS3, USB_PRODUCT_LINKSYS3_WUSB11V28, 198 RadioRFMD2958, ATU_NO_QUIRK }, 199 { USB_VENDOR_MSI, USB_PRODUCT_MSI_WLAN, 200 RadioRFMD2958, ATU_NO_QUIRK }, 201 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101, 202 RadioIntersil, ATU_NO_QUIRK }, 203 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101B, 204 RadioRFMD, ATU_NO_QUIRK }, 205 { USB_VENDOR_OQO, USB_PRODUCT_OQO_WIFI01, 206 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 207 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US11S, 208 RadioRFMD, ATU_NO_QUIRK }, 209 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_SWL2100W, 210 AT76C503_i3863, ATU_NO_QUIRK }, 211 { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WLL013, 212 RadioRFMD, ATU_NO_QUIRK }, 213 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV1, 214 RadioIntersil, ATU_NO_QUIRK }, 215 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV2, 216 AT76C503_rfmd_acc, ATU_NO_QUIRK }, 217 { USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_U300C, 218 RadioIntersil, ATU_NO_QUIRK }, 219 { USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_M4Y750, 220 RadioIntersil, ATU_NO_QUIRK }, 221 }; 222 223 struct atu_radfirm { 224 enum atu_radio_type atur_type; 225 char *atur_internal; 226 char *atur_external; 227 u_int8_t max_rssi; 228 } atu_radfirm[] = { 229 { RadioRFMD, "atu-rfmd-int", "atu-rfmd-ext", 0 }, 230 { RadioRFMD2958, "atu-rfmd2958-int", "atu-rfmd2958-ext", 81 }, 231 { RadioRFMD2958_SMC, "atu-rfmd2958smc-int", "atu-rfmd2958smc-ext", 0 }, 232 { RadioIntersil, "atu-intersil-int", "atu-intersil-ext", 0 }, 233 { 234 AT76C503_i3863, 235 "atu-at76c503-i3863-int", 236 "atu-at76c503-i3863-ext", 237 0 238 }, 239 { 240 AT76C503_rfmd_acc, 241 "atu-at76c503-rfmd-acc-int", 242 "atu-at76c503-rfmd-acc-ext", 243 0 244 }, 245 { 246 AT76C505_rfmd, 247 "atu-at76c505-rfmd-int", 248 "atu-at76c505-rfmd-ext", 249 0 250 } 251 }; 252 253 int atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *); 254 void atu_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 255 void atu_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 256 void atu_start(struct ifnet *); 257 int atu_ioctl(struct ifnet *, u_long, caddr_t); 258 int atu_init(struct ifnet *); 259 void atu_stop(struct ifnet *, int); 260 void atu_watchdog(struct ifnet *); 261 usbd_status atu_usb_request(struct atu_softc *sc, u_int8_t type, 262 u_int8_t request, u_int16_t value, u_int16_t index, 263 u_int16_t length, u_int8_t *data); 264 int atu_send_command(struct atu_softc *sc, u_int8_t *command, int size); 265 int atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd, 266 u_int8_t *status); 267 int atu_wait_completion(struct atu_softc *sc, u_int8_t cmd, 268 u_int8_t *status); 269 int atu_send_mib(struct atu_softc *sc, u_int8_t type, 270 u_int8_t size, u_int8_t index, void *data); 271 int atu_get_mib(struct atu_softc *sc, u_int8_t type, 272 u_int8_t size, u_int8_t index, u_int8_t *buf); 273 #if 0 274 int atu_start_ibss(struct atu_softc *sc); 275 #endif 276 int atu_start_scan(struct atu_softc *sc); 277 int atu_switch_radio(struct atu_softc *sc, int state); 278 int atu_initial_config(struct atu_softc *sc); 279 int atu_join(struct atu_softc *sc, struct ieee80211_node *node); 280 int8_t atu_get_dfu_state(struct atu_softc *sc); 281 u_int8_t atu_get_opmode(struct atu_softc *sc, u_int8_t *mode); 282 void atu_internal_firmware(void *); 283 void atu_external_firmware(void *); 284 int atu_get_card_config(struct atu_softc *sc); 285 int atu_media_change(struct ifnet *ifp); 286 void atu_media_status(struct ifnet *ifp, struct ifmediareq *req); 287 int atu_tx_list_init(struct atu_softc *); 288 int atu_rx_list_init(struct atu_softc *); 289 void atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, 290 int listlen); 291 292 void atu_task(void *); 293 int atu_newstate(struct ieee80211com *, enum ieee80211_state, int); 294 int atu_tx_start(struct atu_softc *, struct ieee80211_node *, 295 struct atu_chain *, struct mbuf *); 296 void atu_complete_attach(struct atu_softc *); 297 u_int8_t atu_calculate_padding(int); 298 299 usbd_status 300 atu_usb_request(struct atu_softc *sc, u_int8_t type, 301 u_int8_t request, u_int16_t value, u_int16_t index, u_int16_t length, 302 u_int8_t *data) 303 { 304 usb_device_request_t req; 305 usbd_xfer_handle xfer; 306 usbd_status err; 307 int total_len = 0, s; 308 309 req.bmRequestType = type; 310 req.bRequest = request; 311 USETW(req.wValue, value); 312 USETW(req.wIndex, index); 313 USETW(req.wLength, length); 314 315 #ifdef ATU_DEBUG 316 if (atudebug) { 317 if ((data == NULL) || (type & UT_READ)) { 318 DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x " 319 "len=%02x\n", sc->atu_dev.dv_xname, request, 320 value, index, length)); 321 } else { 322 DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x " 323 "len=%02x [%8D]\n", sc->atu_dev.dv_xname, 324 request, value, index, length, data, " ")); 325 } 326 } 327 #endif /* ATU_DEBUG */ 328 329 s = splnet(); 330 331 xfer = usbd_alloc_xfer(sc->atu_udev); 332 usbd_setup_default_xfer(xfer, sc->atu_udev, 0, 500000, &req, data, 333 length, USBD_SHORT_XFER_OK, 0); 334 335 err = usbd_sync_transfer(xfer); 336 337 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 338 339 #ifdef ATU_DEBUG 340 if (atudebug) { 341 if (type & UT_READ) { 342 DPRINTFN(20, ("%s: transferred 0x%x bytes in\n", 343 sc->atu_dev.dv_xname, total_len)); 344 DPRINTFN(20, ("%s: dump [%10D]\n", 345 sc->atu_dev.dv_xname, data, " ")); 346 } else { 347 if (total_len != length) 348 DPRINTF(("%s: ARG! wrote only %x bytes\n", 349 sc->atu_dev.dv_xname, total_len)); 350 } 351 } 352 #endif /* ATU_DEBUG */ 353 354 usbd_free_xfer(xfer); 355 356 splx(s); 357 return(err); 358 } 359 360 int 361 atu_send_command(struct atu_softc *sc, u_int8_t *command, int size) 362 { 363 return atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000, 364 0x0000, size, command); 365 } 366 367 int 368 atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status) 369 { 370 /* 371 * all other drivers (including Windoze) request 40 bytes of status 372 * and get a short-xfer of just 6 bytes. we can save 34 bytes of 373 * buffer if we just request those 6 bytes in the first place :) 374 */ 375 /* 376 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd, 377 0x0000, 40, status); 378 */ 379 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd, 380 0x0000, 6, status); 381 } 382 383 int 384 atu_wait_completion(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status) 385 { 386 int idle_count = 0, err; 387 u_int8_t statusreq[6]; 388 389 DPRINTFN(15, ("%s: wait-completion: cmd=%02x\n", 390 sc->atu_dev.dv_xname, cmd)); 391 392 while (1) { 393 err = atu_get_cmd_status(sc, cmd, statusreq); 394 if (err) 395 return err; 396 397 #ifdef ATU_DEBUG 398 if (atudebug) { 399 DPRINTFN(20, ("%s: status=%s cmd=%02x\n", 400 sc->atu_dev.dv_xname, 401 ether_sprintf(statusreq), cmd)); 402 } 403 #endif /* ATU_DEBUG */ 404 405 /* 406 * during normal operations waiting on STATUS_IDLE 407 * will never happen more than once 408 */ 409 if ((statusreq[5] == STATUS_IDLE) && (idle_count++ > 20)) { 410 DPRINTF(("%s: AAARRGGG!!! FIX ME!\n", 411 sc->atu_dev.dv_xname)); 412 return 0; 413 } 414 415 if ((statusreq[5] != STATUS_IN_PROGRESS) && 416 (statusreq[5] != STATUS_IDLE)) { 417 if (status != NULL) 418 *status = statusreq[5]; 419 return 0; 420 } 421 usbd_delay_ms(sc->atu_udev, 25); 422 } 423 } 424 425 int 426 atu_send_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size, 427 u_int8_t index, void *data) 428 { 429 int err; 430 struct atu_cmd_set_mib request; 431 432 /* 433 * We don't construct a MIB packet first and then memcpy it into an 434 * Atmel-command-packet, we just construct it the right way at once :) 435 */ 436 437 memset(&request, 0, sizeof(request)); 438 439 request.AtCmd = CMD_SET_MIB; 440 USETW(request.AtSize, size + 4); 441 442 request.MIBType = type; 443 request.MIBSize = size; 444 request.MIBIndex = index; 445 request.MIBReserved = 0; 446 447 /* 448 * For 1 and 2 byte requests we assume a direct value, 449 * everything bigger than 2 bytes we assume a pointer to the data 450 */ 451 switch (size) { 452 case 0: 453 break; 454 case 1: 455 request.data[0]=(long)data & 0x000000ff; 456 break; 457 case 2: 458 request.data[0]=(long)data & 0x000000ff; 459 request.data[1]=(long)data >> 8; 460 break; 461 default: 462 memcpy(request.data, data, size); 463 break; 464 } 465 466 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000, 467 0x0000, size+8, (uByte *)&request); 468 if (err) 469 return (err); 470 471 DPRINTFN(15, ("%s: sendmib : waitcompletion...\n", 472 sc->atu_dev.dv_xname)); 473 return atu_wait_completion(sc, CMD_SET_MIB, NULL); 474 } 475 476 int 477 atu_get_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size, 478 u_int8_t index, u_int8_t *buf) 479 { 480 481 /* linux/at76c503.c - 478 */ 482 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x033, 483 type << 8, index, size, buf); 484 } 485 486 #if 0 487 int 488 atu_start_ibss(struct atu_softc *sc) 489 { 490 int err; 491 struct atu_cmd_start_ibss Request; 492 493 Request.Cmd = CMD_START_IBSS; 494 Request.Reserved = 0; 495 Request.Size = sizeof(Request) - 4; 496 497 memset(Request.BSSID, 0x00, sizeof(Request.BSSID)); 498 memset(Request.SSID, 0x00, sizeof(Request.SSID)); 499 memcpy(Request.SSID, sc->atu_ssid, sc->atu_ssidlen); 500 Request.SSIDSize = sc->atu_ssidlen; 501 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) 502 Request.Channel = (u_int8_t)sc->atu_desired_channel; 503 else 504 Request.Channel = ATU_DEFAULT_CHANNEL; 505 Request.BSSType = AD_HOC_MODE; 506 memset(Request.Res, 0x00, sizeof(Request.Res)); 507 508 /* Write config to adapter */ 509 err = atu_send_command(sc, (u_int8_t *)&Request, sizeof(Request)); 510 if (err) { 511 DPRINTF(("%s: start ibss failed!\n", 512 sc->atu_dev.dv_xname)); 513 return err; 514 } 515 516 /* Wait for the adapter to do its thing */ 517 err = atu_wait_completion(sc, CMD_START_IBSS, NULL); 518 if (err) { 519 DPRINTF(("%s: error waiting for start_ibss\n", 520 sc->atu_dev.dv_xname)); 521 return err; 522 } 523 524 /* Get the current BSSID */ 525 err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, sc->atu_bssid); 526 if (err) { 527 DPRINTF(("%s: could not get BSSID!\n", 528 sc->atu_dev.dv_xname)); 529 return err; 530 } 531 532 DPRINTF(("%s: started a new IBSS (BSSID=%s)\n", 533 sc->atu_dev.dv_xname, ether_sprintf(sc->atu_bssid))); 534 return 0; 535 } 536 #endif 537 538 int 539 atu_start_scan(struct atu_softc *sc) 540 { 541 struct ieee80211com *ic = &sc->sc_ic; 542 struct atu_cmd_do_scan Scan; 543 usbd_status err; 544 int Cnt; 545 546 memset(&Scan, 0, sizeof(Scan)); 547 548 Scan.Cmd = CMD_START_SCAN; 549 Scan.Reserved = 0; 550 USETW(Scan.Size, sizeof(Scan) - 4); 551 552 /* use the broadcast BSSID (in active scan) */ 553 for (Cnt=0; Cnt<6; Cnt++) 554 Scan.BSSID[Cnt] = 0xff; 555 556 memcpy(Scan.SSID, ic->ic_des_essid, ic->ic_des_esslen); 557 Scan.SSID_Len = ic->ic_des_esslen; 558 559 /* default values for scan */ 560 Scan.ScanType = ATU_SCAN_ACTIVE; 561 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) 562 Scan.Channel = (u_int8_t)sc->atu_desired_channel; 563 else 564 Scan.Channel = sc->atu_channel; 565 566 /* we like scans to be quick :) */ 567 /* the time we wait before sending probe's */ 568 USETW(Scan.ProbeDelay, 0); 569 /* the time we stay on one channel */ 570 USETW(Scan.MinChannelTime, 100); 571 USETW(Scan.MaxChannelTime, 200); 572 /* whether or not we scan all channels */ 573 Scan.InternationalScan = 0xc1; 574 575 #ifdef ATU_DEBUG 576 if (atudebug) { 577 DPRINTFN(20, ("%s: scan cmd len=%02x\n", 578 sc->atu_dev.dv_xname, sizeof(Scan))); 579 DPRINTFN(20, ("%s: scan cmd: %52D\n", sc->atu_dev.dv_xname, 580 (u_int8_t *)&Scan, " ")); 581 } 582 #endif /* ATU_DEBUG */ 583 584 /* Write config to adapter */ 585 err = atu_send_command(sc, (u_int8_t *)&Scan, sizeof(Scan)); 586 if (err) 587 return err; 588 589 /* 590 * We don't wait for the command to finish... the mgmt-thread will do 591 * that for us 592 */ 593 /* 594 err = atu_wait_completion(sc, CMD_START_SCAN, NULL); 595 if (err) 596 return err; 597 */ 598 return 0; 599 } 600 601 int 602 atu_switch_radio(struct atu_softc *sc, int state) 603 { 604 usbd_status err; 605 struct atu_cmd CmdRadio; 606 607 if (sc->atu_radio == RadioIntersil) { 608 /* 609 * Intersil doesn't seem to need/support switching the radio 610 * on/off 611 */ 612 return 0; 613 } 614 615 memset(&CmdRadio, 0, sizeof(CmdRadio)); 616 CmdRadio.Cmd = CMD_RADIO_ON; 617 618 if (sc->atu_radio_on != state) { 619 if (state == 0) 620 CmdRadio.Cmd = CMD_RADIO_OFF; 621 622 err = atu_send_command(sc, (u_int8_t *)&CmdRadio, 623 sizeof(CmdRadio)); 624 if (err) 625 return err; 626 627 err = atu_wait_completion(sc, CmdRadio.Cmd, NULL); 628 if (err) 629 return err; 630 631 DPRINTFN(10, ("%s: radio turned %s\n", 632 sc->atu_dev.dv_xname, state ? "on" : "off")); 633 sc->atu_radio_on = state; 634 } 635 return 0; 636 } 637 638 int 639 atu_initial_config(struct atu_softc *sc) 640 { 641 struct ieee80211com *ic = &sc->sc_ic; 642 u_int32_t i; 643 usbd_status err; 644 /* u_int8_t rates[4] = {0x82, 0x84, 0x8B, 0x96};*/ 645 u_int8_t rates[4] = {0x82, 0x04, 0x0B, 0x16}; 646 struct atu_cmd_card_config cmd; 647 u_int8_t reg_domain; 648 649 DPRINTFN(10, ("%s: sending mac-addr\n", sc->atu_dev.dv_xname)); 650 err = atu_send_mib(sc, MIB_MAC_ADDR__ADDR, ic->ic_myaddr); 651 if (err) { 652 DPRINTF(("%s: error setting mac-addr\n", 653 sc->atu_dev.dv_xname)); 654 return err; 655 } 656 657 /* 658 DPRINTF(("%s: sending reg-domain\n", sc->atu_dev.dv_xname)); 659 err = atu_send_mib(sc, MIB_PHY__REG_DOMAIN, NR(0x30)); 660 if (err) { 661 DPRINTF(("%s: error setting mac-addr\n", 662 sc->atu_dev.dv_xname)); 663 return err; 664 } 665 */ 666 667 memset(&cmd, 0, sizeof(cmd)); 668 cmd.Cmd = CMD_STARTUP; 669 cmd.Reserved = 0; 670 USETW(cmd.Size, sizeof(cmd) - 4); 671 672 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) 673 cmd.Channel = (u_int8_t)sc->atu_desired_channel; 674 else 675 cmd.Channel = sc->atu_channel; 676 cmd.AutoRateFallback = 1; 677 memcpy(cmd.BasicRateSet, rates, 4); 678 679 /* ShortRetryLimit should be 7 according to 802.11 spec */ 680 cmd.ShortRetryLimit = 7; 681 USETW(cmd.RTS_Threshold, 2347); 682 USETW(cmd.FragThreshold, 2346); 683 684 /* Doesn't seem to work, but we'll set it to 1 anyway */ 685 cmd.PromiscuousMode = 1; 686 687 /* this goes into the beacon we transmit */ 688 cmd.PrivacyInvoked = (ic->ic_flags & IEEE80211_F_WEPON) ? 1 : 0; 689 690 cmd.ExcludeUnencrypted = 0; 691 switch (ic->ic_nw_keys[ic->ic_wep_txkey].k_cipher) { 692 case IEEE80211_CIPHER_WEP40: 693 cmd.EncryptionType = ATU_WEP_40BITS; 694 break; 695 case IEEE80211_CIPHER_WEP104: 696 cmd.EncryptionType = ATU_WEP_104BITS; 697 break; 698 default: 699 cmd.EncryptionType = ATU_WEP_OFF; 700 break; 701 } 702 703 cmd.WEP_DefaultKeyID = ic->ic_wep_txkey; 704 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 705 memcpy(cmd.WEP_DefaultKey[i], ic->ic_nw_keys[i].k_key, 706 ic->ic_nw_keys[i].k_len); 707 } 708 709 /* Setting the SSID here doesn't seem to do anything */ 710 memcpy(cmd.SSID, ic->ic_des_essid, ic->ic_des_esslen); 711 cmd.SSID_Len = ic->ic_des_esslen; 712 713 cmd.ShortPreamble = 0; 714 USETW(cmd.BeaconPeriod, 100); 715 /* cmd.BeaconPeriod = 65535; */ 716 717 /* 718 * TODO: 719 * read reg domain MIB_PHY @ 0x17 (1 byte), (reply = 0x30) 720 * we should do something useful with this info. right now it's just 721 * ignored 722 */ 723 err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, ®_domain); 724 if (err) { 725 DPRINTF(("%s: could not get regdomain!\n", 726 sc->atu_dev.dv_xname)); 727 } else { 728 DPRINTF(("%s: we're in reg domain 0x%x according to the " 729 "adapter\n", sc->atu_dev.dv_xname, reg_domain)); 730 } 731 732 #ifdef ATU_DEBUG 733 if (atudebug) { 734 DPRINTFN(20, ("%s: configlen=%02x\n", sc->atu_dev.dv_xname, 735 sizeof(cmd))); 736 DPRINTFN(20, ("%s: configdata= %108D\n", 737 sc->atu_dev.dv_xname, (u_int8_t *)&cmd, " ")); 738 } 739 #endif /* ATU_DEBUG */ 740 741 /* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */ 742 743 err = atu_send_command(sc, (u_int8_t *)&cmd, sizeof(cmd)); 744 if (err) 745 return err; 746 err = atu_wait_completion(sc, CMD_STARTUP, NULL); 747 if (err) 748 return err; 749 750 /* Turn on radio now */ 751 err = atu_switch_radio(sc, 1); 752 if (err) 753 return err; 754 755 /* preamble type = short */ 756 err = atu_send_mib(sc, MIB_LOCAL__PREAMBLE, NR(PREAMBLE_SHORT)); 757 if (err) 758 return err; 759 760 /* frag = 1536 */ 761 err = atu_send_mib(sc, MIB_MAC__FRAG, NR(2346)); 762 if (err) 763 return err; 764 765 /* rts = 1536 */ 766 err = atu_send_mib(sc, MIB_MAC__RTS, NR(2347)); 767 if (err) 768 return err; 769 770 /* auto rate fallback = 1 */ 771 err = atu_send_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, NR(1)); 772 if (err) 773 return err; 774 775 /* power mode = full on, no power saving */ 776 err = atu_send_mib(sc, MIB_MAC_MGMT__POWER_MODE, 777 NR(POWER_MODE_ACTIVE)); 778 if (err) 779 return err; 780 781 DPRINTFN(10, ("%s: completed initial config\n", 782 sc->atu_dev.dv_xname)); 783 return 0; 784 } 785 786 int 787 atu_join(struct atu_softc *sc, struct ieee80211_node *node) 788 { 789 struct atu_cmd_join join; 790 u_int8_t status; 791 usbd_status err; 792 793 memset(&join, 0, sizeof(join)); 794 795 join.Cmd = CMD_JOIN; 796 join.Reserved = 0x00; 797 USETW(join.Size, sizeof(join) - 4); 798 799 DPRINTFN(15, ("%s: pre-join sc->atu_bssid=%s\n", 800 sc->atu_dev.dv_xname, ether_sprintf(sc->atu_bssid))); 801 DPRINTFN(15, ("%s: mode=%d\n", sc->atu_dev.dv_xname, 802 sc->atu_mode)); 803 memcpy(join.bssid, node->ni_bssid, IEEE80211_ADDR_LEN); 804 memcpy(join.essid, node->ni_essid, node->ni_esslen); 805 join.essid_size = node->ni_esslen; 806 if (node->ni_capinfo & IEEE80211_CAPINFO_IBSS) 807 join.bss_type = AD_HOC_MODE; 808 else 809 join.bss_type = INFRASTRUCTURE_MODE; 810 join.channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan); 811 812 USETW(join.timeout, ATU_JOIN_TIMEOUT); 813 join.reserved = 0x00; 814 815 DPRINTFN(10, ("%s: trying to join BSSID=%s\n", 816 sc->atu_dev.dv_xname, ether_sprintf(join.bssid))); 817 err = atu_send_command(sc, (u_int8_t *)&join, sizeof(join)); 818 if (err) { 819 DPRINTF(("%s: ERROR trying to join IBSS\n", 820 sc->atu_dev.dv_xname)); 821 return err; 822 } 823 err = atu_wait_completion(sc, CMD_JOIN, &status); 824 if (err) { 825 DPRINTF(("%s: error joining BSS!\n", 826 sc->atu_dev.dv_xname)); 827 return err; 828 } 829 if (status != STATUS_COMPLETE) { 830 DPRINTF(("%s: error joining... [status=%02x]\n", 831 sc->atu_dev.dv_xname, status)); 832 return status; 833 } else { 834 DPRINTFN(10, ("%s: joined BSS\n", sc->atu_dev.dv_xname)); 835 } 836 return err; 837 } 838 839 /* 840 * Get the state of the DFU unit 841 */ 842 int8_t 843 atu_get_dfu_state(struct atu_softc *sc) 844 { 845 u_int8_t state; 846 847 if (atu_usb_request(sc, DFU_GETSTATE, 0, 0, 1, &state)) 848 return -1; 849 return state; 850 } 851 852 /* 853 * Get MAC opmode 854 */ 855 u_int8_t 856 atu_get_opmode(struct atu_softc *sc, u_int8_t *mode) 857 { 858 859 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0001, 860 0x0000, 1, mode); 861 } 862 863 /* 864 * Upload the internal firmware into the device 865 */ 866 void 867 atu_internal_firmware(void *arg) 868 { 869 struct atu_softc *sc = arg; 870 u_char state, *ptr = NULL, *firm = NULL, status[6]; 871 int block_size, block = 0, err, i; 872 size_t bytes_left = 0; 873 char *name = "unknown-device"; 874 875 /* 876 * Uploading firmware is done with the DFU (Device Firmware Upgrade) 877 * interface. See "Universal Serial Bus - Device Class Specification 878 * for Device Firmware Upgrade" pdf for details of the protocol. 879 * Maybe this could be moved to a separate 'firmware driver' once more 880 * device drivers need it... For now we'll just do it here. 881 * 882 * Just for your information, the Atmel's DFU descriptor looks like 883 * this: 884 * 885 * 07 size 886 * 21 type 887 * 01 capabilities : only firmware download, need reset 888 * after download 889 * 13 05 detach timeout : max 1299ms between DFU_DETACH and 890 * reset 891 * 00 04 max bytes of firmware per transaction : 1024 892 */ 893 894 /* Choose the right firmware for the device */ 895 for (i = 0; i < nitems(atu_radfirm); i++) 896 if (sc->atu_radio == atu_radfirm[i].atur_type) 897 name = atu_radfirm[i].atur_internal; 898 899 DPRINTF(("%s: loading firmware %s...\n", 900 sc->atu_dev.dv_xname, name)); 901 err = loadfirmware(name, &firm, &bytes_left); 902 if (err != 0) { 903 printf("%s: %s loadfirmware error %d\n", 904 sc->atu_dev.dv_xname, name, err); 905 goto fail; 906 } 907 908 ptr = firm; 909 state = atu_get_dfu_state(sc); 910 911 while (block >= 0 && state > 0) { 912 switch (state) { 913 case DFUState_DnLoadSync: 914 /* get DFU status */ 915 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0 , 6, 916 status); 917 if (err) { 918 DPRINTF(("%s: dfu_getstatus failed!\n", 919 sc->atu_dev.dv_xname)); 920 free(firm, M_DEVBUF); 921 goto fail; 922 } 923 /* success means state => DnLoadIdle */ 924 state = DFUState_DnLoadIdle; 925 continue; 926 break; 927 928 case DFUState_DFUIdle: 929 case DFUState_DnLoadIdle: 930 if (bytes_left>=DFU_MaxBlockSize) 931 block_size = DFU_MaxBlockSize; 932 else 933 block_size = bytes_left; 934 DPRINTFN(15, ("%s: firmware block %d\n", 935 sc->atu_dev.dv_xname, block)); 936 937 err = atu_usb_request(sc, DFU_DNLOAD, block++, 0, 938 block_size, ptr); 939 if (err) { 940 DPRINTF(("%s: dfu_dnload failed\n", 941 sc->atu_dev.dv_xname)); 942 free(firm, M_DEVBUF); 943 goto fail; 944 } 945 946 ptr += block_size; 947 bytes_left -= block_size; 948 if (block_size == 0) 949 block = -1; 950 break; 951 952 default: 953 DPRINTFN(20, ("%s: sleeping for a while\n", 954 sc->atu_dev.dv_xname)); 955 usbd_delay_ms(sc->atu_udev, 100); 956 break; 957 } 958 959 state = atu_get_dfu_state(sc); 960 } 961 free(firm, M_DEVBUF); 962 963 if (state != DFUState_ManifestSync) { 964 DPRINTF(("%s: state != manifestsync... eek!\n", 965 sc->atu_dev.dv_xname)); 966 } 967 968 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0, 6, status); 969 if (err) { 970 DPRINTF(("%s: dfu_getstatus failed!\n", 971 sc->atu_dev.dv_xname)); 972 goto fail; 973 } 974 975 DPRINTFN(15, ("%s: sending remap\n", sc->atu_dev.dv_xname)); 976 err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL); 977 if ((err) && (!ISSET(sc->atu_quirk, ATU_QUIRK_NO_REMAP))) { 978 DPRINTF(("%s: remap failed!\n", sc->atu_dev.dv_xname)); 979 goto fail; 980 } 981 982 /* after a lot of trying and measuring I found out the device needs 983 * about 56 miliseconds after sending the remap command before 984 * it's ready to communicate again. So we'll wait just a little bit 985 * longer than that to be sure... 986 */ 987 usbd_delay_ms(sc->atu_udev, 56+100); 988 989 printf("%s: reattaching after firmware upload\n", 990 sc->atu_dev.dv_xname); 991 usb_needs_reattach(sc->atu_udev); 992 993 fail: 994 usbd_deactivate(sc->atu_udev); 995 } 996 997 void 998 atu_external_firmware(void *arg) 999 { 1000 struct atu_softc *sc = arg; 1001 u_char *ptr = NULL, *firm = NULL; 1002 int block_size, block = 0, err, i; 1003 size_t bytes_left = 0; 1004 char *name = "unknown-device"; 1005 1006 for (i = 0; i < nitems(atu_radfirm); i++) 1007 if (sc->atu_radio == atu_radfirm[i].atur_type) 1008 name = atu_radfirm[i].atur_external; 1009 1010 DPRINTF(("%s: loading external firmware %s\n", 1011 sc->atu_dev.dv_xname, name)); 1012 err = loadfirmware(name, &firm, &bytes_left); 1013 if (err != 0) { 1014 printf("%s: %s loadfirmware error %d\n", 1015 sc->atu_dev.dv_xname, name, err); 1016 return; 1017 } 1018 ptr = firm; 1019 1020 while (bytes_left) { 1021 if (bytes_left > 1024) 1022 block_size = 1024; 1023 else 1024 block_size = bytes_left; 1025 1026 DPRINTFN(15, ("%s: block:%d size:%d\n", 1027 sc->atu_dev.dv_xname, block, block_size)); 1028 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 1029 0x0802, block, block_size, ptr); 1030 if (err) { 1031 DPRINTF(("%s: could not load external firmware " 1032 "block\n", sc->atu_dev.dv_xname)); 1033 free(firm, M_DEVBUF); 1034 return; 1035 } 1036 1037 ptr += block_size; 1038 block++; 1039 bytes_left -= block_size; 1040 } 1041 free(firm, M_DEVBUF); 1042 1043 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0802, 1044 block, 0, NULL); 1045 if (err) { 1046 DPRINTF(("%s: could not load last zero-length firmware " 1047 "block\n", sc->atu_dev.dv_xname)); 1048 return; 1049 } 1050 1051 /* 1052 * The SMC2662w V.4 seems to require some time to do its thing with 1053 * the external firmware... 20 ms isn't enough, but 21 ms works 100 1054 * times out of 100 tries. We'll wait a bit longer just to be sure 1055 */ 1056 if (sc->atu_quirk & ATU_QUIRK_FW_DELAY) 1057 usbd_delay_ms(sc->atu_udev, 21 + 100); 1058 1059 DPRINTFN(10, ("%s: external firmware upload done\n", 1060 sc->atu_dev.dv_xname)); 1061 /* complete configuration after the firmwares have been uploaded */ 1062 atu_complete_attach(sc); 1063 } 1064 1065 int 1066 atu_get_card_config(struct atu_softc *sc) 1067 { 1068 struct ieee80211com *ic = &sc->sc_ic; 1069 struct atu_rfmd_conf rfmd_conf; 1070 struct atu_intersil_conf intersil_conf; 1071 int err; 1072 1073 switch (sc->atu_radio) { 1074 1075 case RadioRFMD: 1076 case RadioRFMD2958: 1077 case RadioRFMD2958_SMC: 1078 case AT76C503_rfmd_acc: 1079 case AT76C505_rfmd: 1080 err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 1081 0x0a02, 0x0000, sizeof(rfmd_conf), 1082 (u_int8_t *)&rfmd_conf); 1083 if (err) { 1084 DPRINTF(("%s: could not get rfmd config!\n", 1085 sc->atu_dev.dv_xname)); 1086 return err; 1087 } 1088 memcpy(ic->ic_myaddr, rfmd_conf.MACAddr, IEEE80211_ADDR_LEN); 1089 break; 1090 1091 case RadioIntersil: 1092 case AT76C503_i3863: 1093 err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 1094 0x0902, 0x0000, sizeof(intersil_conf), 1095 (u_int8_t *)&intersil_conf); 1096 if (err) { 1097 DPRINTF(("%s: could not get intersil config!\n", 1098 sc->atu_dev.dv_xname)); 1099 return err; 1100 } 1101 memcpy(ic->ic_myaddr, intersil_conf.MACAddr, 1102 IEEE80211_ADDR_LEN); 1103 break; 1104 } 1105 return 0; 1106 } 1107 1108 /* 1109 * Probe for an AT76c503 chip. 1110 */ 1111 int 1112 atu_match(struct device *parent, void *match, void *aux) 1113 { 1114 struct usb_attach_arg *uaa = aux; 1115 int i; 1116 1117 if (!uaa->iface) 1118 return(UMATCH_NONE); 1119 1120 for (i = 0; i < nitems(atu_devs); i++) { 1121 struct atu_type *t = &atu_devs[i]; 1122 1123 if (uaa->vendor == t->atu_vid && 1124 uaa->product == t->atu_pid) { 1125 return(UMATCH_VENDOR_PRODUCT); 1126 } 1127 } 1128 return(UMATCH_NONE); 1129 } 1130 1131 int 1132 atu_media_change(struct ifnet *ifp) 1133 { 1134 #ifdef ATU_DEBUG 1135 struct atu_softc *sc = ifp->if_softc; 1136 #endif /* ATU_DEBUG */ 1137 int err; 1138 1139 DPRINTFN(10, ("%s: atu_media_change\n", sc->atu_dev.dv_xname)); 1140 1141 err = ieee80211_media_change(ifp); 1142 if (err == ENETRESET) { 1143 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 1144 (IFF_RUNNING|IFF_UP)) 1145 atu_init(ifp); 1146 err = 0; 1147 } 1148 1149 return (err); 1150 } 1151 1152 void 1153 atu_media_status(struct ifnet *ifp, struct ifmediareq *req) 1154 { 1155 #ifdef ATU_DEBUG 1156 struct atu_softc *sc = ifp->if_softc; 1157 #endif /* ATU_DEBUG */ 1158 1159 DPRINTFN(10, ("%s: atu_media_status\n", sc->atu_dev.dv_xname)); 1160 1161 ieee80211_media_status(ifp, req); 1162 } 1163 1164 void 1165 atu_task(void *arg) 1166 { 1167 struct atu_softc *sc = (struct atu_softc *)arg; 1168 struct ieee80211com *ic = &sc->sc_ic; 1169 struct ifnet *ifp = &ic->ic_if; 1170 usbd_status err; 1171 int s; 1172 1173 DPRINTFN(10, ("%s: atu_task\n", sc->atu_dev.dv_xname)); 1174 1175 if (usbd_is_dying(sc->atu_udev)) 1176 return; 1177 1178 switch (sc->sc_cmd) { 1179 case ATU_C_SCAN: 1180 1181 err = atu_start_scan(sc); 1182 if (err) { 1183 DPRINTFN(1, ("%s: atu_init: couldn't start scan!\n", 1184 sc->atu_dev.dv_xname)); 1185 return; 1186 } 1187 1188 err = atu_wait_completion(sc, CMD_START_SCAN, NULL); 1189 if (err) { 1190 DPRINTF(("%s: atu_init: error waiting for scan\n", 1191 sc->atu_dev.dv_xname)); 1192 return; 1193 } 1194 1195 DPRINTF(("%s: ==========================> END OF SCAN!\n", 1196 sc->atu_dev.dv_xname)); 1197 1198 s = splnet(); 1199 /* ieee80211_next_scan(ifp); */ 1200 ieee80211_end_scan(ifp); 1201 splx(s); 1202 1203 DPRINTF(("%s: ----------------------======> END OF SCAN2!\n", 1204 sc->atu_dev.dv_xname)); 1205 break; 1206 1207 case ATU_C_JOIN: 1208 atu_join(sc, ic->ic_bss); 1209 } 1210 } 1211 1212 int 1213 atu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1214 { 1215 struct ifnet *ifp = &ic->ic_if; 1216 struct atu_softc *sc = ifp->if_softc; 1217 enum ieee80211_state ostate = ic->ic_state; 1218 1219 DPRINTFN(10, ("%s: atu_newstate: %s -> %s\n", sc->atu_dev.dv_xname, 1220 ieee80211_state_name[ostate], ieee80211_state_name[nstate])); 1221 1222 switch (nstate) { 1223 case IEEE80211_S_SCAN: 1224 memcpy(ic->ic_chan_scan, ic->ic_chan_active, 1225 sizeof(ic->ic_chan_active)); 1226 ieee80211_free_allnodes(ic); 1227 1228 /* tell the event thread that we want a scan */ 1229 sc->sc_cmd = ATU_C_SCAN; 1230 usb_add_task(sc->atu_udev, &sc->sc_task); 1231 1232 /* handle this ourselves */ 1233 ic->ic_state = nstate; 1234 return (0); 1235 1236 case IEEE80211_S_AUTH: 1237 case IEEE80211_S_RUN: 1238 if (ostate == IEEE80211_S_SCAN) { 1239 sc->sc_cmd = ATU_C_JOIN; 1240 usb_add_task(sc->atu_udev, &sc->sc_task); 1241 } 1242 break; 1243 default: 1244 /* nothing to do */ 1245 break; 1246 } 1247 1248 return (*sc->sc_newstate)(ic, nstate, arg); 1249 } 1250 1251 /* 1252 * Attach the interface. Allocate softc structures, do 1253 * setup and ethernet/BPF attach. 1254 */ 1255 void 1256 atu_attach(struct device *parent, struct device *self, void *aux) 1257 { 1258 struct atu_softc *sc = (struct atu_softc *)self; 1259 struct usb_attach_arg *uaa = aux; 1260 usbd_status err; 1261 usbd_device_handle dev = uaa->device; 1262 u_int8_t mode, channel; 1263 int i; 1264 1265 sc->atu_unit = self->dv_unit; 1266 sc->atu_udev = dev; 1267 1268 err = usbd_set_config_no(dev, ATU_CONFIG_NO, 1); 1269 if (err) { 1270 printf("%s: setting config no failed\n", 1271 sc->atu_dev.dv_xname); 1272 goto fail; 1273 } 1274 1275 err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface); 1276 if (err) { 1277 printf("%s: getting interface handle failed\n", 1278 sc->atu_dev.dv_xname); 1279 goto fail; 1280 } 1281 1282 /* 1283 * look up the radio_type for the device 1284 * basically does the same as USB_MATCH 1285 */ 1286 for (i = 0; i < nitems(atu_devs); i++) { 1287 struct atu_type *t = &atu_devs[i]; 1288 1289 if (uaa->vendor == t->atu_vid && 1290 uaa->product == t->atu_pid) { 1291 sc->atu_radio = t->atu_radio; 1292 sc->atu_quirk = t->atu_quirk; 1293 } 1294 } 1295 1296 /* 1297 * Check in the interface descriptor if we're in DFU mode 1298 * If we're in DFU mode, we upload the external firmware 1299 * If we're not, the PC must have rebooted without power-cycling 1300 * the device.. I've tried this out, a reboot only requeres the 1301 * external firmware to be reloaded :) 1302 * 1303 * Hmm. The at76c505a doesn't report a DFU descriptor when it's 1304 * in DFU mode... Let's just try to get the opmode 1305 */ 1306 err = atu_get_opmode(sc, &mode); 1307 DPRINTFN(20, ("%s: opmode: %d\n", sc->atu_dev.dv_xname, mode)); 1308 if (err || (mode != MODE_NETCARD && mode != MODE_NOFLASHNETCARD)) { 1309 DPRINTF(("%s: starting internal firmware download\n", 1310 sc->atu_dev.dv_xname)); 1311 1312 if (rootvp == NULL) 1313 mountroothook_establish(atu_internal_firmware, sc); 1314 else 1315 atu_internal_firmware(sc); 1316 /* 1317 * atu_internal_firmware will cause a reset of the device 1318 * so we don't want to do any more configuration after this 1319 * point. 1320 */ 1321 return; 1322 } 1323 1324 uaa->iface = sc->atu_iface; 1325 1326 if (mode != MODE_NETCARD) { 1327 DPRINTFN(15, ("%s: device needs external firmware\n", 1328 sc->atu_dev.dv_xname)); 1329 1330 if (mode != MODE_NOFLASHNETCARD) { 1331 DPRINTF(("%s: EEK! unexpected opmode=%d\n", 1332 sc->atu_dev.dv_xname, mode)); 1333 } 1334 1335 /* 1336 * There is no difference in opmode before and after external 1337 * firmware upload with the SMC2662 V.4 . So instead we'll try 1338 * to read the channel number. If we succeed, external 1339 * firmwaremust have been already uploaded... 1340 */ 1341 if (sc->atu_radio != RadioIntersil) { 1342 err = atu_get_mib(sc, MIB_PHY__CHANNEL, &channel); 1343 if (!err) { 1344 DPRINTF(("%s: external firmware has already" 1345 " been downloaded\n", 1346 sc->atu_dev.dv_xname)); 1347 atu_complete_attach(sc); 1348 return; 1349 } 1350 } 1351 1352 if (rootvp == NULL) 1353 mountroothook_establish(atu_external_firmware, sc); 1354 else 1355 atu_external_firmware(sc); 1356 1357 /* 1358 * atu_external_firmware will call atu_complete_attach after 1359 * it's finished so we can just return. 1360 */ 1361 } else { 1362 /* all the firmwares are in place, so complete the attach */ 1363 atu_complete_attach(sc); 1364 } 1365 fail: 1366 usbd_deactivate(sc->atu_udev); 1367 } 1368 1369 void 1370 atu_complete_attach(struct atu_softc *sc) 1371 { 1372 struct ieee80211com *ic = &sc->sc_ic; 1373 struct ifnet *ifp = &ic->ic_if; 1374 usb_interface_descriptor_t *id; 1375 usb_endpoint_descriptor_t *ed; 1376 usbd_status err; 1377 int i; 1378 #ifdef ATU_DEBUG 1379 struct atu_fw fw; 1380 #endif 1381 1382 id = usbd_get_interface_descriptor(sc->atu_iface); 1383 1384 /* Find endpoints. */ 1385 for (i = 0; i < id->bNumEndpoints; i++) { 1386 ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i); 1387 if (!ed) { 1388 DPRINTF(("%s: num_endp:%d\n", sc->atu_dev.dv_xname, 1389 sc->atu_iface->idesc->bNumEndpoints)); 1390 DPRINTF(("%s: couldn't get ep %d\n", 1391 sc->atu_dev.dv_xname, i)); 1392 goto fail; 1393 } 1394 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 1395 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1396 sc->atu_ed[ATU_ENDPT_RX] = ed->bEndpointAddress; 1397 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 1398 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1399 sc->atu_ed[ATU_ENDPT_TX] = ed->bEndpointAddress; 1400 } 1401 } 1402 1403 /* read device config & get MAC address */ 1404 err = atu_get_card_config(sc); 1405 if (err) { 1406 printf("%s: could not get card cfg!\n", 1407 sc->atu_dev.dv_xname); 1408 goto fail; 1409 } 1410 1411 #ifdef ATU_DEBUG 1412 /* DEBUG : try to get firmware version */ 1413 err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0, 1414 (u_int8_t *)&fw); 1415 if (!err) { 1416 DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d " 1417 "build:%d\n", sc->atu_dev.dv_xname, fw.major, fw.minor, 1418 fw.patch, fw.build)); 1419 } else { 1420 DPRINTF(("%s: get firmware version failed\n", 1421 sc->atu_dev.dv_xname)); 1422 } 1423 #endif /* ATU_DEBUG */ 1424 1425 /* Show the world our MAC address */ 1426 printf("%s: address %s\n", sc->atu_dev.dv_xname, 1427 ether_sprintf(ic->ic_myaddr)); 1428 1429 sc->atu_cdata.atu_tx_inuse = 0; 1430 1431 bzero(sc->atu_bssid, ETHER_ADDR_LEN); 1432 sc->atu_channel = ATU_DEFAULT_CHANNEL; 1433 sc->atu_desired_channel = IEEE80211_CHAN_ANY; 1434 sc->atu_mode = INFRASTRUCTURE_MODE; 1435 1436 ic->ic_softc = sc; 1437 ic->ic_phytype = IEEE80211_T_DS; 1438 ic->ic_opmode = IEEE80211_M_STA; 1439 ic->ic_state = IEEE80211_S_INIT; 1440 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP | IEEE80211_C_SCANALL; 1441 ic->ic_max_rssi = atu_radfirm[sc->atu_radio].max_rssi; 1442 1443 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 1444 1445 for (i = 1; i <= 14; i++) { 1446 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B | 1447 IEEE80211_CHAN_PASSIVE; 1448 ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i, 1449 ic->ic_channels[i].ic_flags); 1450 } 1451 1452 ic->ic_ibss_chan = &ic->ic_channels[0]; 1453 1454 ifp->if_softc = sc; 1455 memcpy(ifp->if_xname, sc->atu_dev.dv_xname, IFNAMSIZ); 1456 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1457 ifp->if_start = atu_start; 1458 ifp->if_ioctl = atu_ioctl; 1459 ifp->if_watchdog = atu_watchdog; 1460 ifp->if_mtu = ATU_DEFAULT_MTU; 1461 IFQ_SET_READY(&ifp->if_snd); 1462 1463 /* Call MI attach routine. */ 1464 if_attach(ifp); 1465 ieee80211_ifattach(ifp); 1466 1467 sc->sc_newstate = ic->ic_newstate; 1468 ic->ic_newstate = atu_newstate; 1469 1470 /* setup ifmedia interface */ 1471 ieee80211_media_init(ifp, atu_media_change, atu_media_status); 1472 1473 usb_init_task(&sc->sc_task, atu_task, sc, USB_TASK_TYPE_GENERIC); 1474 1475 #if NBPFILTER > 0 1476 bpfattach(&sc->sc_radiobpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO, 1477 sizeof(struct ieee80211_frame) + 64); 1478 1479 bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu)); 1480 sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu); 1481 sc->sc_rxtap.rr_ihdr.it_present = htole32(ATU_RX_RADIOTAP_PRESENT); 1482 1483 bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu)); 1484 sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu); 1485 sc->sc_txtap.rt_ihdr.it_present = htole32(ATU_TX_RADIOTAP_PRESENT); 1486 #endif 1487 1488 fail: 1489 usbd_deactivate(sc->atu_udev); 1490 } 1491 1492 int 1493 atu_detach(struct device *self, int flags) 1494 { 1495 struct atu_softc *sc = (struct atu_softc *)self; 1496 struct ifnet *ifp = &sc->sc_ic.ic_if; 1497 1498 DPRINTFN(10, ("%s: atu_detach\n", sc->atu_dev.dv_xname)); 1499 1500 if (ifp->if_flags & IFF_RUNNING) 1501 atu_stop(ifp, 1); 1502 1503 usb_rem_task(sc->atu_udev, &sc->sc_task); 1504 1505 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) 1506 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); 1507 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) 1508 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); 1509 1510 if (ifp->if_softc != NULL) { 1511 ieee80211_ifdetach(ifp); 1512 if_detach(ifp); 1513 } 1514 1515 return(0); 1516 } 1517 1518 int 1519 atu_activate(struct device *self, int act) 1520 { 1521 struct atu_softc *sc = (struct atu_softc *)self; 1522 1523 switch (act) { 1524 case DVACT_DEACTIVATE: 1525 usbd_deactivate(sc->atu_udev); 1526 break; 1527 } 1528 return (0); 1529 } 1530 1531 /* 1532 * Initialize an RX descriptor and attach an MBUF cluster. 1533 */ 1534 int 1535 atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m) 1536 { 1537 struct mbuf *m_new = NULL; 1538 1539 if (m == NULL) { 1540 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 1541 if (m_new == NULL) { 1542 DPRINTF(("%s: no memory for rx list\n", 1543 sc->atu_dev.dv_xname)); 1544 return(ENOBUFS); 1545 } 1546 1547 MCLGET(m_new, M_DONTWAIT); 1548 if (!(m_new->m_flags & M_EXT)) { 1549 DPRINTF(("%s: no memory for rx list\n", 1550 sc->atu_dev.dv_xname)); 1551 m_freem(m_new); 1552 return(ENOBUFS); 1553 } 1554 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1555 } else { 1556 m_new = m; 1557 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1558 m_new->m_data = m_new->m_ext.ext_buf; 1559 } 1560 c->atu_mbuf = m_new; 1561 return(0); 1562 } 1563 1564 int 1565 atu_rx_list_init(struct atu_softc *sc) 1566 { 1567 struct atu_cdata *cd = &sc->atu_cdata; 1568 struct atu_chain *c; 1569 int i; 1570 1571 DPRINTFN(15, ("%s: atu_rx_list_init: enter\n", 1572 sc->atu_dev.dv_xname)); 1573 1574 for (i = 0; i < ATU_RX_LIST_CNT; i++) { 1575 c = &cd->atu_rx_chain[i]; 1576 c->atu_sc = sc; 1577 c->atu_idx = i; 1578 if (c->atu_xfer == NULL) { 1579 c->atu_xfer = usbd_alloc_xfer(sc->atu_udev); 1580 if (c->atu_xfer == NULL) 1581 return (ENOBUFS); 1582 c->atu_buf = usbd_alloc_buffer(c->atu_xfer, 1583 ATU_RX_BUFSZ); 1584 if (c->atu_buf == NULL) /* XXX free xfer */ 1585 return (ENOBUFS); 1586 if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */ 1587 return(ENOBUFS); 1588 } 1589 } 1590 return (0); 1591 } 1592 1593 int 1594 atu_tx_list_init(struct atu_softc *sc) 1595 { 1596 struct atu_cdata *cd = &sc->atu_cdata; 1597 struct atu_chain *c; 1598 int i; 1599 1600 DPRINTFN(15, ("%s: atu_tx_list_init\n", 1601 sc->atu_dev.dv_xname)); 1602 1603 SLIST_INIT(&cd->atu_tx_free); 1604 sc->atu_cdata.atu_tx_inuse = 0; 1605 1606 for (i = 0; i < ATU_TX_LIST_CNT; i++) { 1607 c = &cd->atu_tx_chain[i]; 1608 c->atu_sc = sc; 1609 c->atu_idx = i; 1610 if (c->atu_xfer == NULL) { 1611 c->atu_xfer = usbd_alloc_xfer(sc->atu_udev); 1612 if (c->atu_xfer == NULL) 1613 return(ENOBUFS); 1614 c->atu_mbuf = NULL; 1615 c->atu_buf = usbd_alloc_buffer(c->atu_xfer, 1616 ATU_TX_BUFSZ); 1617 if (c->atu_buf == NULL) 1618 return(ENOBUFS); /* XXX free xfer */ 1619 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list); 1620 } 1621 } 1622 return(0); 1623 } 1624 1625 void 1626 atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, 1627 int listlen) 1628 { 1629 int i; 1630 1631 /* Free resources. */ 1632 for (i = 0; i < listlen; i++) { 1633 if (ch[i].atu_buf != NULL) 1634 ch[i].atu_buf = NULL; 1635 if (ch[i].atu_mbuf != NULL) { 1636 m_freem(ch[i].atu_mbuf); 1637 ch[i].atu_mbuf = NULL; 1638 } 1639 if (ch[i].atu_xfer != NULL) { 1640 usbd_free_xfer(ch[i].atu_xfer); 1641 ch[i].atu_xfer = NULL; 1642 } 1643 } 1644 } 1645 1646 /* 1647 * A frame has been uploaded: pass the resulting mbuf chain up to 1648 * the higher level protocols. 1649 */ 1650 void 1651 atu_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1652 { 1653 struct atu_chain *c = (struct atu_chain *)priv; 1654 struct atu_softc *sc = c->atu_sc; 1655 struct ieee80211com *ic = &sc->sc_ic; 1656 struct ifnet *ifp = &ic->ic_if; 1657 struct atu_rx_hdr *h; 1658 struct ieee80211_frame *wh; 1659 struct ieee80211_rxinfo rxi; 1660 struct ieee80211_node *ni; 1661 struct mbuf *m; 1662 u_int32_t len; 1663 int s; 1664 1665 DPRINTFN(25, ("%s: atu_rxeof\n", sc->atu_dev.dv_xname)); 1666 1667 if (usbd_is_dying(sc->atu_udev)) 1668 return; 1669 1670 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) 1671 goto done; 1672 1673 if (status != USBD_NORMAL_COMPLETION) { 1674 DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n", 1675 sc->atu_dev.dv_xname)); 1676 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 1677 return; 1678 } 1679 #if 0 1680 if (status == USBD_IOERROR) { 1681 DPRINTF(("%s: rx: EEK! lost device?\n", 1682 sc->atu_dev.dv_xname)); 1683 1684 /* 1685 * My experience with USBD_IOERROR is that trying to 1686 * restart the transfer will always fail and we'll 1687 * keep on looping restarting transfers untill someone 1688 * pulls the plug of the device. 1689 * So we don't restart the transfer, but just let it 1690 * die... If someone knows of a situation where we can 1691 * recover from USBD_IOERROR, let me know. 1692 */ 1693 splx(s); 1694 return; 1695 } 1696 #endif /* 0 */ 1697 1698 if (usbd_ratecheck(&sc->atu_rx_notice)) { 1699 DPRINTF(("%s: usb error on rx: %s\n", 1700 sc->atu_dev.dv_xname, usbd_errstr(status))); 1701 } 1702 if (status == USBD_STALLED) 1703 usbd_clear_endpoint_stall_async( 1704 sc->atu_ep[ATU_ENDPT_RX]); 1705 goto done; 1706 } 1707 1708 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1709 1710 if (len <= 1) { 1711 DPRINTF(("%s: atu_rxeof: too short\n", 1712 sc->atu_dev.dv_xname)); 1713 goto done; 1714 } 1715 1716 h = (struct atu_rx_hdr *)c->atu_buf; 1717 len = UGETW(h->length) - 4; /* XXX magic number */ 1718 1719 m = c->atu_mbuf; 1720 memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len); 1721 m->m_pkthdr.rcvif = ifp; 1722 m->m_pkthdr.len = m->m_len = len; 1723 1724 wh = mtod(m, struct ieee80211_frame *); 1725 ni = ieee80211_find_rxnode(ic, wh); 1726 1727 ifp->if_ipackets++; 1728 1729 s = splnet(); 1730 1731 if (atu_newbuf(sc, c, NULL) == ENOBUFS) { 1732 ifp->if_ierrors++; 1733 goto done1; /* XXX if we can't allocate, why restart it? */ 1734 } 1735 1736 #if NBPFILTER > 0 1737 if (sc->sc_radiobpf != NULL) { 1738 struct mbuf mb; 1739 struct atu_rx_radiotap_header *rr = &sc->sc_rxtap; 1740 1741 rr->rr_flags = 0; 1742 rr->rr_chan_freq = 1743 htole16(ic->ic_bss->ni_chan->ic_freq); 1744 rr->rr_chan_flags = 1745 htole16(ic->ic_bss->ni_chan->ic_flags); 1746 rr->rr_rssi = h->rssi; 1747 rr->rr_max_rssi = ic->ic_max_rssi; 1748 1749 mb.m_data = (caddr_t)rr; 1750 mb.m_len = sizeof(sc->sc_txtapu); 1751 mb.m_next = m; 1752 mb.m_nextpkt = NULL; 1753 mb.m_type = 0; 1754 mb.m_flags = 0; 1755 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN); 1756 } 1757 #endif /* NBPFILTER > 0 */ 1758 1759 rxi.rxi_flags = 0; 1760 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1761 /* 1762 * WEP is decrypted by hardware. Clear WEP bit 1763 * header for ieee80211_input(). 1764 */ 1765 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 1766 rxi.rxi_flags |= IEEE80211_RXI_HWDEC; 1767 } 1768 1769 rxi.rxi_rssi = h->rssi; 1770 rxi.rxi_tstamp = UGETDW(h->rx_time); 1771 ieee80211_input(ifp, m, ni, &rxi); 1772 1773 ieee80211_release_node(ic, ni); 1774 done1: 1775 splx(s); 1776 done: 1777 /* Setup new transfer. */ 1778 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c, c->atu_buf, 1779 ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, 1780 atu_rxeof); 1781 usbd_transfer(c->atu_xfer); 1782 } 1783 1784 /* 1785 * A frame was downloaded to the chip. It's safe for us to clean up 1786 * the list buffers. 1787 */ 1788 void 1789 atu_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1790 { 1791 struct atu_chain *c = (struct atu_chain *)priv; 1792 struct atu_softc *sc = c->atu_sc; 1793 struct ifnet *ifp = &sc->sc_ic.ic_if; 1794 usbd_status err; 1795 int s; 1796 1797 DPRINTFN(25, ("%s: atu_txeof status=%d\n", sc->atu_dev.dv_xname, 1798 status)); 1799 1800 if (c->atu_mbuf != NULL) { 1801 m_freem(c->atu_mbuf); 1802 c->atu_mbuf = NULL; 1803 } 1804 1805 if (status != USBD_NORMAL_COMPLETION) { 1806 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1807 return; 1808 1809 DPRINTF(("%s: usb error on tx: %s\n", sc->atu_dev.dv_xname, 1810 usbd_errstr(status))); 1811 if (status == USBD_STALLED) 1812 usbd_clear_endpoint_stall_async(sc->atu_ep[ATU_ENDPT_TX]); 1813 return; 1814 } 1815 1816 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, &err); 1817 1818 if (err) 1819 ifp->if_oerrors++; 1820 else 1821 ifp->if_opackets++; 1822 1823 s = splnet(); 1824 SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list); 1825 sc->atu_cdata.atu_tx_inuse--; 1826 if (sc->atu_cdata.atu_tx_inuse == 0) 1827 ifp->if_timer = 0; 1828 ifp->if_flags &= ~IFF_OACTIVE; 1829 splx(s); 1830 1831 atu_start(ifp); 1832 } 1833 1834 u_int8_t 1835 atu_calculate_padding(int size) 1836 { 1837 size %= 64; 1838 1839 if (size < 50) 1840 return (50 - size); 1841 if (size >=61) 1842 return (64 + 50 - size); 1843 return (0); 1844 } 1845 1846 int 1847 atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni, 1848 struct atu_chain *c, struct mbuf *m) 1849 { 1850 int len; 1851 struct atu_tx_hdr *h; 1852 usbd_status err; 1853 u_int8_t pad; 1854 #if NBPFILTER > 0 1855 struct ieee80211com *ic = &sc->sc_ic; 1856 #endif 1857 1858 DPRINTFN(25, ("%s: atu_tx_start\n", sc->atu_dev.dv_xname)); 1859 1860 /* Don't try to send when we're shutting down the driver */ 1861 if (usbd_is_dying(sc->atu_udev)) { 1862 m_freem(m); 1863 return(EIO); 1864 } 1865 1866 #if NBPFILTER > 0 1867 if (sc->sc_radiobpf != NULL) { 1868 struct mbuf mb; 1869 struct atu_tx_radiotap_header *rt = &sc->sc_txtap; 1870 1871 rt->rt_flags = 0; 1872 rt->rt_chan_freq = 1873 htole16(ic->ic_bss->ni_chan->ic_freq); 1874 rt->rt_chan_flags = 1875 htole16(ic->ic_bss->ni_chan->ic_flags); 1876 1877 mb.m_data = (caddr_t)rt; 1878 mb.m_len = sizeof(sc->sc_txtapu); 1879 mb.m_next = m; 1880 mb.m_nextpkt = NULL; 1881 mb.m_type = 0; 1882 mb.m_flags = 0; 1883 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT); 1884 } 1885 #endif 1886 1887 /* 1888 * Copy the mbuf data into a contiguous buffer, leaving 1889 * enough room for the atmel headers 1890 */ 1891 len = m->m_pkthdr.len; 1892 1893 m_copydata(m, 0, m->m_pkthdr.len, c->atu_buf + ATU_TX_HDRLEN); 1894 1895 h = (struct atu_tx_hdr *)c->atu_buf; 1896 memset(h, 0, ATU_TX_HDRLEN); 1897 USETW(h->length, len); 1898 h->tx_rate = 4; /* XXX rate = auto */ 1899 len += ATU_TX_HDRLEN; 1900 1901 pad = atu_calculate_padding(len); 1902 len += pad; 1903 h->padding = pad; 1904 1905 c->atu_length = len; 1906 c->atu_mbuf = m; 1907 1908 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_TX], 1909 c, c->atu_buf, c->atu_length, USBD_NO_COPY, ATU_TX_TIMEOUT, 1910 atu_txeof); 1911 1912 /* Let's get this thing into the air! */ 1913 c->atu_in_xfer = 1; 1914 err = usbd_transfer(c->atu_xfer); 1915 if (err != USBD_IN_PROGRESS) { 1916 DPRINTFN(25, ("%s: atu_tx_start: err=%d\n", 1917 sc->atu_dev.dv_xname, err)); 1918 c->atu_mbuf = NULL; 1919 m_freem(m); 1920 return(EIO); 1921 } 1922 1923 return (0); 1924 } 1925 1926 void 1927 atu_start(struct ifnet *ifp) 1928 { 1929 struct atu_softc *sc = ifp->if_softc; 1930 struct ieee80211com *ic = &sc->sc_ic; 1931 struct atu_cdata *cd = &sc->atu_cdata; 1932 struct ieee80211_node *ni; 1933 struct ieee80211_frame *wh; 1934 struct atu_chain *c; 1935 struct mbuf *m = NULL; 1936 int s; 1937 1938 DPRINTFN(25, ("%s: atu_start: enter\n", sc->atu_dev.dv_xname)); 1939 1940 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) { 1941 DPRINTFN(30, ("%s: atu_start: not running or up\n", 1942 sc->atu_dev.dv_xname)); 1943 return; 1944 } 1945 1946 if (ifp->if_flags & IFF_OACTIVE) { 1947 DPRINTFN(30, ("%s: atu_start: IFF_OACTIVE\n", 1948 sc->atu_dev.dv_xname)); 1949 return; 1950 } 1951 1952 for (;;) { 1953 /* grab a TX buffer */ 1954 s = splnet(); 1955 c = SLIST_FIRST(&cd->atu_tx_free); 1956 if (c != NULL) { 1957 SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list); 1958 cd->atu_tx_inuse++; 1959 if (cd->atu_tx_inuse == ATU_TX_LIST_CNT) 1960 ifp->if_flags |= IFF_OACTIVE; 1961 } 1962 splx(s); 1963 if (c == NULL) { 1964 DPRINTFN(10, ("%s: out of tx xfers\n", 1965 sc->atu_dev.dv_xname)); 1966 ifp->if_flags |= IFF_OACTIVE; 1967 break; 1968 } 1969 1970 /* 1971 * Poll the management queue for frames, it has priority over 1972 * normal data frames. 1973 */ 1974 IF_DEQUEUE(&ic->ic_mgtq, m); 1975 if (m == NULL) { 1976 DPRINTFN(10, ("%s: atu_start: data packet\n", 1977 sc->atu_dev.dv_xname)); 1978 if (ic->ic_state != IEEE80211_S_RUN) { 1979 DPRINTFN(25, ("%s: no data till running\n", 1980 sc->atu_dev.dv_xname)); 1981 /* put the xfer back on the list */ 1982 s = splnet(); 1983 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1984 atu_list); 1985 cd->atu_tx_inuse--; 1986 splx(s); 1987 break; 1988 } 1989 1990 IFQ_DEQUEUE(&ifp->if_snd, m); 1991 if (m == NULL) { 1992 DPRINTFN(25, ("%s: nothing to send\n", 1993 sc->atu_dev.dv_xname)); 1994 s = splnet(); 1995 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1996 atu_list); 1997 cd->atu_tx_inuse--; 1998 splx(s); 1999 break; 2000 } 2001 2002 #if NBPFILTER > 0 2003 if (ifp->if_bpf) 2004 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 2005 #endif 2006 2007 m = ieee80211_encap(ifp, m, &ni); 2008 if (m == NULL) 2009 goto bad; 2010 wh = mtod(m, struct ieee80211_frame *); 2011 2012 #if NBPFILTER > 0 2013 if (ic->ic_rawbpf != NULL) 2014 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT); 2015 #endif 2016 } else { 2017 DPRINTFN(25, ("%s: atu_start: mgmt packet\n", 2018 sc->atu_dev.dv_xname)); 2019 2020 /* 2021 * Hack! The referenced node pointer is in the 2022 * rcvif field of the packet header. This is 2023 * placed there by ieee80211_mgmt_output because 2024 * we need to hold the reference with the frame 2025 * and there's no other way (other than packet 2026 * tags which we consider too expensive to use) 2027 * to pass it along. 2028 */ 2029 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 2030 m->m_pkthdr.rcvif = NULL; 2031 2032 wh = mtod(m, struct ieee80211_frame *); 2033 /* sc->sc_stats.ast_tx_mgmt++; */ 2034 } 2035 2036 if (atu_tx_start(sc, ni, c, m)) { 2037 bad: 2038 s = splnet(); 2039 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 2040 atu_list); 2041 cd->atu_tx_inuse--; 2042 splx(s); 2043 /* ifp_if_oerrors++; */ 2044 if (ni != NULL) 2045 ieee80211_release_node(ic, ni); 2046 continue; 2047 } 2048 ifp->if_timer = 5; 2049 } 2050 } 2051 2052 int 2053 atu_init(struct ifnet *ifp) 2054 { 2055 struct atu_softc *sc = ifp->if_softc; 2056 struct ieee80211com *ic = &sc->sc_ic; 2057 struct atu_chain *c; 2058 usbd_status err; 2059 int i, s; 2060 2061 s = splnet(); 2062 2063 DPRINTFN(10, ("%s: atu_init\n", sc->atu_dev.dv_xname)); 2064 2065 if (ifp->if_flags & IFF_RUNNING) { 2066 splx(s); 2067 return(0); 2068 } 2069 2070 /* Init TX ring */ 2071 if (atu_tx_list_init(sc)) 2072 printf("%s: tx list init failed\n", sc->atu_dev.dv_xname); 2073 2074 /* Init RX ring */ 2075 if (atu_rx_list_init(sc)) 2076 printf("%s: rx list init failed\n", sc->atu_dev.dv_xname); 2077 2078 /* Load the multicast filter. */ 2079 /*atu_setmulti(sc); */ 2080 2081 /* Open RX and TX pipes. */ 2082 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX], 2083 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_RX]); 2084 if (err) { 2085 DPRINTF(("%s: open rx pipe failed: %s\n", 2086 sc->atu_dev.dv_xname, usbd_errstr(err))); 2087 splx(s); 2088 return(EIO); 2089 } 2090 2091 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX], 2092 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_TX]); 2093 if (err) { 2094 DPRINTF(("%s: open tx pipe failed: %s\n", 2095 sc->atu_dev.dv_xname, usbd_errstr(err))); 2096 splx(s); 2097 return(EIO); 2098 } 2099 2100 /* Start up the receive pipe. */ 2101 for (i = 0; i < ATU_RX_LIST_CNT; i++) { 2102 c = &sc->atu_cdata.atu_rx_chain[i]; 2103 2104 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c, 2105 c->atu_buf, ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 2106 USBD_NO_TIMEOUT, atu_rxeof); 2107 usbd_transfer(c->atu_xfer); 2108 } 2109 2110 DPRINTFN(10, ("%s: starting up using MAC=%s\n", 2111 sc->atu_dev.dv_xname, ether_sprintf(ic->ic_myaddr))); 2112 2113 /* Do initial setup */ 2114 err = atu_initial_config(sc); 2115 if (err) { 2116 DPRINTF(("%s: initial config failed!\n", 2117 sc->atu_dev.dv_xname)); 2118 splx(s); 2119 return(EIO); 2120 } 2121 DPRINTFN(10, ("%s: initialised transceiver\n", 2122 sc->atu_dev.dv_xname)); 2123 2124 /* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */ 2125 2126 /* If we want promiscuous mode, set the allframes bit. */ 2127 /* 2128 if (ifp->if_flags & IFF_PROMISC) 2129 sc->atu_rxfilt |= ATU_RXFILT_PROMISC; 2130 */ 2131 2132 ifp->if_flags |= IFF_RUNNING; 2133 ifp->if_flags &= ~IFF_OACTIVE; 2134 splx(s); 2135 2136 /* XXX the following HAS to be replaced */ 2137 s = splnet(); 2138 err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2139 if (err) 2140 DPRINTFN(1, ("%s: atu_init: error calling " 2141 "ieee80211_net_state", sc->atu_dev.dv_xname)); 2142 splx(s); 2143 2144 return 0; 2145 } 2146 2147 int 2148 atu_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 2149 { 2150 struct atu_softc *sc = ifp->if_softc; 2151 struct ifaddr *ifa; 2152 int err = 0, s; 2153 2154 s = splnet(); 2155 switch (command) { 2156 case SIOCSIFADDR: 2157 DPRINTFN(15, ("%s: SIOCSIFADDR\n", sc->atu_dev.dv_xname)); 2158 2159 ifa = (struct ifaddr *)data; 2160 ifp->if_flags |= IFF_UP; 2161 atu_init(ifp); 2162 2163 switch (ifa->ifa_addr->sa_family) { 2164 #ifdef INET 2165 case AF_INET: 2166 arp_ifinit(&sc->sc_ic.ic_ac, ifa); 2167 break; 2168 #endif /* INET */ 2169 } 2170 break; 2171 2172 case SIOCSIFFLAGS: 2173 DPRINTFN(15, ("%s: SIOCSIFFLAGS\n", sc->atu_dev.dv_xname)); 2174 2175 if (ifp->if_flags & IFF_UP) { 2176 if (ifp->if_flags & IFF_RUNNING && 2177 ifp->if_flags & IFF_PROMISC && 2178 !(sc->atu_if_flags & IFF_PROMISC)) { 2179 /* enable promisc */ 2180 #if 0 2181 sc->atu_rxfilt |= ATU_RXFILT_PROMISC; 2182 atu_setword(sc, ATU_CMD_SET_PKT_FILTER, 2183 sc->atu_rxfilt); 2184 #endif 2185 } else if (ifp->if_flags & IFF_RUNNING && 2186 !(ifp->if_flags & IFF_PROMISC) && 2187 sc->atu_if_flags & IFF_PROMISC) { 2188 /* disable promisc */ 2189 #if 0 2190 sc->atu_rxfilt &= ~ATU_RXFILT_PROMISC; 2191 atu_setword(sc, ATU_CMD_SET_PKT_FILTER, 2192 sc->atu_rxfilt); 2193 #endif 2194 } else if (!(ifp->if_flags & IFF_RUNNING)) 2195 atu_init(ifp); 2196 2197 DPRINTFN(15, ("%s: ioctl calling atu_init()\n", 2198 sc->atu_dev.dv_xname)); 2199 atu_init(ifp); 2200 err = atu_switch_radio(sc, 1); 2201 } else { 2202 if (ifp->if_flags & IFF_RUNNING) 2203 atu_stop(ifp, 0); 2204 err = atu_switch_radio(sc, 0); 2205 } 2206 sc->atu_if_flags = ifp->if_flags; 2207 err = 0; 2208 break; 2209 2210 case SIOCADDMULTI: 2211 DPRINTFN(15, ("%s: SIOCADDMULTI\n", sc->atu_dev.dv_xname)); 2212 /* TODO: implement */ 2213 err = 0; 2214 break; 2215 2216 case SIOCDELMULTI: 2217 DPRINTFN(15, ("%s: SIOCDELMULTI\n", sc->atu_dev.dv_xname)); 2218 /* TODO: implement */ 2219 err = 0; 2220 break; 2221 2222 default: 2223 DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n", 2224 sc->atu_dev.dv_xname, command)); 2225 err = ieee80211_ioctl(ifp, command, data); 2226 break; 2227 } 2228 2229 if (err == ENETRESET) { 2230 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 2231 (IFF_RUNNING|IFF_UP)) { 2232 DPRINTF(("%s: atu_ioctl(): netreset\n", 2233 sc->atu_dev.dv_xname)); 2234 atu_init(ifp); 2235 } 2236 err = 0; 2237 } 2238 2239 splx(s); 2240 return (err); 2241 } 2242 2243 void 2244 atu_watchdog(struct ifnet *ifp) 2245 { 2246 struct atu_softc *sc = ifp->if_softc; 2247 struct atu_chain *c; 2248 usbd_status stat; 2249 int cnt, s; 2250 2251 DPRINTF(("%s: atu_watchdog\n", sc->atu_dev.dv_xname)); 2252 2253 ifp->if_timer = 0; 2254 2255 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) 2256 return; 2257 2258 if (usbd_is_dying(sc->atu_udev)) 2259 return; 2260 2261 sc = ifp->if_softc; 2262 s = splnet(); 2263 ifp->if_oerrors++; 2264 DPRINTF(("%s: watchdog timeout\n", sc->atu_dev.dv_xname)); 2265 2266 /* 2267 * TODO: 2268 * we should change this since we have multiple TX transfers... 2269 */ 2270 for (cnt = 0; cnt < ATU_TX_LIST_CNT; cnt++) { 2271 c = &sc->atu_cdata.atu_tx_chain[cnt]; 2272 if (c->atu_in_xfer) { 2273 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, 2274 &stat); 2275 atu_txeof(c->atu_xfer, c, stat); 2276 } 2277 } 2278 2279 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 2280 atu_start(ifp); 2281 splx(s); 2282 2283 ieee80211_watchdog(ifp); 2284 } 2285 2286 /* 2287 * Stop the adapter and free any mbufs allocated to the 2288 * RX and TX lists. 2289 */ 2290 void 2291 atu_stop(struct ifnet *ifp, int disable) 2292 { 2293 struct atu_softc *sc = ifp->if_softc; 2294 struct atu_cdata *cd; 2295 usbd_status err; 2296 int s; 2297 2298 s = splnet(); 2299 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2300 ifp->if_timer = 0; 2301 2302 /* Stop transfers. */ 2303 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) { 2304 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); 2305 if (err) { 2306 DPRINTF(("%s: abort rx pipe failed: %s\n", 2307 sc->atu_dev.dv_xname, usbd_errstr(err))); 2308 } 2309 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]); 2310 if (err) { 2311 DPRINTF(("%s: close rx pipe failed: %s\n", 2312 sc->atu_dev.dv_xname, usbd_errstr(err))); 2313 } 2314 sc->atu_ep[ATU_ENDPT_RX] = NULL; 2315 } 2316 2317 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { 2318 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); 2319 if (err) { 2320 DPRINTF(("%s: abort tx pipe failed: %s\n", 2321 sc->atu_dev.dv_xname, usbd_errstr(err))); 2322 } 2323 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]); 2324 if (err) { 2325 DPRINTF(("%s: close tx pipe failed: %s\n", 2326 sc->atu_dev.dv_xname, usbd_errstr(err))); 2327 } 2328 sc->atu_ep[ATU_ENDPT_TX] = NULL; 2329 } 2330 2331 /* Free RX/TX/MGMT list resources. */ 2332 cd = &sc->atu_cdata; 2333 atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT); 2334 atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT); 2335 2336 /* Let's be nice and turn off the radio before we leave */ 2337 atu_switch_radio(sc, 0); 2338 2339 splx(s); 2340 } 2341