1/*- 2 * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include <sys/cdefs.h> |
18__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_urtw.c 244503 2012-12-20 18:38:02Z hselasky $"); |
19#include <sys/param.h> 20#include <sys/sockio.h> 21#include <sys/sysctl.h> 22#include <sys/lock.h> 23#include <sys/mutex.h> 24#include <sys/mbuf.h> 25#include <sys/kernel.h> 26#include <sys/socket.h> --- 500 unchanged lines hidden (view full) --- 527 .short_xfer_ok = 1 528 }, 529 .callback = urtw_bulk_rx_callback 530 }, 531 [URTW_8187B_BULK_TX_STATUS] = { 532 .type = UE_BULK, 533 .endpoint = 0x89, 534 .direction = UE_DIR_IN, |
535 .bufsize = sizeof(uint64_t), |
536 .flags = { |
537 .pipe_bof = 1, 538 .short_xfer_ok = 1 539 }, 540 .callback = urtw_bulk_tx_status_callback 541 }, 542 [URTW_8187B_BULK_TX_BE] = { 543 .type = UE_BULK, 544 .endpoint = URTW_8187B_TXPIPE_BE, 545 .direction = UE_DIR_OUT, |
546 .bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT, |
547 .flags = { |
548 .force_short_xfer = 1, 549 .pipe_bof = 1, 550 }, 551 .callback = urtw_bulk_tx_callback, 552 .timeout = URTW_DATA_TIMEOUT 553 }, 554 [URTW_8187B_BULK_TX_BK] = { 555 .type = UE_BULK, --- 61 unchanged lines hidden (view full) --- 617 .short_xfer_ok = 1 618 }, 619 .callback = urtw_bulk_rx_callback 620 }, 621 [URTW_8187L_BULK_TX_LOW] = { 622 .type = UE_BULK, 623 .endpoint = 0x2, 624 .direction = UE_DIR_OUT, |
625 .bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT, |
626 .flags = { |
627 .force_short_xfer = 1, 628 .pipe_bof = 1, 629 }, 630 .callback = urtw_bulk_tx_callback, 631 .timeout = URTW_DATA_TIMEOUT 632 }, 633 [URTW_8187L_BULK_TX_NORMAL] = { 634 .type = UE_BULK, --- 184 unchanged lines hidden (view full) --- 819 setup_start, n_setup, sc, &sc->sc_mtx); 820 if (error) { 821 device_printf(dev, "could not allocate USB transfers, " 822 "err=%s\n", usbd_errstr(error)); 823 ret = ENXIO; 824 goto fail0; 825 } 826 |
827 if (sc->sc_flags & URTW_RTL8187B) { 828 sc->sc_tx_dma_buf = 829 usbd_xfer_get_frame_buffer(sc->sc_xfer[ 830 URTW_8187B_BULK_TX_BE], 0); 831 } else { 832 sc->sc_tx_dma_buf = 833 usbd_xfer_get_frame_buffer(sc->sc_xfer[ 834 URTW_8187L_BULK_TX_LOW], 0); 835 } 836 |
837 URTW_LOCK(sc); 838 839 urtw_read32_m(sc, URTW_RX, &data); 840 sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 : 841 URTW_EEPROM_93C46; 842 843 error = urtw_get_rfchip(sc); 844 if (error != 0) --- 94 unchanged lines hidden (view full) --- 939 940 urtw_stop(ifp, 1); 941 ieee80211_draintask(ic, &sc->sc_updateslot_task); 942 ieee80211_draintask(ic, &sc->sc_led_task); 943 944 usb_callout_drain(&sc->sc_led_ch); 945 callout_drain(&sc->sc_watchdog_ch); 946 |
947 ieee80211_ifdetach(ic); 948 |
949 usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ? 950 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS); |
951 952 urtw_free_tx_data_list(sc); 953 urtw_free_rx_data_list(sc); 954 955 if_free(ifp); 956 mtx_destroy(&sc->sc_mtx); 957 958 return (0); --- 24 unchanged lines hidden (view full) --- 983 984 if (fillmbuf == 1) { 985 if (dp->m != NULL) { 986 m_freem(dp->m); 987 dp->m = NULL; 988 dp->buf = NULL; 989 } 990 } else { |
991 dp->buf = NULL; |
992 } 993 if (dp->ni != NULL) { 994 ieee80211_free_node(dp->ni); 995 dp->ni = NULL; 996 } 997 } 998} 999 --- 449 unchanged lines hidden (view full) --- 1449 sc->sc_txtimer = 5; 1450 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); 1451 } 1452 URTW_UNLOCK(sc); 1453} 1454 1455static int 1456urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[], |
1457 int ndata, int maxsz, void *dma_buf) |
1458{ 1459 int i, error; 1460 1461 for (i = 0; i < ndata; i++) { 1462 struct urtw_data *dp = &data[i]; 1463 1464 dp->sc = sc; |
1465 if (dma_buf == NULL) { |
1466 dp->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 1467 if (dp->m == NULL) { 1468 device_printf(sc->sc_dev, 1469 "could not allocate rx mbuf\n"); 1470 error = ENOMEM; 1471 goto fail; 1472 } 1473 dp->buf = mtod(dp->m, uint8_t *); 1474 } else { 1475 dp->m = NULL; |
1476 dp->buf = ((uint8_t *)dma_buf) + 1477 (i * maxsz); |
1478 } 1479 dp->ni = NULL; 1480 } |
1481 return (0); |
1482 |
1483fail: urtw_free_data_list(sc, data, ndata, 1); 1484 return (error); |
1485} 1486 1487static int 1488urtw_alloc_rx_data_list(struct urtw_softc *sc) 1489{ 1490 int error, i; 1491 1492 error = urtw_alloc_data_list(sc, |
1493 sc->sc_rx, URTW_RX_DATA_LIST_COUNT, 1494 MCLBYTES, NULL /* mbufs */); |
1495 if (error != 0) 1496 return (error); 1497 1498 STAILQ_INIT(&sc->sc_rx_active); 1499 STAILQ_INIT(&sc->sc_rx_inactive); 1500 1501 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) 1502 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next); 1503 1504 return (0); 1505} 1506 1507static int 1508urtw_alloc_tx_data_list(struct urtw_softc *sc) 1509{ 1510 int error, i; 1511 1512 error = urtw_alloc_data_list(sc, 1513 sc->sc_tx, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE, |
1514 sc->sc_tx_dma_buf /* no mbufs */); |
1515 if (error != 0) 1516 return (error); 1517 1518 STAILQ_INIT(&sc->sc_tx_active); 1519 STAILQ_INIT(&sc->sc_tx_inactive); 1520 STAILQ_INIT(&sc->sc_tx_pending); 1521 1522 for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++) --- 1178 unchanged lines hidden (view full) --- 2701 DELAY(10); 2702 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN); 2703 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84); 2704 usb_pause_mtx(&sc->sc_mtx, 2); 2705fail: 2706 return (error); 2707} 2708 |
2709static usb_error_t 2710urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index, 2711 uint16_t *data) 2712{ |
2713 uint8_t buf[2]; |
2714 uint16_t data16; |
2715 struct usb_device_request req; |
2716 usb_error_t error = 0; 2717 2718 data16 = *data; |
2719 |
2720 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 2721 req.bRequest = URTW_8187_SETREGS_REQ; 2722 USETW(req.wValue, addr); 2723 USETW(req.wIndex, index); 2724 USETW(req.wLength, sizeof(uint16_t)); |
2725 buf[0] = (data16 & 0x00ff); 2726 buf[1] = (data16 & 0xff00) >> 8; 2727 |
2728 error = urtw_do_request(sc, &req, buf); |
2729 |
2730 return (error); |
2731} 2732 2733static usb_error_t 2734urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan) 2735{ 2736 usb_error_t error; 2737 2738 error = urtw_8225_set_txpwrlvl(sc, chan); --- 1372 unchanged lines hidden (view full) --- 4111 } 4112} 4113 4114static void 4115urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error) 4116{ 4117 struct urtw_softc *sc = usbd_xfer_softc(xfer); 4118 struct ifnet *ifp = sc->sc_ifp; |
4119 void *dma_buf = usbd_xfer_get_frame_buffer(xfer, 0); |
4120 4121 URTW_ASSERT_LOCKED(sc); 4122 4123 switch (USB_GET_STATE(xfer)) { 4124 case USB_ST_TRANSFERRED: 4125 urtw_txstatus_eof(xfer); 4126 /* FALLTHROUGH */ 4127 case USB_ST_SETUP: 4128setup: |
4129 memcpy(dma_buf, &sc->sc_txstatus, sizeof(uint64_t)); |
4130 usbd_transfer_submit(xfer); 4131 break; 4132 default: 4133 if (error != USB_ERR_CANCELLED) { 4134 usbd_xfer_set_stall(xfer); 4135 ifp->if_ierrors++; 4136 goto setup; 4137 } --- 271 unchanged lines hidden (view full) --- 4409 "54 Mbit/s"); 4410#undef URTW_SYSCTL_STAT_ADD32 4411} 4412 4413static device_method_t urtw_methods[] = { 4414 DEVMETHOD(device_probe, urtw_match), 4415 DEVMETHOD(device_attach, urtw_attach), 4416 DEVMETHOD(device_detach, urtw_detach), |
4417 DEVMETHOD_END |
4418}; 4419static driver_t urtw_driver = { 4420 .name = "urtw", 4421 .methods = urtw_methods, 4422 .size = sizeof(struct urtw_softc) 4423}; 4424static devclass_t urtw_devclass; 4425 4426DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, 0); 4427MODULE_DEPEND(urtw, wlan, 1, 1, 1); 4428MODULE_DEPEND(urtw, usb, 1, 1, 1); 4429MODULE_VERSION(urtw, 1); |