Codebase list iw / upstream/5.9+git20210813.1.d59e908
Import upstream version 5.9+git20210813.1.d59e908 Debian Janitor 2 years ago
16 changed file(s) with 536 addition(s) and 155 deletion(s). Raw diff Collapse all Expand all
4444 endif
4545
4646 ifeq ($(NL2FOUND),Y)
47 CFLAGS += -DCONFIG_LIBNL20
48 LIBS += -lnl-genl
47 override CFLAGS += -DCONFIG_LIBNL20
48 override LIBS += -lnl-genl
4949 NLLIBNAME = libnl-2.0
5050 endif
5151
5252 ifeq ($(NL3xFOUND),Y)
5353 # libnl 3.2 might be found as 3.2 and 3.0
5454 NL3FOUND = N
55 CFLAGS += -DCONFIG_LIBNL30
56 LIBS += -lnl-genl-3
55 override CFLAGS += -DCONFIG_LIBNL30
56 override LIBS += -lnl-genl-3
5757 NLLIBNAME = libnl-3.0
5858 endif
5959
6060 ifeq ($(NL3FOUND),Y)
61 CFLAGS += -DCONFIG_LIBNL30
62 LIBS += -lnl-genl
61 override CFLAGS += -DCONFIG_LIBNL30
62 override LIBS += -lnl-genl
6363 NLLIBNAME = libnl-3.0
6464 endif
6565
6666 # nl-3.1 has a broken libnl-gnl-3.1.pc file
6767 # as show by pkg-config --debug --libs --cflags --exact-version=3.1 libnl-genl-3.1;echo $?
6868 ifeq ($(NL31FOUND),Y)
69 CFLAGS += -DCONFIG_LIBNL30
70 LIBS += -lnl-genl
69 override CFLAGS += -DCONFIG_LIBNL30
70 override LIBS += -lnl-genl
7171 NLLIBNAME = libnl-3.1
7272 endif
7373
7575 $(error Cannot find development files for any supported version of libnl)
7676 endif
7777
78 LIBS += $(shell $(PKG_CONFIG) --libs $(NLLIBNAME))
79 CFLAGS += $(shell $(PKG_CONFIG) --cflags $(NLLIBNAME))
78 override LIBS += $(shell $(PKG_CONFIG) --libs $(NLLIBNAME))
79 override CFLAGS += $(shell $(PKG_CONFIG) --cflags $(NLLIBNAME))
8080 endif # NO_PKG_CONFIG
8181
8282 ifeq ($(V),1)
88
99 'iw' is currently maintained at http://git.sipsolutions.net/iw.git/,
1010 some more documentation is available at
11 http://wireless.kernel.org/en/users/Documentation/iw.
11 https://wireless.wiki.kernel.org/en/users/Documentation/iw
1212
1313 Please send all patches to Johannes Berg <johannes@sipsolutions.net>
1414 and CC linux-wireless@vger.kernel.org for community review.
1414 {
1515 char *end;
1616 unsigned char bssid[6];
17 bool need_key = false;
1718 int freq;
1819 int ret;
1920
4748 if (!argc)
4849 return 0;
4950
50 if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
51 if (strcmp(*argv, "auth") == 0) {
52 argv++;
53 argc--;
54
55 if (!argc)
56 return 1;
57
58 if (strcmp(argv[0], "open") == 0) {
59 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
60 NL80211_AUTHTYPE_OPEN_SYSTEM);
61 } else if (strcmp(argv[0], "shared") == 0) {
62 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
63 NL80211_AUTHTYPE_SHARED_KEY);
64 need_key = true;
65 } else {
66 return 1;
67 }
68
69 argv++;
70 argc--;
71 }
72
73 if (need_key && !argc)
74 return 1;
75
76 if (argc && strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
5177 return 1;
5278
5379 argv++;
159185 &printargs);
160186 return 0;
161187 }
162 TOPLEVEL(connect, "[-w] <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1:6162636465] [mfp:req/opt/no]",
188 TOPLEVEL(connect, "[-w] <SSID> [<freq in MHz>] [<bssid>] [auth open|shared] [key 0:abcde d:1:6162636465] [mfp:req/opt/no]",
163189 0, 0, CIB_NETDEV, iw_connect,
164190 "Join the network with the given SSID (and frequency, BSSID).\n"
165191 "With -w, wait for the connect to finish or fail.");
22 #include <net/if.h>
33 #include <errno.h>
44 #include <inttypes.h>
5 #include <time.h>
56 #include "iw.h"
67
78 static int no_seq_check(struct nl_msg *msg, void *arg)
904905 int rem_nst;
905906 __u16 status;
906907
907 if (args->time || args->reltime) {
908 if (args->time || args->reltime || args->ctime) {
908909 unsigned long long usecs, previous;
909910
910911 previous = 1000000ULL * args->ts.tv_sec + args->ts.tv_usec;
911912 gettimeofday(&args->ts, NULL);
912913 usecs = 1000000ULL * args->ts.tv_sec + args->ts.tv_usec;
914
913915 if (args->reltime) {
914916 if (!args->have_ts) {
915917 usecs = 0;
917919 } else
918920 usecs -= previous;
919921 }
920 printf("%llu.%06llu: ", usecs/1000000, usecs % 1000000);
922
923 if (args->ctime) {
924 struct tm *tm = localtime(&args->ts.tv_sec);
925 char buf[255];
926
927 memset(buf, 0, 255);
928 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
929 printf("[%s.%06lu]: ", buf, args->ts.tv_usec);
930 } else {
931 printf("%llu.%06llu: ", usecs/1000000, usecs % 1000000);
932 }
921933 }
922934
923935 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
11701182 (unsigned long long)nla_get_u64(tb[NL80211_ATTR_COOKIE]),
11711183 tb[NL80211_ATTR_ACK] ? "acked" : "no ack");
11721184 break;
1185 case NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS:
1186 printf("ctrl. port TX status (cookie %llx): %s\n",
1187 (unsigned long long)nla_get_u64(tb[NL80211_ATTR_COOKIE]),
1188 tb[NL80211_ATTR_ACK] ? "acked" : "no ack");
1189 break;
11731190 case NL80211_CMD_PMKSA_CANDIDATE:
11741191 printf("PMKSA candidate found\n");
11751192 break;
14011418 enum id_input id)
14021419 {
14031420 struct print_event_args args;
1421 int num_time_formats = 0;
14041422 int ret;
14051423
14061424 memset(&args, 0, sizeof(args));
14111429 while (argc > 0) {
14121430 if (strcmp(argv[0], "-f") == 0)
14131431 args.frame = true;
1414 else if (strcmp(argv[0], "-t") == 0)
1432 else if (strcmp(argv[0], "-t") == 0) {
1433 num_time_formats++;
14151434 args.time = true;
1416 else if (strcmp(argv[0], "-r") == 0)
1435 } else if (strcmp(argv[0], "-T") == 0) {
1436 num_time_formats++;
1437 args.ctime = true;
1438 } else if (strcmp(argv[0], "-r") == 0) {
1439 num_time_formats++;
14171440 args.reltime = true;
1418 else
1441 } else
14191442 return 1;
14201443 argc--;
14211444 argv++;
14221445 }
14231446
1424 if (args.time && args.reltime)
1447 if (num_time_formats > 1)
14251448 return 1;
14261449
14271450 if (argc)
14361459 TOPLEVEL(event, "[-t|-r] [-f]", 0, 0, CIB_NONE, print_events,
14371460 "Monitor events from the kernel.\n"
14381461 "-t - print timestamp\n"
1462 "-T - print absolute, human-readable timestamp\n"
14391463 "-r - print relative timestamp\n"
14401464 "-f - print full frame for auth/assoc etc.");
0 .TH IW 8 "7 June 2012" "iw" "Linux"
0 .TH IW 8 "22 November 2020" "iw" "Linux"
11 .SH NAME
22 iw \- show / manipulate wireless devices and their configuration
33 .SH SYNOPSIS
6262 will print the help for all matching commands.
6363
6464 .SH SEE ALSO
65 .P
6566 .BR ip (8),
6667 .BR crda (8),
6768 .BR regdbdump (8),
68 .BR regulatory.bin (5)
69
70 .BR http://wireless.kernel.org/en/users/Documentation/iw
69 .BR regulatory.bin (5).
70 .
71 .P
72 .UR https://wireless.wiki.kernel.org/en/users/Documentation/iw
73 Documentation at kernel wiki
74 .UE .
286286 int *ret = arg;
287287 int ack_len = sizeof(*nlh) + sizeof(int) + sizeof(*nlh);
288288
289 *ret = err->error;
289 if (err->error > 0) {
290 /*
291 * This is illegal, per netlink(7), but not impossible (think
292 * "vendor commands"). Callers really expect negative error
293 * codes, so make that happen.
294 */
295 fprintf(stderr,
296 "ERROR: received positive netlink error code %d\n",
297 err->error);
298 *ret = -EPROTO;
299 } else {
300 *ret = err->error;
301 }
290302
291303 if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS))
292304 return NL_STOP;
180180 struct print_event_args {
181181 struct timeval ts; /* internal */
182182 bool have_ts; /* must be set false */
183 bool frame, time, reltime;
183 bool frame, time, reltime, ctime;
184184 };
185185
186186 __u32 listen_events(struct nl80211_state *state,
212212 void print_ampdu_spacing(__u8 spacing);
213213 void print_ht_capability(__u16 cap);
214214 void print_vht_info(__u32 capa, const __u8 *mcs);
215 void print_he_capability(const uint8_t *ie, int len);
215216 void print_he_info(struct nlattr *nl_iftype);
216217
217218 char *channel_width_name(enum nl80211_chan_width width);
248249
249250 #define SCHED_SCAN_OPTIONS "[interval <in_msecs> | scan_plans [<interval_secs:iterations>*] <interval_secs>] " \
250251 "[delay <in_secs>] [freqs <freq>+] [matches [ssid <ssid>]+]] [active [ssid <ssid>]+|passive] " \
251 "[randomise[=<addr>/<mask>]]"
252 "[randomise[=<addr>/<mask>]] [coloc] [flush]"
252253 int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv);
253254
254255 DECLARE_SECTION(switch);
281281 const char *file;
282282 int err;
283283
284 if (argc < 1)
285 return HANDLER_RET_USAGE;
286
284287 file = argv[0];
285288 argc--;
286289 argv++;
1010 #include "iw.h"
1111
1212 SECTION(mesh);
13 SECTION(mesh_param);
1314
1415
1516 typedef struct _any_t {
400401
401402 for (i = 0; i < ARRAY_SIZE(_mesh_param_descrs); i++) {
402403 mdescr = &_mesh_param_descrs[i];
403 printf("%s = ", mdescr->name);
404 mdescr->nla_print_fn(mesh_params[mdescr->mesh_param_num]);
405 printf("\n");
404 if (mesh_params[mdescr->mesh_param_num]) {
405 printf("%s = ", mdescr->name);
406 mdescr->nla_print_fn(mesh_params[mdescr->mesh_param_num]);
407 printf("\n");
408 }
406409 }
407410 return NL_SKIP;
408411 }
409412
410413 /* print out the mesh parameter */
411 mdescr->nla_print_fn(mesh_params[mdescr->mesh_param_num]);
412 printf("\n");
414 if (mesh_params[mdescr->mesh_param_num]) {
415 mdescr->nla_print_fn(mesh_params[mdescr->mesh_param_num]);
416 printf("\n");
417 }
413418 return NL_SKIP;
414419 }
415420
442447 NL80211_CMD_GET_MESH_PARAMS, 0, CIB_NETDEV, get_interface_meshparam,
443448 "Retrieve mesh parameter (run command without any to see available ones).");
444449
450 static int dump_interface_meshparam(struct nl80211_state *state,
451 struct nl_msg *msg,
452 int argc, char **argv,
453 enum id_input id)
454 {
455 register_handler(print_mesh_param_handler, NULL);
456 return 0;
457 }
458
459 COMMAND(mesh_param, dump, "",
460 NL80211_CMD_GET_MESH_PARAMS, 0, CIB_NETDEV, dump_interface_meshparam,
461 "List all supported mesh parameters");
462
445463 static int join_mesh(struct nl80211_state *state,
446464 struct nl_msg *msg, int argc, char **argv,
447465 enum id_input id)
5353 size_t match_len;
5454 int ret;
5555
56 if (argc < 2)
57 return HANDLER_RET_USAGE;
58
5659 ret = sscanf(argv[0], "%x", &type);
5760 if (ret != 1) {
5861 printf("invalid frame type: %s\n", argv[0]);
9598 char **mgmt_argv;
9699 unsigned int count = 0;
97100 int err = 0;
98 int i;
99101
100102 mgmt_argv = calloc(mgmt_argc, sizeof(char*));
101103 if (!mgmt_argv)
105107 mgmt_argv[1] = "mgmt";
106108 mgmt_argv[2] = "reg";
107109
108 for (i = 3; i < argc; i += 3) {
109 if (strcmp(argv[i], "count") == 0) {
110 count = 1 + atoi(argv[i + 1]);
111 if (count < 1)
112 count = 1;
113 break;
114 }
110 if (argc < 6) {
111 err = HANDLER_RET_USAGE;
112 goto out;
113 }
115114
116 if (strcmp(argv[i], "frame") != 0) {
117 err = 1;
115 argc -= 3;
116 argv += 3;
117 while (argc >= 3) {
118 if (strcmp(argv[0], "frame") != 0) {
119 err = HANDLER_RET_USAGE;
118120 goto out;
119121 }
120122
121 mgmt_argv[3] = argv[i + 1];
122 mgmt_argv[4] = argv[i + 2];
123 mgmt_argv[3] = argv[1];
124 mgmt_argv[4] = argv[2];
125
126 argc -= 3;
127 argv += 3;
123128
124129 err = handle_cmd(state, II_NETDEV, mgmt_argc, mgmt_argv);
125130 if (err)
126131 goto out;
132 }
133
134 if (argc == 2 && strcmp(argv[0], "count") == 0) {
135 count = 1 + atoi(argv[1]);
136 if (count < 1)
137 count = 1;
138
139 argc -= 2;
140 argv += 2;
141 } else if (argc) {
142 err = HANDLER_RET_USAGE;
143 goto out;
127144 }
128145
129146 mgmt_cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
654654 * When a security association was established on an 802.1X network using
655655 * fast transition, this event should be followed by an
656656 * %NL80211_CMD_PORT_AUTHORIZED event.
657 * Following a %NL80211_CMD_ROAM event userspace can issue
658 * %NL80211_CMD_GET_SCAN in order to obtain the scan information for the
659 * new BSS the card/driver roamed to.
657660 * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
658661 * userspace that a connection was dropped by the AP or due to other
659662 * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
756759 * of any other interfaces, and other interfaces will again take
757760 * precedence when they are used.
758761 *
759 * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
762 * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface
763 * (no longer supported).
760764 *
761765 * @NL80211_CMD_SET_MULTICAST_TO_UNICAST: Configure if this AP should perform
762766 * multicast to unicast conversion. When enabled, all multicast packets
11761180 * includes the contents of the frame. %NL80211_ATTR_ACK flag is included
11771181 * if the recipient acknowledged the frame.
11781182 *
1183 * @NL80211_CMD_SET_SAR_SPECS: SAR power limitation configuration is
1184 * passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to
1185 * specify the wiphy index to be applied to.
1186 *
11791187 * @NL80211_CMD_MAX: highest used command number
11801188 * @__NL80211_CMD_AFTER_LAST: internal use
11811189 */
14051413 NL80211_CMD_UNPROT_BEACON,
14061414
14071415 NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
1416
1417 NL80211_CMD_SET_SAR_SPECS,
14081418
14091419 /* add new commands above here */
14101420
17491759 * specify just a single bitrate, which is to be used for the beacon.
17501760 * The driver must also specify support for this with the extended
17511761 * features NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
1752 * NL80211_EXT_FEATURE_BEACON_RATE_HT and
1753 * NL80211_EXT_FEATURE_BEACON_RATE_VHT.
1762 * NL80211_EXT_FEATURE_BEACON_RATE_HT,
1763 * NL80211_EXT_FEATURE_BEACON_RATE_VHT and
1764 * NL80211_EXT_FEATURE_BEACON_RATE_HE.
17541765 *
17551766 * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain
17561767 * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME.
19541965 * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire
19551966 * probe-response frame. The DA field in the 802.11 header is zero-ed out,
19561967 * to be filled by the FW.
1957 * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
1958 * this feature. Currently, only supported in mac80211 drivers.
1968 * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
1969 * this feature during association. This is a flag attribute.
1970 * Currently only supported in mac80211 drivers.
1971 * @NL80211_ATTR_DISABLE_VHT: Force VHT capable interfaces to disable
1972 * this feature during association. This is a flag attribute.
1973 * Currently only supported in mac80211 drivers.
1974 * @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable
1975 * this feature during association. This is a flag attribute.
1976 * Currently only supported in mac80211 drivers.
19591977 * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
19601978 * ATTR_HT_CAPABILITY to which attention should be paid.
19611979 * Currently, only mac80211 NICs support this feature.
20762094 * until the channel switch event.
20772095 * @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission
20782096 * must be blocked on the current channel (before the channel switch
2079 * operation).
2097 * operation). Also included in the channel switch started event if quiet
2098 * was requested by the AP.
20802099 * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
20812100 * for the time while performing a channel switch.
20822101 * @NL80211_ATTR_CNTDWN_OFFS_BEACON: An array of offsets (u16) to the channel
25262545 * override mask. Used with NL80211_ATTR_S1G_CAPABILITY in
25272546 * NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT.
25282547 *
2548 * @NL80211_ATTR_SAE_PWE: Indicates the mechanism(s) allowed for SAE PWE
2549 * derivation in WPA3-Personal networks which are using SAE authentication.
2550 * This is a u8 attribute that encapsulates one of the values from
2551 * &enum nl80211_sae_pwe_mechanism.
2552 *
2553 * @NL80211_ATTR_SAR_SPEC: SAR power limitation specification when
2554 * used with %NL80211_CMD_SET_SAR_SPECS. The message contains fields
2555 * of %nl80211_sar_attrs which specifies the sar type and related
2556 * sar specs. Sar specs contains array of %nl80211_sar_specs_attrs.
2557 *
2558 * @NL80211_ATTR_RECONNECT_REQUESTED: flag attribute, used with deauth and
2559 * disassoc events to indicate that an immediate reconnect to the AP
2560 * is desired.
2561 *
25292562 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
25302563 * @NL80211_ATTR_MAX: highest attribute number currently defined
25312564 * @__NL80211_ATTR_AFTER_LAST: internal use
30143047
30153048 NL80211_ATTR_S1G_CAPABILITY,
30163049 NL80211_ATTR_S1G_CAPABILITY_MASK,
3050
3051 NL80211_ATTR_SAE_PWE,
3052
3053 NL80211_ATTR_RECONNECT_REQUESTED,
3054
3055 NL80211_ATTR_SAR_SPEC,
3056
3057 NL80211_ATTR_DISABLE_HE,
30173058
30183059 /* add attributes here, update the policy in nl80211.c */
30193060
58955936 * @NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP: Driver/device supports
58965937 * unsolicited broadcast probe response transmission
58975938 *
5939 * @NL80211_EXT_FEATURE_BEACON_RATE_HE: Driver supports beacon rate
5940 * configuration (AP/mesh) with HE rates.
5941 *
58985942 * @NUM_NL80211_EXT_FEATURES: number of extended features.
58995943 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
59005944 */
59555999 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP,
59566000 NL80211_EXT_FEATURE_FILS_DISCOVERY,
59576001 NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
6002 NL80211_EXT_FEATURE_BEACON_RATE_HE,
59586003
59596004 /* add new features before the definition below */
59606005 NUM_NL80211_EXT_FEATURES,
62526297 * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable.
62536298 * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable.
62546299 * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable.
6300 * @NL80211_TDLS_PEER_HE: TDLS peer is HE capable.
62556301 */
62566302 enum nl80211_tdls_peer_capability {
62576303 NL80211_TDLS_PEER_HT = 1<<0,
62586304 NL80211_TDLS_PEER_VHT = 1<<1,
62596305 NL80211_TDLS_PEER_WMM = 1<<2,
6306 NL80211_TDLS_PEER_HE = 1<<3,
62606307 };
62616308
62626309 /**
71237170 NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX =
71247171 __NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST - 1
71257172 };
7173
7174 /**
7175 * enum nl80211_sae_pwe_mechanism - The mechanism(s) allowed for SAE PWE
7176 * derivation. Applicable only when WPA3-Personal SAE authentication is
7177 * used.
7178 *
7179 * @NL80211_SAE_PWE_UNSPECIFIED: not specified, used internally to indicate that
7180 * attribute is not present from userspace.
7181 * @NL80211_SAE_PWE_HUNT_AND_PECK: hunting-and-pecking loop only
7182 * @NL80211_SAE_PWE_HASH_TO_ELEMENT: hash-to-element only
7183 * @NL80211_SAE_PWE_BOTH: both hunting-and-pecking loop and hash-to-element
7184 * can be used.
7185 */
7186 enum nl80211_sae_pwe_mechanism {
7187 NL80211_SAE_PWE_UNSPECIFIED,
7188 NL80211_SAE_PWE_HUNT_AND_PECK,
7189 NL80211_SAE_PWE_HASH_TO_ELEMENT,
7190 NL80211_SAE_PWE_BOTH,
7191 };
7192
7193 /**
7194 * enum nl80211_sar_type - type of SAR specs
7195 *
7196 * @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit
7197 *
7198 */
7199 enum nl80211_sar_type {
7200 NL80211_SAR_TYPE_POWER,
7201
7202 /* add new type here */
7203
7204 /* Keep last */
7205 NUM_NL80211_SAR_TYPE,
7206 };
7207
7208 /**
7209 * enum nl80211_sar_attrs - Attributes for SAR spec
7210 *
7211 * @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type.
7212 *
7213 * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power
7214 * limit specifications. Each specification contains a set
7215 * of %nl80211_sar_specs_attrs.
7216 *
7217 * For SET operation, it contains array of %NL80211_SAR_ATTR_SPECS_POWER
7218 * and %NL80211_SAR_ATTR_SPECS_RANGE_INDEX.
7219 *
7220 * For sar_capa dump, it contains array of
7221 * %NL80211_SAR_ATTR_SPECS_START_FREQ
7222 * and %NL80211_SAR_ATTR_SPECS_END_FREQ.
7223 *
7224 * @__NL80211_SAR_ATTR_LAST: Internal
7225 * @NL80211_SAR_ATTR_MAX: highest sar attribute
7226 *
7227 * These attributes are used with %NL80211_CMD_SET_SAR_SPEC
7228 */
7229 enum nl80211_sar_attrs {
7230 __NL80211_SAR_ATTR_INVALID,
7231
7232 NL80211_SAR_ATTR_TYPE,
7233 NL80211_SAR_ATTR_SPECS,
7234
7235 __NL80211_SAR_ATTR_LAST,
7236 NL80211_SAR_ATTR_MAX = __NL80211_SAR_ATTR_LAST - 1,
7237 };
7238
7239 /**
7240 * enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs
7241 *
7242 * @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual
7243 * power limit value in units of 0.25 dBm if type is
7244 * NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm).
7245 * 0 means userspace doesn't have SAR limitation on this associated range.
7246 *
7247 * @NL80211_SAR_ATTR_SPECS_RANGE_INDEX: Required (u32) value to specify the
7248 * index of exported freq range table and the associated power limitation
7249 * is applied to this range.
7250 *
7251 * Userspace isn't required to set all the ranges advertised by WLAN driver,
7252 * and userspace can skip some certain ranges. These skipped ranges don't
7253 * have SAR limitations, and they are same as setting the
7254 * %NL80211_SAR_ATTR_SPECS_POWER to any unreasonable high value because any
7255 * value higher than regulatory allowed value just means SAR power
7256 * limitation is removed, but it's required to set at least one range.
7257 * It's not allowed to set duplicated range in one SET operation.
7258 *
7259 * Every SET operation overwrites previous SET operation.
7260 *
7261 * @NL80211_SAR_ATTR_SPECS_START_FREQ: Required (u32) value to specify the start
7262 * frequency of this range edge when registering SAR capability to wiphy.
7263 * It's not a channel center frequency. The unit is kHz.
7264 *
7265 * @NL80211_SAR_ATTR_SPECS_END_FREQ: Required (u32) value to specify the end
7266 * frequency of this range edge when registering SAR capability to wiphy.
7267 * It's not a channel center frequency. The unit is kHz.
7268 *
7269 * @__NL80211_SAR_ATTR_SPECS_LAST: Internal
7270 * @NL80211_SAR_ATTR_SPECS_MAX: highest sar specs attribute
7271 */
7272 enum nl80211_sar_specs_attrs {
7273 __NL80211_SAR_ATTR_SPECS_INVALID,
7274
7275 NL80211_SAR_ATTR_SPECS_POWER,
7276 NL80211_SAR_ATTR_SPECS_RANGE_INDEX,
7277 NL80211_SAR_ATTR_SPECS_START_FREQ,
7278 NL80211_SAR_ATTR_SPECS_END_FREQ,
7279
7280 __NL80211_SAR_ATTR_SPECS_LAST,
7281 NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1,
7282 };
7283
71267284 #endif /* __LINUX_NL80211_H */
198198 }
199199
200200 COMMAND(set, freq,
201 "<freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
201 "<freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]\n"
202202 "<control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]",
203203 NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_freq,
204204 "Set frequency/channel the hardware is using, including HT\n"
205205 "configuration.");
206206 COMMAND(set, freq,
207 "<freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
207 "<freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]\n"
208208 "<control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]",
209209 NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_freq, NULL);
210210
221221
222222 return put_chandef(msg, &chandef);
223223 }
224 COMMAND(set, channel, "<channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]",
224 COMMAND(set, channel, "<channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]",
225225 NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_chan, NULL);
226 COMMAND(set, channel, "<channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]",
226 COMMAND(set, channel, "<channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]",
227227 NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_chan, NULL);
228228
229229
7474 return 0;
7575 }
7676
77 COMMAND(get, power_save, "<param>",
77 COMMAND(get, power_save, "",
7878 NL80211_CMD_GET_POWER_SAVE, 0, CIB_NETDEV, get_power_save,
7979 "Retrieve power save state.");
201201 err = parse_random_mac_addr(msg, v[0] + 9);
202202 if (err)
203203 goto nla_put_failure;
204 } else if (!strncmp(v[0], "coloc", 5)) {
205 flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
206 } else if (!strncmp(v[0], "flush", 5)) {
207 flags |= NL80211_SCAN_FLAG_FLUSH;
204208 } else {
205209 /* this element is not for us, so
206210 * return to continue parsing.
419423 break;
420424 } else if (strcmp(argv[i], "ap-force") == 0) {
421425 flags |= NL80211_SCAN_FLAG_AP;
426 break;
427 } else if (strcmp(argv[i], "coloc") == 0) {
428 flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
422429 break;
423430 } else if (strcmp(argv[i], "duration-mandatory") == 0) {
424431 duration_mandatory = true;
507514
508515 if (have_freqs)
509516 nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
517 else
518 flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
510519 if (flags)
511520 NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, flags);
512521 if (duration)
22622271 printf("\n");
22632272 }
22642273
2274 static void print_he_capa(const uint8_t type, uint8_t len, const uint8_t *data,
2275 const struct print_ies_data *ie_buffer)
2276 {
2277 printf("\n");
2278 print_he_capability(data, len);
2279 }
2280
2281 static const struct ie_print ext_printers[] = {
2282 [35] = { "HE capabilities", print_he_capa, 21, 54, BIT(PRINT_SCAN), },
2283 };
2284
2285 static void print_extension(unsigned char len, unsigned char *ie,
2286 bool unknown, enum print_ie_type ptype)
2287 {
2288 unsigned char tag;
2289
2290 if (len < 1) {
2291 printf("\tExtension IE: <empty>\n");
2292 return;
2293 }
2294
2295 tag = ie[0];
2296 if (tag < ARRAY_SIZE(ext_printers) && ext_printers[tag].name &&
2297 ext_printers[tag].flags & BIT(ptype)) {
2298 print_ie(&ext_printers[tag], tag, len - 1, ie + 1, NULL);
2299 return;
2300 }
2301
2302 if (unknown) {
2303 int i;
2304
2305 printf("\tUnknown Extension ID (%d):", ie[0]);
2306 for (i = 1; i < len; i++)
2307 printf(" %.2x", ie[i]);
2308 printf("\n");
2309 }
2310 }
2311
22652312 void print_ies(unsigned char *ie, int ielen, bool unknown,
22662313 enum print_ie_type ptype)
22672314 {
22802327 ie[0], ie[1], ie + 2, &ie_buffer);
22812328 } else if (ie[0] == 221 /* vendor */) {
22822329 print_vendor(ie[1], ie + 2, unknown, ptype);
2330 } else if (ie[0] == 255 /* extension */) {
2331 print_extension(ie[1], ie + 2, unknown, ptype);
22832332 } else if (unknown) {
22842333 int i;
22852334
25992648 NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump,
26002649 "Dump the current scan results. If -u is specified, print unknown\n"
26012650 "data in scan results.");
2602 COMMAND(scan, trigger, "[freq <freq>*] [duration <dur>] [ies <hex as 00:11:..>] [meshid <meshid>] [lowpri,flush,ap-force,duration-mandatory] [randomise[=<addr>/<mask>]] [ssid <ssid>*|passive]",
2651 COMMAND(scan, trigger, "[freq <freq>*] [duration <dur>] [ies <hex as 00:11:..>] [meshid <meshid>] [lowpri,flush,ap-force,duration-mandatory,coloc] [randomise[=<addr>/<mask>]] [ssid <ssid>*|passive]",
26032652 NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan,
26042653 "Trigger a scan on the given frequencies with probing for the given\n"
26052654 "SSIDs (or wildcard if not given) unless passive scanning is requested.\n"
328328 [NL80211_STA_INFO_ACK_SIGNAL] = {.type = NLA_U8 },
329329 [NL80211_STA_INFO_ACK_SIGNAL_AVG] = { .type = NLA_U8 },
330330 [NL80211_STA_INFO_AIRTIME_LINK_METRIC] = { .type = NLA_U32 },
331 [NL80211_STA_INFO_CONNECTED_TO_AS] = { .type = NLA_FLAG },
332 [NL80211_STA_INFO_CONNECTED_TO_GATE] = { .type = NLA_FLAG },
331 [NL80211_STA_INFO_CONNECTED_TO_AS] = { .type = NLA_U8 },
332 [NL80211_STA_INFO_CONNECTED_TO_GATE] = { .type = NLA_U8 },
333333 };
334334 char *chain;
335335 struct timeval now;
336336 unsigned long long now_ms;
337337
338338 gettimeofday(&now, NULL);
339 now_ms = now.tv_sec * 1000;
339 now_ms = now.tv_sec * 1000ULL;
340340 now_ms += (now.tv_usec / 1000);
341341
342342 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
600600 unsigned long long assoc_at_ms;
601601
602602 clock_gettime(CLOCK_BOOTTIME, &now_ts);
603 boot_ns = now_ts.tv_sec * 1000000000;
603 boot_ns = now_ts.tv_sec * 1000000000ULL;
604604 boot_ns += now_ts.tv_nsec;
605605
606606 bt = (unsigned long long)nla_get_u64(sinfo[NL80211_STA_INFO_ASSOC_AT_BOOTTIME]);
+165
-96
util.c less more
575575 * user by giving "NOHT" instead.
576576 *
577577 * The working specifier if chan is set are:
578 * <channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]
578 * <channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]
579579 *
580580 * And if frequency is set:
581 * <freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]
581 * <freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]
582582 * <control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]
583583 *
584584 * If the mode/channel width is not given the NOHT is assumed.
618618 .width = NL80211_CHAN_WIDTH_80,
619619 .freq1_diff = 0,
620620 .chantype = -1 },
621 { .name = "160MHz",
622 .width = NL80211_CHAN_WIDTH_160,
623 .freq1_diff = 0,
624 .chantype = -1 },
621625 };
622626 const struct chanmode *chanmode_selected = NULL;
623627 unsigned int freq;
984988 printf("\t\tVHT TX highest supported: %d Mbps\n", tmp & 0x1fff);
985989 }
986990
987 void print_he_info(struct nlattr *nl_iftype)
988 {
989 struct nlattr *tb[NL80211_BAND_IFTYPE_ATTR_MAX + 1];
990 struct nlattr *tb_flags[NL80211_IFTYPE_MAX + 1];
991 char *iftypes[NUM_NL80211_IFTYPES] = {
992 "Unspec", "Adhoc", "Station", "AP", "AP/VLAN", "WDS", "Monitor",
993 "Mesh", "P2P/Client", "P2P/Go", "P2P/Device", "OCB", "NAN",
994 };
995 __u16 mac_cap[3] = { 0 };
996 __u16 phy_cap[6] = { 0 };
997 __u16 mcs_set[6] = { 0 };
998 __u8 ppet[25] = { 0 };
999 size_t len;
991 static void __print_he_capa(const __u16 *mac_cap,
992 const __u16 *phy_cap,
993 const __u16 *mcs_set, size_t mcs_len,
994 const __u8 *ppet, int ppet_len,
995 bool indent)
996 {
997 size_t mcs_used;
1000998 int i;
999 const char *pre = indent ? "\t" : "";
10011000
10021001 #define PRINT_HE_CAP(_var, _idx, _bit, _str) \
10031002 do { \
10041003 if (_var[_idx] & BIT(_bit)) \
1005 printf("\t\t\t\t" _str "\n"); \
1004 printf("%s\t\t\t" _str "\n", pre); \
10061005 } while (0)
10071006
10081007 #define PRINT_HE_CAP_MASK(_var, _idx, _shift, _mask, _str) \
10091008 do { \
10101009 if ((_var[_idx] >> _shift) & _mask) \
1011 printf("\t\t\t\t" _str ": %d\n", (_var[_idx] >> _shift) & _mask); \
1010 printf("%s\t\t\t" _str ": %d\n", pre, (_var[_idx] >> _shift) & _mask); \
10121011 } while (0)
10131012
10141013 #define PRINT_HE_MAC_CAP(...) PRINT_HE_CAP(mac_cap, __VA_ARGS__)
10171016 #define PRINT_HE_PHY_CAP0(_idx, _bit, ...) PRINT_HE_CAP(phy_cap, _idx, _bit + 8, __VA_ARGS__)
10181017 #define PRINT_HE_PHY_CAP_MASK(...) PRINT_HE_CAP_MASK(phy_cap, __VA_ARGS__)
10191018
1020 nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
1021 nla_data(nl_iftype), nla_len(nl_iftype), NULL);
1022
1023 if (!tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES])
1024 return;
1025
1026 if (nla_parse_nested(tb_flags, NL80211_IFTYPE_MAX,
1027 tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES], NULL))
1028 return;
1029
1030 printf("\t\tHE Iftypes:");
1031 for (i = 0; i < NUM_NL80211_IFTYPES; i++)
1032 if (nla_get_flag(tb_flags[i]) && iftypes[i])
1033 printf(" %s", iftypes[i]);
1034 printf("\n");
1035
1036 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]) {
1037 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]);
1038 if (len > sizeof(mac_cap))
1039 len = sizeof(mac_cap);
1040 memcpy(mac_cap,
1041 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]),
1042 len);
1043 }
1044 printf("\t\t\tHE MAC Capabilities (0x");
1019 printf("%s\t\tHE MAC Capabilities (0x", pre);
10451020 for (i = 0; i < 3; i++)
10461021 printf("%04x", mac_cap[i]);
10471022 printf("):\n");
10811056 PRINT_HE_MAC_CAP(2, 11, "UL 2x996-Tone RU");
10821057 PRINT_HE_MAC_CAP(2, 12, "OM Control UL MU Data Disable RX");
10831058
1084 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]) {
1085 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
1086
1087 if (len > sizeof(phy_cap) - 1)
1088 len = sizeof(phy_cap) - 1;
1089 memcpy(&((__u8 *)phy_cap)[1],
1090 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]),
1091 len);
1092 }
1093 printf("\t\t\tHE PHY Capabilities: (0x");
1059 printf("%s\t\tHE PHY Capabilities: (0x", pre);
10941060 for (i = 0; i < 11; i++)
10951061 printf("%02x", ((__u8 *)phy_cap)[i + 1]);
10961062 printf("):\n");
11601126 PRINT_HE_PHY_CAP(5, 4, "RX Full BW SU Using HE MU PPDU with Compression SIGB");
11611127 PRINT_HE_PHY_CAP(5, 5, "RX Full BW SU Using HE MU PPDU with Non-Compression SIGB");
11621128
1129 mcs_used = 0;
1130 for (i = 0; i < 3; i++) {
1131 __u8 phy_cap_support[] = { BIT(1) | BIT(2), BIT(3), BIT(4) };
1132 char *bw[] = { "<= 80", "160", "80+80" };
1133 int j;
1134
1135 if ((phy_cap[0] & (phy_cap_support[i] << 8)) == 0)
1136 continue;
1137
1138 /* Supports more, but overflow? Abort. */
1139 if ((i * 2 + 2) * sizeof(mcs_set[0]) >= mcs_len)
1140 return;
1141
1142 for (j = 0; j < 2; j++) {
1143 int k;
1144 printf("%s\t\tHE %s MCS and NSS set %s MHz\n", pre, j ? "TX" : "RX", bw[i]);
1145 for (k = 0; k < 8; k++) {
1146 __u16 mcs = mcs_set[(i * 2) + j];
1147 mcs >>= k * 2;
1148 mcs &= 0x3;
1149 printf("%s\t\t\t%d streams: ", pre, k + 1);
1150 if (mcs == 3)
1151 printf("not supported\n");
1152 else
1153 printf("MCS 0-%d\n", 7 + (mcs * 2));
1154 }
1155
1156 }
1157 mcs_used += 2 * sizeof(mcs_set[0]);
1158 }
1159
1160 /* Caller didn't provide ppet; infer it, if there's trailing space. */
1161 if (!ppet) {
1162 ppet = (const void *)((const __u8 *)mcs_set + mcs_used);
1163 if (mcs_used < mcs_len)
1164 ppet_len = mcs_len - mcs_used;
1165 else
1166 ppet_len = 0;
1167 }
1168
1169 if (ppet_len && (phy_cap[3] & BIT(15))) {
1170 printf("%s\t\tPPE Threshold ", pre);
1171 for (i = 0; i < ppet_len; i++)
1172 if (ppet[i])
1173 printf("0x%02x ", ppet[i]);
1174 printf("\n");
1175 }
1176 }
1177
1178 void print_he_info(struct nlattr *nl_iftype)
1179 {
1180 struct nlattr *tb[NL80211_BAND_IFTYPE_ATTR_MAX + 1];
1181 struct nlattr *tb_flags[NL80211_IFTYPE_MAX + 1];
1182 char *iftypes[NUM_NL80211_IFTYPES] = {
1183 "Unspec", "Adhoc", "Station", "AP", "AP/VLAN", "WDS", "Monitor",
1184 "Mesh", "P2P/Client", "P2P/Go", "P2P/Device", "OCB", "NAN",
1185 };
1186 __u16 mac_cap[3] = { 0 };
1187 __u16 phy_cap[6] = { 0 };
1188 __u16 mcs_set[6] = { 0 };
1189 __u8 ppet[25] = { 0 };
1190 size_t len;
1191 int i;
1192 int mcs_len = 0, ppet_len = 0;
1193
1194 nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
1195 nla_data(nl_iftype), nla_len(nl_iftype), NULL);
1196
1197 if (!tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES])
1198 return;
1199
1200 if (nla_parse_nested(tb_flags, NL80211_IFTYPE_MAX,
1201 tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES], NULL))
1202 return;
1203
1204 printf("\t\tHE Iftypes:");
1205 for (i = 0; i < NUM_NL80211_IFTYPES; i++)
1206 if (nla_get_flag(tb_flags[i]) && iftypes[i])
1207 printf(" %s", iftypes[i]);
1208 printf("\n");
1209
1210 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]) {
1211 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]);
1212 if (len > sizeof(mac_cap))
1213 len = sizeof(mac_cap);
1214 memcpy(mac_cap,
1215 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]),
1216 len);
1217 }
1218
1219 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]) {
1220 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
1221
1222 if (len > sizeof(phy_cap) - 1)
1223 len = sizeof(phy_cap) - 1;
1224 memcpy(&((__u8 *)phy_cap)[1],
1225 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]),
1226 len);
1227 }
1228
11631229 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]) {
11641230 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]);
11651231 if (len > sizeof(mcs_set))
11671233 memcpy(mcs_set,
11681234 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]),
11691235 len);
1170 }
1171
1172 for (i = 0; i < 3; i++) {
1173 __u8 phy_cap_support[] = { BIT(1) | BIT(2), BIT(3), BIT(4) };
1174 char *bw[] = { "<= 80", "160", "80+80" };
1175 int j;
1176
1177 if ((phy_cap[0] & (phy_cap_support[i] << 8)) == 0)
1178 continue;
1179
1180 for (j = 0; j < 2; j++) {
1181 int k;
1182 printf("\t\t\tHE %s MCS and NSS set %s MHz\n", j ? "TX" : "RX", bw[i]);
1183 for (k = 0; k < 8; k++) {
1184 __u16 mcs = mcs_set[(i * 2) + j];
1185 mcs >>= k * 2;
1186 mcs &= 0x3;
1187 printf("\t\t\t\t\t %d streams: ", k + 1);
1188 if (mcs == 3)
1189 printf("not supported\n");
1190 else
1191 printf("MCS 0-%d\n", 7 + (mcs * 2));
1192 }
1193
1194 }
1195 }
1196
1197 len = 0;
1236 mcs_len = len;
1237 }
1238
11981239 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]) {
11991240 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]);
12001241 if (len > sizeof(ppet))
12021243 memcpy(ppet,
12031244 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]),
12041245 len);
1205 }
1206
1207 if (len && (phy_cap[3] & BIT(15))) {
1208 size_t i;
1209
1210 printf("\t\t\tPPE Threshold ");
1211 for (i = 0; i < len; i++)
1212 if (ppet[i])
1213 printf("0x%02x ", ppet[i]);
1214 printf("\n");
1215 }
1246 ppet_len = len;
1247 }
1248
1249 __print_he_capa(mac_cap, phy_cap, mcs_set, mcs_len, ppet, ppet_len,
1250 true);
1251 }
1252
1253 void print_he_capability(const uint8_t *ie, int len)
1254 {
1255 const void *mac_cap, *phy_cap, *mcs_set;
1256 int mcs_len;
1257 int i = 0;
1258
1259 mac_cap = &ie[i];
1260 i += 6;
1261
1262 phy_cap = &ie[i];
1263 i += 11;
1264
1265 mcs_set = &ie[i];
1266 mcs_len = len - i;
1267
1268 __print_he_capa(mac_cap, phy_cap - 1, mcs_set, mcs_len, NULL, 0, false);
12161269 }
12171270
12181271 void iw_hexdump(const char *prefix, const __u8 *buf, size_t size)
12311284 int get_cf1(const struct chanmode *chanmode, unsigned long freq)
12321285 {
12331286 unsigned int cf1 = freq, j;
1234 unsigned int vht80[] = { 5180, 5260, 5500, 5580, 5660, 5745 };
1287 unsigned int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745,
1288 5955, 6035, 6115, 6195, 6275, 6355,
1289 6435, 6515, 6595, 6675, 6755, 6835,
1290 6195, 6995 };
1291 unsigned int vht160[] = { 5180, 5500 };
12351292
12361293 switch (chanmode->width) {
12371294 case NL80211_CHAN_WIDTH_80:
12381295 /* setup center_freq1 */
1239 for (j = 0; j < ARRAY_SIZE(vht80); j++) {
1240 if (freq >= vht80[j] && freq < vht80[j] + 80)
1296 for (j = 0; j < ARRAY_SIZE(bw80); j++) {
1297 if (freq >= bw80[j] && freq < bw80[j] + 80)
12411298 break;
12421299 }
12431300
1244 if (j == ARRAY_SIZE(vht80))
1301 if (j == ARRAY_SIZE(bw80))
12451302 break;
12461303
1247 cf1 = vht80[j] + 30;
1304 cf1 = bw80[j] + 30;
1305 break;
1306 case NL80211_CHAN_WIDTH_160:
1307 /* setup center_freq1 */
1308 for (j = 0; j < ARRAY_SIZE(vht160); j++) {
1309 if (freq >= vht160[j] && freq < vht160[j] + 160)
1310 break;
1311 }
1312
1313 if (j == ARRAY_SIZE(vht160))
1314 break;
1315
1316 cf1 = vht160[j] + 70;
12481317 break;
12491318 default:
12501319 cf1 = freq + chanmode->freq1_diff;