1/*- 2 * Copyright (c) 2006 Sam Leffler, Errno Consulting 3 * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org> 4 * 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: --- 35 unchanged lines hidden (view full) --- 44 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 45 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 46 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 47 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 48 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 49 */ 50 51#include <sys/cdefs.h> |
52__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_uath.c 244503 2012-12-20 18:38:02Z hselasky $"); |
53 54/*- 55 * Driver for Atheros AR5523 USB parts. 56 * 57 * The driver requires firmware to be loaded into the device. This 58 * is done on device discovery from a user application (uathload) 59 * that is launched by devd when a device with suitable product ID 60 * is recognized. Once firmware has been loaded the device will --- 151 unchanged lines hidden (view full) --- 212 .short_xfer_ok = 1 213 }, 214 .callback = uath_intr_rx_callback 215 }, 216 [UATH_INTR_TX] = { 217 .type = UE_BULK, 218 .endpoint = 0x1, 219 .direction = UE_DIR_OUT, |
220 .bufsize = UATH_MAX_CMDSZ * UATH_CMD_LIST_COUNT, |
221 .flags = { |
222 .force_short_xfer = 1, 223 .pipe_bof = 1, 224 }, 225 .callback = uath_intr_tx_callback, 226 .timeout = UATH_CMD_TIMEOUT 227 }, 228 [UATH_BULK_RX] = { 229 .type = UE_BULK, --- 6 unchanged lines hidden (view full) --- 236 .short_xfer_ok = 1 237 }, 238 .callback = uath_bulk_rx_callback 239 }, 240 [UATH_BULK_TX] = { 241 .type = UE_BULK, 242 .endpoint = 0x2, 243 .direction = UE_DIR_OUT, |
244 .bufsize = UATH_MAX_TXBUFSZ * UATH_TX_DATA_LIST_COUNT, |
245 .flags = { |
246 .force_short_xfer = 1, 247 .pipe_bof = 1 248 }, 249 .callback = uath_bulk_tx_callback, 250 .timeout = UATH_DATA_TIMEOUT 251 } 252}; 253 254static struct ieee80211vap *uath_vap_create(struct ieee80211com *, 255 const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 256 const uint8_t [IEEE80211_ADDR_LEN], 257 const uint8_t [IEEE80211_ADDR_LEN]); 258static void uath_vap_delete(struct ieee80211vap *); |
259static int uath_alloc_cmd_list(struct uath_softc *, struct uath_cmd []); 260static void uath_free_cmd_list(struct uath_softc *, struct uath_cmd []); |
261static int uath_host_available(struct uath_softc *); 262static int uath_get_capability(struct uath_softc *, uint32_t, uint32_t *); 263static int uath_get_devcap(struct uath_softc *); 264static struct uath_cmd * 265 uath_get_cmdbuf(struct uath_softc *); 266static int uath_cmd_read(struct uath_softc *, uint32_t, const void *, 267 int, void *, int, int); 268static int uath_cmd_write(struct uath_softc *, uint32_t, const void *, --- 87 unchanged lines hidden (view full) --- 356 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, 357 MTX_DEF); 358 callout_init(&sc->stat_ch, 0); 359 callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); 360 361 /* 362 * Allocate xfers for firmware commands. 363 */ |
364 error = uath_alloc_cmd_list(sc, sc->sc_cmd); |
365 if (error != 0) { 366 device_printf(sc->sc_dev, 367 "could not allocate Tx command list\n"); 368 goto fail; 369 } 370 371 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, 372 uath_usbconfig, UATH_N_XFERS, sc, &sc->sc_mtx); 373 if (error) { 374 device_printf(dev, "could not allocate USB transfers, " 375 "err=%s\n", usbd_errstr(error)); 376 goto fail1; 377 } 378 |
379 sc->sc_cmd_dma_buf = 380 usbd_xfer_get_frame_buffer(sc->sc_xfer[UATH_INTR_TX], 0); 381 sc->sc_tx_dma_buf = 382 usbd_xfer_get_frame_buffer(sc->sc_xfer[UATH_BULK_TX], 0); 383 |
384 /* 385 * We're now ready to send+receive firmware commands. 386 */ 387 UATH_LOCK(sc); 388 error = uath_host_available(sc); 389 if (error != 0) { 390 device_printf(sc->sc_dev, "could not initialize adapter\n"); 391 goto fail3; --- 96 unchanged lines hidden (view full) --- 488 if (bootverbose) 489 ieee80211_announce(ic); 490 491 return (0); 492 493fail4: if_free(ifp); 494fail3: UATH_UNLOCK(sc); 495fail2: usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS); |
496fail1: uath_free_cmd_list(sc, sc->sc_cmd); |
497fail: 498 return (error); 499} 500 501static int 502uath_detach(device_t dev) 503{ 504 struct uath_softc *sc = device_get_softc(dev); --- 14 unchanged lines hidden (view full) --- 519 callout_drain(&sc->watchdog_ch); 520 521 usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS); 522 523 /* free buffers */ 524 UATH_LOCK(sc); 525 uath_free_rx_data_list(sc); 526 uath_free_tx_data_list(sc); |
527 uath_free_cmd_list(sc, sc->sc_cmd); |
528 UATH_UNLOCK(sc); 529 530 if_free(ifp); 531 mtx_destroy(&sc->sc_mtx); 532 return (0); 533} 534 535static void |
536uath_free_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[]) |
537{ 538 int i; 539 |
540 for (i = 0; i != UATH_CMD_LIST_COUNT; i++) 541 cmds[i].buf = NULL; |
542} 543 544static int |
545uath_alloc_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[]) |
546{ |
547 int i; |
548 549 STAILQ_INIT(&sc->sc_cmd_active); 550 STAILQ_INIT(&sc->sc_cmd_pending); 551 STAILQ_INIT(&sc->sc_cmd_waiting); 552 STAILQ_INIT(&sc->sc_cmd_inactive); 553 |
554 for (i = 0; i != UATH_CMD_LIST_COUNT; i++) { |
555 struct uath_cmd *cmd = &cmds[i]; 556 557 cmd->sc = sc; /* backpointer for callbacks */ 558 cmd->msgid = i; |
559 cmd->buf = ((uint8_t *)sc->sc_cmd_dma_buf) + 560 (i * UATH_MAX_CMDSZ); |
561 STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next); 562 UATH_STAT_INC(sc, st_cmd_inactive); 563 } 564 return (0); |
565} 566 567static int 568uath_host_available(struct uath_softc *sc) 569{ 570 struct uath_cmd_host_available setup; 571 572 UATH_ASSERT_LOCKED(sc); --- 354 unchanged lines hidden (view full) --- 927 928 if (fillmbuf == 1) { 929 if (dp->m != NULL) { 930 m_freem(dp->m); 931 dp->m = NULL; 932 dp->buf = NULL; 933 } 934 } else { |
935 dp->buf = NULL; |
936 } 937#ifdef UATH_DEBUG 938 if (dp->ni != NULL) 939 device_printf(sc->sc_dev, "Node isn't NULL\n"); 940#endif 941 } 942} 943 944static int 945uath_alloc_data_list(struct uath_softc *sc, struct uath_data data[], |
946 int ndata, int maxsz, void *dma_buf) |
947{ 948 int i, error; 949 950 for (i = 0; i < ndata; i++) { 951 struct uath_data *dp = &data[i]; 952 953 dp->sc = sc; |
954 if (dma_buf == NULL) { |
955 /* XXX check maxsz */ 956 dp->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 957 if (dp->m == NULL) { 958 device_printf(sc->sc_dev, 959 "could not allocate rx mbuf\n"); 960 error = ENOMEM; 961 goto fail; 962 } 963 dp->buf = mtod(dp->m, uint8_t *); 964 } else { 965 dp->m = NULL; |
966 dp->buf = ((uint8_t *)dma_buf) + (i * maxsz); |
967 } 968 dp->ni = NULL; 969 } 970 971 return (0); 972 |
973fail: uath_free_data_list(sc, data, ndata, 1 /* free mbufs */); |
974 return (error); 975} 976 977static int 978uath_alloc_rx_data_list(struct uath_softc *sc) 979{ 980 int error, i; 981 982 /* XXX is it enough to store the RX packet with MCLBYTES bytes? */ 983 error = uath_alloc_data_list(sc, 984 sc->sc_rx, UATH_RX_DATA_LIST_COUNT, MCLBYTES, |
985 NULL /* setup mbufs */); |
986 if (error != 0) 987 return (error); 988 989 STAILQ_INIT(&sc->sc_rx_active); 990 STAILQ_INIT(&sc->sc_rx_inactive); 991 992 for (i = 0; i < UATH_RX_DATA_LIST_COUNT; i++) { 993 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], --- 6 unchanged lines hidden (view full) --- 1000 1001static int 1002uath_alloc_tx_data_list(struct uath_softc *sc) 1003{ 1004 int error, i; 1005 1006 error = uath_alloc_data_list(sc, 1007 sc->sc_tx, UATH_TX_DATA_LIST_COUNT, UATH_MAX_TXBUFSZ, |
1008 sc->sc_tx_dma_buf); |
1009 if (error != 0) 1010 return (error); 1011 1012 STAILQ_INIT(&sc->sc_tx_active); 1013 STAILQ_INIT(&sc->sc_tx_inactive); 1014 STAILQ_INIT(&sc->sc_tx_pending); 1015 1016 for (i = 0; i < UATH_TX_DATA_LIST_COUNT; i++) { --- 1700 unchanged lines hidden (view full) --- 2717setup: 2718 data = STAILQ_FIRST(&sc->sc_rx_inactive); 2719 if (data == NULL) 2720 return; 2721 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next); 2722 UATH_STAT_DEC(sc, st_rx_inactive); 2723 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next); 2724 UATH_STAT_INC(sc, st_rx_active); |
2725 usbd_xfer_set_frame_data(xfer, 0, data->buf, MCLBYTES); |
2726 usbd_transfer_submit(xfer); 2727 2728 /* 2729 * To avoid LOR we should unlock our private mutex here to call 2730 * ieee80211_input() because here is at the end of a USB 2731 * callback and safe to unlock. 2732 */ 2733 if (sc->sc_flags & UATH_FLAG_INVALID) { --- 131 unchanged lines hidden (view full) --- 2865 break; 2866 } 2867} 2868 2869static device_method_t uath_methods[] = { 2870 DEVMETHOD(device_probe, uath_match), 2871 DEVMETHOD(device_attach, uath_attach), 2872 DEVMETHOD(device_detach, uath_detach), |
2873 DEVMETHOD_END |
2874}; 2875static driver_t uath_driver = { 2876 .name = "uath", 2877 .methods = uath_methods, 2878 .size = sizeof(struct uath_softc) 2879}; 2880static devclass_t uath_devclass; 2881 2882DRIVER_MODULE(uath, uhub, uath_driver, uath_devclass, NULL, 0); 2883MODULE_DEPEND(uath, wlan, 1, 1, 1); 2884MODULE_DEPEND(uath, usb, 1, 1, 1); 2885MODULE_VERSION(uath, 1); |