Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Mar 2015 20:51:57 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r280084 - head/sys/dev/wpi
Message-ID:  <201503152051.t2FKpvlX074064@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sun Mar 15 20:51:56 2015
New Revision: 280084
URL: https://svnweb.freebsd.org/changeset/base/280084

Log:
  Use ieee80211_beacon_update() for dynamic beacon contents.
  
  PR:		kern/197143
  Submitted by:	Andriy Voskoboinyk <s3erios@gmail.com>

Modified:
  head/sys/dev/wpi/if_wpi.c
  head/sys/dev/wpi/if_wpivar.h

Modified: head/sys/dev/wpi/if_wpi.c
==============================================================================
--- head/sys/dev/wpi/if_wpi.c	Sun Mar 15 20:51:06 2015	(r280083)
+++ head/sys/dev/wpi/if_wpi.c	Sun Mar 15 20:51:56 2015	(r280084)
@@ -227,8 +227,9 @@ static uint16_t	wpi_get_passive_dwell_ti
 		    struct ieee80211_channel *);
 static int	wpi_scan(struct wpi_softc *, struct ieee80211_channel *);
 static int	wpi_auth(struct wpi_softc *, struct ieee80211vap *);
-static void	wpi_update_beacon(struct ieee80211vap *, int);
+static int	wpi_config_beacon(struct wpi_vap *);
 static int	wpi_setup_beacon(struct wpi_softc *, struct ieee80211_node *);
+static void	wpi_update_beacon(struct ieee80211vap *, int);
 static void	wpi_newassoc(struct ieee80211_node *, int);
 static int	wpi_run(struct wpi_softc *, struct ieee80211vap *);
 static int	wpi_key_alloc(struct ieee80211vap *, struct ieee80211_key *,
@@ -639,10 +640,17 @@ static void
 wpi_vap_delete(struct ieee80211vap *vap)
 {
 	struct wpi_vap *wvp = WPI_VAP(vap);
+	struct wpi_buf *bcn = &wvp->wv_bcbuf;
+	enum ieee80211_opmode opmode = vap->iv_opmode;
 
 	ieee80211_ratectl_deinit(vap);
 	ieee80211_vap_detach(vap);
 
+	if (opmode == IEEE80211_M_IBSS) {
+		if (bcn->m != NULL)
+			m_freem(bcn->m);
+	}
+
 	free(wvp, M_80211_VAP);
 }
 
@@ -3945,51 +3953,127 @@ wpi_auth(struct wpi_softc *sc, struct ie
 }
 
 static int
+wpi_config_beacon(struct wpi_vap *wvp)
+{
+	struct ieee80211com *ic = wvp->vap.iv_ic;
+	struct ieee80211_beacon_offsets *bo = &wvp->wv_boff;
+	struct wpi_buf *bcn = &wvp->wv_bcbuf;
+	struct wpi_softc *sc = ic->ic_ifp->if_softc;
+	struct wpi_cmd_beacon *cmd = (struct wpi_cmd_beacon *)&bcn->data;
+	struct ieee80211_tim_ie *tie;
+	struct mbuf *m;
+	uint8_t *ptr;
+	int error;
+
+	DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__);
+
+	WPI_LOCK_ASSERT(sc);
+
+	cmd->len = htole16(bcn->m->m_pkthdr.len);
+	cmd->plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ?
+	    wpi_ridx_to_plcp[WPI_RIDX_OFDM6] : wpi_ridx_to_plcp[WPI_RIDX_CCK1];
+
+	/* XXX seems to be unused */
+	if (*(bo->bo_tim) == IEEE80211_ELEMID_TIM) {
+		tie = (struct ieee80211_tim_ie *) bo->bo_tim;
+		ptr = mtod(bcn->m, uint8_t *);
+
+		cmd->tim = htole16(bo->bo_tim - ptr);
+		cmd->timsz = tie->tim_len;
+	}
+
+	/* Necessary for recursion in ieee80211_beacon_update(). */
+	m = bcn->m;
+	bcn->m = m_dup(m, M_NOWAIT);
+	if (bcn->m == NULL) {
+		device_printf(sc->sc_dev,
+		    "%s: could not copy beacon frame\n", __func__);
+		error = ENOMEM;
+		goto end;
+	}
+
+	if ((error = wpi_cmd2(sc, bcn)) != 0) {
+		device_printf(sc->sc_dev,
+		    "%s: could not update beacon frame, error %d", __func__,
+		    error);
+	}
+
+	/* Restore mbuf. */
+end:	bcn->m = m;
+
+	return error;
+}
+
+static int
 wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni)
 {
-	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
 	struct wpi_vap *wvp = WPI_VAP(ni->ni_vap);
 	struct wpi_buf *bcn = &wvp->wv_bcbuf;
-	struct ieee80211_beacon_offsets bo;
-	struct wpi_cmd_beacon *cmd = (struct wpi_cmd_beacon *)&bcn->data;
+	struct ieee80211_beacon_offsets *bo = &wvp->wv_boff;
 	struct mbuf *m;
+	int error;
 
 	DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__);
 
 	if (ni->ni_chan == IEEE80211_CHAN_ANYC)
 		return EINVAL;
 
-	m = ieee80211_beacon_alloc(ni, &bo);
+	m = ieee80211_beacon_alloc(ni, bo);
 	if (m == NULL) {
 		device_printf(sc->sc_dev,
 		    "%s: could not allocate beacon frame\n", __func__);
 		return ENOMEM;
 	}
 
-	cmd->len = htole16(m->m_pkthdr.len);
-	cmd->plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ?
-	    wpi_ridx_to_plcp[WPI_RIDX_OFDM6] : wpi_ridx_to_plcp[WPI_RIDX_CCK1];
+	if (bcn->m != NULL)
+		m_freem(bcn->m);
 
-	/* NB: m will be freed in wpi_cmd_done() */
 	bcn->m = m;
 
-	return wpi_cmd2(sc, bcn);
+	error = wpi_config_beacon(wvp);
+
+	return error;
 }
 
 static void
 wpi_update_beacon(struct ieee80211vap *vap, int item)
 {
 	struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+	struct wpi_vap *wvp = WPI_VAP(vap);
+	struct wpi_buf *bcn = &wvp->wv_bcbuf;
+	struct ieee80211_beacon_offsets *bo = &wvp->wv_boff;
 	struct ieee80211_node *ni = vap->iv_bss;
-	int error;
+	int mcast = 0;
+
+	DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
 
 	WPI_LOCK(sc);
-	if ((error = wpi_setup_beacon(sc, ni)) != 0) {
-		device_printf(sc->sc_dev,
-		    "%s: could not update beacon frame, error %d", __func__,
-		    error);
+	if (bcn->m == NULL) {
+		bcn->m = ieee80211_beacon_alloc(ni, bo);
+		if (bcn->m == NULL) {
+			device_printf(sc->sc_dev,
+			    "%s: could not allocate beacon frame\n", __func__);
+			WPI_UNLOCK(sc);
+
+			DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR,
+			    __func__);
+
+			return;
+		}
 	}
 	WPI_UNLOCK(sc);
+
+	if (item == IEEE80211_BEACON_TIM)
+		mcast = 1;	/* TODO */
+
+	setbit(bo->bo_flags, item);
+	ieee80211_beacon_update(ni, bo, bcn->m, mcast);
+
+	WPI_LOCK(sc);
+	wpi_config_beacon(wvp);
+	WPI_UNLOCK(sc);
+
+	DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__);
 }
 
 static void

Modified: head/sys/dev/wpi/if_wpivar.h
==============================================================================
--- head/sys/dev/wpi/if_wpivar.h	Sun Mar 15 20:51:06 2015	(r280083)
+++ head/sys/dev/wpi/if_wpivar.h	Sun Mar 15 20:51:56 2015	(r280084)
@@ -121,11 +121,13 @@ struct wpi_buf {
 };
 
 struct wpi_vap {
-	struct ieee80211vap	vap;
-	struct wpi_buf		wv_bcbuf;
+	struct ieee80211vap		vap;
 
-	int			(*newstate)(struct ieee80211vap *,
-				    enum ieee80211_state, int);
+	struct wpi_buf			wv_bcbuf;
+	struct ieee80211_beacon_offsets	wv_boff;
+
+	int				(*newstate)(struct ieee80211vap *,
+					    enum ieee80211_state, int);
 };
 #define	WPI_VAP(vap)	((struct wpi_vap *)(vap))
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503152051.t2FKpvlX074064>