* [PATCH v4 1/2] cfg80211/nl80211: rename packet pattern related structures and enums
@ 2013-06-26 2:03 Bing Zhao
2013-06-26 2:03 ` [PATCH v4 2/2] cfg80211/nl80211: Add packet coalesce support Bing Zhao
2013-06-26 15:04 ` [PATCH v4 1/2] cfg80211/nl80211: rename packet pattern related structures and enums Johannes Berg
0 siblings, 2 replies; 5+ messages in thread
From: Bing Zhao @ 2013-06-26 2:03 UTC (permalink / raw)
To: linux-wireless
Cc: Johannes Berg, Luis R. Rodriguez, Jouni Malinen,
Vasanthakumar Thiagarajan, Senthil Balasubramanian,
Luciano Coelho, Amitkumar Karwar, Bing Zhao
From: Amitkumar Karwar <akarwar@marvell.com>
Currently packet patterns and it's enum/structures are used only
for WoWLAN feature. As we intend to reuse them for new feature
packet coalesce, they are renamed in this patch.
Older names are kept for backward compatibility purpose.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
v2: more details about the renames in commit log (Luis R. Rodriguez)
don't break the API with existing applications (Johannes Berg)
v3: __NL80211_PKTPAT_INVALID (Johannes Berg)
v4: similar to wowlan, take coalesce support information out of
wiphy structure so that we don't need to allocate the space for
devices which don't advertise the feature. (Johannes Berg)
drivers/net/wireless/ath/ath9k/main.c | 2 +-
drivers/net/wireless/mwifiex/cfg80211.c | 3 +--
drivers/net/wireless/ti/wlcore/main.c | 10 ++++----
include/net/cfg80211.h | 6 ++---
include/uapi/linux/nl80211.h | 45 ++++++++++++++++++++-------------
net/wireless/nl80211.c | 34 ++++++++++++-------------
6 files changed, 53 insertions(+), 47 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index cc5a98b..d1ce3da 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2098,7 +2098,7 @@ static void ath9k_wow_add_pattern(struct ath_softc *sc,
{
struct ath_hw *ah = sc->sc_ah;
struct ath9k_wow_pattern *wow_pattern = NULL;
- struct cfg80211_wowlan_trig_pkt_pattern *patterns = wowlan->patterns;
+ struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
int mask_len;
s8 i = 0;
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 856aea2..aa7e66f 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2295,8 +2295,7 @@ EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
#ifdef CONFIG_PM
static bool
-mwifiex_is_pattern_supported(struct cfg80211_wowlan_trig_pkt_pattern *pat,
- s8 *byte_seq)
+mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq)
{
int j, k, valid_byte_cnt = 0;
bool dont_care_byte = false;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 796928b..d89d58a 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1328,7 +1328,7 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
#ifdef CONFIG_PM
static int
-wl1271_validate_wowlan_pattern(struct cfg80211_wowlan_trig_pkt_pattern *p)
+wl1271_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p)
{
int num_fields = 0, in_field = 0, fields_size = 0;
int i, pattern_len = 0;
@@ -1471,9 +1471,9 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
* Allocates an RX filter returned through f
* which needs to be freed using rx_filter_free()
*/
-static int wl1271_convert_wowlan_pattern_to_rx_filter(
- struct cfg80211_wowlan_trig_pkt_pattern *p,
- struct wl12xx_rx_filter **f)
+static int
+wl1271_convert_wowlan_pattern_to_rx_filter(struct cfg80211_pkt_pattern *p,
+ struct wl12xx_rx_filter **f)
{
int i, j, ret = 0;
struct wl12xx_rx_filter *filter;
@@ -1575,7 +1575,7 @@ static int wl1271_configure_wowlan(struct wl1271 *wl,
/* Translate WoWLAN patterns into filters */
for (i = 0; i < wow->n_patterns; i++) {
- struct cfg80211_wowlan_trig_pkt_pattern *p;
+ struct cfg80211_pkt_pattern *p;
struct wl12xx_rx_filter *filter = NULL;
p = &wow->patterns[i];
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7b0730a..207b079 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1698,7 +1698,7 @@ struct cfg80211_pmksa {
};
/**
- * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern
+ * struct cfg80211_pkt_pattern - packet pattern
* @mask: bitmask where to match pattern and where to ignore bytes,
* one bit per byte, in same format as nl80211
* @pattern: bytes to match where bitmask is 1
@@ -1708,7 +1708,7 @@ struct cfg80211_pmksa {
* Internal note: @mask and @pattern are allocated in one chunk of
* memory, free @mask only!
*/
-struct cfg80211_wowlan_trig_pkt_pattern {
+struct cfg80211_pkt_pattern {
u8 *mask, *pattern;
int pattern_len;
int pkt_offset;
@@ -1770,7 +1770,7 @@ struct cfg80211_wowlan {
bool any, disconnect, magic_pkt, gtk_rekey_failure,
eap_identity_req, four_way_handshake,
rfkill_release;
- struct cfg80211_wowlan_trig_pkt_pattern *patterns;
+ struct cfg80211_pkt_pattern *patterns;
struct cfg80211_wowlan_tcp *tcp;
int n_patterns;
};
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 861e5eb..de0ce80 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3060,11 +3060,11 @@ enum nl80211_tx_power_setting {
};
/**
- * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute
- * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute
- * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has
+ * enum nl80211_packet_pattern_attr - packet pattern attribute
+ * @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
+ * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
* a zero bit are ignored
- * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have
+ * @NL80211_PKTPAT_MASK: pattern mask, must be long enough to have
* a bit for each byte in the pattern. The lowest-order bit corresponds
* to the first byte of the pattern, but the bytes of the pattern are
* in a little-endian-like format, i.e. the 9th byte of the pattern
@@ -3075,23 +3075,23 @@ enum nl80211_tx_power_setting {
* Note that the pattern matching is done as though frames were not
* 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
* first (including SNAP header unpacking) and then matched.
- * @NL80211_WOWLAN_PKTPAT_OFFSET: packet offset, pattern is matched after
+ * @NL80211_PKTPAT_OFFSET: packet offset, pattern is matched after
* these fixed number of bytes of received packet
- * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes
- * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number
+ * @NUM_NL80211_PKTPAT: number of attributes
+ * @MAX_NL80211_PKTPAT: max attribute number
*/
-enum nl80211_wowlan_packet_pattern_attr {
- __NL80211_WOWLAN_PKTPAT_INVALID,
- NL80211_WOWLAN_PKTPAT_MASK,
- NL80211_WOWLAN_PKTPAT_PATTERN,
- NL80211_WOWLAN_PKTPAT_OFFSET,
+enum nl80211_packet_pattern_attr {
+ __NL80211_PKTPAT_INVALID,
+ NL80211_PKTPAT_MASK,
+ NL80211_PKTPAT_PATTERN,
+ NL80211_PKTPAT_OFFSET,
- NUM_NL80211_WOWLAN_PKTPAT,
- MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,
+ NUM_NL80211_PKTPAT,
+ MAX_NL80211_PKTPAT = NUM_NL80211_PKTPAT - 1,
};
/**
- * struct nl80211_wowlan_pattern_support - pattern support information
+ * struct nl80211_pattern_support - packet pattern support information
* @max_patterns: maximum number of patterns supported
* @min_pattern_len: minimum length of each pattern
* @max_pattern_len: maximum length of each pattern
@@ -3101,13 +3101,22 @@ enum nl80211_wowlan_packet_pattern_attr {
* that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
* capability information given by the kernel to userspace.
*/
-struct nl80211_wowlan_pattern_support {
+struct nl80211_pattern_support {
__u32 max_patterns;
__u32 min_pattern_len;
__u32 max_pattern_len;
__u32 max_pkt_offset;
} __attribute__((packed));
+/* only for backward compatibility */
+#define __NL80211_WOWLAN_PKTPAT_INVALID __NL80211_PKTPAT_INVALID
+#define NL80211_WOWLAN_PKTPAT_MASK NL80211_PKTPAT_MASK
+#define NL80211_WOWLAN_PKTPAT_PATTERN NL80211_PKTPAT_PATTERN
+#define NL80211_WOWLAN_PKTPAT_OFFSET NL80211_PKTPAT_OFFSET
+#define NUM_NL80211_WOWLAN_PKTPAT NUM_NL80211_PKTPAT
+#define MAX_NL80211_WOWLAN_PKTPAT MAX_NL80211_PKTPAT
+#define nl80211_wowlan_pattern_support nl80211_pattern_support
+
/**
* enum nl80211_wowlan_triggers - WoWLAN trigger definitions
* @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes
@@ -3127,7 +3136,7 @@ struct nl80211_wowlan_pattern_support {
* pattern matching is done after the packet is converted to the MSDU.
*
* In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
- * carrying a &struct nl80211_wowlan_pattern_support.
+ * carrying a &struct nl80211_pattern_support.
*
* When reporting wakeup. it is a u32 attribute containing the 0-based
* index of the pattern that caused the wakeup, in the patterns passed
@@ -3284,7 +3293,7 @@ struct nl80211_wowlan_tcp_data_token_feature {
* @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a
* u32 attribute holding the maximum length
* @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for
- * feature advertising. The mask works like @NL80211_WOWLAN_PKTPAT_MASK
+ * feature advertising. The mask works like @NL80211_PKTPAT_MASK
* but on the TCP payload only.
* @NUM_NL80211_WOWLAN_TCP: number of TCP attributes
* @MAX_NL80211_WOWLAN_TCP: highest attribute number
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index bed6af5..785761f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -974,7 +974,7 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
return -ENOBUFS;
if (dev->wiphy.wowlan->n_patterns) {
- struct nl80211_wowlan_pattern_support pat = {
+ struct nl80211_pattern_support pat = {
.max_patterns = dev->wiphy.wowlan->n_patterns,
.min_pattern_len = dev->wiphy.wowlan->pattern_min_len,
.max_pattern_len = dev->wiphy.wowlan->pattern_max_len,
@@ -7591,12 +7591,11 @@ static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
if (!nl_pat)
return -ENOBUFS;
pat_len = wowlan->patterns[i].pattern_len;
- if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
- DIV_ROUND_UP(pat_len, 8),
+ if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
wowlan->patterns[i].mask) ||
- nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
- pat_len, wowlan->patterns[i].pattern) ||
- nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET,
+ nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
+ wowlan->patterns[i].pattern) ||
+ nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
wowlan->patterns[i].pkt_offset))
return -ENOBUFS;
nla_nest_end(msg, nl_pat);
@@ -7937,7 +7936,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
struct nlattr *pat;
int n_patterns = 0;
int rem, pat_len, mask_len, pkt_offset;
- struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
+ struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
rem)
@@ -7956,26 +7955,25 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
rem) {
- nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT,
- nla_data(pat), nla_len(pat), NULL);
+ nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
+ nla_len(pat), NULL);
err = -EINVAL;
- if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] ||
- !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN])
+ if (!pat_tb[NL80211_PKTPAT_MASK] ||
+ !pat_tb[NL80211_PKTPAT_PATTERN])
goto error;
- pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]);
+ pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
mask_len = DIV_ROUND_UP(pat_len, 8);
- if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) !=
- mask_len)
+ if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
goto error;
if (pat_len > wowlan->pattern_max_len ||
pat_len < wowlan->pattern_min_len)
goto error;
- if (!pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET])
+ if (!pat_tb[NL80211_PKTPAT_OFFSET])
pkt_offset = 0;
else
pkt_offset = nla_get_u32(
- pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET]);
+ pat_tb[NL80211_PKTPAT_OFFSET]);
if (pkt_offset > wowlan->max_pkt_offset)
goto error;
new_triggers.patterns[i].pkt_offset = pkt_offset;
@@ -7989,11 +7987,11 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
new_triggers.patterns[i].pattern =
new_triggers.patterns[i].mask + mask_len;
memcpy(new_triggers.patterns[i].mask,
- nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]),
+ nla_data(pat_tb[NL80211_PKTPAT_MASK]),
mask_len);
new_triggers.patterns[i].pattern_len = pat_len;
memcpy(new_triggers.patterns[i].pattern,
- nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]),
+ nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
pat_len);
i++;
}
--
1.8.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v4 2/2] cfg80211/nl80211: Add packet coalesce support 2013-06-26 2:03 [PATCH v4 1/2] cfg80211/nl80211: rename packet pattern related structures and enums Bing Zhao @ 2013-06-26 2:03 ` Bing Zhao 2013-06-26 15:13 ` Johannes Berg 2013-06-26 15:04 ` [PATCH v4 1/2] cfg80211/nl80211: rename packet pattern related structures and enums Johannes Berg 1 sibling, 1 reply; 5+ messages in thread From: Bing Zhao @ 2013-06-26 2:03 UTC (permalink / raw) To: linux-wireless Cc: Johannes Berg, Luis R. Rodriguez, Jouni Malinen, Vasanthakumar Thiagarajan, Senthil Balasubramanian, Luciano Coelho, Amitkumar Karwar, Bing Zhao From: Amitkumar Karwar <akarwar@marvell.com> In most cases, host that receives IPv4 and IPv6 multicast/broadcast packets does not do anything with these packets. Therefore the reception of these unwanted packets causes unnecessary processing and power consumption. Packet coalesce feature helps to reduce number of received interrupts to host by buffering these packets in firmware/hardware for some predefined time. Received interrupt will be generated when one of the following events occur. a) Expiration of hardware timer whose expiration time is set to maximum coalescing delay of matching coalesce rule. b) Coalescing buffer in hardware reaches it's limit. c) Packet doesn't match any of the configured coalesce rules. This patch adds set/get configuration support for packet coalesce. User needs to configure following parameters for creating a coalesce rule. a) Maximum coalescing delay b) List of packet patterns which needs to be matched c) Condition for coalescence. pattern 'match' or 'no match' Multiple such rules can be created. This feature needs to be advertised during driver initialization. Drivers are supposed to do required firmware/hardware settings based on user configuration. Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> --- v2: add documentation in nl80211.h and elabiration of "coalesce" in commit log (Luis R. Rodriguez) v3: address comments (Johannes Berg): use enum variable for 'condition'; remove new feature flag; remove spurious; update documentation v4: similar to wowlan, take coalesce support information out of wiphy structure so that we don't need to allocate the space for devices which don't advertise the feature. (Johannes Berg) set/clear coalesce rules through configuration file. (Johannes Berg) include/net/cfg80211.h | 51 ++++++++ include/uapi/linux/nl80211.h | 89 ++++++++++++- net/wireless/core.c | 11 ++ net/wireless/core.h | 2 + net/wireless/nl80211.c | 293 +++++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 2 + 6 files changed, 446 insertions(+), 2 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 207b079..ad61475 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1776,6 +1776,35 @@ struct cfg80211_wowlan { }; /** + * struct cfg80211_coalesce_rules - Coalesce rule parameters + * + * This structure defines coalesce rule for the device. + * @delay: maximum coalescing delay in msecs. + * @condition: condition for packet coalescence. + * see &enum nl80211_coalesce_condition. + * @patterns: array of packet patterns + * @n_patterns: number of patterns + */ +struct cfg80211_coalesce_rules { + int delay; + enum nl80211_coalesce_condition condition; + struct cfg80211_pkt_pattern *patterns; + int n_patterns; +}; + +/** + * struct cfg80211_coalesce - Packet coalescing settings + * + * This structure defines coalescing settings. + * @rules: array of coalesce rules + * @n_rules: number of rules + */ +struct cfg80211_coalesce { + struct cfg80211_coalesce_rules **rules; + int n_rules; +}; + +/** * struct cfg80211_wowlan_wakeup - wakeup report * @disconnect: woke up by getting disconnected * @magic_pkt: woke up by receiving magic packet @@ -2071,6 +2100,7 @@ struct cfg80211_update_ft_ies_params { * driver can take the most appropriate actions. * @crit_proto_stop: Indicates critical protocol no longer needs increased link * reliability. This operation can not fail. + * @set_coalesce: Set coalesce parameters. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -2306,6 +2336,8 @@ struct cfg80211_ops { u16 duration); void (*crit_proto_stop)(struct wiphy *wiphy, struct wireless_dev *wdev); + int (*set_coalesce)(struct wiphy *wiphy, + struct cfg80211_coalesce *coalesce); }; /* @@ -2532,6 +2564,23 @@ struct wiphy_wowlan_support { }; /** + * struct wiphy_coalesce_support - coalesce support data + * @n_rules: maximum number of coalesce rules + * @n_patterns: number of supported patterns + * (see nl80211.h for the pattern definition) + * @pattern_max_len: maximum length of each pattern + * @pattern_min_len: minimum length of each pattern + * @max_pkt_offset: maximum Rx packet offset + */ +struct wiphy_coalesce_support { + int n_rules; + int n_patterns; + int pattern_max_len; + int pattern_min_len; + int max_pkt_offset; +}; + +/** * struct wiphy - wireless hardware description * @reg_notifier: the driver's regulatory notification callback, * note that if your driver uses wiphy_apply_custom_regulatory() @@ -2641,6 +2690,7 @@ struct wiphy_wowlan_support { * 802.11-2012 8.4.2.29 for the defined fields. * @extended_capabilities_mask: mask of the valid values * @extended_capabilities_len: length of the extended capabilities + * @wiphy_coalesce_support coalesce: coalesce support information */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -2750,6 +2800,7 @@ struct wiphy { const struct iw_handler_def *wext; #endif + const struct wiphy_coalesce_support *coalesce; char priv[0] __aligned(NETDEV_ALIGN); }; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index de0ce80..fb5bbad 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -126,6 +126,31 @@ */ /** + * DOC: packet coalesce support + * + * In most cases, host that receives IPv4 and IPv6 multicast/broadcast + * packets does not do anything with these packets. Therefore the + * reception of these unwanted packets causes unnecessary processing + * and power consumption. + * + * Packet coalesce feature helps to reduce number of received interrupts + * to host by buffering these packets in firmware/hardware for some + * predefined time. Received interrupt will be generated when one of the + * following events occur. + * a) Expiration of hardware timer whose expiration time is set to maximum + * coalescing delay of matching coalesce rule. + * b) Coalescing buffer in hardware reaches it's limit. + * c) Packet doesn't match any of the configured coalesce rules. + * + * User needs to configure following parameters for creating a coalesce + * rule. + * a) Maximum coalescing delay + * b) List of packet patterns which needs to be matched + * c) Condition for coalescence. pattern 'match' or 'no match' + * Multiple such rules can be created. + */ + +/** * enum nl80211_commands - supported nl80211 commands * * @NL80211_CMD_UNSPEC: unspecified command to catch errors @@ -648,6 +673,10 @@ * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can * return back to normal. * + * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules. + * + * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -810,6 +839,9 @@ enum nl80211_commands { NL80211_CMD_CRIT_PROTOCOL_START, NL80211_CMD_CRIT_PROTOCOL_STOP, + NL80211_CMD_GET_COALESCE, + NL80211_CMD_SET_COALESCE, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -1436,6 +1468,8 @@ enum nl80211_commands { * allowed to be used with the first @NL80211_CMD_SET_STATION command to * update a TDLS peer STA entry. * + * @NL80211_ATTR_COALESCE_RULE: Coalesce rule information. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1736,6 +1770,8 @@ enum nl80211_attrs { NL80211_ATTR_PEER_AID, + NL80211_ATTR_COALESCE_RULE, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -3098,8 +3134,10 @@ enum nl80211_packet_pattern_attr { * @max_pkt_offset: maximum Rx packet offset * * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when - * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the - * capability information given by the kernel to userspace. + * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED or in + * %NL80211_ATTR_COALESCE_RULE_PKT_PATTERN when that is part of + * %NL80211_ATTR_COALESCE_RULE in the capability information given + * by the kernel to userspace. */ struct nl80211_pattern_support { __u32 max_patterns; @@ -3318,6 +3356,53 @@ enum nl80211_wowlan_tcp_attrs { }; /** + * struct nl80211_coalesce_rule_support - coalesce rule support information + * @max_rules: maximum number of rules supported + * @pat: packet pattern support information + * + * This struct is carried in %NL80211_ATTR_COALESCE_RULE in the + * capability information given by the kernel to userspace. + */ +struct nl80211_coalesce_rule_support { + __u32 max_rules; + struct nl80211_pattern_support pat; +} __attribute__((packed)); + +/** + * enum nl80211_attr_coalesce_rule - coalesce rule attribute + * @__NL80211_COALESCE_RULE_INVALID: invalid number for nested attribute + * @NL80211_ATTR_COALESCE_RULE_DELAY: delay in msecs used for packet coalescing + * @NL80211_ATTR_COALESCE_RULE_CONDITION: condition for packet coalescence, + * see &enum nl80211_coalesce_condition. + * @NL80211_ATTR_COALESCE_RULE_PKT_PATTERN: packet offset, pattern is matched + * after these fixed number of bytes of received packet + * @NUM_NL80211_ATTR_COALESCE_RULE: number of attributes + * @NL80211_ATTR_COALESCE_RULE_MAX: max attribute number + */ +enum nl80211_attr_coalesce_rule { + __NL80211_COALESCE_RULE_INVALID, + NL80211_ATTR_COALESCE_RULE_DELAY, + NL80211_ATTR_COALESCE_RULE_CONDITION, + NL80211_ATTR_COALESCE_RULE_PKT_PATTERN, + + /* keep last */ + NUM_NL80211_ATTR_COALESCE_RULE, + NL80211_ATTR_COALESCE_RULE_MAX = NUM_NL80211_ATTR_COALESCE_RULE - 1 +}; + +/** + * enum nl80211_coalesce_condition - coalesce rule conditions + * @NL80211_COALESCE_CONDITION_MATCH: coalaesce Rx packets when patterns + * in a rule are matched. + * @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns + * in a rule are not matched. + */ +enum nl80211_coalesce_condition { + NL80211_COALESCE_CONDITION_MATCH, + NL80211_COALESCE_CONDITION_NO_MATCH +}; + +/** * enum nl80211_iface_limit_attrs - limit attributes * @NL80211_IFACE_LIMIT_UNSPEC: (reserved) * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that diff --git a/net/wireless/core.c b/net/wireless/core.c index 672459b..853f754 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -462,6 +462,14 @@ int wiphy_register(struct wiphy *wiphy) return -EINVAL; #endif + if (WARN_ON(wiphy->coalesce && + (!wiphy->coalesce->n_rules || + !wiphy->wowlan->n_patterns) && + (!wiphy->coalesce->pattern_min_len || + wiphy->coalesce->pattern_min_len > + wiphy->coalesce->pattern_max_len))) + return -EINVAL; + if (WARN_ON(wiphy->ap_sme_capa && !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME))) return -EINVAL; @@ -668,6 +676,9 @@ void wiphy_unregister(struct wiphy *wiphy) rdev_set_wakeup(rdev, false); #endif cfg80211_rdev_free_wowlan(rdev); + + cfg80211_rdev_free_coalesce(rdev->coalesce); + rdev->coalesce = NULL; } EXPORT_SYMBOL(wiphy_unregister); diff --git a/net/wireless/core.h b/net/wireless/core.h index a6b45bf..9ad43c6 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -79,6 +79,8 @@ struct cfg80211_registered_device { /* netlink port which started critical protocol (0 means not started) */ u32 crit_proto_nlportid; + struct cfg80211_coalesce *coalesce; + /* must be last because of the way we do wiphy_priv(), * and it should at least be aligned to NETDEV_ALIGN */ struct wiphy wiphy __aligned(NETDEV_ALIGN); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 785761f..cc736ac 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -403,6 +403,14 @@ nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = { [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 }, }; +/* policy for coalesce rule attributes */ +static const struct nla_policy +nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = { + [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 }, + [NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U32 }, + [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED }, +}; + /* policy for GTK rekey offload attributes */ static const struct nla_policy nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { @@ -995,6 +1003,26 @@ static int nl80211_send_wowlan(struct sk_buff *msg, } #endif +static int nl80211_send_coalesce(struct sk_buff *msg, + struct cfg80211_registered_device *dev) +{ + struct nl80211_coalesce_rule_support rule; + + if (!dev->wiphy.coalesce) + return 0; + + rule.max_rules = dev->wiphy.coalesce->n_rules; + rule.pat.max_patterns = dev->wiphy.coalesce->n_patterns; + rule.pat.min_pattern_len = dev->wiphy.coalesce->pattern_min_len; + rule.pat.max_pattern_len = dev->wiphy.coalesce->pattern_max_len; + rule.pat.max_pkt_offset = dev->wiphy.coalesce->max_pkt_offset; + + if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule)) + return -ENOBUFS; + + return 0; +} + static int nl80211_send_band_rateinfo(struct sk_buff *msg, struct ieee80211_supported_band *sband) { @@ -1513,6 +1541,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, dev->wiphy.vht_capa_mod_mask)) goto nla_put_failure; + state->split_start++; + break; + case 10: + if (nl80211_send_coalesce(msg, dev)) + goto nla_put_failure; + /* done */ state->split_start = 0; break; @@ -8030,6 +8064,250 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) } #endif +static int nl80211_send_coalesce_rules(struct sk_buff *msg, + struct cfg80211_registered_device *rdev) +{ + struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules; + int i, j, pat_len; + struct cfg80211_coalesce_rules *rule; + + if (!rdev->coalesce->n_rules) + return 0; + + nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE); + if (!nl_rules) + return -ENOBUFS; + + for (i = 0; i < rdev->coalesce->n_rules; i++) { + nl_rule = nla_nest_start(msg, i + 1); + if (!nl_rule) + return -ENOBUFS; + + rule = rdev->coalesce->rules[i]; + if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY, + rule->delay)) + return -ENOBUFS; + + if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION, + rule->condition)) + return -ENOBUFS; + + nl_pats = nla_nest_start(msg, + NL80211_ATTR_COALESCE_RULE_PKT_PATTERN); + if (!nl_pats) + return -ENOBUFS; + + for (j = 0; j < rule->n_patterns; j++) { + nl_pat = nla_nest_start(msg, j + 1); + if (!nl_pat) + return -ENOBUFS; + pat_len = rule->patterns[j].pattern_len; + if (nla_put(msg, NL80211_PKTPAT_MASK, + DIV_ROUND_UP(pat_len, 8), + rule->patterns[j].mask) || + nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len, + rule->patterns[j].pattern) || + nla_put_u32(msg, NL80211_PKTPAT_OFFSET, + rule->patterns[j].pkt_offset)) + return -ENOBUFS; + nla_nest_end(msg, nl_pat); + } + nla_nest_end(msg, nl_pats); + nla_nest_end(msg, nl_rule); + } + nla_nest_end(msg, nl_rules); + + return 0; +} + +static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct sk_buff *msg; + void *hdr; + + if (!rdev->wiphy.coalesce) + return -EOPNOTSUPP; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, + NL80211_CMD_GET_COALESCE); + if (!hdr) + goto nla_put_failure; + + if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev)) + goto nla_put_failure; + + genlmsg_end(msg, hdr); + return genlmsg_reply(msg, info); + +nla_put_failure: + nlmsg_free(msg); + return -ENOBUFS; +} + +void cfg80211_rdev_free_coalesce(struct cfg80211_coalesce *coalesce) +{ + int i, j; + struct cfg80211_coalesce_rules *rule; + + if (!coalesce) + return; + + for (i = 0; i < coalesce->n_rules; i++) { + rule = coalesce->rules[i]; + for (j = 0; j < rule->n_patterns; j++) + kfree(rule->patterns[j].mask); + kfree(rule->patterns); + kfree(rule); + } + kfree(coalesce->rules); + kfree(coalesce); +} + +static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, + struct nlattr *rule, + struct cfg80211_coalesce_rules *new_rule) +{ + int err, i; + const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce; + struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat; + int rem, pat_len, mask_len, pkt_offset, n_patterns = 0; + struct nlattr *pat_tb[NUM_NL80211_PKTPAT]; + + err = nla_parse(tb, NL80211_ATTR_COALESCE_RULE_MAX, nla_data(rule), + nla_len(rule), nl80211_coalesce_policy); + if (err) + return err; + + memset(new_rule, 0, sizeof(*new_rule)); + new_rule->delay = nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]); + new_rule->condition = + nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]); + if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH && + new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH) + return -EINVAL; + + if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN]) + return -EINVAL; + + nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN], + rem) + n_patterns++; + if (n_patterns > coalesce->n_patterns) + return -EINVAL; + + new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]), + GFP_KERNEL); + if (!new_rule->patterns) + return -ENOMEM; + + new_rule->n_patterns = n_patterns; + i = 0; + + nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN], + rem) { + err = -EINVAL; + nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), + nla_len(pat), NULL); + if (!pat_tb[NL80211_PKTPAT_MASK] || + !pat_tb[NL80211_PKTPAT_PATTERN]) + goto error; + pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]); + mask_len = DIV_ROUND_UP(pat_len, 8); + if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len) + goto error; + if (pat_len > coalesce->pattern_max_len || + pat_len < coalesce->pattern_min_len) + goto error; + + if (!pat_tb[NL80211_PKTPAT_OFFSET]) + pkt_offset = 0; + else + pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]); + if (pkt_offset > coalesce->max_pkt_offset) + goto error; + new_rule->patterns[i].pkt_offset = pkt_offset; + + new_rule->patterns[i].mask = + kmalloc(mask_len + pat_len, GFP_KERNEL); + err = -ENOMEM; + if (!new_rule->patterns[i].mask) + goto error; + new_rule->patterns[i].pattern = + new_rule->patterns[i].mask + mask_len; + memcpy(new_rule->patterns[i].mask, + nla_data(pat_tb[NL80211_PKTPAT_MASK]), mask_len); + new_rule->patterns[i].pattern_len = pat_len; + memcpy(new_rule->patterns[i].pattern, + nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), pat_len); + i++; + } + + return 0; +error: + for (i = 0; i < new_rule->n_patterns; i++) + kfree(new_rule->patterns[i].mask); + kfree(new_rule->patterns); + return err; +} + +static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce; + struct cfg80211_coalesce_rules new_rule = {}; + struct cfg80211_coalesce_rules *nrule; + struct cfg80211_coalesce *new_coalesce; + int err, rem_rule; + struct nlattr *rule; + + if (!rdev->wiphy.coalesce) + return -EOPNOTSUPP; + if (!rdev->ops->set_coalesce) + return -EOPNOTSUPP; + + if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) { + cfg80211_rdev_free_coalesce(rdev->coalesce); + rdev->coalesce = NULL; + rdev->ops->set_coalesce(&rdev->wiphy, NULL); + return 0; + } + + new_coalesce = kzalloc(sizeof(*new_coalesce), GFP_KERNEL); + new_coalesce->rules = kcalloc(coalesce->n_rules, + sizeof(void *), GFP_KERNEL); + nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE], + rem_rule) { + memset(&new_rule, 0, sizeof(new_rule)); + err = nl80211_parse_coalesce_rule(rdev, rule, &new_rule); + if (err) + goto error; + + nrule = kmemdup(&new_rule, sizeof(new_rule), GFP_KERNEL); + if (!nrule) { + err = -ENOMEM; + goto error; + } + new_coalesce->rules[new_coalesce->n_rules++] = nrule; + } + + cfg80211_rdev_free_coalesce(rdev->coalesce); + rdev->coalesce = new_coalesce; + + err = rdev->ops->set_coalesce(&rdev->wiphy, rdev->coalesce); + if (err) + goto error; + + return 0; +error: + cfg80211_rdev_free_coalesce(new_coalesce); + return err; +} + static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -9037,6 +9315,21 @@ static struct genl_ops nl80211_ops[] = { .flags = GENL_ADMIN_PERM, .internal_flags = NL80211_FLAG_NEED_WDEV_UP | NL80211_FLAG_NEED_RTNL, + }, + { + .cmd = NL80211_CMD_GET_COALESCE, + .doit = nl80211_get_coalesce, + .policy = nl80211_policy, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, + }, + { + .cmd = NL80211_CMD_SET_COALESCE, + .doit = nl80211_set_coalesce, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, } }; diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index a4073e8..d5ef819 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -74,4 +74,6 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev, enum nl80211_radar_event event, struct net_device *netdev, gfp_t gfp); +void cfg80211_rdev_free_coalesce(struct cfg80211_coalesce *coalesce); + #endif /* __NET_WIRELESS_NL80211_H */ -- 1.8.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 2/2] cfg80211/nl80211: Add packet coalesce support 2013-06-26 2:03 ` [PATCH v4 2/2] cfg80211/nl80211: Add packet coalesce support Bing Zhao @ 2013-06-26 15:13 ` Johannes Berg 2013-06-26 18:53 ` Amitkumar Karwar 0 siblings, 1 reply; 5+ messages in thread From: Johannes Berg @ 2013-06-26 15:13 UTC (permalink / raw) To: Bing Zhao Cc: linux-wireless, Luis R. Rodriguez, Jouni Malinen, Vasanthakumar Thiagarajan, Senthil Balasubramanian, Luciano Coelho, Amitkumar Karwar On Tue, 2013-06-25 at 19:03 -0700, Bing Zhao wrote: > +/** > + * struct cfg80211_coalesce - Packet coalescing settings > + * > + * This structure defines coalescing settings. > + * @rules: array of coalesce rules > + * @n_rules: number of rules > + */ > +struct cfg80211_coalesce { > + struct cfg80211_coalesce_rules **rules; I don't really see why this should be a double pointer? The coalesce_rules struct is small enough that you could just allocate an array of that, no? > /** > + * struct wiphy_coalesce_support - coalesce support data > + * @n_rules: maximum number of coalesce rules > + * @n_patterns: number of supported patterns > + * (see nl80211.h for the pattern definition) > + * @pattern_max_len: maximum length of each pattern > + * @pattern_min_len: minimum length of each pattern > + * @max_pkt_offset: maximum Rx packet offset Should there be any limits on the timer? Will the firmware actually work if I set it to (useless) values like 2^32-1 msecs? Also -- is n_patterns per rule, or global? It seems global, but in the rules you can have multiple patterns per rule? > +/** > * enum nl80211_commands - supported nl80211 commands > * > * @NL80211_CMD_UNSPEC: unspecified command to catch errors > @@ -648,6 +673,10 @@ > * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can > * return back to normal. > * > + * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules. > + * > + * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules. I'd prefer no space between the two :) > +struct nl80211_coalesce_rule_support { > + __u32 max_rules; > + struct nl80211_pattern_support pat; (timing stuff would also go here, I suppose) > +static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, > + struct nlattr *rule, > + struct cfg80211_coalesce_rules *new_rule) > +{ > + int err, i; > + const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce; > + struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat; > + int rem, pat_len, mask_len, pkt_offset, n_patterns = 0; > + struct nlattr *pat_tb[NUM_NL80211_PKTPAT]; > + > + err = nla_parse(tb, NL80211_ATTR_COALESCE_RULE_MAX, nla_data(rule), > + nla_len(rule), nl80211_coalesce_policy); > + if (err) > + return err; > + > + memset(new_rule, 0, sizeof(*new_rule)); > + new_rule->delay = nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]); no check that it actually exists? > + new_rule->condition = > + nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]); ditto. easy to crash, no? > +static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info) > +{ > + struct cfg80211_registered_device *rdev = info->user_ptr[0]; > + const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce; > + struct cfg80211_coalesce_rules new_rule = {}; > + struct cfg80211_coalesce_rules *nrule; > + struct cfg80211_coalesce *new_coalesce; > + int err, rem_rule; > + struct nlattr *rule; > + > + if (!rdev->wiphy.coalesce) > + return -EOPNOTSUPP; > + if (!rdev->ops->set_coalesce) > + return -EOPNOTSUPP; could combine the conditions :) > + new_coalesce = kzalloc(sizeof(*new_coalesce), GFP_KERNEL); > + new_coalesce->rules = kcalloc(coalesce->n_rules, > + sizeof(void *), GFP_KERNEL); *kaboom* > + cfg80211_rdev_free_coalesce(rdev->coalesce); > + rdev->coalesce = new_coalesce; > + > + err = rdev->ops->set_coalesce(&rdev->wiphy, rdev->coalesce); > + if (err) > + goto error; > + > + return 0; > +error: > + cfg80211_rdev_free_coalesce(new_coalesce); *kaboom* if it ever fails, and you then do get_coalesce -- should probably assign only after setting the new value successfully? johannes ^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH v4 2/2] cfg80211/nl80211: Add packet coalesce support 2013-06-26 15:13 ` Johannes Berg @ 2013-06-26 18:53 ` Amitkumar Karwar 0 siblings, 0 replies; 5+ messages in thread From: Amitkumar Karwar @ 2013-06-26 18:53 UTC (permalink / raw) To: Johannes Berg, Bing Zhao Cc: linux-wireless@vger.kernel.org, Luis R. Rodriguez, Jouni Malinen, Vasanthakumar Thiagarajan, Senthil Balasubramanian, Luciano Coelho Hi Johannes, Thanks for your comments. >> +struct cfg80211_coalesce { >> + struct cfg80211_coalesce_rules **rules; >I don't really see why this should be a double pointer? The >coalesce_rules struct is small enough that you could just allocate an >array of that, no? Actually it came from our previous design which used to add one rule per iw command by allocating an array of rule pointers. You are right. We will use normal pointer and allocate an array of rules in updated version. >> /** >> + * struct wiphy_coalesce_support - coalesce support data >> + * @n_rules: maximum number of coalesce rules >> + * @n_patterns: number of supported patterns >> + * (see nl80211.h for the pattern definition) >> + * @pattern_max_len: maximum length of each pattern >> + * @pattern_min_len: minimum length of each pattern >> + * @max_pkt_offset: maximum Rx packet offset >Should there be any limits on the timer? Will the firmware actually work >if I set it to (useless) values like 2^32-1 msecs? Makes sense. There should be a limit for colaescing delay. We will add new parameter 'max_delay'. >Also -- is n_patterns per rule, or global? It seems global, but in the >rules you can have multiple patterns per rule? n_patterns is per rule. We will update description of 'n_patterns'. >> + * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules. >> + * >> + * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules. > I'd prefer no space between the two :) Sure. >> +struct nl80211_coalesce_rule_support { >> + __u32 max_rules; >> + struct nl80211_pattern_support pat; >(timing stuff would also go here, I suppose) Yes. The new parameter will be added here. >> + new_rule->delay = nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]); >no check that it actually exists? >> + new_rule->condition = >> + nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]); >ditto. easy to crash, no? Thanks. We will add checks to see if these attributes are present. > + if (!rdev->wiphy.coalesce) > + return -EOPNOTSUPP; > + if (!rdev->ops->set_coalesce) > + return -EOPNOTSUPP; >could combine the conditions :) Ack. >> + new_coalesce = kzalloc(sizeof(*new_coalesce), GFP_KERNEL); >> + new_coalesce->rules = kcalloc(coalesce->n_rules, >> + sizeof(void *), GFP_KERNEL); >*kaboom* >> + cfg80211_rdev_free_coalesce(rdev->coalesce); >> + rdev->coalesce = new_coalesce; >> + >> + err = rdev->ops->set_coalesce(&rdev->wiphy, rdev->coalesce); >> + if (err) >> + goto error; >> + >> + return 0; >> +error: >> + cfg80211_rdev_free_coalesce(new_coalesce); >*kaboom* if it ever fails, and you then do get_coalesce -- should >probably assign only after setting the new value successfully? Thanks for pointing this out. We will take care of this error path. Regards, Amitkumar Karwar ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v4 1/2] cfg80211/nl80211: rename packet pattern related structures and enums 2013-06-26 2:03 [PATCH v4 1/2] cfg80211/nl80211: rename packet pattern related structures and enums Bing Zhao 2013-06-26 2:03 ` [PATCH v4 2/2] cfg80211/nl80211: Add packet coalesce support Bing Zhao @ 2013-06-26 15:04 ` Johannes Berg 1 sibling, 0 replies; 5+ messages in thread From: Johannes Berg @ 2013-06-26 15:04 UTC (permalink / raw) To: Bing Zhao Cc: linux-wireless, Luis R. Rodriguez, Jouni Malinen, Vasanthakumar Thiagarajan, Senthil Balasubramanian, Luciano Coelho, Amitkumar Karwar On Tue, 2013-06-25 at 19:03 -0700, Bing Zhao wrote: > From: Amitkumar Karwar <akarwar@marvell.com> > > Currently packet patterns and it's enum/structures are used only > for WoWLAN feature. As we intend to reuse them for new feature > packet coalesce, they are renamed in this patch. This looks good, applied. johannes ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-06-26 18:55 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-06-26 2:03 [PATCH v4 1/2] cfg80211/nl80211: rename packet pattern related structures and enums Bing Zhao 2013-06-26 2:03 ` [PATCH v4 2/2] cfg80211/nl80211: Add packet coalesce support Bing Zhao 2013-06-26 15:13 ` Johannes Berg 2013-06-26 18:53 ` Amitkumar Karwar 2013-06-26 15:04 ` [PATCH v4 1/2] cfg80211/nl80211: rename packet pattern related structures and enums Johannes Berg
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox