svn commit: r290651 - head/sys/dev/usb/wlan

Renato Botelho garga at FreeBSD.org
Wed Nov 11 09:55:02 UTC 2015


> On Nov 10, 2015, at 18:19, Renato Botelho <garga at FreeBSD.org> wrote:
> 
>> 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

FYI, after talk with adrian, I updated src to latest rev (r290668) and manually reverted this commit and also 290663 (that broke the build) and system is still working as expected. This is the hardware I’m using:

urtwn0: <vendor 0x050d product 0x1102, class 0/0, rev 2.00/2.00, addr 3> on usbus1
urtwn0: MAC/BB RTL8188CUS, RF 6052 1T1R

--
Renato Botelho



More information about the svn-src-all mailing list