1 /* $OpenBSD: if_atu.c,v 1.92 2008/07/21 18:43:19 damien 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/kthread.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 *, enum devact); 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: transfered 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 < sizeof(atu_radfirm)/sizeof(atu_radfirm[0]); 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 return; 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 return; 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 return; 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 return; 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 return; 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 994 void 995 atu_external_firmware(void *arg) 996 { 997 struct atu_softc *sc = arg; 998 u_char *ptr = NULL, *firm = NULL; 999 int block_size, block = 0, err, i; 1000 size_t bytes_left = 0; 1001 char *name = "unknown-device"; 1002 1003 for (i = 0; i < sizeof(atu_radfirm)/sizeof(atu_radfirm[0]); i++) 1004 if (sc->atu_radio == atu_radfirm[i].atur_type) 1005 name = atu_radfirm[i].atur_external; 1006 1007 DPRINTF(("%s: loading external firmware %s\n", 1008 sc->atu_dev.dv_xname, name)); 1009 err = loadfirmware(name, &firm, &bytes_left); 1010 if (err != 0) { 1011 printf("%s: %s loadfirmware error %d\n", 1012 sc->atu_dev.dv_xname, name, err); 1013 return; 1014 } 1015 ptr = firm; 1016 1017 while (bytes_left) { 1018 if (bytes_left > 1024) 1019 block_size = 1024; 1020 else 1021 block_size = bytes_left; 1022 1023 DPRINTFN(15, ("%s: block:%d size:%d\n", 1024 sc->atu_dev.dv_xname, block, block_size)); 1025 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 1026 0x0802, block, block_size, ptr); 1027 if (err) { 1028 DPRINTF(("%s: could not load external firmware " 1029 "block\n", sc->atu_dev.dv_xname)); 1030 free(firm, M_DEVBUF); 1031 return; 1032 } 1033 1034 ptr += block_size; 1035 block++; 1036 bytes_left -= block_size; 1037 } 1038 free(firm, M_DEVBUF); 1039 1040 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0802, 1041 block, 0, NULL); 1042 if (err) { 1043 DPRINTF(("%s: could not load last zero-length firmware " 1044 "block\n", sc->atu_dev.dv_xname)); 1045 return; 1046 } 1047 1048 /* 1049 * The SMC2662w V.4 seems to require some time to do its thing with 1050 * the external firmware... 20 ms isn't enough, but 21 ms works 100 1051 * times out of 100 tries. We'll wait a bit longer just to be sure 1052 */ 1053 if (sc->atu_quirk & ATU_QUIRK_FW_DELAY) 1054 usbd_delay_ms(sc->atu_udev, 21 + 100); 1055 1056 DPRINTFN(10, ("%s: external firmware upload done\n", 1057 sc->atu_dev.dv_xname)); 1058 /* complete configuration after the firmwares have been uploaded */ 1059 atu_complete_attach(sc); 1060 } 1061 1062 int 1063 atu_get_card_config(struct atu_softc *sc) 1064 { 1065 struct ieee80211com *ic = &sc->sc_ic; 1066 struct atu_rfmd_conf rfmd_conf; 1067 struct atu_intersil_conf intersil_conf; 1068 int err; 1069 1070 switch (sc->atu_radio) { 1071 1072 case RadioRFMD: 1073 case RadioRFMD2958: 1074 case RadioRFMD2958_SMC: 1075 case AT76C503_rfmd_acc: 1076 case AT76C505_rfmd: 1077 err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 1078 0x0a02, 0x0000, sizeof(rfmd_conf), 1079 (u_int8_t *)&rfmd_conf); 1080 if (err) { 1081 DPRINTF(("%s: could not get rfmd config!\n", 1082 sc->atu_dev.dv_xname)); 1083 return err; 1084 } 1085 memcpy(ic->ic_myaddr, rfmd_conf.MACAddr, IEEE80211_ADDR_LEN); 1086 break; 1087 1088 case RadioIntersil: 1089 case AT76C503_i3863: 1090 err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 1091 0x0902, 0x0000, sizeof(intersil_conf), 1092 (u_int8_t *)&intersil_conf); 1093 if (err) { 1094 DPRINTF(("%s: could not get intersil config!\n", 1095 sc->atu_dev.dv_xname)); 1096 return err; 1097 } 1098 memcpy(ic->ic_myaddr, intersil_conf.MACAddr, 1099 IEEE80211_ADDR_LEN); 1100 break; 1101 } 1102 return 0; 1103 } 1104 1105 /* 1106 * Probe for an AT76c503 chip. 1107 */ 1108 int 1109 atu_match(struct device *parent, void *match, void *aux) 1110 { 1111 struct usb_attach_arg *uaa = aux; 1112 int i; 1113 1114 if (!uaa->iface) 1115 return(UMATCH_NONE); 1116 1117 for (i = 0; i < sizeof(atu_devs)/sizeof(atu_devs[0]); i++) { 1118 struct atu_type *t = &atu_devs[i]; 1119 1120 if (uaa->vendor == t->atu_vid && 1121 uaa->product == t->atu_pid) { 1122 return(UMATCH_VENDOR_PRODUCT); 1123 } 1124 } 1125 return(UMATCH_NONE); 1126 } 1127 1128 int 1129 atu_media_change(struct ifnet *ifp) 1130 { 1131 #ifdef ATU_DEBUG 1132 struct atu_softc *sc = ifp->if_softc; 1133 #endif /* ATU_DEBUG */ 1134 int err; 1135 1136 DPRINTFN(10, ("%s: atu_media_change\n", sc->atu_dev.dv_xname)); 1137 1138 err = ieee80211_media_change(ifp); 1139 if (err == ENETRESET) { 1140 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 1141 (IFF_RUNNING|IFF_UP)) 1142 atu_init(ifp); 1143 err = 0; 1144 } 1145 1146 return (err); 1147 } 1148 1149 void 1150 atu_media_status(struct ifnet *ifp, struct ifmediareq *req) 1151 { 1152 #ifdef ATU_DEBUG 1153 struct atu_softc *sc = ifp->if_softc; 1154 #endif /* ATU_DEBUG */ 1155 1156 DPRINTFN(10, ("%s: atu_media_status\n", sc->atu_dev.dv_xname)); 1157 1158 ieee80211_media_status(ifp, req); 1159 } 1160 1161 void 1162 atu_task(void *arg) 1163 { 1164 struct atu_softc *sc = (struct atu_softc *)arg; 1165 struct ieee80211com *ic = &sc->sc_ic; 1166 struct ifnet *ifp = &ic->ic_if; 1167 usbd_status err; 1168 int s; 1169 1170 DPRINTFN(10, ("%s: atu_task\n", sc->atu_dev.dv_xname)); 1171 1172 if (sc->sc_state != ATU_S_OK) 1173 return; 1174 1175 switch (sc->sc_cmd) { 1176 case ATU_C_SCAN: 1177 1178 err = atu_start_scan(sc); 1179 if (err) { 1180 DPRINTFN(1, ("%s: atu_init: couldn't start scan!\n", 1181 sc->atu_dev.dv_xname)); 1182 return; 1183 } 1184 1185 err = atu_wait_completion(sc, CMD_START_SCAN, NULL); 1186 if (err) { 1187 DPRINTF(("%s: atu_init: error waiting for scan\n", 1188 sc->atu_dev.dv_xname)); 1189 return; 1190 } 1191 1192 DPRINTF(("%s: ==========================> END OF SCAN!\n", 1193 sc->atu_dev.dv_xname)); 1194 1195 s = splnet(); 1196 /* ieee80211_next_scan(ifp); */ 1197 ieee80211_end_scan(ifp); 1198 splx(s); 1199 1200 DPRINTF(("%s: ----------------------======> END OF SCAN2!\n", 1201 sc->atu_dev.dv_xname)); 1202 break; 1203 1204 case ATU_C_JOIN: 1205 atu_join(sc, ic->ic_bss); 1206 } 1207 } 1208 1209 int 1210 atu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1211 { 1212 struct ifnet *ifp = &ic->ic_if; 1213 struct atu_softc *sc = ifp->if_softc; 1214 enum ieee80211_state ostate = ic->ic_state; 1215 1216 DPRINTFN(10, ("%s: atu_newstate: %s -> %s\n", sc->atu_dev.dv_xname, 1217 ieee80211_state_name[ostate], ieee80211_state_name[nstate])); 1218 1219 switch (nstate) { 1220 case IEEE80211_S_SCAN: 1221 memcpy(ic->ic_chan_scan, ic->ic_chan_active, 1222 sizeof(ic->ic_chan_active)); 1223 ieee80211_free_allnodes(ic); 1224 1225 /* tell the event thread that we want a scan */ 1226 sc->sc_cmd = ATU_C_SCAN; 1227 usb_add_task(sc->atu_udev, &sc->sc_task); 1228 1229 /* handle this ourselves */ 1230 ic->ic_state = nstate; 1231 return (0); 1232 1233 case IEEE80211_S_AUTH: 1234 case IEEE80211_S_RUN: 1235 if (ostate == IEEE80211_S_SCAN) { 1236 sc->sc_cmd = ATU_C_JOIN; 1237 usb_add_task(sc->atu_udev, &sc->sc_task); 1238 } 1239 break; 1240 default: 1241 /* nothing to do */ 1242 break; 1243 } 1244 1245 return (*sc->sc_newstate)(ic, nstate, arg); 1246 } 1247 1248 /* 1249 * Attach the interface. Allocate softc structures, do 1250 * setup and ethernet/BPF attach. 1251 */ 1252 void 1253 atu_attach(struct device *parent, struct device *self, void *aux) 1254 { 1255 struct atu_softc *sc = (struct atu_softc *)self; 1256 struct usb_attach_arg *uaa = aux; 1257 usbd_status err; 1258 usbd_device_handle dev = uaa->device; 1259 u_int8_t mode, channel; 1260 int i; 1261 1262 sc->sc_state = ATU_S_UNCONFIG; 1263 1264 err = usbd_set_config_no(dev, ATU_CONFIG_NO, 1); 1265 if (err) { 1266 printf("%s: setting config no failed\n", 1267 sc->atu_dev.dv_xname); 1268 return; 1269 } 1270 1271 err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface); 1272 if (err) { 1273 printf("%s: getting interface handle failed\n", 1274 sc->atu_dev.dv_xname); 1275 return; 1276 } 1277 1278 sc->atu_unit = self->dv_unit; 1279 sc->atu_udev = dev; 1280 1281 /* 1282 * look up the radio_type for the device 1283 * basically does the same as USB_MATCH 1284 */ 1285 for (i = 0; i < sizeof(atu_devs)/sizeof(atu_devs[0]); i++) { 1286 struct atu_type *t = &atu_devs[i]; 1287 1288 if (uaa->vendor == t->atu_vid && 1289 uaa->product == t->atu_pid) { 1290 sc->atu_radio = t->atu_radio; 1291 sc->atu_quirk = t->atu_quirk; 1292 } 1293 } 1294 1295 /* 1296 * Check in the interface descriptor if we're in DFU mode 1297 * If we're in DFU mode, we upload the external firmware 1298 * If we're not, the PC must have rebooted without power-cycling 1299 * the device.. I've tried this out, a reboot only requeres the 1300 * external firmware to be reloaded :) 1301 * 1302 * Hmm. The at76c505a doesn't report a DFU descriptor when it's 1303 * in DFU mode... Let's just try to get the opmode 1304 */ 1305 err = atu_get_opmode(sc, &mode); 1306 DPRINTFN(20, ("%s: opmode: %d\n", sc->atu_dev.dv_xname, mode)); 1307 if (err || (mode != MODE_NETCARD && mode != MODE_NOFLASHNETCARD)) { 1308 DPRINTF(("%s: starting internal firmware download\n", 1309 sc->atu_dev.dv_xname)); 1310 1311 if (rootvp == NULL) 1312 mountroothook_establish(atu_internal_firmware, sc); 1313 else 1314 atu_internal_firmware(sc); 1315 /* 1316 * atu_internal_firmware will cause a reset of the device 1317 * so we don't want to do any more configuration after this 1318 * point. 1319 */ 1320 return; 1321 } 1322 1323 uaa->iface = sc->atu_iface; 1324 1325 if (mode != MODE_NETCARD) { 1326 DPRINTFN(15, ("%s: device needs external firmware\n", 1327 sc->atu_dev.dv_xname)); 1328 1329 if (mode != MODE_NOFLASHNETCARD) { 1330 DPRINTF(("%s: EEK! unexpected opmode=%d\n", 1331 sc->atu_dev.dv_xname, mode)); 1332 } 1333 1334 /* 1335 * There is no difference in opmode before and after external 1336 * firmware upload with the SMC2662 V.4 . So instead we'll try 1337 * to read the channel number. If we succeed, external 1338 * firmwaremust have been already uploaded... 1339 */ 1340 if (sc->atu_radio != RadioIntersil) { 1341 err = atu_get_mib(sc, MIB_PHY__CHANNEL, &channel); 1342 if (!err) { 1343 DPRINTF(("%s: external firmware has already" 1344 " been downloaded\n", 1345 sc->atu_dev.dv_xname)); 1346 atu_complete_attach(sc); 1347 return; 1348 } 1349 } 1350 1351 if (rootvp == NULL) 1352 mountroothook_establish(atu_external_firmware, sc); 1353 else 1354 atu_external_firmware(sc); 1355 1356 /* 1357 * atu_external_firmware will call atu_complete_attach after 1358 * it's finished so we can just return. 1359 */ 1360 } else { 1361 /* all the firmwares are in place, so complete the attach */ 1362 atu_complete_attach(sc); 1363 } 1364 } 1365 1366 void 1367 atu_complete_attach(struct atu_softc *sc) 1368 { 1369 struct ieee80211com *ic = &sc->sc_ic; 1370 struct ifnet *ifp = &ic->ic_if; 1371 usb_interface_descriptor_t *id; 1372 usb_endpoint_descriptor_t *ed; 1373 usbd_status err; 1374 int i; 1375 #ifdef ATU_DEBUG 1376 struct atu_fw fw; 1377 #endif 1378 1379 id = usbd_get_interface_descriptor(sc->atu_iface); 1380 1381 /* Find endpoints. */ 1382 for (i = 0; i < id->bNumEndpoints; i++) { 1383 ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i); 1384 if (!ed) { 1385 DPRINTF(("%s: num_endp:%d\n", sc->atu_dev.dv_xname, 1386 sc->atu_iface->idesc->bNumEndpoints)); 1387 DPRINTF(("%s: couldn't get ep %d\n", 1388 sc->atu_dev.dv_xname, i)); 1389 return; 1390 } 1391 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 1392 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1393 sc->atu_ed[ATU_ENDPT_RX] = ed->bEndpointAddress; 1394 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 1395 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1396 sc->atu_ed[ATU_ENDPT_TX] = ed->bEndpointAddress; 1397 } 1398 } 1399 1400 /* read device config & get MAC address */ 1401 err = atu_get_card_config(sc); 1402 if (err) { 1403 printf("%s: could not get card cfg!\n", 1404 sc->atu_dev.dv_xname); 1405 return; 1406 } 1407 1408 #ifdef ATU_DEBUG 1409 /* DEBUG : try to get firmware version */ 1410 err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0, 1411 (u_int8_t *)&fw); 1412 if (!err) { 1413 DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d " 1414 "build:%d\n", sc->atu_dev.dv_xname, fw.major, fw.minor, 1415 fw.patch, fw.build)); 1416 } else { 1417 DPRINTF(("%s: get firmware version failed\n", 1418 sc->atu_dev.dv_xname)); 1419 } 1420 #endif /* ATU_DEBUG */ 1421 1422 /* Show the world our MAC address */ 1423 printf("%s: address %s\n", sc->atu_dev.dv_xname, 1424 ether_sprintf(ic->ic_myaddr)); 1425 1426 sc->atu_cdata.atu_tx_inuse = 0; 1427 1428 bzero(sc->atu_bssid, ETHER_ADDR_LEN); 1429 sc->atu_channel = ATU_DEFAULT_CHANNEL; 1430 sc->atu_desired_channel = IEEE80211_CHAN_ANY; 1431 sc->atu_mode = INFRASTRUCTURE_MODE; 1432 1433 ic->ic_softc = sc; 1434 ic->ic_phytype = IEEE80211_T_DS; 1435 ic->ic_opmode = IEEE80211_M_STA; 1436 ic->ic_state = IEEE80211_S_INIT; 1437 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP | IEEE80211_C_SCANALL; 1438 ic->ic_max_rssi = atu_radfirm[sc->atu_radio].max_rssi; 1439 1440 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 1441 1442 for (i = 1; i <= 14; i++) { 1443 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B | 1444 IEEE80211_CHAN_PASSIVE; 1445 ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i, 1446 ic->ic_channels[i].ic_flags); 1447 } 1448 1449 ic->ic_ibss_chan = &ic->ic_channels[0]; 1450 1451 ifp->if_softc = sc; 1452 memcpy(ifp->if_xname, sc->atu_dev.dv_xname, IFNAMSIZ); 1453 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1454 ifp->if_start = atu_start; 1455 ifp->if_ioctl = atu_ioctl; 1456 ifp->if_watchdog = atu_watchdog; 1457 ifp->if_mtu = ATU_DEFAULT_MTU; 1458 IFQ_SET_READY(&ifp->if_snd); 1459 1460 /* Call MI attach routine. */ 1461 if_attach(ifp); 1462 ieee80211_ifattach(ifp); 1463 1464 sc->sc_newstate = ic->ic_newstate; 1465 ic->ic_newstate = atu_newstate; 1466 1467 /* setup ifmedia interface */ 1468 ieee80211_media_init(ifp, atu_media_change, atu_media_status); 1469 1470 usb_init_task(&sc->sc_task, atu_task, sc); 1471 1472 #if NBPFILTER > 0 1473 bpfattach(&sc->sc_radiobpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO, 1474 sizeof(struct ieee80211_frame) + 64); 1475 1476 bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu)); 1477 sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu); 1478 sc->sc_rxtap.rr_ihdr.it_present = htole32(ATU_RX_RADIOTAP_PRESENT); 1479 1480 bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu)); 1481 sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu); 1482 sc->sc_txtap.rt_ihdr.it_present = htole32(ATU_TX_RADIOTAP_PRESENT); 1483 #endif 1484 1485 sc->sc_state = ATU_S_OK; 1486 } 1487 1488 int 1489 atu_detach(struct device *self, int flags) 1490 { 1491 struct atu_softc *sc = (struct atu_softc *)self; 1492 struct ifnet *ifp = &sc->sc_ic.ic_if; 1493 1494 DPRINTFN(10, ("%s: atu_detach state=%d\n", sc->atu_dev.dv_xname, 1495 sc->sc_state)); 1496 1497 if (sc->sc_state != ATU_S_UNCONFIG) { 1498 atu_stop(ifp, 1); 1499 ieee80211_ifdetach(ifp); 1500 if_detach(ifp); 1501 1502 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) 1503 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); 1504 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) 1505 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); 1506 1507 usb_rem_task(sc->atu_udev, &sc->sc_task); 1508 } 1509 1510 return(0); 1511 } 1512 1513 int 1514 atu_activate(struct device *self, enum devact act) 1515 { 1516 struct atu_softc *sc = (struct atu_softc *)self; 1517 1518 switch (act) { 1519 case DVACT_ACTIVATE: 1520 break; 1521 case DVACT_DEACTIVATE: 1522 if (sc->sc_state != ATU_S_UNCONFIG) 1523 sc->sc_state = ATU_S_DEAD; 1524 break; 1525 } 1526 return (0); 1527 } 1528 1529 /* 1530 * Initialize an RX descriptor and attach an MBUF cluster. 1531 */ 1532 int 1533 atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m) 1534 { 1535 struct mbuf *m_new = NULL; 1536 1537 if (m == NULL) { 1538 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 1539 if (m_new == NULL) { 1540 DPRINTF(("%s: no memory for rx list\n", 1541 sc->atu_dev.dv_xname)); 1542 return(ENOBUFS); 1543 } 1544 1545 MCLGET(m_new, M_DONTWAIT); 1546 if (!(m_new->m_flags & M_EXT)) { 1547 DPRINTF(("%s: no memory for rx list\n", 1548 sc->atu_dev.dv_xname)); 1549 m_freem(m_new); 1550 return(ENOBUFS); 1551 } 1552 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1553 } else { 1554 m_new = m; 1555 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1556 m_new->m_data = m_new->m_ext.ext_buf; 1557 } 1558 c->atu_mbuf = m_new; 1559 return(0); 1560 } 1561 1562 int 1563 atu_rx_list_init(struct atu_softc *sc) 1564 { 1565 struct atu_cdata *cd = &sc->atu_cdata; 1566 struct atu_chain *c; 1567 int i; 1568 1569 DPRINTFN(15, ("%s: atu_rx_list_init: enter\n", 1570 sc->atu_dev.dv_xname)); 1571 1572 for (i = 0; i < ATU_RX_LIST_CNT; i++) { 1573 c = &cd->atu_rx_chain[i]; 1574 c->atu_sc = sc; 1575 c->atu_idx = i; 1576 if (c->atu_xfer == NULL) { 1577 c->atu_xfer = usbd_alloc_xfer(sc->atu_udev); 1578 if (c->atu_xfer == NULL) 1579 return (ENOBUFS); 1580 c->atu_buf = usbd_alloc_buffer(c->atu_xfer, 1581 ATU_RX_BUFSZ); 1582 if (c->atu_buf == NULL) /* XXX free xfer */ 1583 return (ENOBUFS); 1584 if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */ 1585 return(ENOBUFS); 1586 } 1587 } 1588 return (0); 1589 } 1590 1591 int 1592 atu_tx_list_init(struct atu_softc *sc) 1593 { 1594 struct atu_cdata *cd = &sc->atu_cdata; 1595 struct atu_chain *c; 1596 int i; 1597 1598 DPRINTFN(15, ("%s: atu_tx_list_init\n", 1599 sc->atu_dev.dv_xname)); 1600 1601 SLIST_INIT(&cd->atu_tx_free); 1602 sc->atu_cdata.atu_tx_inuse = 0; 1603 1604 for (i = 0; i < ATU_TX_LIST_CNT; i++) { 1605 c = &cd->atu_tx_chain[i]; 1606 c->atu_sc = sc; 1607 c->atu_idx = i; 1608 if (c->atu_xfer == NULL) { 1609 c->atu_xfer = usbd_alloc_xfer(sc->atu_udev); 1610 if (c->atu_xfer == NULL) 1611 return(ENOBUFS); 1612 c->atu_mbuf = NULL; 1613 c->atu_buf = usbd_alloc_buffer(c->atu_xfer, 1614 ATU_TX_BUFSZ); 1615 if (c->atu_buf == NULL) 1616 return(ENOBUFS); /* XXX free xfer */ 1617 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list); 1618 } 1619 } 1620 return(0); 1621 } 1622 1623 void 1624 atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, 1625 int listlen) 1626 { 1627 int i; 1628 1629 /* Free resources. */ 1630 for (i = 0; i < listlen; i++) { 1631 if (ch[i].atu_buf != NULL) 1632 ch[i].atu_buf = NULL; 1633 if (ch[i].atu_mbuf != NULL) { 1634 m_freem(ch[i].atu_mbuf); 1635 ch[i].atu_mbuf = NULL; 1636 } 1637 if (ch[i].atu_xfer != NULL) { 1638 usbd_free_xfer(ch[i].atu_xfer); 1639 ch[i].atu_xfer = NULL; 1640 } 1641 } 1642 } 1643 1644 /* 1645 * A frame has been uploaded: pass the resulting mbuf chain up to 1646 * the higher level protocols. 1647 */ 1648 void 1649 atu_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1650 { 1651 struct atu_chain *c = (struct atu_chain *)priv; 1652 struct atu_softc *sc = c->atu_sc; 1653 struct ieee80211com *ic = &sc->sc_ic; 1654 struct ifnet *ifp = &ic->ic_if; 1655 struct atu_rx_hdr *h; 1656 struct ieee80211_frame *wh; 1657 struct ieee80211_rxinfo rxi; 1658 struct ieee80211_node *ni; 1659 struct mbuf *m; 1660 u_int32_t len; 1661 int s; 1662 1663 DPRINTFN(25, ("%s: atu_rxeof\n", sc->atu_dev.dv_xname)); 1664 1665 if (sc->sc_state != ATU_S_OK) 1666 return; 1667 1668 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) 1669 goto done; 1670 1671 if (status != USBD_NORMAL_COMPLETION) { 1672 DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n", 1673 sc->atu_dev.dv_xname)); 1674 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 1675 return; 1676 } 1677 #if 0 1678 if (status == USBD_IOERROR) { 1679 DPRINTF(("%s: rx: EEK! lost device?\n", 1680 sc->atu_dev.dv_xname)); 1681 1682 /* 1683 * My experience with USBD_IOERROR is that trying to 1684 * restart the transfer will always fail and we'll 1685 * keep on looping restarting transfers untill someone 1686 * pulls the plug of the device. 1687 * So we don't restart the transfer, but just let it 1688 * die... If someone knows of a situation where we can 1689 * recover from USBD_IOERROR, let me know. 1690 */ 1691 splx(s); 1692 return; 1693 } 1694 #endif /* 0 */ 1695 1696 if (usbd_ratecheck(&sc->atu_rx_notice)) { 1697 DPRINTF(("%s: usb error on rx: %s\n", 1698 sc->atu_dev.dv_xname, usbd_errstr(status))); 1699 } 1700 if (status == USBD_STALLED) 1701 usbd_clear_endpoint_stall_async( 1702 sc->atu_ep[ATU_ENDPT_RX]); 1703 goto done; 1704 } 1705 1706 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1707 1708 if (len <= 1) { 1709 DPRINTF(("%s: atu_rxeof: too short\n", 1710 sc->atu_dev.dv_xname)); 1711 goto done; 1712 } 1713 1714 h = (struct atu_rx_hdr *)c->atu_buf; 1715 len = UGETW(h->length) - 4; /* XXX magic number */ 1716 1717 m = c->atu_mbuf; 1718 memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len); 1719 m->m_pkthdr.rcvif = ifp; 1720 m->m_pkthdr.len = m->m_len = len; 1721 1722 wh = mtod(m, struct ieee80211_frame *); 1723 ni = ieee80211_find_rxnode(ic, wh); 1724 1725 ifp->if_ipackets++; 1726 1727 s = splnet(); 1728 1729 if (atu_newbuf(sc, c, NULL) == ENOBUFS) { 1730 ifp->if_ierrors++; 1731 goto done1; /* XXX if we can't allocate, why restart it? */ 1732 } 1733 1734 #if NBPFILTER > 0 1735 if (sc->sc_radiobpf != NULL) { 1736 struct mbuf mb; 1737 struct atu_rx_radiotap_header *rr = &sc->sc_rxtap; 1738 1739 rr->rr_flags = 0; 1740 rr->rr_chan_freq = 1741 htole16(ic->ic_bss->ni_chan->ic_freq); 1742 rr->rr_chan_flags = 1743 htole16(ic->ic_bss->ni_chan->ic_flags); 1744 rr->rr_rssi = h->rssi; 1745 rr->rr_max_rssi = ic->ic_max_rssi; 1746 1747 mb.m_data = (caddr_t)rr; 1748 mb.m_len = sizeof(sc->sc_txtapu); 1749 mb.m_next = m; 1750 mb.m_nextpkt = NULL; 1751 mb.m_type = 0; 1752 mb.m_flags = 0; 1753 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN); 1754 } 1755 #endif /* NBPFILTER > 0 */ 1756 1757 rxi.rxi_flags = 0; 1758 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1759 /* 1760 * WEP is decrypted by hardware. Clear WEP bit 1761 * header for ieee80211_input(). 1762 */ 1763 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 1764 rxi.rxi_flags |= IEEE80211_RXI_HWDEC; 1765 } 1766 1767 rxi.rxi_rssi = h->rssi; 1768 rxi.rxi_tstamp = UGETDW(h->rx_time); 1769 ieee80211_input(ifp, m, ni, &rxi); 1770 1771 ieee80211_release_node(ic, ni); 1772 done1: 1773 splx(s); 1774 done: 1775 /* Setup new transfer. */ 1776 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c, c->atu_buf, 1777 ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, 1778 atu_rxeof); 1779 usbd_transfer(c->atu_xfer); 1780 } 1781 1782 /* 1783 * A frame was downloaded to the chip. It's safe for us to clean up 1784 * the list buffers. 1785 */ 1786 void 1787 atu_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1788 { 1789 struct atu_chain *c = (struct atu_chain *)priv; 1790 struct atu_softc *sc = c->atu_sc; 1791 struct ifnet *ifp = &sc->sc_ic.ic_if; 1792 usbd_status err; 1793 int s; 1794 1795 DPRINTFN(25, ("%s: atu_txeof status=%d\n", sc->atu_dev.dv_xname, 1796 status)); 1797 1798 if (c->atu_mbuf != NULL) { 1799 m_freem(c->atu_mbuf); 1800 c->atu_mbuf = NULL; 1801 } 1802 1803 if (status != USBD_NORMAL_COMPLETION) { 1804 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1805 return; 1806 1807 DPRINTF(("%s: usb error on tx: %s\n", sc->atu_dev.dv_xname, 1808 usbd_errstr(status))); 1809 if (status == USBD_STALLED) 1810 usbd_clear_endpoint_stall_async(sc->atu_ep[ATU_ENDPT_TX]); 1811 return; 1812 } 1813 1814 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, &err); 1815 1816 if (err) 1817 ifp->if_oerrors++; 1818 else 1819 ifp->if_opackets++; 1820 1821 s = splnet(); 1822 SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list); 1823 sc->atu_cdata.atu_tx_inuse--; 1824 if (sc->atu_cdata.atu_tx_inuse == 0) 1825 ifp->if_timer = 0; 1826 ifp->if_flags &= ~IFF_OACTIVE; 1827 splx(s); 1828 1829 atu_start(ifp); 1830 } 1831 1832 u_int8_t 1833 atu_calculate_padding(int size) 1834 { 1835 size %= 64; 1836 1837 if (size < 50) 1838 return (50 - size); 1839 if (size >=61) 1840 return (64 + 50 - size); 1841 return (0); 1842 } 1843 1844 int 1845 atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni, 1846 struct atu_chain *c, struct mbuf *m) 1847 { 1848 int len; 1849 struct atu_tx_hdr *h; 1850 usbd_status err; 1851 u_int8_t pad; 1852 #if NBPFILTER > 0 1853 struct ieee80211com *ic = &sc->sc_ic; 1854 #endif 1855 1856 DPRINTFN(25, ("%s: atu_tx_start\n", sc->atu_dev.dv_xname)); 1857 1858 /* Don't try to send when we're shutting down the driver */ 1859 if (sc->sc_state != ATU_S_OK) { 1860 m_freem(m); 1861 return(EIO); 1862 } 1863 1864 #if NBPFILTER > 0 1865 if (sc->sc_radiobpf != NULL) { 1866 struct mbuf mb; 1867 struct atu_tx_radiotap_header *rt = &sc->sc_txtap; 1868 1869 rt->rt_flags = 0; 1870 rt->rt_chan_freq = 1871 htole16(ic->ic_bss->ni_chan->ic_freq); 1872 rt->rt_chan_flags = 1873 htole16(ic->ic_bss->ni_chan->ic_flags); 1874 1875 mb.m_data = (caddr_t)rt; 1876 mb.m_len = sizeof(sc->sc_txtapu); 1877 mb.m_next = m; 1878 mb.m_nextpkt = NULL; 1879 mb.m_type = 0; 1880 mb.m_flags = 0; 1881 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT); 1882 } 1883 #endif 1884 1885 /* 1886 * Copy the mbuf data into a contiguous buffer, leaving 1887 * enough room for the atmel headers 1888 */ 1889 len = m->m_pkthdr.len; 1890 1891 m_copydata(m, 0, m->m_pkthdr.len, c->atu_buf + ATU_TX_HDRLEN); 1892 1893 h = (struct atu_tx_hdr *)c->atu_buf; 1894 memset(h, 0, ATU_TX_HDRLEN); 1895 USETW(h->length, len); 1896 h->tx_rate = 4; /* XXX rate = auto */ 1897 len += ATU_TX_HDRLEN; 1898 1899 pad = atu_calculate_padding(len); 1900 len += pad; 1901 h->padding = pad; 1902 1903 c->atu_length = len; 1904 c->atu_mbuf = m; 1905 1906 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_TX], 1907 c, c->atu_buf, c->atu_length, USBD_NO_COPY, ATU_TX_TIMEOUT, 1908 atu_txeof); 1909 1910 /* Let's get this thing into the air! */ 1911 c->atu_in_xfer = 1; 1912 err = usbd_transfer(c->atu_xfer); 1913 if (err != USBD_IN_PROGRESS) { 1914 DPRINTFN(25, ("%s: atu_tx_start: err=%d\n", 1915 sc->atu_dev.dv_xname, err)); 1916 c->atu_mbuf = NULL; 1917 m_freem(m); 1918 return(EIO); 1919 } 1920 1921 return (0); 1922 } 1923 1924 void 1925 atu_start(struct ifnet *ifp) 1926 { 1927 struct atu_softc *sc = ifp->if_softc; 1928 struct ieee80211com *ic = &sc->sc_ic; 1929 struct atu_cdata *cd = &sc->atu_cdata; 1930 struct ieee80211_node *ni; 1931 struct ieee80211_frame *wh; 1932 struct atu_chain *c; 1933 struct mbuf *m = NULL; 1934 int s; 1935 1936 DPRINTFN(25, ("%s: atu_start: enter\n", sc->atu_dev.dv_xname)); 1937 1938 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) { 1939 DPRINTFN(30, ("%s: atu_start: not running or up\n", 1940 sc->atu_dev.dv_xname)); 1941 return; 1942 } 1943 1944 if (ifp->if_flags & IFF_OACTIVE) { 1945 DPRINTFN(30, ("%s: atu_start: IFF_OACTIVE\n", 1946 sc->atu_dev.dv_xname)); 1947 return; 1948 } 1949 1950 for (;;) { 1951 /* grab a TX buffer */ 1952 s = splnet(); 1953 c = SLIST_FIRST(&cd->atu_tx_free); 1954 if (c != NULL) { 1955 SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list); 1956 cd->atu_tx_inuse++; 1957 if (cd->atu_tx_inuse == ATU_TX_LIST_CNT) 1958 ifp->if_flags |= IFF_OACTIVE; 1959 } 1960 splx(s); 1961 if (c == NULL) { 1962 DPRINTFN(10, ("%s: out of tx xfers\n", 1963 sc->atu_dev.dv_xname)); 1964 ifp->if_flags |= IFF_OACTIVE; 1965 break; 1966 } 1967 1968 /* 1969 * Poll the management queue for frames, it has priority over 1970 * normal data frames. 1971 */ 1972 IF_DEQUEUE(&ic->ic_mgtq, m); 1973 if (m == NULL) { 1974 DPRINTFN(10, ("%s: atu_start: data packet\n", 1975 sc->atu_dev.dv_xname)); 1976 if (ic->ic_state != IEEE80211_S_RUN) { 1977 DPRINTFN(25, ("%s: no data till running\n", 1978 sc->atu_dev.dv_xname)); 1979 /* put the xfer back on the list */ 1980 s = splnet(); 1981 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1982 atu_list); 1983 cd->atu_tx_inuse--; 1984 splx(s); 1985 break; 1986 } 1987 1988 IFQ_DEQUEUE(&ifp->if_snd, m); 1989 if (m == NULL) { 1990 DPRINTFN(25, ("%s: nothing to send\n", 1991 sc->atu_dev.dv_xname)); 1992 s = splnet(); 1993 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1994 atu_list); 1995 cd->atu_tx_inuse--; 1996 splx(s); 1997 break; 1998 } 1999 2000 #if NBPFILTER > 0 2001 if (ifp->if_bpf) 2002 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 2003 #endif 2004 2005 m = ieee80211_encap(ifp, m, &ni); 2006 if (m == NULL) 2007 goto bad; 2008 wh = mtod(m, struct ieee80211_frame *); 2009 2010 #if NBPFILTER > 0 2011 if (ic->ic_rawbpf != NULL) 2012 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT); 2013 #endif 2014 } else { 2015 DPRINTFN(25, ("%s: atu_start: mgmt packet\n", 2016 sc->atu_dev.dv_xname)); 2017 2018 /* 2019 * Hack! The referenced node pointer is in the 2020 * rcvif field of the packet header. This is 2021 * placed there by ieee80211_mgmt_output because 2022 * we need to hold the reference with the frame 2023 * and there's no other way (other than packet 2024 * tags which we consider too expensive to use) 2025 * to pass it along. 2026 */ 2027 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 2028 m->m_pkthdr.rcvif = NULL; 2029 2030 wh = mtod(m, struct ieee80211_frame *); 2031 /* sc->sc_stats.ast_tx_mgmt++; */ 2032 } 2033 2034 if (atu_tx_start(sc, ni, c, m)) { 2035 bad: 2036 s = splnet(); 2037 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 2038 atu_list); 2039 cd->atu_tx_inuse--; 2040 splx(s); 2041 /* ifp_if_oerrors++; */ 2042 if (ni != NULL) 2043 ieee80211_release_node(ic, ni); 2044 continue; 2045 } 2046 ifp->if_timer = 5; 2047 } 2048 } 2049 2050 int 2051 atu_init(struct ifnet *ifp) 2052 { 2053 struct atu_softc *sc = ifp->if_softc; 2054 struct ieee80211com *ic = &sc->sc_ic; 2055 struct atu_chain *c; 2056 usbd_status err; 2057 int i, s; 2058 2059 s = splnet(); 2060 2061 DPRINTFN(10, ("%s: atu_init\n", sc->atu_dev.dv_xname)); 2062 2063 if (ifp->if_flags & IFF_RUNNING) { 2064 splx(s); 2065 return(0); 2066 } 2067 2068 /* Init TX ring */ 2069 if (atu_tx_list_init(sc)) 2070 printf("%s: tx list init failed\n", sc->atu_dev.dv_xname); 2071 2072 /* Init RX ring */ 2073 if (atu_rx_list_init(sc)) 2074 printf("%s: rx list init failed\n", sc->atu_dev.dv_xname); 2075 2076 /* Load the multicast filter. */ 2077 /*atu_setmulti(sc); */ 2078 2079 /* Open RX and TX pipes. */ 2080 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX], 2081 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_RX]); 2082 if (err) { 2083 DPRINTF(("%s: open rx pipe failed: %s\n", 2084 sc->atu_dev.dv_xname, usbd_errstr(err))); 2085 splx(s); 2086 return(EIO); 2087 } 2088 2089 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX], 2090 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_TX]); 2091 if (err) { 2092 DPRINTF(("%s: open tx pipe failed: %s\n", 2093 sc->atu_dev.dv_xname, usbd_errstr(err))); 2094 splx(s); 2095 return(EIO); 2096 } 2097 2098 /* Start up the receive pipe. */ 2099 for (i = 0; i < ATU_RX_LIST_CNT; i++) { 2100 c = &sc->atu_cdata.atu_rx_chain[i]; 2101 2102 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c, 2103 c->atu_buf, ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 2104 USBD_NO_TIMEOUT, atu_rxeof); 2105 usbd_transfer(c->atu_xfer); 2106 } 2107 2108 DPRINTFN(10, ("%s: starting up using MAC=%s\n", 2109 sc->atu_dev.dv_xname, ether_sprintf(ic->ic_myaddr))); 2110 2111 /* Do initial setup */ 2112 err = atu_initial_config(sc); 2113 if (err) { 2114 DPRINTF(("%s: initial config failed!\n", 2115 sc->atu_dev.dv_xname)); 2116 splx(s); 2117 return(EIO); 2118 } 2119 DPRINTFN(10, ("%s: initialised transceiver\n", 2120 sc->atu_dev.dv_xname)); 2121 2122 /* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */ 2123 2124 /* If we want promiscuous mode, set the allframes bit. */ 2125 /* 2126 if (ifp->if_flags & IFF_PROMISC) 2127 sc->atu_rxfilt |= ATU_RXFILT_PROMISC; 2128 */ 2129 2130 ifp->if_flags |= IFF_RUNNING; 2131 ifp->if_flags &= ~IFF_OACTIVE; 2132 splx(s); 2133 2134 /* XXX the following HAS to be replaced */ 2135 s = splnet(); 2136 err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2137 if (err) 2138 DPRINTFN(1, ("%s: atu_init: error calling " 2139 "ieee80211_net_state", sc->atu_dev.dv_xname)); 2140 splx(s); 2141 2142 return 0; 2143 } 2144 2145 int 2146 atu_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 2147 { 2148 struct atu_softc *sc = ifp->if_softc; 2149 struct ifaddr *ifa; 2150 int err = 0, s; 2151 2152 s = splnet(); 2153 switch (command) { 2154 case SIOCSIFADDR: 2155 DPRINTFN(15, ("%s: SIOCSIFADDR\n", sc->atu_dev.dv_xname)); 2156 2157 ifa = (struct ifaddr *)data; 2158 ifp->if_flags |= IFF_UP; 2159 atu_init(ifp); 2160 2161 switch (ifa->ifa_addr->sa_family) { 2162 #ifdef INET 2163 case AF_INET: 2164 arp_ifinit(&sc->sc_ic.ic_ac, ifa); 2165 break; 2166 #endif /* INET */ 2167 } 2168 break; 2169 2170 case SIOCSIFFLAGS: 2171 DPRINTFN(15, ("%s: SIOCSIFFLAGS\n", sc->atu_dev.dv_xname)); 2172 2173 if (ifp->if_flags & IFF_UP) { 2174 if (ifp->if_flags & IFF_RUNNING && 2175 ifp->if_flags & IFF_PROMISC && 2176 !(sc->atu_if_flags & IFF_PROMISC)) { 2177 /* enable promisc */ 2178 #if 0 2179 sc->atu_rxfilt |= ATU_RXFILT_PROMISC; 2180 atu_setword(sc, ATU_CMD_SET_PKT_FILTER, 2181 sc->atu_rxfilt); 2182 #endif 2183 } else if (ifp->if_flags & IFF_RUNNING && 2184 !(ifp->if_flags & IFF_PROMISC) && 2185 sc->atu_if_flags & IFF_PROMISC) { 2186 /* disable promisc */ 2187 #if 0 2188 sc->atu_rxfilt &= ~ATU_RXFILT_PROMISC; 2189 atu_setword(sc, ATU_CMD_SET_PKT_FILTER, 2190 sc->atu_rxfilt); 2191 #endif 2192 } else if (!(ifp->if_flags & IFF_RUNNING)) 2193 atu_init(ifp); 2194 2195 DPRINTFN(15, ("%s: ioctl calling atu_init()\n", 2196 sc->atu_dev.dv_xname)); 2197 atu_init(ifp); 2198 err = atu_switch_radio(sc, 1); 2199 } else { 2200 if (ifp->if_flags & IFF_RUNNING) 2201 atu_stop(ifp, 0); 2202 err = atu_switch_radio(sc, 0); 2203 } 2204 sc->atu_if_flags = ifp->if_flags; 2205 err = 0; 2206 break; 2207 2208 case SIOCADDMULTI: 2209 DPRINTFN(15, ("%s: SIOCADDMULTI\n", sc->atu_dev.dv_xname)); 2210 /* TODO: implement */ 2211 err = 0; 2212 break; 2213 2214 case SIOCDELMULTI: 2215 DPRINTFN(15, ("%s: SIOCDELMULTI\n", sc->atu_dev.dv_xname)); 2216 /* TODO: implement */ 2217 err = 0; 2218 break; 2219 2220 default: 2221 DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n", 2222 sc->atu_dev.dv_xname, command)); 2223 err = ieee80211_ioctl(ifp, command, data); 2224 break; 2225 } 2226 2227 if (err == ENETRESET) { 2228 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 2229 (IFF_RUNNING|IFF_UP)) { 2230 DPRINTF(("%s: atu_ioctl(): netreset\n", 2231 sc->atu_dev.dv_xname)); 2232 atu_init(ifp); 2233 } 2234 err = 0; 2235 } 2236 2237 splx(s); 2238 return (err); 2239 } 2240 2241 void 2242 atu_watchdog(struct ifnet *ifp) 2243 { 2244 struct atu_softc *sc = ifp->if_softc; 2245 struct atu_chain *c; 2246 usbd_status stat; 2247 int cnt, s; 2248 2249 DPRINTF(("%s: atu_watchdog\n", sc->atu_dev.dv_xname)); 2250 2251 ifp->if_timer = 0; 2252 2253 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) 2254 return; 2255 2256 if (sc->sc_state != ATU_S_OK) 2257 return; 2258 2259 sc = ifp->if_softc; 2260 s = splnet(); 2261 ifp->if_oerrors++; 2262 DPRINTF(("%s: watchdog timeout\n", sc->atu_dev.dv_xname)); 2263 2264 /* 2265 * TODO: 2266 * we should change this since we have multiple TX transfers... 2267 */ 2268 for (cnt = 0; cnt < ATU_TX_LIST_CNT; cnt++) { 2269 c = &sc->atu_cdata.atu_tx_chain[cnt]; 2270 if (c->atu_in_xfer) { 2271 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, 2272 &stat); 2273 atu_txeof(c->atu_xfer, c, stat); 2274 } 2275 } 2276 2277 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 2278 atu_start(ifp); 2279 splx(s); 2280 2281 ieee80211_watchdog(ifp); 2282 } 2283 2284 /* 2285 * Stop the adapter and free any mbufs allocated to the 2286 * RX and TX lists. 2287 */ 2288 void 2289 atu_stop(struct ifnet *ifp, int disable) 2290 { 2291 struct atu_softc *sc = ifp->if_softc; 2292 struct atu_cdata *cd; 2293 usbd_status err; 2294 int s; 2295 2296 s = splnet(); 2297 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2298 ifp->if_timer = 0; 2299 2300 /* Stop transfers. */ 2301 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) { 2302 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); 2303 if (err) { 2304 DPRINTF(("%s: abort rx pipe failed: %s\n", 2305 sc->atu_dev.dv_xname, usbd_errstr(err))); 2306 } 2307 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]); 2308 if (err) { 2309 DPRINTF(("%s: close rx pipe failed: %s\n", 2310 sc->atu_dev.dv_xname, usbd_errstr(err))); 2311 } 2312 sc->atu_ep[ATU_ENDPT_RX] = NULL; 2313 } 2314 2315 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { 2316 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); 2317 if (err) { 2318 DPRINTF(("%s: abort tx pipe failed: %s\n", 2319 sc->atu_dev.dv_xname, usbd_errstr(err))); 2320 } 2321 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]); 2322 if (err) { 2323 DPRINTF(("%s: close tx pipe failed: %s\n", 2324 sc->atu_dev.dv_xname, usbd_errstr(err))); 2325 } 2326 sc->atu_ep[ATU_ENDPT_TX] = NULL; 2327 } 2328 2329 /* Free RX/TX/MGMT list resources. */ 2330 cd = &sc->atu_cdata; 2331 atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT); 2332 atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT); 2333 2334 /* Let's be nice and turn off the radio before we leave */ 2335 atu_switch_radio(sc, 0); 2336 2337 splx(s); 2338 } 2339