Date: Sun, 3 May 2015 23:39:44 +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: r282401 - head/sys/dev/wpi Message-ID: <201505032339.t43NdiEX096022@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Sun May 3 23:39:44 2015 New Revision: 282401 URL: https://svnweb.freebsd.org/changeset/base/282401 Log: Handle properly IBSS merges (works with patch from bug 199632). 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 May 3 23:39:02 2015 (r282400) +++ head/sys/dev/wpi/if_wpi.c Sun May 3 23:39:44 2015 (r282401) @@ -174,9 +174,13 @@ static int wpi_setregdomain(struct ieee8 struct ieee80211_channel[]); static int wpi_read_eeprom_group(struct wpi_softc *, int); static int wpi_add_node_entry_adhoc(struct wpi_softc *); -static void wpi_node_free(struct ieee80211_node *); static struct ieee80211_node *wpi_node_alloc(struct ieee80211vap *, const uint8_t mac[IEEE80211_ADDR_LEN]); +static void wpi_node_free(struct ieee80211_node *); +static void wpi_recv_mgmt(struct ieee80211_node *, struct mbuf *, int, int, + int); +static void wpi_restore_node(void *, struct ieee80211_node *); +static void wpi_restore_node_table(struct wpi_softc *, struct wpi_vap *); static int wpi_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void wpi_calib_timeout(void *); static void wpi_rx_done(struct wpi_softc *, struct wpi_rx_desc *, @@ -654,6 +658,8 @@ wpi_vap_create(struct ieee80211com *ic, /* Override with driver methods. */ vap->iv_key_set = wpi_key_set; vap->iv_key_delete = wpi_key_delete; + wvp->wv_recv_mgmt = vap->iv_recv_mgmt; + vap->iv_recv_mgmt = wpi_recv_mgmt; wvp->wv_newstate = vap->iv_newstate; vap->iv_newstate = wpi_newstate; vap->iv_update_beacon = wpi_update_beacon; @@ -1685,6 +1691,66 @@ wpi_check_bss_filter(struct wpi_softc *s return (sc->rxon.filter & htole32(WPI_FILTER_BSS)) != 0; } +static void +wpi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, int rssi, + int nf) +{ + struct ieee80211vap *vap = ni->ni_vap; + struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct wpi_vap *wvp = WPI_VAP(vap); + uint64_t ni_tstamp, rx_tstamp; + + wvp->wv_recv_mgmt(ni, m, subtype, rssi, nf); + + if (vap->iv_opmode == IEEE80211_M_IBSS && + vap->iv_state == IEEE80211_S_RUN && + (subtype == IEEE80211_FC0_SUBTYPE_BEACON || + subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) { + ni_tstamp = le64toh(ni->ni_tstamp.tsf); + rx_tstamp = le64toh(sc->rx_tstamp); + + if (ni_tstamp >= rx_tstamp) { + DPRINTF(sc, WPI_DEBUG_STATE, + "ibss merge, tsf %ju tstamp %ju\n", + (uintmax_t)rx_tstamp, (uintmax_t)ni_tstamp); + (void) ieee80211_ibss_merge(ni); + } + } +} + +static void +wpi_restore_node(void *arg, struct ieee80211_node *ni) +{ + struct wpi_softc *sc = arg; + struct wpi_node *wn = WPI_NODE(ni); + int error; + + WPI_NT_LOCK(sc); + if (wn->id != WPI_ID_UNDEFINED) { + wn->id = WPI_ID_UNDEFINED; + if ((error = wpi_add_ibss_node(sc, ni)) != 0) { + device_printf(sc->sc_dev, + "%s: could not add IBSS node, error %d\n", + __func__, error); + } + } + WPI_NT_UNLOCK(sc); +} + +static void +wpi_restore_node_table(struct wpi_softc *sc, struct wpi_vap *wvp) +{ + struct ieee80211com *ic = sc->sc_ifp->if_l2com; + + /* Set group keys once. */ + WPI_NT_LOCK(sc); + wvp->wv_gtk = 0; + WPI_NT_UNLOCK(sc); + + ieee80211_iterate_nodes(&ic->ic_sta, wpi_restore_node, sc); + ieee80211_crypto_reload_keys(ic); +} + /** * Called by net80211 when ever there is a change to 80211 state machine */ @@ -1751,13 +1817,36 @@ wpi_newstate(struct ieee80211vap *vap, e case IEEE80211_S_RUN: /* - * RUN -> RUN transition; Just restart the timers. + * RUN -> RUN transition: + * STA mode: Just restart the timers. + * IBSS mode: Process IBSS merge. */ if (vap->iv_state == IEEE80211_S_RUN) { - WPI_RXON_LOCK(sc); - wpi_calib_timeout(sc); - WPI_RXON_UNLOCK(sc); - break; + if (vap->iv_opmode != IEEE80211_M_IBSS) { + WPI_RXON_LOCK(sc); + wpi_calib_timeout(sc); + WPI_RXON_UNLOCK(sc); + break; + } else { + /* + * Drop the BSS_FILTER bit + * (there is no another way to change bssid). + */ + WPI_RXON_LOCK(sc); + sc->rxon.filter &= ~htole32(WPI_FILTER_BSS); + if ((error = wpi_send_rxon(sc, 0, 1)) != 0) { + device_printf(sc->sc_dev, + "%s: could not send RXON\n", + __func__); + } + WPI_RXON_UNLOCK(sc); + + /* Restore all what was lost. */ + wpi_restore_node_table(sc, wvp); + + /* XXX set conditionally? */ + wpi_updateedca(ic); + } } /* @@ -1945,6 +2034,7 @@ wpi_rx_done(struct wpi_softc *sc, struct } ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); + sc->rx_tstamp = tail->tstamp; if (ieee80211_radiotap_active(ic)) { struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap; Modified: head/sys/dev/wpi/if_wpivar.h ============================================================================== --- head/sys/dev/wpi/if_wpivar.h Sun May 3 23:39:02 2015 (r282400) +++ head/sys/dev/wpi/if_wpivar.h Sun May 3 23:39:44 2015 (r282401) @@ -121,17 +121,19 @@ struct wpi_buf { }; struct wpi_vap { - struct ieee80211vap wv_vap; + struct ieee80211vap wv_vap; - struct wpi_buf wv_bcbuf; - struct ieee80211_beacon_offsets wv_boff; - struct mtx wv_mtx; - - uint32_t wv_gtk; -#define WPI_VAP_KEY(kid) (1 << kid) - - int (*wv_newstate)(struct ieee80211vap *, - enum ieee80211_state, int); + struct wpi_buf wv_bcbuf; + struct ieee80211_beacon_offsets wv_boff; + struct mtx wv_mtx; + + uint32_t wv_gtk; +#define WPI_VAP_KEY(kid) (1 << kid) + + int (*wv_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); + void (*wv_recv_mgmt)(struct ieee80211_node *, + struct mbuf *, int, int, int); }; #define WPI_VAP(vap) ((struct wpi_vap *)(vap)) @@ -180,6 +182,7 @@ struct wpi_softc { uint32_t txq_active; struct wpi_rx_ring rxq; + uint64_t rx_tstamp; /* TX Thermal Callibration. */ struct callout calib_to;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505032339.t43NdiEX096022>