aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ath/if_ath.c
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@FreeBSD.org>2009-07-11 15:02:45 +0000
committerRui Paulo <rpaulo@FreeBSD.org>2009-07-11 15:02:45 +0000
commit59aa14a91db84e940b6732cd1ff069f0268793bf (patch)
tree7dd4e6a8c026ec13b70ca0a34e625684d79ec055 /sys/dev/ath/if_ath.c
parent35ea6959ac1cd556d2165973d7424798d45da5be (diff)
downloadsrc-59aa14a91db84e940b6732cd1ff069f0268793bf.tar.gz
src-59aa14a91db84e940b6732cd1ff069f0268793bf.zip
Implementation of the upcoming Wireless Mesh standard, 802.11s, on the
net80211 wireless stack. This work is based on the March 2009 D3.0 draft standard. This standard is expected to become final next year. This includes two main net80211 modules, ieee80211_mesh.c which deals with peer link management, link metric calculation, routing table control and mesh configuration and ieee80211_hwmp.c which deals with the actually routing process on the mesh network. HWMP is the mandatory routing protocol on by the mesh standard, but others, such as RA-OLSR, can be implemented. Authentication and encryption are not implemented. There are several scripts under tools/tools/net80211/scripts that can be used to test different mesh network topologies and they also teach you how to setup a mesh vap (for the impatient: ifconfig wlan0 create wlandev ... wlanmode mesh). A new build option is available: IEEE80211_SUPPORT_MESH and it's enabled by default on GENERIC kernels for i386, amd64, sparc64 and pc98. Drivers that support mesh networks right now are: ath, ral and mwl. More information at: http://wiki.freebsd.org/WifiMesh Please note that this work is experimental. Also, please note that bridging a mesh vap with another network interface is not yet supported. Many thanks to the FreeBSD Foundation for sponsoring this project and to Sam Leffler for his support. Also, I would like to thank Gateworks Corporation for sending me a Cambria board which was used during the development of this project. Reviewed by: sam Approved by: re (kensmith) Obtained from: projects/mesh11s
Notes
Notes: svn path=/head/; revision=195618
Diffstat (limited to 'sys/dev/ath/if_ath.c')
-rw-r--r--sys/dev/ath/if_ath.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 7d0eb5ebce43..c201265d6c05 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -578,6 +578,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
| IEEE80211_C_MONITOR /* monitor mode */
| IEEE80211_C_AHDEMO /* adhoc demo mode */
| IEEE80211_C_WDS /* 4-address traffic works */
+ | IEEE80211_C_MBSS /* mesh point link mode */
| IEEE80211_C_SHPREAMBLE /* short preamble supported */
| IEEE80211_C_SHSLOT /* short slot time supported */
| IEEE80211_C_WPA /* capable of WPA1+WPA2 */
@@ -655,6 +656,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
if (ath_hal_hasbursting(ah))
ic->ic_caps |= IEEE80211_C_BURST;
sc->sc_hasbmask = ath_hal_hasbssidmask(ah);
+ sc->sc_hasbmatch = ath_hal_hasbssidmatch(ah);
sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
if (ath_hal_hasfastframes(ah))
ic->ic_caps |= IEEE80211_C_FF;
@@ -918,6 +920,7 @@ ath_vap_create(struct ieee80211com *ic,
}
break;
case IEEE80211_M_HOSTAP:
+ case IEEE80211_M_MBSS:
needbeacon = 1;
break;
case IEEE80211_M_WDS:
@@ -936,7 +939,6 @@ ath_vap_create(struct ieee80211com *ic,
ic_opmode = IEEE80211_M_HOSTAP;
else
ic_opmode = ic->ic_opmode;
- break;
default:
device_printf(sc->sc_dev, "unknown opmode %d\n", opmode);
goto bad;
@@ -950,7 +952,7 @@ ath_vap_create(struct ieee80211com *ic,
}
/* STA, AHDEMO? */
- if (opmode == IEEE80211_M_HOSTAP) {
+ if (opmode == IEEE80211_M_HOSTAP || opmode == IEEE80211_M_MBSS) {
assign_address(sc, mac, flags & IEEE80211_CLONE_BSSID);
ath_hal_setbssidmask(sc->sc_ah, sc->sc_hwbssidmask);
}
@@ -1042,6 +1044,7 @@ ath_vap_create(struct ieee80211com *ic,
/* fall thru... */
#endif
case IEEE80211_M_HOSTAP:
+ case IEEE80211_M_MBSS:
sc->sc_opmode = HAL_M_HOSTAP;
break;
case IEEE80211_M_MONITOR:
@@ -1129,7 +1132,8 @@ ath_vap_delete(struct ieee80211vap *vap)
sc->sc_nstavaps--;
if (sc->sc_nstavaps == 0 && sc->sc_swbmiss)
sc->sc_swbmiss = 0;
- } else if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
+ } else if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
+ vap->iv_opmode == IEEE80211_M_MBSS) {
reclaim_address(sc, vap->iv_myaddr);
ath_hal_setbssidmask(ah, sc->sc_hwbssidmask);
}
@@ -2330,7 +2334,7 @@ ath_key_update_end(struct ieee80211vap *vap)
* NB: older hal's add rx filter bits out of sight and we need to
* blindly preserve them
* o probe request frames are accepted only when operating in
- * hostap, adhoc, or monitor modes
+ * hostap, adhoc, mesh, or monitor modes
* o enable promiscuous mode
* - when in monitor mode
* - if interface marked PROMISC (assumes bridge setting is filtered)
@@ -2343,6 +2347,7 @@ ath_key_update_end(struct ieee80211vap *vap)
* - when doing s/w beacon miss (e.g. for ap+sta)
* - when operating in ap mode in 11g to detect overlapping bss that
* require protection
+ * - when operating in mesh mode to detect neighbors
* o accept control frames:
* - when in monitor mode
* XXX BAR frames for 11n
@@ -2375,6 +2380,13 @@ ath_calcrxfilter(struct ath_softc *sc)
if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
rfilt |= HAL_RX_FILTER_BEACON;
+ if (ic->ic_opmode == IEEE80211_M_MBSS) {
+ rfilt |= HAL_RX_FILTER_BEACON;
+ if (sc->sc_hasbmatch)
+ rfilt |= HAL_RX_FILTER_BSSID;
+ else
+ rfilt |= HAL_RX_FILTER_PROM;
+ }
if (ic->ic_opmode == IEEE80211_M_MONITOR)
rfilt |= HAL_RX_FILTER_CONTROL;
DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x, %s if_flags 0x%x\n",
@@ -2500,7 +2512,8 @@ ath_updateslot(struct ifnet *ifp)
* immediately. For other operation we defer the change
* until beacon updates have propagated to the stations.
*/
- if (ic->ic_opmode == IEEE80211_M_HOSTAP)
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
+ ic->ic_opmode == IEEE80211_M_MBSS)
sc->sc_updateslot = UPDATE;
else
ath_setslottime(sc);
@@ -2535,7 +2548,8 @@ ath_beaconq_config(struct ath_softc *sc)
HAL_TXQ_INFO qi;
ath_hal_gettxqueueprops(ah, sc->sc_bhalq, &qi);
- if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
+ ic->ic_opmode == IEEE80211_M_MBSS) {
/*
* Always burst out beacon and CAB traffic.
*/
@@ -3087,9 +3101,10 @@ ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
/* extract tstamp from last beacon and convert to TU */
nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4),
LE_READ_4(ni->ni_tstamp.data));
- if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
+ ic->ic_opmode == IEEE80211_M_MBSS) {
/*
- * For multi-bss ap support beacons are either staggered
+ * For multi-bss ap/mesh support beacons are either staggered
* evenly over N slots or burst together. For the former
* arrange for the SWBA to be delivered for each slot.
* Slots that are not occupied will generate nothing.
@@ -3230,10 +3245,11 @@ ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
} while (nexttbtt < tsftu);
}
ath_beaconq_config(sc);
- } else if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ } else if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
+ ic->ic_opmode == IEEE80211_M_MBSS) {
/*
- * In AP mode we enable the beacon timers and
- * SWBA interrupts to prepare beacon frames.
+ * In AP/mesh mode we enable the beacon timers
+ * and SWBA interrupts to prepare beacon frames.
*/
intval |= HAL_BEACON_ENA;
sc->sc_imask |= HAL_INT_SWBA; /* beacon prepare */
@@ -5602,6 +5618,7 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
#endif
case IEEE80211_M_HOSTAP:
case IEEE80211_M_IBSS:
+ case IEEE80211_M_MBSS:
/*
* Allocate and setup the beacon frame.
*