Skip to content

Commit 0c546fb

Browse files
committed
iwlwifi: mvm: support v2 of the WoWLAN patterns command
Add new definitions for the WoWLAN patterns API version 2 and support for version 2 of the WoWLAN patterns command without implementing the new features. With this commit we only supporting the existing bitmask pattern match. Use the new version only if the TLV is set. Signed-off-by: Luca Coelho <[email protected]>
1 parent 30f24ea commit 0c546fb

File tree

3 files changed

+184
-11
lines changed

3 files changed

+184
-11
lines changed

drivers/net/wireless/intel/iwlwifi/fw/api/d3.h

Lines changed: 130 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
99
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
1010
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
11-
* Copyright(c) 2018 Intel Corporation
11+
* Copyright(c) 2018 - 2019 Intel Corporation
1212
*
1313
* This program is free software; you can redistribute it and/or modify
1414
* it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
3131
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
3232
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
3333
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
34-
* Copyright(c) 2018 Intel Corporation
34+
* Copyright(c) 2018 - 2019 Intel Corporation
3535
* All rights reserved.
3636
*
3737
* Redistribution and use in source and binary forms, with or without
@@ -214,7 +214,7 @@ struct iwl_proto_offload_cmd_v3_large {
214214
#define IWL_WOWLAN_MIN_PATTERN_LEN 16
215215
#define IWL_WOWLAN_MAX_PATTERN_LEN 128
216216

217-
struct iwl_wowlan_pattern {
217+
struct iwl_wowlan_pattern_v1 {
218218
u8 mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];
219219
u8 pattern[IWL_WOWLAN_MAX_PATTERN_LEN];
220220
u8 mask_size;
@@ -227,7 +227,7 @@ struct iwl_wowlan_pattern {
227227
/**
228228
* struct iwl_wowlan_patterns_cmd - WoWLAN wakeup patterns
229229
*/
230-
struct iwl_wowlan_patterns_cmd {
230+
struct iwl_wowlan_patterns_cmd_v1 {
231231
/**
232232
* @n_patterns: number of patterns
233233
*/
@@ -236,9 +236,129 @@ struct iwl_wowlan_patterns_cmd {
236236
/**
237237
* @patterns: the patterns, array length in @n_patterns
238238
*/
239-
struct iwl_wowlan_pattern patterns[];
239+
struct iwl_wowlan_pattern_v1 patterns[];
240240
} __packed; /* WOWLAN_PATTERN_ARRAY_API_S_VER_1 */
241241

242+
#define IPV4_ADDR_SIZE 4
243+
#define IPV6_ADDR_SIZE 16
244+
245+
enum iwl_wowlan_pattern_type {
246+
WOWLAN_PATTERN_TYPE_BITMASK,
247+
WOWLAN_PATTERN_TYPE_IPV4_TCP_SYN,
248+
WOWLAN_PATTERN_TYPE_IPV6_TCP_SYN,
249+
WOWLAN_PATTERN_TYPE_IPV4_TCP_SYN_WILDCARD,
250+
WOWLAN_PATTERN_TYPE_IPV6_TCP_SYN_WILDCARD,
251+
}; /* WOWLAN_PATTERN_TYPE_API_E_VER_1 */
252+
253+
/**
254+
* struct iwl_wowlan_ipv4_tcp_syn - WoWLAN IPv4 TCP SYN pattern data
255+
*/
256+
struct iwl_wowlan_ipv4_tcp_syn {
257+
/**
258+
* @src_addr: source IP address to match
259+
*/
260+
u8 src_addr[IPV4_ADDR_SIZE];
261+
262+
/**
263+
* @dst_addr: destination IP address to match
264+
*/
265+
u8 dst_addr[IPV4_ADDR_SIZE];
266+
267+
/**
268+
* @src_port: source TCP port to match
269+
*/
270+
__le16 src_port;
271+
272+
/**
273+
* @dst_port: destination TCP port to match
274+
*/
275+
__le16 dst_port;
276+
} __packed; /* WOWLAN_IPV4_TCP_SYN_API_S_VER_1 */
277+
278+
/**
279+
* struct iwl_wowlan_ipv6_tcp_syn - WoWLAN Ipv6 TCP SYN pattern data
280+
*/
281+
struct iwl_wowlan_ipv6_tcp_syn {
282+
/**
283+
* @src_addr: source IP address to match
284+
*/
285+
u8 src_addr[IPV6_ADDR_SIZE];
286+
287+
/**
288+
* @dst_addr: destination IP address to match
289+
*/
290+
u8 dst_addr[IPV6_ADDR_SIZE];
291+
292+
/**
293+
* @src_port: source TCP port to match
294+
*/
295+
__le16 src_port;
296+
297+
/**
298+
* @dst_port: destination TCP port to match
299+
*/
300+
__le16 dst_port;
301+
} __packed; /* WOWLAN_IPV6_TCP_SYN_API_S_VER_1 */
302+
303+
/**
304+
* union iwl_wowlan_pattern_data - Data for the different pattern types
305+
*
306+
* If wildcard addresses/ports are to be used, the union can be left
307+
* undefined.
308+
*/
309+
union iwl_wowlan_pattern_data {
310+
/**
311+
* @bitmask: bitmask pattern data
312+
*/
313+
struct iwl_wowlan_pattern_v1 bitmask;
314+
315+
/**
316+
* @ipv4_tcp_syn: IPv4 TCP SYN pattern data
317+
*/
318+
struct iwl_wowlan_ipv4_tcp_syn ipv4_tcp_syn;
319+
320+
/**
321+
* @ipv6_tcp_syn: IPv6 TCP SYN pattern data
322+
*/
323+
struct iwl_wowlan_ipv6_tcp_syn ipv6_tcp_syn;
324+
}; /* WOWLAN_PATTERN_API_U_VER_1 */
325+
326+
/**
327+
* struct iwl_wowlan_pattern_v2 - Pattern entry for the WoWLAN wakeup patterns
328+
*/
329+
struct iwl_wowlan_pattern_v2 {
330+
/**
331+
* @pattern_type: defines the struct type to be used in the union
332+
*/
333+
u8 pattern_type;
334+
335+
/**
336+
* @reserved: reserved for alignment
337+
*/
338+
u8 reserved[3];
339+
340+
/**
341+
* @u: the union containing the match data, or undefined for
342+
* wildcard matches
343+
*/
344+
union iwl_wowlan_pattern_data u;
345+
} __packed; /* WOWLAN_PATTERN_API_S_VER_2 */
346+
347+
/**
348+
* struct iwl_wowlan_patterns_cmd - WoWLAN wakeup patterns command
349+
*/
350+
struct iwl_wowlan_patterns_cmd {
351+
/**
352+
* @n_patterns: number of patterns
353+
*/
354+
__le32 n_patterns;
355+
356+
/**
357+
* @patterns: the patterns, array length in @n_patterns
358+
*/
359+
struct iwl_wowlan_pattern_v2 patterns[];
360+
} __packed; /* WOWLAN_PATTERN_ARRAY_API_S_VER_2 */
361+
242362
enum iwl_wowlan_wakeup_filters {
243363
IWL_WOWLAN_WAKEUP_MAGIC_PACKET = BIT(0),
244364
IWL_WOWLAN_WAKEUP_PATTERN_MATCH = BIT(1),
@@ -383,7 +503,11 @@ enum iwl_wowlan_wakeup_reason {
383503
IWL_WOWLAN_WAKEUP_BY_D3_WAKEUP_HOST_TIMER = BIT(14),
384504
IWL_WOWLAN_WAKEUP_BY_RXFRAME_FILTERED_IN = BIT(15),
385505
IWL_WOWLAN_WAKEUP_BY_BEACON_FILTERED_IN = BIT(16),
386-
506+
IWL_WAKEUP_BY_11W_UNPROTECTED_DEAUTH_OR_DISASSOC = BIT(17),
507+
IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN = BIT(18),
508+
IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN_WILDCARD = BIT(19),
509+
IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN = BIT(20),
510+
IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN_WILDCARD = BIT(21),
387511
}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
388512

389513
struct iwl_wowlan_gtk_status_v1 {

drivers/net/wireless/intel/iwlwifi/fw/file.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ enum iwl_ucode_tlv_api {
311311
IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ = (__force iwl_ucode_tlv_api_t)49,
312312
IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS = (__force iwl_ucode_tlv_api_t)50,
313313
IWL_UCODE_TLV_API_MBSSID_HE = (__force iwl_ucode_tlv_api_t)52,
314+
IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE = (__force iwl_ucode_tlv_api_t)53,
314315
IWL_UCODE_TLV_API_FTM_RTT_ACCURACY = (__force iwl_ucode_tlv_api_t)54,
315316

316317
NUM_IWL_UCODE_TLV_API

drivers/net/wireless/intel/iwlwifi/mvm/d3.c

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,10 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
385385
}
386386
}
387387

388-
static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
389-
struct cfg80211_wowlan *wowlan)
388+
static int iwl_mvm_send_patterns_v1(struct iwl_mvm *mvm,
389+
struct cfg80211_wowlan *wowlan)
390390
{
391-
struct iwl_wowlan_patterns_cmd *pattern_cmd;
391+
struct iwl_wowlan_patterns_cmd_v1 *pattern_cmd;
392392
struct iwl_host_cmd cmd = {
393393
.id = WOWLAN_PATTERNS,
394394
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
@@ -399,7 +399,7 @@ static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
399399
return 0;
400400

401401
cmd.len[0] = sizeof(*pattern_cmd) +
402-
wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern);
402+
wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern_v1);
403403

404404
pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
405405
if (!pattern_cmd)
@@ -426,6 +426,50 @@ static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
426426
return err;
427427
}
428428

429+
static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
430+
struct cfg80211_wowlan *wowlan)
431+
{
432+
struct iwl_wowlan_patterns_cmd *pattern_cmd;
433+
struct iwl_host_cmd cmd = {
434+
.id = WOWLAN_PATTERNS,
435+
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
436+
};
437+
int i, err;
438+
439+
if (!wowlan->n_patterns)
440+
return 0;
441+
442+
cmd.len[0] = sizeof(*pattern_cmd) +
443+
wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern_v2);
444+
445+
pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
446+
if (!pattern_cmd)
447+
return -ENOMEM;
448+
449+
pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);
450+
451+
for (i = 0; i < wowlan->n_patterns; i++) {
452+
int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
453+
454+
pattern_cmd->patterns[i].pattern_type =
455+
WOWLAN_PATTERN_TYPE_BITMASK;
456+
457+
memcpy(&pattern_cmd->patterns[i].u.bitmask.mask,
458+
wowlan->patterns[i].mask, mask_len);
459+
memcpy(&pattern_cmd->patterns[i].u.bitmask.pattern,
460+
wowlan->patterns[i].pattern,
461+
wowlan->patterns[i].pattern_len);
462+
pattern_cmd->patterns[i].u.bitmask.mask_size = mask_len;
463+
pattern_cmd->patterns[i].u.bitmask.pattern_size =
464+
wowlan->patterns[i].pattern_len;
465+
}
466+
467+
cmd.data[0] = pattern_cmd;
468+
err = iwl_mvm_send_cmd(mvm, &cmd);
469+
kfree(pattern_cmd);
470+
return err;
471+
}
472+
429473
static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
430474
struct ieee80211_sta *ap_sta)
431475
{
@@ -851,7 +895,11 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
851895
if (ret)
852896
return ret;
853897

854-
ret = iwl_mvm_send_patterns(mvm, wowlan);
898+
if (fw_has_api(&mvm->fw->ucode_capa,
899+
IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE))
900+
ret = iwl_mvm_send_patterns(mvm, wowlan);
901+
else
902+
ret = iwl_mvm_send_patterns_v1(mvm, wowlan);
855903
if (ret)
856904
return ret;
857905

0 commit comments

Comments
 (0)