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