Commit a69cc44f authored by Chun-Yeow Yeoh's avatar Chun-Yeow Yeoh Committed by Johannes Berg

mac80211: implement the proactive PREQ generation

Generate the proactive PREQ element as defined in
Sec. 13.10.9.3 (Case C) of IEEE Std. 802.11-2012
based on the selection of dot11MeshHWMPRootMode as follow:
dot11MeshHWMPRootMode (2) is proactivePREQnoPREP
dot11MeshHWMPRootMode (3) is proactivePREQwithPREP

The proactive PREQ is generated based on the interval
defined by dot11MeshHWMProotInterval.

With this change, proactive RANN element is now generated
if the dot11MeshHWMPRootMode is set to (4) instead of (1).
Signed-off-by: default avatarChun-Yeow Yeoh <yeohchunyeow@gmail.com>
[line-break commit log]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent ac1073a6
...@@ -567,6 +567,26 @@ struct ieee80211s_hdr { ...@@ -567,6 +567,26 @@ struct ieee80211s_hdr {
#define MESH_FLAGS_AE 0x3 #define MESH_FLAGS_AE 0x3
#define MESH_FLAGS_PS_DEEP 0x4 #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 * struct ieee80211_quiet_ie
* *
...@@ -1474,6 +1494,28 @@ enum { ...@@ -1474,6 +1494,28 @@ enum {
IEEE80211_PATH_METRIC_VENDOR = 255, 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 * IEEE 802.11-2007 7.3.2.9 Country information element
......
...@@ -541,11 +541,17 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, ...@@ -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) static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
{ {
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
u32 interval;
mesh_path_tx_root_frame(sdata); 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, mod_timer(&ifmsh->mesh_path_root_timer,
round_jiffies(TU_TO_EXP_TIME( round_jiffies(TU_TO_EXP_TIME(interval)));
ifmsh->mshcfg.dot11MeshHWMPRannInterval)));
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
......
...@@ -1154,13 +1154,34 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) ...@@ -1154,13 +1154,34 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
{ {
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
u8 flags; u8 flags, target_flags = 0;
flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol) flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol)
? RANN_FLAG_IS_GATE : 0; ? RANN_FLAG_IS_GATE : 0;
switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) {
case IEEE80211_PROACTIVE_RANN:
mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
cpu_to_le32(++ifmsh->sn), cpu_to_le32(++ifmsh->sn),
0, NULL, 0, broadcast_addr, 0, NULL, 0, broadcast_addr,
0, sdata->u.mesh.mshcfg.element_ttl, 0, ifmsh->mshcfg.element_ttl,
cpu_to_le32(interval), 0, 0, sdata); 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;
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment