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
1576 * one bit per byte, in same format as nl802111576 * one bit per byte, in same format as nl80211
1577 * @pattern: bytes to match where bitmask is 11577 * @pattern: bytes to match where bitmask is 1
1578 * @pattern_len: length of pattern (in bytes)1578 * @pattern_len: length of pattern (in bytes)
1579 * @pkt_offset: packet offset (in bytes)
1579 *1580 *
1580 * Internal note: @mask and @pattern are allocated in one chunk of1581 * Internal note: @mask and @pattern are allocated in one chunk of
1581 * memory, free @mask only!1582 * memory, free @mask only!
@@ -1583,6 +1584,7 @@ struct cfg80211_pmksa { · 1 unmodified line
1583struct cfg80211_wowlan_trig_pkt_pattern {1584struct cfg80211_wowlan_trig_pkt_pattern {
1584 u8 *mask, *pattern;1585 u8 *mask, *pattern;
1585 int pattern_len;1586 int pattern_len;
1587 int pkt_offset;
1586};1588};
1587 1589
1588/**1590/**
@@ -2290,12 +2292,14 @@ enum wiphy_wowlan_support_flags { · 701 unmodified lines
2290 * (see nl80211.h for the pattern definition)2292 * (see nl80211.h for the pattern definition)
2291 * @pattern_max_len: maximum length of each pattern2293 * @pattern_max_len: maximum length of each pattern
2292 * @pattern_min_len: minimum length of each pattern2294 * @pattern_min_len: minimum length of each pattern
2295 * @max_pkt_offset: maximum Rx packet offset
2293 */2296 */
2294struct wiphy_wowlan_support {2297struct wiphy_wowlan_support {
2295 u32 flags;2298 u32 flags;
2296 int n_patterns;2299 int n_patterns;
2297 int pattern_max_len;2300 int pattern_max_len;
2298 int pattern_min_len;2301 int pattern_min_len;
2302 int max_pkt_offset;
2299};2303};
2300 2304
2301/**2305/**
include/uapi/linux/nl80211.h+9−3
@@ -2910,6 +2910,8 @@ enum nl80211_tx_power_setting { · 2909 unmodified lines
2910 * Note that the pattern matching is done as though frames were not2910 * Note that the pattern matching is done as though frames were not
2911 * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked2911 * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
2912 * first (including SNAP header unpacking) and then matched.2912 * 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
2913 * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes2915 * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes
2914 * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number2916 * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number
2915 */2917 */
@@ -2917,6 +2919,7 @@ enum nl80211_wowlan_packet_pattern_attr { · 1 unmodified line
2917 __NL80211_WOWLAN_PKTPAT_INVALID,2919 __NL80211_WOWLAN_PKTPAT_INVALID,
2918 NL80211_WOWLAN_PKTPAT_MASK,2920 NL80211_WOWLAN_PKTPAT_MASK,
2919 NL80211_WOWLAN_PKTPAT_PATTERN,2921 NL80211_WOWLAN_PKTPAT_PATTERN,
2922 NL80211_WOWLAN_PKTPAT_OFFSET,
2920 2923
2921 NUM_NL80211_WOWLAN_PKTPAT,2924 NUM_NL80211_WOWLAN_PKTPAT,
2922 MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,2925 MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,
@@ -2927,6 +2930,7 @@ enum nl80211_wowlan_packet_pattern_attr { · 4 unmodified lines
2927 * @max_patterns: maximum number of patterns supported2930 * @max_patterns: maximum number of patterns supported
2928 * @min_pattern_len: minimum length of each pattern2931 * @min_pattern_len: minimum length of each pattern
2929 * @max_pattern_len: maximum length of each pattern2932 * @max_pattern_len: maximum length of each pattern
2933 * @max_pkt_offset: maximum Rx packet offset
2930 *2934 *
2931 * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when2935 * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when
2932 * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the2936 * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
@@ -2936,6 +2940,7 @@ struct nl80211_wowlan_pattern_support { · 3 unmodified lines
2936 __u32 max_patterns;2940 __u32 max_patterns;
2937 __u32 min_pattern_len;2941 __u32 min_pattern_len;
2938 __u32 max_pattern_len;2942 __u32 max_pattern_len;
2943 __u32 max_pkt_offset;
2939} __attribute__((packed));2944} __attribute__((packed));
2940 2945
2941/**2946/**
@@ -2951,9 +2956,10 @@ struct nl80211_wowlan_pattern_support { · 9 unmodified lines
2951 * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns2956 * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns
2952 * which are passed in an array of nested attributes, each nested attribute2957 * which are passed in an array of nested attributes, each nested attribute
2953 * defining a with attributes from &struct nl80211_wowlan_trig_pkt_pattern.2958 * 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,2959 * Each pattern defines a wakeup packet. Packet offset is associated with
2955 * i.e. as though the packet was an 802.3 packet, so the pattern matching2960 * each pattern which is used while matching the pattern. The matching is
2956 * is done after the packet is converted to the MSDU.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.
2957 *2963 *
2958 * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute2964 * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
2959 * carrying a &struct nl80211_wowlan_pattern_support.2965 * 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
1238 dev->wiphy.wowlan.pattern_min_len,1238 dev->wiphy.wowlan.pattern_min_len,
1239 .max_pattern_len =1239 .max_pattern_len =
1240 dev->wiphy.wowlan.pattern_max_len,1240 dev->wiphy.wowlan.pattern_max_len,
1241 .max_pkt_offset =
1242 dev->wiphy.wowlan.max_pkt_offset,
1241 };1243 };
1242 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,1244 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1243 sizeof(pat), &pat))1245 sizeof(pat), &pat))
@@ -6895,6 +6897,39 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) · 5651 unmodified lines
6895}6897}
6896 6898
6897#ifdef CONFIG_PM6899#ifdef CONFIG_PM
6900static 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
6898static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)6933static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
6899{6934{
6900 struct cfg80211_registered_device *rdev = info->user_ptr[0];6935 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
6935 (rdev->wowlan->rfkill_release &&6970 (rdev->wowlan->rfkill_release &&
6936 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))6971 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
6937 goto nla_put_failure;6972 goto nla_put_failure;
6938 if (rdev->wowlan->n_patterns) {6973 if (nl80211_send_wowlan_patterns(msg, rdev))
6939 struct nlattr *nl_pats, *nl_pat;6974 goto nla_put_failure;
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
6964 nla_nest_end(msg, nl_wowlan);6975 nla_nest_end(msg, nl_wowlan);
6965 }6976 }
6966 6977
@@ -7046,7 +7057,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) · 79 unmodified lines
7046 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {7057 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
7047 struct nlattr *pat;7058 struct nlattr *pat;
7048 int n_patterns = 0;7059 int n_patterns = 0;
7049 int rem, pat_len, mask_len;7060 int rem, pat_len, mask_len, pkt_offset;
7050 struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];7061 struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
7051 7062
7052 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],7063 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
7081 pat_len < wowlan->pattern_min_len)7092 pat_len < wowlan->pattern_min_len)
7082 goto error;7093 goto error;
7083 7094
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
7084 new_triggers.patterns[i].mask =7104 new_triggers.patterns[i].mask =
7085 kmalloc(mask_len + pat_len, GFP_KERNEL);7105 kmalloc(mask_len + pat_len, GFP_KERNEL);
7086 if (!new_triggers.patterns[i].mask) {7106 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