if_rsu.c (288094) | if_rsu.c (288257) |
---|---|
1/* $OpenBSD: if_rsu.c,v 1.17 2013/04/15 09:23:01 mglocker Exp $ */ 2 3/*- 4 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18#include <sys/cdefs.h> | 1/* $OpenBSD: if_rsu.c,v 1.17 2013/04/15 09:23:01 mglocker Exp $ */ 2 3/*- 4 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18#include <sys/cdefs.h> |
19__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_rsu.c 288094 2015-09-22 05:48:51Z adrian $"); | 19__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_rsu.c 288257 2015-09-26 07:25:53Z adrian $"); |
20 21/* 22 * Driver for Realtek RTL8188SU/RTL8191SU/RTL8192SU. 23 * 24 * TODO: | 20 21/* 22 * Driver for Realtek RTL8188SU/RTL8191SU/RTL8192SU. 23 * 24 * TODO: |
25 * o 11n HT40 support | |
26 * o h/w crypto 27 * o hostap / ibss / mesh 28 * o sensible RSSI levels 29 * o power-save operation 30 */ 31 32#include <sys/param.h> 33#include <sys/endian.h> --- 451 unchanged lines hidden (view full) --- 485 device_printf(sc->sc_dev, "%s: enabling 11n\n", __func__); 486 487 /* Enable basic HT */ 488 ic->ic_htcaps = IEEE80211_HTC_HT | 489 IEEE80211_HTC_AMPDU | 490 IEEE80211_HTC_AMSDU | 491 IEEE80211_HTCAP_MAXAMSDU_3839 | 492 IEEE80211_HTCAP_SMPS_OFF; | 25 * o h/w crypto 26 * o hostap / ibss / mesh 27 * o sensible RSSI levels 28 * o power-save operation 29 */ 30 31#include <sys/param.h> 32#include <sys/endian.h> --- 451 unchanged lines hidden (view full) --- 484 device_printf(sc->sc_dev, "%s: enabling 11n\n", __func__); 485 486 /* Enable basic HT */ 487 ic->ic_htcaps = IEEE80211_HTC_HT | 488 IEEE80211_HTC_AMPDU | 489 IEEE80211_HTC_AMSDU | 490 IEEE80211_HTCAP_MAXAMSDU_3839 | 491 IEEE80211_HTCAP_SMPS_OFF; |
493 494 /* 495 * XXX HT40 isn't working in this driver yet - there's 496 * something missing. Disable it for now. 497 */ 498#if 0 | |
499 ic->ic_htcaps |= IEEE80211_HTCAP_CHWIDTH40; | 492 ic->ic_htcaps |= IEEE80211_HTCAP_CHWIDTH40; |
500#endif | |
501 502 /* set number of spatial streams */ 503 ic->ic_txstream = 1; 504 ic->ic_rxstream = 1; 505 } 506 507 /* Set supported .11b and .11g rates. */ 508 bands = 0; --- 864 unchanged lines hidden (view full) --- 1373 /* Write IEs to be included in the association request. */ 1374 frm = (uint8_t *)&fixed[1]; 1375 frm = ieee80211_add_rsn(frm, vap); 1376 frm = ieee80211_add_wpa(frm, vap); 1377 frm = ieee80211_add_qos(frm, ni); 1378 if ((ic->ic_flags & IEEE80211_F_WME) && 1379 (ni->ni_ies.wme_ie != NULL)) 1380 frm = ieee80211_add_wme_info(frm, &ic->ic_wme); | 493 494 /* set number of spatial streams */ 495 ic->ic_txstream = 1; 496 ic->ic_rxstream = 1; 497 } 498 499 /* Set supported .11b and .11g rates. */ 500 bands = 0; --- 864 unchanged lines hidden (view full) --- 1365 /* Write IEs to be included in the association request. */ 1366 frm = (uint8_t *)&fixed[1]; 1367 frm = ieee80211_add_rsn(frm, vap); 1368 frm = ieee80211_add_wpa(frm, vap); 1369 frm = ieee80211_add_qos(frm, ni); 1370 if ((ic->ic_flags & IEEE80211_F_WME) && 1371 (ni->ni_ies.wme_ie != NULL)) 1372 frm = ieee80211_add_wme_info(frm, &ic->ic_wme); |
1381 if (ni->ni_flags & IEEE80211_NODE_HT) | 1373 if (ni->ni_flags & IEEE80211_NODE_HT) { |
1382 frm = ieee80211_add_htcap(frm, ni); | 1374 frm = ieee80211_add_htcap(frm, ni); |
1375 frm = ieee80211_add_htinfo(frm, ni); 1376 } |
|
1383 bss->ieslen = htole32(frm - (uint8_t *)fixed); 1384 bss->len = htole32(((frm - buf) + 3) & ~3); 1385 RSU_DPRINTF(sc, RSU_DEBUG_RESET | RSU_DEBUG_FWCMD, 1386 "%s: sending join bss command to %s chan %d\n", 1387 __func__, 1388 ether_sprintf(bss->macaddr), le32toh(bss->config.dsconfig)); 1389 return (rsu_fw_cmd(sc, R92S_CMD_JOIN_BSS, buf, sizeof(buf))); 1390} --- 448 unchanged lines hidden (view full) --- 1839 if (data == NULL) 1840 goto tr_setup; 1841 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); 1842 m = rsu_rxeof(xfer, data, &rssi); 1843 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); 1844 /* FALLTHROUGH */ 1845 case USB_ST_SETUP: 1846tr_setup: | 1377 bss->ieslen = htole32(frm - (uint8_t *)fixed); 1378 bss->len = htole32(((frm - buf) + 3) & ~3); 1379 RSU_DPRINTF(sc, RSU_DEBUG_RESET | RSU_DEBUG_FWCMD, 1380 "%s: sending join bss command to %s chan %d\n", 1381 __func__, 1382 ether_sprintf(bss->macaddr), le32toh(bss->config.dsconfig)); 1383 return (rsu_fw_cmd(sc, R92S_CMD_JOIN_BSS, buf, sizeof(buf))); 1384} --- 448 unchanged lines hidden (view full) --- 1833 if (data == NULL) 1834 goto tr_setup; 1835 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); 1836 m = rsu_rxeof(xfer, data, &rssi); 1837 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); 1838 /* FALLTHROUGH */ 1839 case USB_ST_SETUP: 1840tr_setup: |
1841 /* 1842 * XXX TODO: if we have an mbuf list, but then 1843 * we hit data == NULL, what now? 1844 */ |
|
1847 data = STAILQ_FIRST(&sc->sc_rx_inactive); 1848 if (data == NULL) { 1849 KASSERT(m == NULL, ("mbuf isn't NULL")); 1850 return; 1851 } 1852 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next); 1853 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next); 1854 usbd_xfer_set_frame_data(xfer, 0, data->buf, --- 141 unchanged lines hidden (view full) --- 1996 struct rsu_softc *sc = usbd_xfer_softc(xfer); 1997 1998 rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_H2C); 1999 2000 /* This kicks the TX taskqueue */ 2001 rsu_start(sc); 2002} 2003 | 1845 data = STAILQ_FIRST(&sc->sc_rx_inactive); 1846 if (data == NULL) { 1847 KASSERT(m == NULL, ("mbuf isn't NULL")); 1848 return; 1849 } 1850 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next); 1851 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next); 1852 usbd_xfer_set_frame_data(xfer, 0, data->buf, --- 141 unchanged lines hidden (view full) --- 1994 struct rsu_softc *sc = usbd_xfer_softc(xfer); 1995 1996 rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_H2C); 1997 1998 /* This kicks the TX taskqueue */ 1999 rsu_start(sc); 2000} 2001 |
2002/* 2003 * Transmit the given frame. 2004 * 2005 * This doesn't free the node or mbuf upon failure. 2006 */ |
|
2004static int 2005rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, 2006 struct mbuf *m0, struct rsu_data *data) 2007{ 2008 struct ieee80211com *ic = &sc->sc_ic; 2009 struct ieee80211vap *vap = ni->ni_vap; 2010 struct ieee80211_frame *wh; 2011 struct ieee80211_key *k = NULL; --- 14 unchanged lines hidden (view full) --- 2026 __func__, data, m0); 2027 2028 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 2029 k = ieee80211_crypto_encap(ni, m0); 2030 if (k == NULL) { 2031 device_printf(sc->sc_dev, 2032 "ieee80211_crypto_encap returns NULL.\n"); 2033 /* XXX we don't expect the fragmented frames */ | 2007static int 2008rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, 2009 struct mbuf *m0, struct rsu_data *data) 2010{ 2011 struct ieee80211com *ic = &sc->sc_ic; 2012 struct ieee80211vap *vap = ni->ni_vap; 2013 struct ieee80211_frame *wh; 2014 struct ieee80211_key *k = NULL; --- 14 unchanged lines hidden (view full) --- 2029 __func__, data, m0); 2030 2031 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 2032 k = ieee80211_crypto_encap(ni, m0); 2033 if (k == NULL) { 2034 device_printf(sc->sc_dev, 2035 "ieee80211_crypto_encap returns NULL.\n"); 2036 /* XXX we don't expect the fragmented frames */ |
2034 m_freem(m0); | |
2035 return (ENOBUFS); 2036 } 2037 wh = mtod(m0, struct ieee80211_frame *); 2038 } 2039 /* If we have QoS then use it */ 2040 /* XXX TODO: mbuf WME/PRI versus TID? */ 2041 if (IEEE80211_QOS_HAS_SEQ(wh)) { 2042 /* Has QoS */ --- 99 unchanged lines hidden (view full) --- 2142 struct rsu_softc *sc = ic->ic_softc; 2143 int error; 2144 2145 RSU_LOCK(sc); 2146 if (!sc->sc_running) { 2147 RSU_UNLOCK(sc); 2148 return (ENXIO); 2149 } | 2037 return (ENOBUFS); 2038 } 2039 wh = mtod(m0, struct ieee80211_frame *); 2040 } 2041 /* If we have QoS then use it */ 2042 /* XXX TODO: mbuf WME/PRI versus TID? */ 2043 if (IEEE80211_QOS_HAS_SEQ(wh)) { 2044 /* Has QoS */ --- 99 unchanged lines hidden (view full) --- 2144 struct rsu_softc *sc = ic->ic_softc; 2145 int error; 2146 2147 RSU_LOCK(sc); 2148 if (!sc->sc_running) { 2149 RSU_UNLOCK(sc); 2150 return (ENXIO); 2151 } |
2152 2153 /* 2154 * XXX TODO: ensure that we treat 'm' as a list of frames 2155 * to transmit! 2156 */ |
|
2150 error = mbufq_enqueue(&sc->sc_snd, m); 2151 if (error) { 2152 RSU_DPRINTF(sc, RSU_DEBUG_TX, 2153 "%s: mbufq_enable: failed (%d)\n", 2154 __func__, 2155 error); 2156 RSU_UNLOCK(sc); 2157 return (error); --- 44 unchanged lines hidden (view full) --- 2202 2203 if (rsu_tx_start(sc, ni, m, bf) != 0) { 2204 RSU_DPRINTF(sc, RSU_DEBUG_TX, 2205 "%s: failed to transmit\n", __func__); 2206 if_inc_counter(ni->ni_vap->iv_ifp, 2207 IFCOUNTER_OERRORS, 1); 2208 rsu_freebuf(sc, bf); 2209 ieee80211_free_node(ni); | 2157 error = mbufq_enqueue(&sc->sc_snd, m); 2158 if (error) { 2159 RSU_DPRINTF(sc, RSU_DEBUG_TX, 2160 "%s: mbufq_enable: failed (%d)\n", 2161 __func__, 2162 error); 2163 RSU_UNLOCK(sc); 2164 return (error); --- 44 unchanged lines hidden (view full) --- 2209 2210 if (rsu_tx_start(sc, ni, m, bf) != 0) { 2211 RSU_DPRINTF(sc, RSU_DEBUG_TX, 2212 "%s: failed to transmit\n", __func__); 2213 if_inc_counter(ni->ni_vap->iv_ifp, 2214 IFCOUNTER_OERRORS, 1); 2215 rsu_freebuf(sc, bf); 2216 ieee80211_free_node(ni); |
2217 m_freem(m); |
|
2210 break; 2211 } 2212 } 2213} 2214 2215static void 2216rsu_start(struct rsu_softc *sc) 2217{ --- 497 unchanged lines hidden (view full) --- 2715 if (bf == NULL) { 2716 ieee80211_free_node(ni); 2717 m_freem(m); 2718 RSU_UNLOCK(sc); 2719 return (ENOBUFS); 2720 } 2721 if (rsu_tx_start(sc, ni, m, bf) != 0) { 2722 ieee80211_free_node(ni); | 2218 break; 2219 } 2220 } 2221} 2222 2223static void 2224rsu_start(struct rsu_softc *sc) 2225{ --- 497 unchanged lines hidden (view full) --- 2723 if (bf == NULL) { 2724 ieee80211_free_node(ni); 2725 m_freem(m); 2726 RSU_UNLOCK(sc); 2727 return (ENOBUFS); 2728 } 2729 if (rsu_tx_start(sc, ni, m, bf) != 0) { 2730 ieee80211_free_node(ni); |
2731 m_freem(m); |
|
2723 rsu_freebuf(sc, bf); 2724 RSU_UNLOCK(sc); 2725 return (EIO); 2726 } 2727 RSU_UNLOCK(sc); 2728 2729 return (0); 2730} --- 73 unchanged lines hidden (view full) --- 2804 /* Set PS mode fully active */ 2805 error = rsu_set_fw_power_state(sc, RSU_PWR_ACTIVE); 2806 2807 if (error != 0) { 2808 device_printf(sc->sc_dev, "could not set PS mode\n"); 2809 goto fail; 2810 } 2811 | 2732 rsu_freebuf(sc, bf); 2733 RSU_UNLOCK(sc); 2734 return (EIO); 2735 } 2736 RSU_UNLOCK(sc); 2737 2738 return (0); 2739} --- 73 unchanged lines hidden (view full) --- 2813 /* Set PS mode fully active */ 2814 error = rsu_set_fw_power_state(sc, RSU_PWR_ACTIVE); 2815 2816 if (error != 0) { 2817 device_printf(sc->sc_dev, "could not set PS mode\n"); 2818 goto fail; 2819 } 2820 |
2812 if (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) { 2813 /* Enable 40MHz mode. */ 2814 error = rsu_fw_iocmd(sc, 2815 SM(R92S_IOCMD_CLASS, 0xf4) | 2816 SM(R92S_IOCMD_INDEX, 0x00) | 2817 SM(R92S_IOCMD_VALUE, 0x0007)); 2818 if (error != 0) { 2819 device_printf(sc->sc_dev, 2820 "could not enable 40MHz mode\n"); 2821 goto fail; 2822 } 2823 } 2824 | |
2825 sc->sc_scan_pass = 0; 2826 usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]); 2827 2828 /* We're ready to go. */ 2829 sc->sc_running = 1; 2830 sc->sc_scanning = 0; 2831 return; 2832fail: --- 38 unchanged lines hidden --- | 2821 sc->sc_scan_pass = 0; 2822 usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]); 2823 2824 /* We're ready to go. */ 2825 sc->sc_running = 1; 2826 sc->sc_scanning = 0; 2827 return; 2828fail: --- 38 unchanged lines hidden --- |