| .. | .. |
|---|
| 7 | 7 | * |
|---|
| 8 | 8 | * Copyright(c) 2014 Intel Mobile Communications GmbH |
|---|
| 9 | 9 | * Copyright(c) 2017 Intel Deutschland GmbH |
|---|
| 10 | | - * Copyright(C) 2018 Intel Corporation |
|---|
| 10 | + * Copyright(C) 2018 - 2020 Intel Corporation |
|---|
| 11 | 11 | * |
|---|
| 12 | 12 | * This program is free software; you can redistribute it and/or modify |
|---|
| 13 | 13 | * it under the terms of version 2 of the GNU General Public License as |
|---|
| .. | .. |
|---|
| 17 | 17 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 18 | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 19 | 19 | * General Public License for more details. |
|---|
| 20 | | - * |
|---|
| 21 | | - * You should have received a copy of the GNU General Public License |
|---|
| 22 | | - * along with this program. |
|---|
| 23 | 20 | * |
|---|
| 24 | 21 | * The full GNU General Public License is included in this distribution |
|---|
| 25 | 22 | * in the file called COPYING. |
|---|
| .. | .. |
|---|
| 32 | 29 | * |
|---|
| 33 | 30 | * Copyright(c) 2014 Intel Mobile Communications GmbH |
|---|
| 34 | 31 | * Copyright(c) 2017 Intel Deutschland GmbH |
|---|
| 35 | | - * Copyright(C) 2018 Intel Corporation |
|---|
| 32 | + * Copyright(C) 2018 - 2020 Intel Corporation |
|---|
| 36 | 33 | * All rights reserved. |
|---|
| 37 | 34 | * |
|---|
| 38 | 35 | * Redistribution and use in source and binary forms, with or without |
|---|
| .. | .. |
|---|
| 80 | 77 | |
|---|
| 81 | 78 | lockdep_assert_held(&mvm->mutex); |
|---|
| 82 | 79 | |
|---|
| 83 | | - for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) { |
|---|
| 80 | + for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) { |
|---|
| 84 | 81 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], |
|---|
| 85 | 82 | lockdep_is_held(&mvm->mutex)); |
|---|
| 86 | 83 | if (!sta || IS_ERR(sta) || !sta->tdls) |
|---|
| .. | .. |
|---|
| 103 | 100 | |
|---|
| 104 | 101 | lockdep_assert_held(&mvm->mutex); |
|---|
| 105 | 102 | |
|---|
| 106 | | - for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) { |
|---|
| 103 | + for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) { |
|---|
| 107 | 104 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], |
|---|
| 108 | 105 | lockdep_is_held(&mvm->mutex)); |
|---|
| 109 | 106 | if (!sta || IS_ERR(sta) || !sta->tdls) |
|---|
| .. | .. |
|---|
| 147 | 144 | |
|---|
| 148 | 145 | /* populate TDLS peer data */ |
|---|
| 149 | 146 | cnt = 0; |
|---|
| 150 | | - for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) { |
|---|
| 147 | + for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) { |
|---|
| 151 | 148 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], |
|---|
| 152 | 149 | lockdep_is_held(&mvm->mutex)); |
|---|
| 153 | 150 | if (IS_ERR_OR_NULL(sta) || !sta->tdls) |
|---|
| .. | .. |
|---|
| 208 | 205 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
|---|
| 209 | 206 | u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int; |
|---|
| 210 | 207 | |
|---|
| 211 | | - /* |
|---|
| 212 | | - * iwl_mvm_protect_session() reads directly from the device |
|---|
| 213 | | - * (the system time), so make sure it is available. |
|---|
| 214 | | - */ |
|---|
| 215 | | - if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS)) |
|---|
| 216 | | - return; |
|---|
| 217 | | - |
|---|
| 218 | | - mutex_lock(&mvm->mutex); |
|---|
| 219 | 208 | /* Protect the session to hear the TDLS setup response on the channel */ |
|---|
| 220 | | - iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true); |
|---|
| 209 | + mutex_lock(&mvm->mutex); |
|---|
| 210 | + if (fw_has_capa(&mvm->fw->ucode_capa, |
|---|
| 211 | + IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) |
|---|
| 212 | + iwl_mvm_schedule_session_protection(mvm, vif, duration, |
|---|
| 213 | + duration, true); |
|---|
| 214 | + else |
|---|
| 215 | + iwl_mvm_protect_session(mvm, vif, duration, |
|---|
| 216 | + duration, 100, true); |
|---|
| 221 | 217 | mutex_unlock(&mvm->mutex); |
|---|
| 222 | | - |
|---|
| 223 | | - iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); |
|---|
| 224 | 218 | } |
|---|
| 225 | 219 | |
|---|
| 226 | 220 | static const char * |
|---|
| .. | .. |
|---|
| 255 | 249 | |
|---|
| 256 | 250 | /* we only send requests to our switching peer - update sent time */ |
|---|
| 257 | 251 | if (state == IWL_MVM_TDLS_SW_REQ_SENT) |
|---|
| 258 | | - mvm->tdls_cs.peer.sent_timestamp = |
|---|
| 259 | | - iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); |
|---|
| 252 | + mvm->tdls_cs.peer.sent_timestamp = iwl_mvm_get_systime(mvm); |
|---|
| 260 | 253 | |
|---|
| 261 | 254 | if (state == IWL_MVM_TDLS_SW_IDLE) |
|---|
| 262 | 255 | mvm->tdls_cs.cur_sta_id = IWL_MVM_INVALID_STA; |
|---|
| .. | .. |
|---|
| 280 | 273 | return; |
|---|
| 281 | 274 | } |
|---|
| 282 | 275 | |
|---|
| 283 | | - if (WARN_ON(sta_id >= IWL_MVM_STATION_COUNT)) |
|---|
| 276 | + if (WARN_ON(sta_id >= mvm->fw->ucode_capa.num_stations)) |
|---|
| 284 | 277 | return; |
|---|
| 285 | 278 | |
|---|
| 286 | 279 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], |
|---|
| .. | .. |
|---|
| 402 | 395 | struct ieee80211_tx_info *info; |
|---|
| 403 | 396 | struct ieee80211_hdr *hdr; |
|---|
| 404 | 397 | struct iwl_tdls_channel_switch_cmd cmd = {0}; |
|---|
| 398 | + struct iwl_tdls_channel_switch_cmd_tail *tail = |
|---|
| 399 | + iwl_mvm_chan_info_cmd_tail(mvm, &cmd.ci); |
|---|
| 400 | + u16 len = sizeof(cmd) - iwl_mvm_chan_info_padding(mvm); |
|---|
| 405 | 401 | int ret; |
|---|
| 406 | 402 | |
|---|
| 407 | 403 | lockdep_assert_held(&mvm->mutex); |
|---|
| .. | .. |
|---|
| 417 | 413 | } |
|---|
| 418 | 414 | |
|---|
| 419 | 415 | cmd.switch_type = type; |
|---|
| 420 | | - cmd.timing.frame_timestamp = cpu_to_le32(timestamp); |
|---|
| 421 | | - cmd.timing.switch_time = cpu_to_le32(switch_time); |
|---|
| 422 | | - cmd.timing.switch_timeout = cpu_to_le32(switch_timeout); |
|---|
| 416 | + tail->timing.frame_timestamp = cpu_to_le32(timestamp); |
|---|
| 417 | + tail->timing.switch_time = cpu_to_le32(switch_time); |
|---|
| 418 | + tail->timing.switch_timeout = cpu_to_le32(switch_timeout); |
|---|
| 423 | 419 | |
|---|
| 424 | 420 | rcu_read_lock(); |
|---|
| 425 | 421 | sta = ieee80211_find_sta(vif, peer); |
|---|
| .. | .. |
|---|
| 451 | 447 | } |
|---|
| 452 | 448 | } |
|---|
| 453 | 449 | |
|---|
| 454 | | - if (chandef) { |
|---|
| 455 | | - cmd.ci.band = (chandef->chan->band == NL80211_BAND_2GHZ ? |
|---|
| 456 | | - PHY_BAND_24 : PHY_BAND_5); |
|---|
| 457 | | - cmd.ci.channel = chandef->chan->hw_value; |
|---|
| 458 | | - cmd.ci.width = iwl_mvm_get_channel_width(chandef); |
|---|
| 459 | | - cmd.ci.ctrl_pos = iwl_mvm_get_ctrl_pos(chandef); |
|---|
| 460 | | - } |
|---|
| 450 | + if (chandef) |
|---|
| 451 | + iwl_mvm_set_chan_info_chandef(mvm, &cmd.ci, chandef); |
|---|
| 461 | 452 | |
|---|
| 462 | 453 | /* keep quota calculation simple for now - 50% of DTIM for TDLS */ |
|---|
| 463 | | - cmd.timing.max_offchan_duration = |
|---|
| 454 | + tail->timing.max_offchan_duration = |
|---|
| 464 | 455 | cpu_to_le32(TU_TO_US(vif->bss_conf.dtim_period * |
|---|
| 465 | 456 | vif->bss_conf.beacon_int) / 2); |
|---|
| 466 | 457 | |
|---|
| 467 | 458 | /* Switch time is the first element in the switch-timing IE. */ |
|---|
| 468 | | - cmd.frame.switch_time_offset = cpu_to_le32(ch_sw_tm_ie + 2); |
|---|
| 459 | + tail->frame.switch_time_offset = cpu_to_le32(ch_sw_tm_ie + 2); |
|---|
| 469 | 460 | |
|---|
| 470 | 461 | info = IEEE80211_SKB_CB(skb); |
|---|
| 471 | 462 | hdr = (void *)skb->data; |
|---|
| .. | .. |
|---|
| 475 | 466 | ret = -EINVAL; |
|---|
| 476 | 467 | goto out; |
|---|
| 477 | 468 | } |
|---|
| 478 | | - iwl_mvm_set_tx_cmd_ccmp(info, &cmd.frame.tx_cmd); |
|---|
| 469 | + iwl_mvm_set_tx_cmd_ccmp(info, &tail->frame.tx_cmd); |
|---|
| 479 | 470 | } |
|---|
| 480 | 471 | |
|---|
| 481 | | - iwl_mvm_set_tx_cmd(mvm, skb, &cmd.frame.tx_cmd, info, |
|---|
| 472 | + iwl_mvm_set_tx_cmd(mvm, skb, &tail->frame.tx_cmd, info, |
|---|
| 482 | 473 | mvmsta->sta_id); |
|---|
| 483 | 474 | |
|---|
| 484 | | - iwl_mvm_set_tx_cmd_rate(mvm, &cmd.frame.tx_cmd, info, sta, |
|---|
| 475 | + iwl_mvm_set_tx_cmd_rate(mvm, &tail->frame.tx_cmd, info, sta, |
|---|
| 485 | 476 | hdr->frame_control); |
|---|
| 486 | 477 | rcu_read_unlock(); |
|---|
| 487 | 478 | |
|---|
| 488 | | - memcpy(cmd.frame.data, skb->data, skb->len); |
|---|
| 479 | + memcpy(tail->frame.data, skb->data, skb->len); |
|---|
| 489 | 480 | |
|---|
| 490 | | - ret = iwl_mvm_send_cmd_pdu(mvm, TDLS_CHANNEL_SWITCH_CMD, 0, |
|---|
| 491 | | - sizeof(cmd), &cmd); |
|---|
| 481 | + ret = iwl_mvm_send_cmd_pdu(mvm, TDLS_CHANNEL_SWITCH_CMD, 0, len, &cmd); |
|---|
| 492 | 482 | if (ret) { |
|---|
| 493 | 483 | IWL_ERR(mvm, "Failed to send TDLS_CHANNEL_SWITCH cmd: %d\n", |
|---|
| 494 | 484 | ret); |
|---|