diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 98c86ff657bb1faa82d5541f950fde2bea4af8d9..6e0601189db94e1c150c65f64b1ce09d7da6fa8e 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -567,6 +567,26 @@ struct ieee80211s_hdr { #define MESH_FLAGS_AE 0x3 #define MESH_FLAGS_PS_DEEP 0x4 +/** + * enum ieee80211_preq_flags - mesh PREQ element flags + * + * @IEEE80211_PREQ_PROACTIVE_PREP_FLAG: proactive PREP subfield + */ +enum ieee80211_preq_flags { + IEEE80211_PREQ_PROACTIVE_PREP_FLAG = 1<<2, +}; + +/** + * enum ieee80211_preq_target_flags - mesh PREQ element per target flags + * + * @IEEE80211_PREQ_TO_FLAG: target only subfield + * @IEEE80211_PREQ_USN_FLAG: unknown target HWMP sequence number subfield + */ +enum ieee80211_preq_target_flags { + IEEE80211_PREQ_TO_FLAG = 1<<0, + IEEE80211_PREQ_USN_FLAG = 1<<2, +}; + /** * struct ieee80211_quiet_ie * @@ -1474,6 +1494,28 @@ enum { IEEE80211_PATH_METRIC_VENDOR = 255, }; +/** + * enum ieee80211_root_mode_identifier - root mesh STA mode identifier + * + * These attribute are used by dot11MeshHWMPRootMode to set root mesh STA mode + * + * @IEEE80211_ROOTMODE_NO_ROOT: the mesh STA is not a root mesh STA (default) + * @IEEE80211_ROOTMODE_ROOT: the mesh STA is a root mesh STA if greater than + * this value + * @IEEE80211_PROACTIVE_PREQ_NO_PREP: the mesh STA is a root mesh STA supports + * the proactive PREQ with proactive PREP subfield set to 0 + * @IEEE80211_PROACTIVE_PREQ_WITH_PREP: the mesh STA is a root mesh STA + * supports the proactive PREQ with proactive PREP subfield set to 1 + * @IEEE80211_PROACTIVE_RANN: the mesh STA is a root mesh STA supports + * the proactive RANN + */ +enum ieee80211_root_mode_identifier { + IEEE80211_ROOTMODE_NO_ROOT = 0, + IEEE80211_ROOTMODE_ROOT = 1, + IEEE80211_PROACTIVE_PREQ_NO_PREP = 2, + IEEE80211_PROACTIVE_PREQ_WITH_PREP = 3, + IEEE80211_PROACTIVE_RANN = 4, +}; /* * IEEE 802.11-2007 7.3.2.9 Country information element diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 7cf19509fb682f21d69716a7352b345127ed3f4c..6bff3c4d17dd986cc7282b6bf4e93e56a9c6091f 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -541,11 +541,17 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + u32 interval; mesh_path_tx_root_frame(sdata); + + if (ifmsh->mshcfg.dot11MeshHWMPRootMode == IEEE80211_PROACTIVE_RANN) + interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; + else + interval = ifmsh->mshcfg.dot11MeshHWMProotInterval; + mod_timer(&ifmsh->mesh_path_root_timer, - round_jiffies(TU_TO_EXP_TIME( - ifmsh->mshcfg.dot11MeshHWMPRannInterval))); + round_jiffies(TU_TO_EXP_TIME(interval))); } #ifdef CONFIG_PM diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 9b6da2de660d5a75f80ef15f47ea404d5a780d0e..a6b08f5c4612bfe60d56c64910f75a0b82e157a3 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -1154,13 +1154,34 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; - u8 flags; + u8 flags, target_flags = 0; flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol) ? RANN_FLAG_IS_GATE : 0; - mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, + + switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) { + case IEEE80211_PROACTIVE_RANN: + mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, cpu_to_le32(++ifmsh->sn), 0, NULL, 0, broadcast_addr, - 0, sdata->u.mesh.mshcfg.element_ttl, + 0, ifmsh->mshcfg.element_ttl, cpu_to_le32(interval), 0, 0, sdata); + break; + case IEEE80211_PROACTIVE_PREQ_WITH_PREP: + flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG; + case IEEE80211_PROACTIVE_PREQ_NO_PREP: + interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout; + target_flags |= IEEE80211_PREQ_TO_FLAG | + IEEE80211_PREQ_USN_FLAG; + mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr, + cpu_to_le32(++ifmsh->sn), target_flags, + (u8 *) broadcast_addr, 0, broadcast_addr, + 0, ifmsh->mshcfg.element_ttl, + cpu_to_le32(interval), + 0, cpu_to_le32(ifmsh->preq_id++), sdata); + break; + default: + mhwmp_dbg("Proactive mechanism not supported"); + return; + } }