History

nl80211: add packet offset information for wowlan pattern

If user knows the location of a wowlan pattern to be matched in Rx packet, he can provide an offset with the pattern. This will help drivers to ignore initial bytes and match the pattern efficiently.

Amitkumar Karwar committed 13 years ago

Commit bb92d191 parent 66d57573 files · +60 −30Browse files

Unified · Split

3 files
  1. include/net/cfg80211.h +4 −0
  2. include/uapi/linux/nl80211.h +9 −3
  3. net/wireless/nl80211.c +47 −27
include/net/cfg80211.h+4−0
@@ -1576,6 +1576,7 @@ struct cfg80211_pmksa { · 1575 unmodified lines
15761576 * one bit per byte, in same format as nl80211
15771577 * @pattern: bytes to match where bitmask is 1
15781578 * @pattern_len: length of pattern (in bytes)
1579+ * @pkt_offset: packet offset (in bytes)
15791580 *
15801581 * Internal note: @mask and @pattern are allocated in one chunk of
15811582 * memory, free @mask only!
@@ -1583,6 +1584,7 @@ struct cfg80211_pmksa { · 1 unmodified line
15831584 struct cfg80211_wowlan_trig_pkt_pattern {
15841585 u8 *mask, *pattern;
15851586 int pattern_len;
1587+ int pkt_offset;
15861588 };
15871589
15881590 /**
@@ -2290,12 +2292,14 @@ enum wiphy_wowlan_support_flags { · 701 unmodified lines
22902292 * (see nl80211.h for the pattern definition)
22912293 * @pattern_max_len: maximum length of each pattern
22922294 * @pattern_min_len: minimum length of each pattern
2295+ * @max_pkt_offset: maximum Rx packet offset
22932296 */
22942297 struct wiphy_wowlan_support {
22952298 u32 flags;
22962299 int n_patterns;
22972300 int pattern_max_len;
22982301 int pattern_min_len;
2302+ int max_pkt_offset;
22992303 };
23002304
23012305 /**
include/uapi/linux/nl80211.h+9−3
@@ -2910,6 +2910,8 @@ enum nl80211_tx_power_setting { · 2909 unmodified lines
29102910 * Note that the pattern matching is done as though frames were not
29112911 * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
29122912 * first (including SNAP header unpacking) and then matched.
2913+ * @NL80211_WOWLAN_PKTPAT_OFFSET: packet offset, pattern is matched after
2914+ * these fixed number of bytes of received packet
29132915 * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes
29142916 * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number
29152917 */
@@ -2917,6 +2919,7 @@ enum nl80211_wowlan_packet_pattern_attr { · 1 unmodified line
29172919 __NL80211_WOWLAN_PKTPAT_INVALID,
29182920 NL80211_WOWLAN_PKTPAT_MASK,
29192921 NL80211_WOWLAN_PKTPAT_PATTERN,
2922+ NL80211_WOWLAN_PKTPAT_OFFSET,
29202923
29212924 NUM_NL80211_WOWLAN_PKTPAT,
29222925 MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,
@@ -2927,6 +2930,7 @@ enum nl80211_wowlan_packet_pattern_attr { · 4 unmodified lines
29272930 * @max_patterns: maximum number of patterns supported
29282931 * @min_pattern_len: minimum length of each pattern
29292932 * @max_pattern_len: maximum length of each pattern
2933+ * @max_pkt_offset: maximum Rx packet offset
29302934 *
29312935 * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when
29322936 * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
@@ -2936,6 +2940,7 @@ struct nl80211_wowlan_pattern_support { · 3 unmodified lines
29362940 __u32 max_patterns;
29372941 __u32 min_pattern_len;
29382942 __u32 max_pattern_len;
2943+ __u32 max_pkt_offset;
29392944 } __attribute__((packed));
29402945
29412946 /**
@@ -2951,9 +2956,10 @@ struct nl80211_wowlan_pattern_support { · 9 unmodified lines
29512956 * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns
29522957 * which are passed in an array of nested attributes, each nested attribute
29532958 * defining a with attributes from &struct nl80211_wowlan_trig_pkt_pattern.
2954− * Each pattern defines a wakeup packet. The matching is done on the MSDU,
2955− * i.e. as though the packet was an 802.3 packet, so the pattern matching
2956− * is done after the packet is converted to the MSDU.
2959+ * Each pattern defines a wakeup packet. Packet offset is associated with
2960+ * each pattern which is used while matching the pattern. The matching is
2961+ * done on the MSDU, i.e. as though the packet was an 802.3 packet, so the
2962+ * pattern matching is done after the packet is converted to the MSDU.
29572963 *
29582964 * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
29592965 * carrying a &struct nl80211_wowlan_pattern_support.
net/wireless/nl80211.c+47−27
@@ -1238,6 +1238,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag · 1237 unmodified lines
12381238 dev->wiphy.wowlan.pattern_min_len,
12391239 .max_pattern_len =
12401240 dev->wiphy.wowlan.pattern_max_len,
1241+ .max_pkt_offset =
1242+ dev->wiphy.wowlan.max_pkt_offset,
12411243 };
12421244 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
12431245 sizeof(pat), &pat))
@@ -6895,6 +6897,39 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) · 5651 unmodified lines
68956897 }
68966898
68976899 #ifdef CONFIG_PM
6900+static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
6901+ struct cfg80211_registered_device *rdev)
6902+{
6903+ struct nlattr *nl_pats, *nl_pat;
6904+ int i, pat_len;
6905+
6906+ if (!rdev->wowlan->n_patterns)
6907+ return 0;
6908+
6909+ nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
6910+ if (!nl_pats)
6911+ return -ENOBUFS;
6912+
6913+ for (i = 0; i < rdev->wowlan->n_patterns; i++) {
6914+ nl_pat = nla_nest_start(msg, i + 1);
6915+ if (!nl_pat)
6916+ return -ENOBUFS;
6917+ pat_len = rdev->wowlan->patterns[i].pattern_len;
6918+ if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
6919+ DIV_ROUND_UP(pat_len, 8),
6920+ rdev->wowlan->patterns[i].mask) ||
6921+ nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
6922+ pat_len, rdev->wowlan->patterns[i].pattern) ||
6923+ nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET,
6924+ rdev->wowlan->patterns[i].pkt_offset))
6925+ return -ENOBUFS;
6926+ nla_nest_end(msg, nl_pat);
6927+ }
6928+ nla_nest_end(msg, nl_pats);
6929+
6930+ return 0;
6931+}
6932+
68986933 static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
68996934 {
69006935 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6935,32 +6970,8 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) · 34 unmodified lines
69356970 (rdev->wowlan->rfkill_release &&
69366971 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
69376972 goto nla_put_failure;
6938− if (rdev->wowlan->n_patterns) {
6939− struct nlattr *nl_pats, *nl_pat;
6940− int i, pat_len;
6941−
6942− nl_pats = nla_nest_start(msg,
6943− NL80211_WOWLAN_TRIG_PKT_PATTERN);
6944− if (!nl_pats)
6945− goto nla_put_failure;
6946−
6947− for (i = 0; i < rdev->wowlan->n_patterns; i++) {
6948− nl_pat = nla_nest_start(msg, i + 1);
6949− if (!nl_pat)
6950− goto nla_put_failure;
6951− pat_len = rdev->wowlan->patterns[i].pattern_len;
6952− if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
6953− DIV_ROUND_UP(pat_len, 8),
6954− rdev->wowlan->patterns[i].mask) ||
6955− nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
6956− pat_len,
6957− rdev->wowlan->patterns[i].pattern))
6958− goto nla_put_failure;
6959− nla_nest_end(msg, nl_pat);
6960− }
6961− nla_nest_end(msg, nl_pats);
6962− }
6963−
6973+ if (nl80211_send_wowlan_patterns(msg, rdev))
6974+ goto nla_put_failure;
69646975 nla_nest_end(msg, nl_wowlan);
69656976 }
69666977
@@ -7046,7 +7057,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) · 79 unmodified lines
70467057 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
70477058 struct nlattr *pat;
70487059 int n_patterns = 0;
7049− int rem, pat_len, mask_len;
7060+ int rem, pat_len, mask_len, pkt_offset;
70507061 struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
70517062
70527063 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
@@ -7081,6 +7092,15 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) · 28 unmodified lines
70817092 pat_len < wowlan->pattern_min_len)
70827093 goto error;
70837094
7095+ if (!pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET])
7096+ pkt_offset = 0;
7097+ else
7098+ pkt_offset = nla_get_u32(
7099+ pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET]);
7100+ if (pkt_offset > wowlan->max_pkt_offset)
7101+ goto error;
7102+ new_triggers.patterns[i].pkt_offset = pkt_offset;
7103+
70847104 new_triggers.patterns[i].mask =
70857105 kmalloc(mask_len + pat_len, GFP_KERNEL);
70867106 if (!new_triggers.patterns[i].mask) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t