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