Skip to content

Commit 3830a01

Browse files
AviSternlucacoelho
authored andcommitted
iwlwifi: mvm: add support for responder dynamic config command version 3
Version 3 of the dynamic config command adds support for configuring the HLTK for secure ranging with a station. Signed-off-by: Avraham Stern <[email protected]> Signed-off-by: Luca Coelho <[email protected]> Link: https://lore.kernel.org/r/iwlwifi.20200928121852.f54be85420dd.I39b498fbbbc2f6eed6ce1f77b0f59f7a72fab343@changeid Signed-off-by: Luca Coelho <[email protected]>
1 parent 1c096d8 commit 3830a01

File tree

2 files changed

+141
-8
lines changed

2 files changed

+141
-8
lines changed

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

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,54 @@ struct iwl_tof_responder_config_cmd {
321321
* data (if exists) follows, and then 0-padding again to complete a
322322
* 4-multiple long buffer.
323323
*/
324-
struct iwl_tof_responder_dyn_config_cmd {
324+
struct iwl_tof_responder_dyn_config_cmd_v2 {
325325
__le32 lci_len;
326326
__le32 civic_len;
327327
u8 lci_civic[];
328328
} __packed; /* TOF_RESPONDER_DYN_CONFIG_CMD_API_S_VER_2 */
329329

330+
#define IWL_LCI_MAX_SIZE 160
331+
#define IWL_CIVIC_MAX_SIZE 160
332+
#define HLTK_11AZ_LEN 32
333+
334+
/**
335+
* enum iwl_responder_dyn_cfg_valid_flags - valid flags for dyn_config_cmd
336+
* @IWL_RESPONDER_DYN_CFG_VALID_LCI: LCI data is valid
337+
* @IWL_RESPONDER_DYN_CFG_VALID_CIVIC: Civic data is valid
338+
* @IWL_RESPONDER_DYN_CFG_VALID_PASN_STA: the pasn_addr, HLTK and cipher fields
339+
* are valid.
340+
*/
341+
enum iwl_responder_dyn_cfg_valid_flags {
342+
IWL_RESPONDER_DYN_CFG_VALID_LCI = BIT(0),
343+
IWL_RESPONDER_DYN_CFG_VALID_CIVIC = BIT(1),
344+
IWL_RESPONDER_DYN_CFG_VALID_PASN_STA = BIT(2),
345+
};
346+
347+
/**
348+
* struct iwl_tof_responder_dyn_config_cmd - Dynamic responder settings
349+
* @cipher: The negotiated cipher. see &enum iwl_location_cipher.
350+
* @valid_flags: flags indicating which fields in the command are valid. see
351+
* &enum iwl_responder_dyn_cfg_valid_flags.
352+
* @lci_len: length of the LCI data in bytes
353+
* @civic_len: length of the Civic data in bytes
354+
* @lci_buf: the LCI buffer
355+
* @civic_buf: the Civic buffer
356+
* @hltk_buf: HLTK for secure LTF bits generation for the specified station
357+
* @addr: mac address of the station for which to use the HLTK
358+
* @reserved: for alignment
359+
*/
360+
struct iwl_tof_responder_dyn_config_cmd {
361+
u8 cipher;
362+
u8 valid_flags;
363+
u8 lci_len;
364+
u8 civic_len;
365+
u8 lci_buf[IWL_LCI_MAX_SIZE];
366+
u8 civic_buf[IWL_LCI_MAX_SIZE];
367+
u8 hltk_buf[HLTK_11AZ_LEN];
368+
u8 addr[ETH_ALEN];
369+
u8 reserved[2];
370+
} __packed; /* TOF_RESPONDER_DYN_CONFIG_CMD_API_S_VER_3 */
371+
330372
/**
331373
* struct iwl_tof_range_req_ext_cmd - extended range req for WLS
332374
* @tsf_timer_offset_msec: the recommended time offset (mSec) from the AP's TSF
@@ -507,7 +549,6 @@ enum iwl_location_bw {
507549
IWL_LOCATION_BW_80MHZ,
508550
};
509551

510-
#define HLTK_11AZ_LEN 32
511552
#define TK_11AZ_LEN 32
512553

513554
#define LOCATION_BW_POS 4

drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ struct iwl_mvm_pasn_sta {
6868
u8 addr[ETH_ALEN];
6969
};
7070

71+
struct iwl_mvm_pasn_hltk_data {
72+
u8 *addr;
73+
u8 cipher;
74+
u8 *hltk;
75+
};
76+
7177
static int iwl_mvm_ftm_responder_set_bw_v1(struct cfg80211_chan_def *chandef,
7278
u8 *bw, u8 *ctrl_ch_position)
7379
{
@@ -143,8 +149,7 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
143149
.sta_id = mvmvif->bcast_sta.sta_id,
144150
};
145151
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LOCATION_GROUP,
146-
TOF_RESPONDER_CONFIG_CMD,
147-
IWL_FW_CMD_VER_UNKNOWN);
152+
TOF_RESPONDER_CONFIG_CMD, 6);
148153
int err;
149154

150155
lockdep_assert_held(&mvm->mutex);
@@ -169,11 +174,11 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
169174
}
170175

171176
static int
172-
iwl_mvm_ftm_responder_dyn_cfg_cmd(struct iwl_mvm *mvm,
173-
struct ieee80211_vif *vif,
174-
struct ieee80211_ftm_responder_params *params)
177+
iwl_mvm_ftm_responder_dyn_cfg_v2(struct iwl_mvm *mvm,
178+
struct ieee80211_vif *vif,
179+
struct ieee80211_ftm_responder_params *params)
175180
{
176-
struct iwl_tof_responder_dyn_config_cmd cmd = {
181+
struct iwl_tof_responder_dyn_config_cmd_v2 cmd = {
177182
.lci_len = cpu_to_le32(params->lci_len + 2),
178183
.civic_len = cpu_to_le32(params->civicloc_len + 2),
179184
};
@@ -214,6 +219,93 @@ iwl_mvm_ftm_responder_dyn_cfg_cmd(struct iwl_mvm *mvm,
214219
return iwl_mvm_send_cmd(mvm, &hcmd);
215220
}
216221

222+
static int
223+
iwl_mvm_ftm_responder_dyn_cfg_v3(struct iwl_mvm *mvm,
224+
struct ieee80211_vif *vif,
225+
struct ieee80211_ftm_responder_params *params,
226+
struct iwl_mvm_pasn_hltk_data *hltk_data)
227+
{
228+
struct iwl_tof_responder_dyn_config_cmd cmd;
229+
struct iwl_host_cmd hcmd = {
230+
.id = iwl_cmd_id(TOF_RESPONDER_DYN_CONFIG_CMD,
231+
LOCATION_GROUP, 0),
232+
.data[0] = &cmd,
233+
.len[0] = sizeof(cmd),
234+
/* may not be able to DMA from stack */
235+
.dataflags[0] = IWL_HCMD_DFL_DUP,
236+
};
237+
238+
lockdep_assert_held(&mvm->mutex);
239+
240+
cmd.valid_flags = 0;
241+
242+
if (params) {
243+
if (params->lci_len + 2 > sizeof(cmd.lci_buf) ||
244+
params->civicloc_len + 2 > sizeof(cmd.civic_buf)) {
245+
IWL_ERR(mvm,
246+
"LCI/civic data too big (lci=%zd, civic=%zd)\n",
247+
params->lci_len, params->civicloc_len);
248+
return -ENOBUFS;
249+
}
250+
251+
cmd.lci_buf[0] = WLAN_EID_MEASURE_REPORT;
252+
cmd.lci_buf[1] = params->lci_len;
253+
memcpy(cmd.lci_buf + 2, params->lci, params->lci_len);
254+
cmd.lci_len = params->lci_len + 2;
255+
256+
cmd.civic_buf[0] = WLAN_EID_MEASURE_REPORT;
257+
cmd.civic_buf[1] = params->civicloc_len;
258+
memcpy(cmd.civic_buf + 2, params->civicloc,
259+
params->civicloc_len);
260+
cmd.civic_len = params->civicloc_len + 2;
261+
262+
cmd.valid_flags |= IWL_RESPONDER_DYN_CFG_VALID_LCI |
263+
IWL_RESPONDER_DYN_CFG_VALID_CIVIC;
264+
}
265+
266+
if (hltk_data) {
267+
if (hltk_data->cipher > IWL_LOCATION_CIPHER_GCMP_256) {
268+
IWL_ERR(mvm, "invalid cipher: %u\n",
269+
hltk_data->cipher);
270+
return -EINVAL;
271+
}
272+
273+
cmd.cipher = hltk_data->cipher;
274+
memcpy(cmd.addr, hltk_data->addr, sizeof(cmd.addr));
275+
memcpy(cmd.hltk_buf, hltk_data->hltk, sizeof(cmd.hltk_buf));
276+
cmd.valid_flags |= IWL_RESPONDER_DYN_CFG_VALID_PASN_STA;
277+
}
278+
279+
return iwl_mvm_send_cmd(mvm, &hcmd);
280+
}
281+
282+
static int
283+
iwl_mvm_ftm_responder_dyn_cfg_cmd(struct iwl_mvm *mvm,
284+
struct ieee80211_vif *vif,
285+
struct ieee80211_ftm_responder_params *params)
286+
{
287+
int ret;
288+
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LOCATION_GROUP,
289+
TOF_RESPONDER_DYN_CONFIG_CMD, 2);
290+
291+
switch (cmd_ver) {
292+
case 2:
293+
ret = iwl_mvm_ftm_responder_dyn_cfg_v2(mvm, vif,
294+
params);
295+
break;
296+
case 3:
297+
ret = iwl_mvm_ftm_responder_dyn_cfg_v3(mvm, vif,
298+
params, NULL);
299+
break;
300+
default:
301+
IWL_ERR(mvm, "Unsupported DYN_CONFIG_CMD version %u\n",
302+
cmd_ver);
303+
ret = -ENOTSUPP;
304+
}
305+
306+
return ret;
307+
}
308+
217309
int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm,
218310
struct ieee80211_vif *vif,
219311
u8 *addr, u32 cipher, u8 *tk, u32 tk_len,

0 commit comments

Comments
 (0)