History

wifi: cfg80211: add NTB continuous ranging and FTM request type support

Enable NTB continuous ranging with configurable timing and measurement parameters as per the Wi-Fi Alliance specification "Proximity Ranging (PR) Implementation Consideration Draft 1.9 Rev 1, section 5.3". Add new FTM request attributes for min/max time between measurements, nominal time (mandatory for NTB), AW duration, and total measurement count. Add NL80211_PMSR_PEER_ATTR_REQ_TYPE attribute using the new nl80211_peer_measurement_ftm_req_type enum to allow userspace to specify the ranging request type per peer: - NL80211_PMSR_FTM_REQ_TYPE_INFRA: STA-to-AP or AP-to-STA ranging (default if attribute is absent) - NL80211_PMSR_FTM_REQ_TYPE_PD: peer-to-peer ranging Validate the request type against the device TYPE_CAPS capabilities advertised via NL80211_PMSR_FTM_CAPA_ATTR_TYPE_CAPS. Reject PD requests if the device does not advertise PD support. Reject PD requests that set trigger-based ranging, as TB ranging is not compatible with peer-to-peer proximity detection. Add ftms_per_burst limit of 4 for PD NTB ranging requests.

Peddolla Harshavardhan Reddy committed 6 months ago

Commit 8823a9b1 parent 18709c64 files · +163 −6Browse files

Unified · Split

4 files
  1. include/net/cfg80211.h +34 −1
  2. include/uapi/linux/nl80211.h +60 −2
  3. net/wireless/nl80211.c +11 −0
  4. net/wireless/pmsr.c +58 −3
include/net/cfg80211.h+34−1
@@ -4527,7 +4527,8 @@ struct cfg80211_pmsr_result { · 4526 unmodified lines
4527 * @burst_duration: burst duration. If @trigger_based or @non_trigger_based is4527 * @burst_duration: burst duration. If @trigger_based or @non_trigger_based is
4528 * set, this is the burst duration in milliseconds, and zero means the4528 * set, this is the burst duration in milliseconds, and zero means the
4529 * device should pick an appropriate value based on @ftms_per_burst.4529 * device should pick an appropriate value based on @ftms_per_burst.
4530 * @ftms_per_burst: number of FTMs per burst4530 * @ftms_per_burst: number of FTMs per burst. If set to 0, the firmware or
4531 * driver can automatically select an appropriate value.
4531 * @ftmr_retries: number of retries for FTM request4532 * @ftmr_retries: number of retries for FTM request
4532 * @request_lci: request LCI information4533 * @request_lci: request LCI information
4533 * @request_civicloc: request civic location information4534 * @request_civicloc: request civic location information
@@ -4544,6 +4545,31 @@ struct cfg80211_pmsr_result { · 10 unmodified lines
4544 * @bss_color: the bss color of the responder. Optional. Set to zero to4545 * @bss_color: the bss color of the responder. Optional. Set to zero to
4545 * indicate the driver should set the BSS color. Only valid if4546 * indicate the driver should set the BSS color. Only valid if
4546 * @non_trigger_based or @trigger_based is set.4547 * @non_trigger_based or @trigger_based is set.
4548 * @request_type: ranging request type, one of
4549 * &enum nl80211_peer_measurement_ftm_req_type. Defaults to
4550 * %NL80211_PMSR_FTM_REQ_TYPE_INFRA if not specified.
4551 * @min_time_between_measurements: minimum time between two consecutive range
4552 * measurements in units of 100 microseconds, for non-trigger based
4553 * ranging. Should be set as short as possible to minimize turnaround
4554 * time, since two-way ranging with delayed LMR requires two measurements.
4555 * Only valid if @non_trigger_based is set.
4556 * @max_time_between_measurements: maximum time between two consecutive range
4557 * measurements in units of 10 milliseconds, for non-trigger based
4558 * ranging. Acts as a session timeout; if exceeded, the ranging session
4559 * should be terminated. Only valid if @non_trigger_based is set.
4560 * @availability_window: duration of the availability window (AW) in units of
4561 * 1 millisecond (0-255 ms). Only valid if @non_trigger_based is set.
4562 * If set to 0, the firmware or driver can automatically select an
4563 * appropriate value.
4564 * @nominal_time: Nominal duration between adjacent availability windows
4565 * in units of milli seconds. Only valid if @non_trigger_based is set.
4566 * If set to 0, the firmware or driver can automatically select an
4567 * appropriate value.
4568 * @num_measurements: number of Availability Windows (AWs) to schedule
4569 * for non-trigger-based ranging. Each AW may contain multiple FTM
4570 * exchanges as configured by @ftms_per_burst. Only valid if
4571 * @non_trigger_based is set. If set to 0, the firmware or driver
4572 * can automatically select an appropriate value.
4547 *4573 *
4548 * See also nl80211 for the respective attribute documentation.4574 * See also nl80211 for the respective attribute documentation.
4549 */4575 */
@@ -4563,6 +4589,13 @@ struct cfg80211_pmsr_ftm_request_peer { · 13 unmodified lines
4563 u8 ftms_per_burst;4589 u8 ftms_per_burst;
4564 u8 ftmr_retries;4590 u8 ftmr_retries;
4565 u8 bss_color;4591 u8 bss_color;
4592
4593 u32 request_type;
4594 u32 min_time_between_measurements;
4595 u32 max_time_between_measurements;
4596 u8 availability_window;
4597 u32 nominal_time;
4598 u32 num_measurements;
4566};4599};
4567 4600
4568/**4601/**
include/uapi/linux/nl80211.h+60−2
@@ -7991,6 +7991,26 @@ enum nl80211_peer_measurement_resp { · 7990 unmodified lines
7991 NL80211_PMSR_RESP_ATTR_MAX = NUM_NL80211_PMSR_RESP_ATTRS - 17991 NL80211_PMSR_RESP_ATTR_MAX = NUM_NL80211_PMSR_RESP_ATTRS - 1
7992};7992};
7993 7993
7994/**
7995 * enum nl80211_peer_measurement_ftm_req_type - FTM ranging request type,
7996 * used with %NL80211_PMSR_PEER_ATTR_REQ_TYPE
7997 *
7998 * @NL80211_PMSR_FTM_REQ_TYPE_INFRA: infrastructure ranging, i.e. STA-to-AP
7999 * @NL80211_PMSR_FTM_REQ_TYPE_PD: peer-to-peer ranging as defined in the
8000 * Wi-Fi Alliance specification "Proximity Ranging (PR) Implementation
8001 * Consideration Draft 1.9 Rev 1"
8002 * @NUM_NL80211_PMSR_FTM_REQ_TYPE: internal
8003 * @NL80211_PMSR_FTM_REQ_TYPE_MAX: highest request type value
8004 */
8005enum nl80211_peer_measurement_ftm_req_type {
8006 NL80211_PMSR_FTM_REQ_TYPE_INFRA,
8007 NL80211_PMSR_FTM_REQ_TYPE_PD,
8008
8009 /* keep last */
8010 NUM_NL80211_PMSR_FTM_REQ_TYPE,
8011 NL80211_PMSR_FTM_REQ_TYPE_MAX = NUM_NL80211_PMSR_FTM_REQ_TYPE - 1
8012};
8013
7994/**8014/**
7995 * enum nl80211_peer_measurement_peer_attrs - peer attributes for measurement8015 * enum nl80211_peer_measurement_peer_attrs - peer attributes for measurement
7996 * @__NL80211_PMSR_PEER_ATTR_INVALID: invalid8016 * @__NL80211_PMSR_PEER_ATTR_INVALID: invalid
@@ -8004,6 +8024,9 @@ enum nl80211_peer_measurement_resp { · 7 unmodified lines
8004 * @NL80211_PMSR_PEER_ATTR_RESP: This is a nested attribute indexed by8024 * @NL80211_PMSR_PEER_ATTR_RESP: This is a nested attribute indexed by
8005 * measurement type, with attributes from the8025 * measurement type, with attributes from the
8006 * &enum nl80211_peer_measurement_resp inside.8026 * &enum nl80211_peer_measurement_resp inside.
8027 * @NL80211_PMSR_PEER_ATTR_REQ_TYPE: u32 attribute specifying the ranging
8028 * request type, using values from &enum nl80211_peer_measurement_ftm_req_type.
8029 * If absent, defaults to %NL80211_PMSR_FTM_REQ_TYPE_INFRA.
8007 *8030 *
8008 * @NUM_NL80211_PMSR_PEER_ATTRS: internal8031 * @NUM_NL80211_PMSR_PEER_ATTRS: internal
8009 * @NL80211_PMSR_PEER_ATTR_MAX: highest attribute number8032 * @NL80211_PMSR_PEER_ATTR_MAX: highest attribute number
@@ -8015,6 +8038,7 @@ enum nl80211_peer_measurement_peer_attrs { · 5 unmodified lines
8015 NL80211_PMSR_PEER_ATTR_CHAN,8038 NL80211_PMSR_PEER_ATTR_CHAN,
8016 NL80211_PMSR_PEER_ATTR_REQ,8039 NL80211_PMSR_PEER_ATTR_REQ,
8017 NL80211_PMSR_PEER_ATTR_RESP,8040 NL80211_PMSR_PEER_ATTR_RESP,
8041 NL80211_PMSR_PEER_ATTR_REQ_TYPE,
8018 8042
8019 /* keep last */8043 /* keep last */
8020 NUM_NL80211_PMSR_PEER_ATTRS,8044 NUM_NL80211_PMSR_PEER_ATTRS,
@@ -8238,9 +8262,11 @@ enum nl80211_peer_measurement_ftm_type_capa { · 217 unmodified lines
8238 * default 15 i.e. "no preference"). For non-EDCA ranging, this is the8262 * default 15 i.e. "no preference"). For non-EDCA ranging, this is the
8239 * burst duration in milliseconds (optional with default 0, i.e. let the8263 * burst duration in milliseconds (optional with default 0, i.e. let the
8240 * device decide).8264 * device decide).
8241 * @NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST: number of successful FTM frames8265 * @NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST: (Optional) number of successful
8242 * requested per burst8266 * FTM frames requested per burst
8243 * (u8, 0-31, optional with default 0 i.e. "no preference")8267 * (u8, 0-31, optional with default 0 i.e. "no preference")
8268 * If the attribute is absent ("no preference"), the driver or firmware can
8269 * choose a suitable value.
8244 * @NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES: number of FTMR frame retries8270 * @NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES: number of FTMR frame retries
8245 * (u8, default 3)8271 * (u8, default 3)
8246 * @NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI: request LCI data (flag)8272 * @NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI: request LCI data (flag)
@@ -8274,6 +8300,33 @@ enum nl80211_peer_measurement_ftm_type_capa { · 27 unmodified lines
8274 * Only valid if %NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK is set (so the8300 * Only valid if %NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK is set (so the
8275 * RSTA will have the measurement results to report back in the FTM8301 * RSTA will have the measurement results to report back in the FTM
8276 * response).8302 * response).
8303 * @NL80211_PMSR_FTM_REQ_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS: minimum time
8304 * between two consecutive range measurements in units of 100 microseconds,
8305 * for non-trigger based ranging (u32). Should be set as short as possible
8306 * to minimize turnaround time, since two-way ranging with delayed LMR
8307 * requires two measurements. Only valid if
8308 * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set.
8309 * @NL80211_PMSR_FTM_REQ_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS: maximum time
8310 * between two consecutive range measurements in units of 10 milliseconds,
8311 * for non-trigger based ranging (u32). Acts as a session timeout; if
8312 * exceeded, the ranging session should be terminated. Only valid if
8313 * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set.
8314 * @NL80211_PMSR_FTM_REQ_ATTR_NOMINAL_TIME: The nominal time field shall be
8315 * set to the nominal duration between adjacent Availability Windows in
8316 * units of milli seconds (u32). Mandatory if
8317 * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set.
8318 * @NL80211_PMSR_FTM_REQ_ATTR_AW_DURATION: (Optional) The AW duration field
8319 * shall be set to the duration of the AW in units of 1ms (0-255 ms) (u32).
8320 * Only valid if %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set.
8321 * If the attribute is absent ("no preference"), the driver or firmware
8322 * can choose a suitable value.
8323 * @NL80211_PMSR_FTM_REQ_ATTR_NUM_MEASUREMENTS: (Optional) number of
8324 * Availability Windows (AWs) to schedule for non-trigger-based ranging.
8325 * Each AW may contain multiple FTM exchanges as configured by
8326 * %NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST. Only valid if
8327 * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set.
8328 * If the attribute is absent ("no preference"), the driver or firmware
8329 * can choose a suitable value.
8277 *8330 *
8278 * @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal8331 * @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal
8279 * @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number8332 * @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number
@@ -8295,6 +8348,11 @@ enum nl80211_peer_measurement_ftm_req { · 15 unmodified lines
8295 NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK,8348 NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK,
8296 NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR,8349 NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR,
8297 NL80211_PMSR_FTM_REQ_ATTR_RSTA,8350 NL80211_PMSR_FTM_REQ_ATTR_RSTA,
8351 NL80211_PMSR_FTM_REQ_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS,
8352 NL80211_PMSR_FTM_REQ_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS,
8353 NL80211_PMSR_FTM_REQ_ATTR_NOMINAL_TIME,
8354 NL80211_PMSR_FTM_REQ_ATTR_AW_DURATION,
8355 NL80211_PMSR_FTM_REQ_ATTR_NUM_MEASUREMENTS,
8298 8356
8299 /* keep last */8357 /* keep last */
8300 NUM_NL80211_PMSR_FTM_REQ_ATTR,8358 NUM_NL80211_PMSR_FTM_REQ_ATTR,
net/wireless/nl80211.c+11−0
@@ -476,6 +476,15 @@ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = { · 475 unmodified lines
476 [NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK] = { .type = NLA_FLAG },476 [NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK] = { .type = NLA_FLAG },
477 [NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR] = { .type = NLA_U8 },477 [NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR] = { .type = NLA_U8 },
478 [NL80211_PMSR_FTM_REQ_ATTR_RSTA] = { .type = NLA_FLAG },478 [NL80211_PMSR_FTM_REQ_ATTR_RSTA] = { .type = NLA_FLAG },
479 [NL80211_PMSR_FTM_REQ_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS] = {
480 .type = NLA_U32
481 },
482 [NL80211_PMSR_FTM_REQ_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS] = {
483 .type = NLA_U32
484 },
485 [NL80211_PMSR_FTM_REQ_ATTR_NOMINAL_TIME] = { .type = NLA_U32 },
486 [NL80211_PMSR_FTM_REQ_ATTR_AW_DURATION] = NLA_POLICY_MAX(NLA_U32, 255),
487 [NL80211_PMSR_FTM_REQ_ATTR_NUM_MEASUREMENTS] = { .type = NLA_U32 },
479};488};
480 489
481static const struct nla_policy490static const struct nla_policy
@@ -498,6 +507,8 @@ nl80211_pmsr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = { · 16 unmodified lines
498 [NL80211_PMSR_PEER_ATTR_REQ] =507 [NL80211_PMSR_PEER_ATTR_REQ] =
499 NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),508 NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),
500 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },509 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
510 [NL80211_PMSR_PEER_ATTR_REQ_TYPE] =
511 NLA_POLICY_MAX(NLA_U32, NL80211_PMSR_FTM_REQ_TYPE_MAX),
501};512};
502 513
503static const struct nla_policy514static const struct nla_policy
net/wireless/pmsr.c+58−3
@@ -91,11 +91,10 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, · 90 unmodified lines
91 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]);91 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]);
92 92
93 if (capa->ftm.max_ftms_per_burst &&93 if (capa->ftm.max_ftms_per_burst &&
94 (out->ftm.ftms_per_burst > capa->ftm.max_ftms_per_burst ||94 out->ftm.ftms_per_burst > capa->ftm.max_ftms_per_burst) {
95 out->ftm.ftms_per_burst == 0)) {
96 NL_SET_ERR_MSG_ATTR(info->extack,95 NL_SET_ERR_MSG_ATTR(info->extack,
97 tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST],96 tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST],
98 "FTM: FTMs per burst must be set lower than the device limit but non-zero");97 "FTM: FTMs per burst must be set lower than the device limit");
99 return -EINVAL;98 return -EINVAL;
100 }99 }
101 100
@@ -128,6 +127,14 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, · 26 unmodified lines
128 return -EINVAL;127 return -EINVAL;
129 }128 }
130 129
130 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD &&
131 out->ftm.trigger_based) {
132 NL_SET_ERR_MSG_ATTR(info->extack,
133 ftmreq,
134 "FTM: TB ranging is not supported for PD request type");
135 return -EINVAL;
136 }
137
131 out->ftm.non_trigger_based =138 out->ftm.non_trigger_based =
132 !!tb[NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED];139 !!tb[NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED];
133 if (out->ftm.non_trigger_based && !capa->ftm.non_trigger_based) {140 if (out->ftm.non_trigger_based && !capa->ftm.non_trigger_based) {
@@ -143,6 +150,14 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, · 9 unmodified lines
143 return -EINVAL;150 return -EINVAL;
144 }151 }
145 152
153 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD &&
154 out->ftm.non_trigger_based && out->ftm.ftms_per_burst > 4) {
155 NL_SET_ERR_MSG_ATTR(info->extack,
156 tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST],
157 "FTM: FTMs per burst must not exceed 4 for PD NTB ranging");
158 return -ERANGE;
159 }
160
146 if (out->ftm.ftms_per_burst > 31 && !out->ftm.non_trigger_based &&161 if (out->ftm.ftms_per_burst > 31 && !out->ftm.non_trigger_based &&
147 !out->ftm.trigger_based) {162 !out->ftm.trigger_based) {
148 NL_SET_ERR_MSG_ATTR(info->extack,163 NL_SET_ERR_MSG_ATTR(info->extack,
@@ -222,6 +237,33 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, · 73 unmodified lines
222 return -EINVAL;237 return -EINVAL;
223 }238 }
224 239
240 if (out->ftm.non_trigger_based) {
241 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD &&
242 !tb[NL80211_PMSR_FTM_REQ_ATTR_NOMINAL_TIME]) {
243 NL_SET_ERR_MSG(info->extack,
244 "FTM: nominal time is required for PD NTB ranging");
245 return -EINVAL;
246 }
247 out->ftm.nominal_time =
248 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NOMINAL_TIME]);
249
250 if (tb[NL80211_PMSR_FTM_REQ_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS])
251 out->ftm.min_time_between_measurements =
252 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS]);
253
254 if (tb[NL80211_PMSR_FTM_REQ_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS])
255 out->ftm.max_time_between_measurements =
256 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS]);
257
258 if (tb[NL80211_PMSR_FTM_REQ_ATTR_AW_DURATION])
259 out->ftm.availability_window =
260 nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_AW_DURATION]);
261
262 if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_MEASUREMENTS])
263 out->ftm.num_measurements =
264 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_MEASUREMENTS]);
265 }
266
225 return 0;267 return 0;
226}268}
227 269
@@ -249,6 +291,19 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev, · 21 unmodified lines
249 291
250 memcpy(out->addr, nla_data(tb[NL80211_PMSR_PEER_ATTR_ADDR]), ETH_ALEN);292 memcpy(out->addr, nla_data(tb[NL80211_PMSR_PEER_ATTR_ADDR]), ETH_ALEN);
251 293
294 if (tb[NL80211_PMSR_PEER_ATTR_REQ_TYPE])
295 out->ftm.request_type =
296 nla_get_u32(tb[NL80211_PMSR_PEER_ATTR_REQ_TYPE]);
297 else
298 out->ftm.request_type = NL80211_PMSR_FTM_REQ_TYPE_INFRA;
299
300 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD &&
301 !rdev->wiphy.pmsr_capa->ftm.type.pd_support) {
302 NL_SET_ERR_MSG_ATTR(info->extack,
303 tb[NL80211_PMSR_PEER_ATTR_REQ_TYPE],
304 "FTM: PD request type not supported by device");
305 return -EINVAL;
306 }
252 /* reuse info->attrs */307 /* reuse info->attrs */
253 memset(info->attrs, 0, sizeof(*info->attrs) * (NL80211_ATTR_MAX + 1));308 memset(info->attrs, 0, sizeof(*info->attrs) * (NL80211_ATTR_MAX + 1));
254 err = nla_parse_nested_deprecated(info->attrs, NL80211_ATTR_MAX,309 err = nla_parse_nested_deprecated(info->attrs, NL80211_ATTR_MAX,