svn commit: r290651 - head/sys/dev/usb/wlan
Renato Botelho
garga at FreeBSD.org
Tue Nov 10 20:20:04 UTC 2015
> On Nov 10, 2015, at 10:52, Andriy Voskoboinyk <avos at FreeBSD.org> wrote:
>
> Author: avos
> Date: Tue Nov 10 12:52:26 2015
> New Revision: 290651
> URL: https://svnweb.freebsd.org/changeset/base/290651
>
> Log:
> urtwn(4): add IBSS mode support
>
> Tested with RTL8188EU, IBSS and STA modes.
>
> Reviewed by: kevlo
> Approved by: adrian (mentor)
> Differential Revision: https://reviews.freebsd.org/D4038
>
> Modified:
> head/sys/dev/usb/wlan/if_urtwn.c
> head/sys/dev/usb/wlan/if_urtwnvar.h
>
> Modified: head/sys/dev/usb/wlan/if_urtwn.c
> ==============================================================================
> --- head/sys/dev/usb/wlan/if_urtwn.c Tue Nov 10 12:20:22 2015 (r290650)
> +++ head/sys/dev/usb/wlan/if_urtwn.c Tue Nov 10 12:52:26 2015 (r290651)
> @@ -228,10 +228,14 @@ static int urtwn_setup_beacon(struct ur
> static void urtwn_update_beacon(struct ieee80211vap *, int);
> static int urtwn_tx_beacon(struct urtwn_softc *sc,
> struct urtwn_vap *);
> +static void urtwn_tsf_task_adhoc(void *, int);
> static void urtwn_tsf_sync_enable(struct urtwn_softc *,
> struct ieee80211vap *);
> static void urtwn_set_led(struct urtwn_softc *, int, int);
> static void urtwn_set_mode(struct urtwn_softc *, uint8_t);
> +static void urtwn_ibss_recv_mgmt(struct ieee80211_node *,
> + struct mbuf *, int,
> + const struct ieee80211_rx_stats *, int, int);
> static int urtwn_newstate(struct ieee80211vap *,
> enum ieee80211_state, int);
> static void urtwn_watchdog(void *);
> @@ -449,6 +453,7 @@ urtwn_attach(device_t self)
> ic->ic_caps =
> IEEE80211_C_STA /* station mode */
> | IEEE80211_C_MONITOR /* monitor mode */
> + | IEEE80211_C_IBSS /* adhoc mode */
> | IEEE80211_C_HOSTAP /* hostap mode */
> | IEEE80211_C_SHPREAMBLE /* short preamble supported */
> | IEEE80211_C_SHSLOT /* short slot time supported */
> @@ -592,13 +597,18 @@ urtwn_vap_create(struct ieee80211com *ic
> return (NULL);
> }
>
> - if (opmode == IEEE80211_M_HOSTAP)
> + if (opmode == IEEE80211_M_HOSTAP || opmode == IEEE80211_M_IBSS)
> urtwn_init_beacon(sc, uvp);
>
> /* override state transition machine */
> uvp->newstate = vap->iv_newstate;
> vap->iv_newstate = urtwn_newstate;
> vap->iv_update_beacon = urtwn_update_beacon;
> + if (opmode == IEEE80211_M_IBSS) {
> + uvp->recv_mgmt = vap->iv_recv_mgmt;
> + vap->iv_recv_mgmt = urtwn_ibss_recv_mgmt;
> + TASK_INIT(&uvp->tsf_task_adhoc, 0, urtwn_tsf_task_adhoc, vap);
> + }
>
> /* complete setup */
> ieee80211_vap_attach(vap, ieee80211_media_change,
> @@ -610,13 +620,13 @@ urtwn_vap_create(struct ieee80211com *ic
> static void
> urtwn_vap_delete(struct ieee80211vap *vap)
> {
> + struct ieee80211com *ic = vap->iv_ic;
> struct urtwn_vap *uvp = URTWN_VAP(vap);
> - enum ieee80211_opmode opmode = vap->iv_opmode;
>
> - if (opmode == IEEE80211_M_HOSTAP) {
> - if (uvp->bcn_mbuf != NULL)
> - m_freem(uvp->bcn_mbuf);
> - }
> + if (uvp->bcn_mbuf != NULL)
> + m_freem(uvp->bcn_mbuf);
> + if (vap->iv_opmode == IEEE80211_M_IBSS)
> + ieee80211_draintask(ic, &uvp->tsf_task_adhoc);
> ieee80211_vap_detach(vap);
> free(uvp, M_80211_VAP);
> }
> @@ -1611,8 +1621,50 @@ urtwn_tx_beacon(struct urtwn_softc *sc,
> }
>
> static void
> +urtwn_tsf_task_adhoc(void *arg, int pending)
> +{
> + struct ieee80211vap *vap = arg;
> + struct urtwn_softc *sc = vap->iv_ic->ic_softc;
> + struct ieee80211_node *ni;
> + uint32_t reg;
> +
> + URTWN_LOCK(sc);
> + ni = ieee80211_ref_node(vap->iv_bss);
> + reg = urtwn_read_1(sc, R92C_BCN_CTRL);
> +
> + /* Accept beacons with the same BSSID. */
> + urtwn_set_rx_bssid_all(sc, 0);
> +
> + /* Enable synchronization. */
> + reg &= ~R92C_BCN_CTRL_DIS_TSF_UDT0;
> + urtwn_write_1(sc, R92C_BCN_CTRL, reg);
> +
> + /* Synchronize. */
> + usb_pause_mtx(&sc->sc_mtx, hz * ni->ni_intval * 5 / 1000);
> +
> + /* Disable synchronization. */
> + reg |= R92C_BCN_CTRL_DIS_TSF_UDT0;
> + urtwn_write_1(sc, R92C_BCN_CTRL, reg);
> +
> + /* Remove beacon filter. */
> + urtwn_set_rx_bssid_all(sc, 1);
> +
> + /* Enable beaconing. */
> + urtwn_write_1(sc, R92C_MBID_NUM,
> + urtwn_read_1(sc, R92C_MBID_NUM) | R92C_MBID_TXBCN_RPT0);
> + reg |= R92C_BCN_CTRL_EN_BCN;
> +
> + urtwn_write_1(sc, R92C_BCN_CTRL, reg);
> + ieee80211_free_node(ni);
> + URTWN_UNLOCK(sc);
> +}
> +
> +static void
> urtwn_tsf_sync_enable(struct urtwn_softc *sc, struct ieee80211vap *vap)
> {
> + struct ieee80211com *ic = &sc->sc_ic;
> + struct urtwn_vap *uvp = URTWN_VAP(vap);
> +
> /* Reset TSF. */
> urtwn_write_1(sc, R92C_DUAL_TSF_RST, R92C_DUAL_TSF_RST0);
>
> @@ -1623,6 +1675,9 @@ urtwn_tsf_sync_enable(struct urtwn_softc
> urtwn_read_1(sc, R92C_BCN_CTRL) &
> ~R92C_BCN_CTRL_DIS_TSF_UDT0);
> break;
> + case IEEE80211_M_IBSS:
> + ieee80211_runtask(ic, &uvp->tsf_task_adhoc);
> + break;
> case IEEE80211_M_HOSTAP:
> /* Enable beaconing. */
> urtwn_write_1(sc, R92C_MBID_NUM,
> @@ -1674,6 +1729,37 @@ urtwn_set_mode(struct urtwn_softc *sc, u
> urtwn_write_1(sc, R92C_MSR, reg);
> }
>
> +static void
> +urtwn_ibss_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype,
> + const struct ieee80211_rx_stats *rxs,
> + int rssi, int nf)
> +{
> + struct ieee80211vap *vap = ni->ni_vap;
> + struct urtwn_softc *sc = vap->iv_ic->ic_softc;
> + struct urtwn_vap *uvp = URTWN_VAP(vap);
> + uint64_t ni_tstamp, curr_tstamp;
> +
> + uvp->recv_mgmt(ni, m, subtype, rxs, rssi, nf);
> +
> + if (vap->iv_state == IEEE80211_S_RUN &&
> + (subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
> + subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) {
> + ni_tstamp = le64toh(ni->ni_tstamp.tsf);
> +#ifdef D3831
> + URTWN_LOCK(sc);
> + urtwn_get_tsf(sc, &curr_tstamp);
> + URTWN_UNLOCK(sc);
> + curr_tstamp = le64toh(curr_tstamp);
> +
> + if (ni_tstamp >= curr_tstamp)
> + (void) ieee80211_ibss_merge(ni);
> +#else
> + (void) sc;
> + (void) curr_tstamp;
> +#endif
> + }
> +}
> +
> static int
> urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
> {
> @@ -1757,6 +1843,9 @@ urtwn_newstate(struct ieee80211vap *vap,
> case IEEE80211_M_STA:
> mode = R92C_MSR_INFRA;
> break;
> + case IEEE80211_M_IBSS:
> + mode = R92C_MSR_ADHOC;
> + break;
> case IEEE80211_M_HOSTAP:
> mode = R92C_MSR_AP;
> break;
> @@ -1794,13 +1883,14 @@ urtwn_newstate(struct ieee80211vap *vap,
>
> if (vap->iv_opmode != IEEE80211_M_HOSTAP)
> reg |= R92C_RCR_CBSSID_DATA;
> -
> - reg |= R92C_RCR_CBSSID_BCN;
> + if (vap->iv_opmode != IEEE80211_M_IBSS)
> + reg |= R92C_RCR_CBSSID_BCN;
>
> urtwn_write_4(sc, R92C_RCR, reg);
> }
>
> - if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
> + if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
> + vap->iv_opmode == IEEE80211_M_IBSS) {
> error = urtwn_setup_beacon(sc, ni);
> if (error != 0) {
> device_printf(sc->sc_dev,
> @@ -3007,6 +3097,7 @@ urtwn_rxfilter_init(struct urtwn_softc *
> R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_BEACON));
> break;
> case IEEE80211_M_MONITOR:
> + case IEEE80211_M_IBSS:
> break;
> default:
> device_printf(sc->sc_dev, "%s: undefined opmode %d\n",
> @@ -3335,7 +3426,9 @@ urtwn_scan_start(struct ieee80211com *ic
>
> URTWN_LOCK(sc);
> /* Receive beacons / probe responses from any BSSID. */
> - urtwn_set_rx_bssid_all(sc, 1);
> + if (ic->ic_opmode != IEEE80211_M_IBSS)
> + urtwn_set_rx_bssid_all(sc, 1);
> +
> /* Set gain for scanning. */
> urtwn_set_gain(sc, 0x20);
> URTWN_UNLOCK(sc);
> @@ -3348,8 +3441,9 @@ urtwn_scan_end(struct ieee80211com *ic)
>
> URTWN_LOCK(sc);
> /* Restore limitations. */
> - if (ic->ic_promisc == 0)
> + if (ic->ic_promisc == 0 && ic->ic_opmode != IEEE80211_M_IBSS)
> urtwn_set_rx_bssid_all(sc, 0);
> +
> /* Set gain under link. */
> urtwn_set_gain(sc, 0x32);
> URTWN_UNLOCK(sc);
> @@ -3393,6 +3487,9 @@ urtwn_set_promisc(struct urtwn_softc *sc
> case IEEE80211_M_HOSTAP:
> mask2 |= R92C_RCR_CBSSID_BCN;
> break;
> + case IEEE80211_M_IBSS:
> + mask2 |= R92C_RCR_CBSSID_DATA;
> + break;
> default:
> device_printf(sc->sc_dev, "%s: undefined opmode %d\n",
> __func__, vap->iv_opmode);
>
> Modified: head/sys/dev/usb/wlan/if_urtwnvar.h
> ==============================================================================
> --- head/sys/dev/usb/wlan/if_urtwnvar.h Tue Nov 10 12:20:22 2015 (r290650)
> +++ head/sys/dev/usb/wlan/if_urtwnvar.h Tue Nov 10 12:52:26 2015 (r290651)
> @@ -87,13 +87,18 @@ struct urtwn_fw_info {
> };
>
> struct urtwn_vap {
> - struct ieee80211vap vap;
> + struct ieee80211vap vap;
>
> - struct r92c_tx_desc bcn_desc;
> - struct mbuf *bcn_mbuf;
> -
> - int (*newstate)(struct ieee80211vap *,
> - enum ieee80211_state, int);
> + struct r92c_tx_desc bcn_desc;
> + struct mbuf *bcn_mbuf;
> + struct task tsf_task_adhoc;
> +
> + int (*newstate)(struct ieee80211vap *,
> + enum ieee80211_state, int);
> + void (*recv_mgmt)(struct ieee80211_node *,
> + struct mbuf *, int,
> + const struct ieee80211_rx_stats *,
> + int, int);
> };
> #define URTWN_VAP(vap) ((struct urtwn_vap *)(vap))
>
After this revision, every time I insert my urtwn card into USB port I get this panic [1]. Moving back to 290650 fixed the problem.
[1] http://imgur.com/6p78GIT
--
Renato Botelho
More information about the svn-src-all
mailing list