1e705c121SKalle Valo /****************************************************************************** 2e705c121SKalle Valo * 3e705c121SKalle Valo * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 4e705c121SKalle Valo * 5e705c121SKalle Valo * Portions of this file are derived from the ipw3945 project, as well 6e705c121SKalle Valo * as portions of the ieee80211 subsystem header files. 7e705c121SKalle Valo * 8e705c121SKalle Valo * This program is free software; you can redistribute it and/or modify it 9e705c121SKalle Valo * under the terms of version 2 of the GNU General Public License as 10e705c121SKalle Valo * published by the Free Software Foundation. 11e705c121SKalle Valo * 12e705c121SKalle Valo * This program is distributed in the hope that it will be useful, but WITHOUT 13e705c121SKalle Valo * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14e705c121SKalle Valo * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15e705c121SKalle Valo * more details. 16e705c121SKalle Valo * 17e705c121SKalle Valo * You should have received a copy of the GNU General Public License along with 18e705c121SKalle Valo * this program; if not, write to the Free Software Foundation, Inc., 19e705c121SKalle Valo * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 20e705c121SKalle Valo * 21e705c121SKalle Valo * The full GNU General Public License is included in this distribution in the 22e705c121SKalle Valo * file called LICENSE. 23e705c121SKalle Valo * 24e705c121SKalle Valo * Contact Information: 25e705c121SKalle Valo * Intel Linux Wireless <ilw@linux.intel.com> 26e705c121SKalle Valo * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 27e705c121SKalle Valo * 28e705c121SKalle Valo *****************************************************************************/ 29e705c121SKalle Valo #include <linux/etherdevice.h> 30e705c121SKalle Valo #include <net/mac80211.h> 31e705c121SKalle Valo #include "iwl-trans.h" 32e705c121SKalle Valo #include "dev.h" 33e705c121SKalle Valo #include "agn.h" 34e705c121SKalle Valo 35e705c121SKalle Valo const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 36e705c121SKalle Valo 37e705c121SKalle Valo static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) 38e705c121SKalle Valo { 39e705c121SKalle Valo lockdep_assert_held(&priv->sta_lock); 40e705c121SKalle Valo 41e705c121SKalle Valo if (sta_id >= IWLAGN_STATION_COUNT) { 42e705c121SKalle Valo IWL_ERR(priv, "invalid sta_id %u\n", sta_id); 43e705c121SKalle Valo return -EINVAL; 44e705c121SKalle Valo } 45e705c121SKalle Valo if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) 46e705c121SKalle Valo IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u " 47e705c121SKalle Valo "addr %pM\n", 48e705c121SKalle Valo sta_id, priv->stations[sta_id].sta.sta.addr); 49e705c121SKalle Valo 50e705c121SKalle Valo if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) { 51e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, 52e705c121SKalle Valo "STA id %u addr %pM already present in uCode " 53e705c121SKalle Valo "(according to driver)\n", 54e705c121SKalle Valo sta_id, priv->stations[sta_id].sta.sta.addr); 55e705c121SKalle Valo } else { 56e705c121SKalle Valo priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE; 57e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n", 58e705c121SKalle Valo sta_id, priv->stations[sta_id].sta.sta.addr); 59e705c121SKalle Valo } 60e705c121SKalle Valo return 0; 61e705c121SKalle Valo } 62e705c121SKalle Valo 63e705c121SKalle Valo static void iwl_process_add_sta_resp(struct iwl_priv *priv, 64e705c121SKalle Valo struct iwl_rx_packet *pkt) 65e705c121SKalle Valo { 66e705c121SKalle Valo struct iwl_add_sta_resp *add_sta_resp = (void *)pkt->data; 67e705c121SKalle Valo 68e705c121SKalle Valo IWL_DEBUG_INFO(priv, "Processing response for adding station\n"); 69e705c121SKalle Valo 70e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 71e705c121SKalle Valo 72e705c121SKalle Valo switch (add_sta_resp->status) { 73e705c121SKalle Valo case ADD_STA_SUCCESS_MSK: 74e705c121SKalle Valo IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); 75e705c121SKalle Valo break; 76e705c121SKalle Valo case ADD_STA_NO_ROOM_IN_TABLE: 77e705c121SKalle Valo IWL_ERR(priv, "Adding station failed, no room in table.\n"); 78e705c121SKalle Valo break; 79e705c121SKalle Valo case ADD_STA_NO_BLOCK_ACK_RESOURCE: 80e705c121SKalle Valo IWL_ERR(priv, 81e705c121SKalle Valo "Adding station failed, no block ack resource.\n"); 82e705c121SKalle Valo break; 83e705c121SKalle Valo case ADD_STA_MODIFY_NON_EXIST_STA: 84e705c121SKalle Valo IWL_ERR(priv, "Attempting to modify non-existing station\n"); 85e705c121SKalle Valo break; 86e705c121SKalle Valo default: 87e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", 88e705c121SKalle Valo add_sta_resp->status); 89e705c121SKalle Valo break; 90e705c121SKalle Valo } 91e705c121SKalle Valo 92e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 93e705c121SKalle Valo } 94e705c121SKalle Valo 95e705c121SKalle Valo void iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb) 96e705c121SKalle Valo { 97e705c121SKalle Valo struct iwl_rx_packet *pkt = rxb_addr(rxb); 98e705c121SKalle Valo 99e705c121SKalle Valo iwl_process_add_sta_resp(priv, pkt); 100e705c121SKalle Valo } 101e705c121SKalle Valo 102e705c121SKalle Valo int iwl_send_add_sta(struct iwl_priv *priv, 103e705c121SKalle Valo struct iwl_addsta_cmd *sta, u8 flags) 104e705c121SKalle Valo { 105e705c121SKalle Valo int ret = 0; 106e705c121SKalle Valo struct iwl_host_cmd cmd = { 107e705c121SKalle Valo .id = REPLY_ADD_STA, 108e705c121SKalle Valo .flags = flags, 109e705c121SKalle Valo .data = { sta, }, 110e705c121SKalle Valo .len = { sizeof(*sta), }, 111e705c121SKalle Valo }; 112e705c121SKalle Valo u8 sta_id __maybe_unused = sta->sta.sta_id; 113e705c121SKalle Valo struct iwl_rx_packet *pkt; 114e705c121SKalle Valo struct iwl_add_sta_resp *add_sta_resp; 115e705c121SKalle Valo 116e705c121SKalle Valo IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n", 117e705c121SKalle Valo sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); 118e705c121SKalle Valo 119e705c121SKalle Valo if (!(flags & CMD_ASYNC)) { 120e705c121SKalle Valo cmd.flags |= CMD_WANT_SKB; 121e705c121SKalle Valo might_sleep(); 122e705c121SKalle Valo } 123e705c121SKalle Valo 124e705c121SKalle Valo ret = iwl_dvm_send_cmd(priv, &cmd); 125e705c121SKalle Valo 126e705c121SKalle Valo if (ret || (flags & CMD_ASYNC)) 127e705c121SKalle Valo return ret; 128e705c121SKalle Valo 129e705c121SKalle Valo pkt = cmd.resp_pkt; 130e705c121SKalle Valo add_sta_resp = (void *)pkt->data; 131e705c121SKalle Valo 132e705c121SKalle Valo /* debug messages are printed in the handler */ 133e705c121SKalle Valo if (add_sta_resp->status == ADD_STA_SUCCESS_MSK) { 134e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 135e705c121SKalle Valo ret = iwl_sta_ucode_activate(priv, sta_id); 136e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 137e705c121SKalle Valo } else { 138e705c121SKalle Valo ret = -EIO; 139e705c121SKalle Valo } 140e705c121SKalle Valo 141e705c121SKalle Valo iwl_free_resp(&cmd); 142e705c121SKalle Valo 143e705c121SKalle Valo return ret; 144e705c121SKalle Valo } 145e705c121SKalle Valo 146e705c121SKalle Valo bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, 147e705c121SKalle Valo struct iwl_rxon_context *ctx, 148e705c121SKalle Valo struct ieee80211_sta *sta) 149e705c121SKalle Valo { 150e705c121SKalle Valo if (!ctx->ht.enabled || !ctx->ht.is_40mhz) 151e705c121SKalle Valo return false; 152e705c121SKalle Valo 153e705c121SKalle Valo #ifdef CONFIG_IWLWIFI_DEBUGFS 154e705c121SKalle Valo if (priv->disable_ht40) 155e705c121SKalle Valo return false; 156e705c121SKalle Valo #endif 157e705c121SKalle Valo 158e705c121SKalle Valo /* special case for RXON */ 159e705c121SKalle Valo if (!sta) 160e705c121SKalle Valo return true; 161e705c121SKalle Valo 162e705c121SKalle Valo return sta->bandwidth >= IEEE80211_STA_RX_BW_40; 163e705c121SKalle Valo } 164e705c121SKalle Valo 165e705c121SKalle Valo static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, 166e705c121SKalle Valo struct ieee80211_sta *sta, 167e705c121SKalle Valo struct iwl_rxon_context *ctx, 168e705c121SKalle Valo __le32 *flags, __le32 *mask) 169e705c121SKalle Valo { 170e705c121SKalle Valo struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; 171e705c121SKalle Valo 172e705c121SKalle Valo *mask = STA_FLG_RTS_MIMO_PROT_MSK | 173e705c121SKalle Valo STA_FLG_MIMO_DIS_MSK | 174e705c121SKalle Valo STA_FLG_HT40_EN_MSK | 175e705c121SKalle Valo STA_FLG_MAX_AGG_SIZE_MSK | 176e705c121SKalle Valo STA_FLG_AGG_MPDU_DENSITY_MSK; 177e705c121SKalle Valo *flags = 0; 178e705c121SKalle Valo 179e705c121SKalle Valo if (!sta || !sta_ht_inf->ht_supported) 180e705c121SKalle Valo return; 181e705c121SKalle Valo 182e705c121SKalle Valo IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n", 183e705c121SKalle Valo sta->addr, 184e705c121SKalle Valo (sta->smps_mode == IEEE80211_SMPS_STATIC) ? 185e705c121SKalle Valo "static" : 186e705c121SKalle Valo (sta->smps_mode == IEEE80211_SMPS_DYNAMIC) ? 187e705c121SKalle Valo "dynamic" : "disabled"); 188e705c121SKalle Valo 189e705c121SKalle Valo switch (sta->smps_mode) { 190e705c121SKalle Valo case IEEE80211_SMPS_STATIC: 191e705c121SKalle Valo *flags |= STA_FLG_MIMO_DIS_MSK; 192e705c121SKalle Valo break; 193e705c121SKalle Valo case IEEE80211_SMPS_DYNAMIC: 194e705c121SKalle Valo *flags |= STA_FLG_RTS_MIMO_PROT_MSK; 195e705c121SKalle Valo break; 196e705c121SKalle Valo case IEEE80211_SMPS_OFF: 197e705c121SKalle Valo break; 198e705c121SKalle Valo default: 199e705c121SKalle Valo IWL_WARN(priv, "Invalid MIMO PS mode %d\n", sta->smps_mode); 200e705c121SKalle Valo break; 201e705c121SKalle Valo } 202e705c121SKalle Valo 203e705c121SKalle Valo *flags |= cpu_to_le32( 204e705c121SKalle Valo (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); 205e705c121SKalle Valo 206e705c121SKalle Valo *flags |= cpu_to_le32( 207e705c121SKalle Valo (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); 208e705c121SKalle Valo 209e705c121SKalle Valo if (iwl_is_ht40_tx_allowed(priv, ctx, sta)) 210e705c121SKalle Valo *flags |= STA_FLG_HT40_EN_MSK; 211e705c121SKalle Valo } 212e705c121SKalle Valo 213e705c121SKalle Valo int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 214e705c121SKalle Valo struct ieee80211_sta *sta) 215e705c121SKalle Valo { 216e705c121SKalle Valo u8 sta_id = iwl_sta_id(sta); 217e705c121SKalle Valo __le32 flags, mask; 218e705c121SKalle Valo struct iwl_addsta_cmd cmd; 219e705c121SKalle Valo 220e705c121SKalle Valo if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) 221e705c121SKalle Valo return -EINVAL; 222e705c121SKalle Valo 223e705c121SKalle Valo iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); 224e705c121SKalle Valo 225e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 226e705c121SKalle Valo priv->stations[sta_id].sta.station_flags &= ~mask; 227e705c121SKalle Valo priv->stations[sta_id].sta.station_flags |= flags; 228e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 229e705c121SKalle Valo 230e705c121SKalle Valo memset(&cmd, 0, sizeof(cmd)); 231e705c121SKalle Valo cmd.mode = STA_CONTROL_MODIFY_MSK; 232e705c121SKalle Valo cmd.station_flags_msk = mask; 233e705c121SKalle Valo cmd.station_flags = flags; 234e705c121SKalle Valo cmd.sta.sta_id = sta_id; 235e705c121SKalle Valo 236e705c121SKalle Valo return iwl_send_add_sta(priv, &cmd, 0); 237e705c121SKalle Valo } 238e705c121SKalle Valo 239e705c121SKalle Valo static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, 240e705c121SKalle Valo struct ieee80211_sta *sta, 241e705c121SKalle Valo struct iwl_rxon_context *ctx) 242e705c121SKalle Valo { 243e705c121SKalle Valo __le32 flags, mask; 244e705c121SKalle Valo 245e705c121SKalle Valo iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); 246e705c121SKalle Valo 247e705c121SKalle Valo lockdep_assert_held(&priv->sta_lock); 248e705c121SKalle Valo priv->stations[index].sta.station_flags &= ~mask; 249e705c121SKalle Valo priv->stations[index].sta.station_flags |= flags; 250e705c121SKalle Valo } 251e705c121SKalle Valo 252e705c121SKalle Valo /** 253e705c121SKalle Valo * iwl_prep_station - Prepare station information for addition 254e705c121SKalle Valo * 255e705c121SKalle Valo * should be called with sta_lock held 256e705c121SKalle Valo */ 257e705c121SKalle Valo u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 258e705c121SKalle Valo const u8 *addr, bool is_ap, struct ieee80211_sta *sta) 259e705c121SKalle Valo { 260e705c121SKalle Valo struct iwl_station_entry *station; 261e705c121SKalle Valo int i; 262e705c121SKalle Valo u8 sta_id = IWL_INVALID_STATION; 263e705c121SKalle Valo 264e705c121SKalle Valo if (is_ap) 265e705c121SKalle Valo sta_id = ctx->ap_sta_id; 266e705c121SKalle Valo else if (is_broadcast_ether_addr(addr)) 267e705c121SKalle Valo sta_id = ctx->bcast_sta_id; 268e705c121SKalle Valo else 269e705c121SKalle Valo for (i = IWL_STA_ID; i < IWLAGN_STATION_COUNT; i++) { 270e705c121SKalle Valo if (ether_addr_equal(priv->stations[i].sta.sta.addr, 271e705c121SKalle Valo addr)) { 272e705c121SKalle Valo sta_id = i; 273e705c121SKalle Valo break; 274e705c121SKalle Valo } 275e705c121SKalle Valo 276e705c121SKalle Valo if (!priv->stations[i].used && 277e705c121SKalle Valo sta_id == IWL_INVALID_STATION) 278e705c121SKalle Valo sta_id = i; 279e705c121SKalle Valo } 280e705c121SKalle Valo 281e705c121SKalle Valo /* 282e705c121SKalle Valo * These two conditions have the same outcome, but keep them 283e705c121SKalle Valo * separate 284e705c121SKalle Valo */ 285e705c121SKalle Valo if (unlikely(sta_id == IWL_INVALID_STATION)) 286e705c121SKalle Valo return sta_id; 287e705c121SKalle Valo 288e705c121SKalle Valo /* 289e705c121SKalle Valo * uCode is not able to deal with multiple requests to add a 290e705c121SKalle Valo * station. Keep track if one is in progress so that we do not send 291e705c121SKalle Valo * another. 292e705c121SKalle Valo */ 293e705c121SKalle Valo if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { 294e705c121SKalle Valo IWL_DEBUG_INFO(priv, "STA %d already in process of being " 295e705c121SKalle Valo "added.\n", sta_id); 296e705c121SKalle Valo return sta_id; 297e705c121SKalle Valo } 298e705c121SKalle Valo 299e705c121SKalle Valo if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && 300e705c121SKalle Valo (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) && 301e705c121SKalle Valo ether_addr_equal(priv->stations[sta_id].sta.sta.addr, addr)) { 302e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " 303e705c121SKalle Valo "adding again.\n", sta_id, addr); 304e705c121SKalle Valo return sta_id; 305e705c121SKalle Valo } 306e705c121SKalle Valo 307e705c121SKalle Valo station = &priv->stations[sta_id]; 308e705c121SKalle Valo station->used = IWL_STA_DRIVER_ACTIVE; 309e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n", 310e705c121SKalle Valo sta_id, addr); 311e705c121SKalle Valo priv->num_stations++; 312e705c121SKalle Valo 313e705c121SKalle Valo /* Set up the REPLY_ADD_STA command to send to device */ 314e705c121SKalle Valo memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd)); 315e705c121SKalle Valo memcpy(station->sta.sta.addr, addr, ETH_ALEN); 316e705c121SKalle Valo station->sta.mode = 0; 317e705c121SKalle Valo station->sta.sta.sta_id = sta_id; 318e705c121SKalle Valo station->sta.station_flags = ctx->station_flags; 319e705c121SKalle Valo station->ctxid = ctx->ctxid; 320e705c121SKalle Valo 321e705c121SKalle Valo if (sta) { 322e705c121SKalle Valo struct iwl_station_priv *sta_priv; 323e705c121SKalle Valo 324e705c121SKalle Valo sta_priv = (void *)sta->drv_priv; 325e705c121SKalle Valo sta_priv->ctx = ctx; 326e705c121SKalle Valo } 327e705c121SKalle Valo 328e705c121SKalle Valo /* 329e705c121SKalle Valo * OK to call unconditionally, since local stations (IBSS BSSID 330e705c121SKalle Valo * STA and broadcast STA) pass in a NULL sta, and mac80211 331e705c121SKalle Valo * doesn't allow HT IBSS. 332e705c121SKalle Valo */ 333e705c121SKalle Valo iwl_set_ht_add_station(priv, sta_id, sta, ctx); 334e705c121SKalle Valo 335e705c121SKalle Valo return sta_id; 336e705c121SKalle Valo 337e705c121SKalle Valo } 338e705c121SKalle Valo 339e705c121SKalle Valo #define STA_WAIT_TIMEOUT (HZ/2) 340e705c121SKalle Valo 341e705c121SKalle Valo /** 342e705c121SKalle Valo * iwl_add_station_common - 343e705c121SKalle Valo */ 344e705c121SKalle Valo int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 345e705c121SKalle Valo const u8 *addr, bool is_ap, 346e705c121SKalle Valo struct ieee80211_sta *sta, u8 *sta_id_r) 347e705c121SKalle Valo { 348e705c121SKalle Valo int ret = 0; 349e705c121SKalle Valo u8 sta_id; 350e705c121SKalle Valo struct iwl_addsta_cmd sta_cmd; 351e705c121SKalle Valo 352e705c121SKalle Valo *sta_id_r = 0; 353e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 354e705c121SKalle Valo sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta); 355e705c121SKalle Valo if (sta_id == IWL_INVALID_STATION) { 356e705c121SKalle Valo IWL_ERR(priv, "Unable to prepare station %pM for addition\n", 357e705c121SKalle Valo addr); 358e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 359e705c121SKalle Valo return -EINVAL; 360e705c121SKalle Valo } 361e705c121SKalle Valo 362e705c121SKalle Valo /* 363e705c121SKalle Valo * uCode is not able to deal with multiple requests to add a 364e705c121SKalle Valo * station. Keep track if one is in progress so that we do not send 365e705c121SKalle Valo * another. 366e705c121SKalle Valo */ 367e705c121SKalle Valo if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { 368e705c121SKalle Valo IWL_DEBUG_INFO(priv, "STA %d already in process of being " 369e705c121SKalle Valo "added.\n", sta_id); 370e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 371e705c121SKalle Valo return -EEXIST; 372e705c121SKalle Valo } 373e705c121SKalle Valo 374e705c121SKalle Valo if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && 375e705c121SKalle Valo (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { 376e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " 377e705c121SKalle Valo "adding again.\n", sta_id, addr); 378e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 379e705c121SKalle Valo return -EEXIST; 380e705c121SKalle Valo } 381e705c121SKalle Valo 382e705c121SKalle Valo priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; 383e705c121SKalle Valo memcpy(&sta_cmd, &priv->stations[sta_id].sta, 384e705c121SKalle Valo sizeof(struct iwl_addsta_cmd)); 385e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 386e705c121SKalle Valo 387e705c121SKalle Valo /* Add station to device's station table */ 388e705c121SKalle Valo ret = iwl_send_add_sta(priv, &sta_cmd, 0); 389e705c121SKalle Valo if (ret) { 390e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 391e705c121SKalle Valo IWL_ERR(priv, "Adding station %pM failed.\n", 392e705c121SKalle Valo priv->stations[sta_id].sta.sta.addr); 393e705c121SKalle Valo priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; 394e705c121SKalle Valo priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; 395e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 396e705c121SKalle Valo } 397e705c121SKalle Valo *sta_id_r = sta_id; 398e705c121SKalle Valo return ret; 399e705c121SKalle Valo } 400e705c121SKalle Valo 401e705c121SKalle Valo /** 402e705c121SKalle Valo * iwl_sta_ucode_deactivate - deactivate ucode status for a station 403e705c121SKalle Valo */ 404e705c121SKalle Valo static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) 405e705c121SKalle Valo { 406e705c121SKalle Valo lockdep_assert_held(&priv->sta_lock); 407e705c121SKalle Valo 408e705c121SKalle Valo /* Ucode must be active and driver must be non active */ 409e705c121SKalle Valo if ((priv->stations[sta_id].used & 410e705c121SKalle Valo (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != 411e705c121SKalle Valo IWL_STA_UCODE_ACTIVE) 412e705c121SKalle Valo IWL_ERR(priv, "removed non active STA %u\n", sta_id); 413e705c121SKalle Valo 414e705c121SKalle Valo priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; 415e705c121SKalle Valo 416e705c121SKalle Valo memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry)); 417e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id); 418e705c121SKalle Valo } 419e705c121SKalle Valo 420e705c121SKalle Valo static int iwl_send_remove_station(struct iwl_priv *priv, 421e705c121SKalle Valo const u8 *addr, int sta_id, 422e705c121SKalle Valo bool temporary) 423e705c121SKalle Valo { 424e705c121SKalle Valo struct iwl_rx_packet *pkt; 425e705c121SKalle Valo int ret; 426e705c121SKalle Valo struct iwl_rem_sta_cmd rm_sta_cmd; 427e705c121SKalle Valo struct iwl_rem_sta_resp *rem_sta_resp; 428e705c121SKalle Valo 429e705c121SKalle Valo struct iwl_host_cmd cmd = { 430e705c121SKalle Valo .id = REPLY_REMOVE_STA, 431e705c121SKalle Valo .len = { sizeof(struct iwl_rem_sta_cmd), }, 432e705c121SKalle Valo .data = { &rm_sta_cmd, }, 433e705c121SKalle Valo }; 434e705c121SKalle Valo 435e705c121SKalle Valo memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 436e705c121SKalle Valo rm_sta_cmd.num_sta = 1; 437e705c121SKalle Valo memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN); 438e705c121SKalle Valo 439e705c121SKalle Valo cmd.flags |= CMD_WANT_SKB; 440e705c121SKalle Valo 441e705c121SKalle Valo ret = iwl_dvm_send_cmd(priv, &cmd); 442e705c121SKalle Valo 443e705c121SKalle Valo if (ret) 444e705c121SKalle Valo return ret; 445e705c121SKalle Valo 446e705c121SKalle Valo pkt = cmd.resp_pkt; 447e705c121SKalle Valo rem_sta_resp = (void *)pkt->data; 448e705c121SKalle Valo 449e705c121SKalle Valo switch (rem_sta_resp->status) { 450e705c121SKalle Valo case REM_STA_SUCCESS_MSK: 451e705c121SKalle Valo if (!temporary) { 452e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 453e705c121SKalle Valo iwl_sta_ucode_deactivate(priv, sta_id); 454e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 455e705c121SKalle Valo } 456e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); 457e705c121SKalle Valo break; 458e705c121SKalle Valo default: 459e705c121SKalle Valo ret = -EIO; 460e705c121SKalle Valo IWL_ERR(priv, "REPLY_REMOVE_STA failed\n"); 461e705c121SKalle Valo break; 462e705c121SKalle Valo } 463e705c121SKalle Valo 464e705c121SKalle Valo iwl_free_resp(&cmd); 465e705c121SKalle Valo 466e705c121SKalle Valo return ret; 467e705c121SKalle Valo } 468e705c121SKalle Valo 469e705c121SKalle Valo /** 470e705c121SKalle Valo * iwl_remove_station - Remove driver's knowledge of station. 471e705c121SKalle Valo */ 472e705c121SKalle Valo int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, 473e705c121SKalle Valo const u8 *addr) 474e705c121SKalle Valo { 475e705c121SKalle Valo u8 tid; 476e705c121SKalle Valo 477e705c121SKalle Valo if (!iwl_is_ready(priv)) { 478e705c121SKalle Valo IWL_DEBUG_INFO(priv, 479e705c121SKalle Valo "Unable to remove station %pM, device not ready.\n", 480e705c121SKalle Valo addr); 481e705c121SKalle Valo /* 482e705c121SKalle Valo * It is typical for stations to be removed when we are 483e705c121SKalle Valo * going down. Return success since device will be down 484e705c121SKalle Valo * soon anyway 485e705c121SKalle Valo */ 486e705c121SKalle Valo return 0; 487e705c121SKalle Valo } 488e705c121SKalle Valo 489e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n", 490e705c121SKalle Valo sta_id, addr); 491e705c121SKalle Valo 492e705c121SKalle Valo if (WARN_ON(sta_id == IWL_INVALID_STATION)) 493e705c121SKalle Valo return -EINVAL; 494e705c121SKalle Valo 495e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 496e705c121SKalle Valo 497e705c121SKalle Valo if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { 498e705c121SKalle Valo IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n", 499e705c121SKalle Valo addr); 500e705c121SKalle Valo goto out_err; 501e705c121SKalle Valo } 502e705c121SKalle Valo 503e705c121SKalle Valo if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { 504e705c121SKalle Valo IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n", 505e705c121SKalle Valo addr); 506e705c121SKalle Valo goto out_err; 507e705c121SKalle Valo } 508e705c121SKalle Valo 509e705c121SKalle Valo if (priv->stations[sta_id].used & IWL_STA_LOCAL) { 510e705c121SKalle Valo kfree(priv->stations[sta_id].lq); 511e705c121SKalle Valo priv->stations[sta_id].lq = NULL; 512e705c121SKalle Valo } 513e705c121SKalle Valo 514e705c121SKalle Valo for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) 515e705c121SKalle Valo memset(&priv->tid_data[sta_id][tid], 0, 516e705c121SKalle Valo sizeof(priv->tid_data[sta_id][tid])); 517e705c121SKalle Valo 518e705c121SKalle Valo priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; 519e705c121SKalle Valo 520e705c121SKalle Valo priv->num_stations--; 521e705c121SKalle Valo 522e705c121SKalle Valo if (WARN_ON(priv->num_stations < 0)) 523e705c121SKalle Valo priv->num_stations = 0; 524e705c121SKalle Valo 525e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 526e705c121SKalle Valo 527e705c121SKalle Valo return iwl_send_remove_station(priv, addr, sta_id, false); 528e705c121SKalle Valo out_err: 529e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 530e705c121SKalle Valo return -EINVAL; 531e705c121SKalle Valo } 532e705c121SKalle Valo 533e705c121SKalle Valo void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, 534e705c121SKalle Valo const u8 *addr) 535e705c121SKalle Valo { 536e705c121SKalle Valo u8 tid; 537e705c121SKalle Valo 538e705c121SKalle Valo if (!iwl_is_ready(priv)) { 539e705c121SKalle Valo IWL_DEBUG_INFO(priv, 540e705c121SKalle Valo "Unable to remove station %pM, device not ready.\n", 541e705c121SKalle Valo addr); 542e705c121SKalle Valo return; 543e705c121SKalle Valo } 544e705c121SKalle Valo 545e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id); 546e705c121SKalle Valo 547e705c121SKalle Valo if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) 548e705c121SKalle Valo return; 549e705c121SKalle Valo 550e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 551e705c121SKalle Valo 552e705c121SKalle Valo WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)); 553e705c121SKalle Valo 554e705c121SKalle Valo for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) 555e705c121SKalle Valo memset(&priv->tid_data[sta_id][tid], 0, 556e705c121SKalle Valo sizeof(priv->tid_data[sta_id][tid])); 557e705c121SKalle Valo 558e705c121SKalle Valo priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; 559e705c121SKalle Valo priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; 560e705c121SKalle Valo 561e705c121SKalle Valo priv->num_stations--; 562e705c121SKalle Valo 563e705c121SKalle Valo if (WARN_ON_ONCE(priv->num_stations < 0)) 564e705c121SKalle Valo priv->num_stations = 0; 565e705c121SKalle Valo 566e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 567e705c121SKalle Valo } 568e705c121SKalle Valo 569e705c121SKalle Valo static void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 570e705c121SKalle Valo u8 sta_id, struct iwl_link_quality_cmd *link_cmd) 571e705c121SKalle Valo { 572e705c121SKalle Valo int i, r; 573e705c121SKalle Valo u32 rate_flags = 0; 574e705c121SKalle Valo __le32 rate_n_flags; 575e705c121SKalle Valo 576e705c121SKalle Valo lockdep_assert_held(&priv->mutex); 577e705c121SKalle Valo 578e705c121SKalle Valo memset(link_cmd, 0, sizeof(*link_cmd)); 579e705c121SKalle Valo 580e705c121SKalle Valo /* Set up the rate scaling to start at selected rate, fall back 581e705c121SKalle Valo * all the way down to 1M in IEEE order, and then spin on 1M */ 582e705c121SKalle Valo if (priv->band == IEEE80211_BAND_5GHZ) 583e705c121SKalle Valo r = IWL_RATE_6M_INDEX; 584e705c121SKalle Valo else if (ctx && ctx->vif && ctx->vif->p2p) 585e705c121SKalle Valo r = IWL_RATE_6M_INDEX; 586e705c121SKalle Valo else 587e705c121SKalle Valo r = IWL_RATE_1M_INDEX; 588e705c121SKalle Valo 589e705c121SKalle Valo if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) 590e705c121SKalle Valo rate_flags |= RATE_MCS_CCK_MSK; 591e705c121SKalle Valo 592e705c121SKalle Valo rate_flags |= first_antenna(priv->nvm_data->valid_tx_ant) << 593e705c121SKalle Valo RATE_MCS_ANT_POS; 594e705c121SKalle Valo rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); 595e705c121SKalle Valo for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) 596e705c121SKalle Valo link_cmd->rs_table[i].rate_n_flags = rate_n_flags; 597e705c121SKalle Valo 598e705c121SKalle Valo link_cmd->general_params.single_stream_ant_msk = 599e705c121SKalle Valo first_antenna(priv->nvm_data->valid_tx_ant); 600e705c121SKalle Valo 601e705c121SKalle Valo link_cmd->general_params.dual_stream_ant_msk = 602e705c121SKalle Valo priv->nvm_data->valid_tx_ant & 603e705c121SKalle Valo ~first_antenna(priv->nvm_data->valid_tx_ant); 604e705c121SKalle Valo if (!link_cmd->general_params.dual_stream_ant_msk) { 605e705c121SKalle Valo link_cmd->general_params.dual_stream_ant_msk = ANT_AB; 606e705c121SKalle Valo } else if (num_of_ant(priv->nvm_data->valid_tx_ant) == 2) { 607e705c121SKalle Valo link_cmd->general_params.dual_stream_ant_msk = 608e705c121SKalle Valo priv->nvm_data->valid_tx_ant; 609e705c121SKalle Valo } 610e705c121SKalle Valo 611e705c121SKalle Valo link_cmd->agg_params.agg_dis_start_th = 612e705c121SKalle Valo LINK_QUAL_AGG_DISABLE_START_DEF; 613e705c121SKalle Valo link_cmd->agg_params.agg_time_limit = 614e705c121SKalle Valo cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); 615e705c121SKalle Valo 616e705c121SKalle Valo link_cmd->sta_id = sta_id; 617e705c121SKalle Valo } 618e705c121SKalle Valo 619e705c121SKalle Valo /** 620e705c121SKalle Valo * iwl_clear_ucode_stations - clear ucode station table bits 621e705c121SKalle Valo * 622e705c121SKalle Valo * This function clears all the bits in the driver indicating 623e705c121SKalle Valo * which stations are active in the ucode. Call when something 624e705c121SKalle Valo * other than explicit station management would cause this in 625e705c121SKalle Valo * the ucode, e.g. unassociated RXON. 626e705c121SKalle Valo */ 627e705c121SKalle Valo void iwl_clear_ucode_stations(struct iwl_priv *priv, 628e705c121SKalle Valo struct iwl_rxon_context *ctx) 629e705c121SKalle Valo { 630e705c121SKalle Valo int i; 631e705c121SKalle Valo bool cleared = false; 632e705c121SKalle Valo 633e705c121SKalle Valo IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n"); 634e705c121SKalle Valo 635e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 636e705c121SKalle Valo for (i = 0; i < IWLAGN_STATION_COUNT; i++) { 637e705c121SKalle Valo if (ctx && ctx->ctxid != priv->stations[i].ctxid) 638e705c121SKalle Valo continue; 639e705c121SKalle Valo 640e705c121SKalle Valo if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) { 641e705c121SKalle Valo IWL_DEBUG_INFO(priv, 642e705c121SKalle Valo "Clearing ucode active for station %d\n", i); 643e705c121SKalle Valo priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; 644e705c121SKalle Valo cleared = true; 645e705c121SKalle Valo } 646e705c121SKalle Valo } 647e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 648e705c121SKalle Valo 649e705c121SKalle Valo if (!cleared) 650e705c121SKalle Valo IWL_DEBUG_INFO(priv, 651e705c121SKalle Valo "No active stations found to be cleared\n"); 652e705c121SKalle Valo } 653e705c121SKalle Valo 654e705c121SKalle Valo /** 655e705c121SKalle Valo * iwl_restore_stations() - Restore driver known stations to device 656e705c121SKalle Valo * 657e705c121SKalle Valo * All stations considered active by driver, but not present in ucode, is 658e705c121SKalle Valo * restored. 659e705c121SKalle Valo * 660e705c121SKalle Valo * Function sleeps. 661e705c121SKalle Valo */ 662e705c121SKalle Valo void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) 663e705c121SKalle Valo { 664e705c121SKalle Valo struct iwl_addsta_cmd sta_cmd; 665e705c121SKalle Valo static const struct iwl_link_quality_cmd zero_lq = {}; 666e705c121SKalle Valo struct iwl_link_quality_cmd lq; 667e705c121SKalle Valo int i; 668e705c121SKalle Valo bool found = false; 669e705c121SKalle Valo int ret; 670e705c121SKalle Valo bool send_lq; 671e705c121SKalle Valo 672e705c121SKalle Valo if (!iwl_is_ready(priv)) { 673e705c121SKalle Valo IWL_DEBUG_INFO(priv, 674e705c121SKalle Valo "Not ready yet, not restoring any stations.\n"); 675e705c121SKalle Valo return; 676e705c121SKalle Valo } 677e705c121SKalle Valo 678e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); 679e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 680e705c121SKalle Valo for (i = 0; i < IWLAGN_STATION_COUNT; i++) { 681e705c121SKalle Valo if (ctx->ctxid != priv->stations[i].ctxid) 682e705c121SKalle Valo continue; 683e705c121SKalle Valo if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) && 684e705c121SKalle Valo !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) { 685e705c121SKalle Valo IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n", 686e705c121SKalle Valo priv->stations[i].sta.sta.addr); 687e705c121SKalle Valo priv->stations[i].sta.mode = 0; 688e705c121SKalle Valo priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS; 689e705c121SKalle Valo found = true; 690e705c121SKalle Valo } 691e705c121SKalle Valo } 692e705c121SKalle Valo 693e705c121SKalle Valo for (i = 0; i < IWLAGN_STATION_COUNT; i++) { 694e705c121SKalle Valo if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) { 695e705c121SKalle Valo memcpy(&sta_cmd, &priv->stations[i].sta, 696e705c121SKalle Valo sizeof(struct iwl_addsta_cmd)); 697e705c121SKalle Valo send_lq = false; 698e705c121SKalle Valo if (priv->stations[i].lq) { 699e705c121SKalle Valo if (priv->wowlan) 700e705c121SKalle Valo iwl_sta_fill_lq(priv, ctx, i, &lq); 701e705c121SKalle Valo else 702e705c121SKalle Valo memcpy(&lq, priv->stations[i].lq, 703e705c121SKalle Valo sizeof(struct iwl_link_quality_cmd)); 704e705c121SKalle Valo 705e705c121SKalle Valo if (memcmp(&lq, &zero_lq, sizeof(lq))) 706e705c121SKalle Valo send_lq = true; 707e705c121SKalle Valo } 708e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 709e705c121SKalle Valo ret = iwl_send_add_sta(priv, &sta_cmd, 0); 710e705c121SKalle Valo if (ret) { 711e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 712e705c121SKalle Valo IWL_ERR(priv, "Adding station %pM failed.\n", 713e705c121SKalle Valo priv->stations[i].sta.sta.addr); 714e705c121SKalle Valo priv->stations[i].used &= 715e705c121SKalle Valo ~IWL_STA_DRIVER_ACTIVE; 716e705c121SKalle Valo priv->stations[i].used &= 717e705c121SKalle Valo ~IWL_STA_UCODE_INPROGRESS; 718e705c121SKalle Valo continue; 719e705c121SKalle Valo } 720e705c121SKalle Valo /* 721e705c121SKalle Valo * Rate scaling has already been initialized, send 722e705c121SKalle Valo * current LQ command 723e705c121SKalle Valo */ 724e705c121SKalle Valo if (send_lq) 725e705c121SKalle Valo iwl_send_lq_cmd(priv, ctx, &lq, 0, true); 726e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 727e705c121SKalle Valo priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; 728e705c121SKalle Valo } 729e705c121SKalle Valo } 730e705c121SKalle Valo 731e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 732e705c121SKalle Valo if (!found) 733e705c121SKalle Valo IWL_DEBUG_INFO(priv, "Restoring all known stations .... " 734e705c121SKalle Valo "no stations to be restored.\n"); 735e705c121SKalle Valo else 736e705c121SKalle Valo IWL_DEBUG_INFO(priv, "Restoring all known stations .... " 737e705c121SKalle Valo "complete.\n"); 738e705c121SKalle Valo } 739e705c121SKalle Valo 740e705c121SKalle Valo int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) 741e705c121SKalle Valo { 742e705c121SKalle Valo int i; 743e705c121SKalle Valo 744e705c121SKalle Valo for (i = 0; i < priv->sta_key_max_num; i++) 745e705c121SKalle Valo if (!test_and_set_bit(i, &priv->ucode_key_table)) 746e705c121SKalle Valo return i; 747e705c121SKalle Valo 748e705c121SKalle Valo return WEP_INVALID_OFFSET; 749e705c121SKalle Valo } 750e705c121SKalle Valo 751e705c121SKalle Valo void iwl_dealloc_bcast_stations(struct iwl_priv *priv) 752e705c121SKalle Valo { 753e705c121SKalle Valo int i; 754e705c121SKalle Valo 755e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 756e705c121SKalle Valo for (i = 0; i < IWLAGN_STATION_COUNT; i++) { 757e705c121SKalle Valo if (!(priv->stations[i].used & IWL_STA_BCAST)) 758e705c121SKalle Valo continue; 759e705c121SKalle Valo 760e705c121SKalle Valo priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; 761e705c121SKalle Valo priv->num_stations--; 762e705c121SKalle Valo if (WARN_ON(priv->num_stations < 0)) 763e705c121SKalle Valo priv->num_stations = 0; 764e705c121SKalle Valo kfree(priv->stations[i].lq); 765e705c121SKalle Valo priv->stations[i].lq = NULL; 766e705c121SKalle Valo } 767e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 768e705c121SKalle Valo } 769e705c121SKalle Valo 770e705c121SKalle Valo #ifdef CONFIG_IWLWIFI_DEBUG 771e705c121SKalle Valo static void iwl_dump_lq_cmd(struct iwl_priv *priv, 772e705c121SKalle Valo struct iwl_link_quality_cmd *lq) 773e705c121SKalle Valo { 774e705c121SKalle Valo int i; 775e705c121SKalle Valo IWL_DEBUG_RATE(priv, "lq station id 0x%x\n", lq->sta_id); 776e705c121SKalle Valo IWL_DEBUG_RATE(priv, "lq ant 0x%X 0x%X\n", 777e705c121SKalle Valo lq->general_params.single_stream_ant_msk, 778e705c121SKalle Valo lq->general_params.dual_stream_ant_msk); 779e705c121SKalle Valo 780e705c121SKalle Valo for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) 781e705c121SKalle Valo IWL_DEBUG_RATE(priv, "lq index %d 0x%X\n", 782e705c121SKalle Valo i, lq->rs_table[i].rate_n_flags); 783e705c121SKalle Valo } 784e705c121SKalle Valo #else 785e705c121SKalle Valo static inline void iwl_dump_lq_cmd(struct iwl_priv *priv, 786e705c121SKalle Valo struct iwl_link_quality_cmd *lq) 787e705c121SKalle Valo { 788e705c121SKalle Valo } 789e705c121SKalle Valo #endif 790e705c121SKalle Valo 791e705c121SKalle Valo /** 792e705c121SKalle Valo * is_lq_table_valid() - Test one aspect of LQ cmd for validity 793e705c121SKalle Valo * 794e705c121SKalle Valo * It sometimes happens when a HT rate has been in use and we 795e705c121SKalle Valo * loose connectivity with AP then mac80211 will first tell us that the 796e705c121SKalle Valo * current channel is not HT anymore before removing the station. In such a 797e705c121SKalle Valo * scenario the RXON flags will be updated to indicate we are not 798e705c121SKalle Valo * communicating HT anymore, but the LQ command may still contain HT rates. 799e705c121SKalle Valo * Test for this to prevent driver from sending LQ command between the time 800e705c121SKalle Valo * RXON flags are updated and when LQ command is updated. 801e705c121SKalle Valo */ 802e705c121SKalle Valo static bool is_lq_table_valid(struct iwl_priv *priv, 803e705c121SKalle Valo struct iwl_rxon_context *ctx, 804e705c121SKalle Valo struct iwl_link_quality_cmd *lq) 805e705c121SKalle Valo { 806e705c121SKalle Valo int i; 807e705c121SKalle Valo 808e705c121SKalle Valo if (ctx->ht.enabled) 809e705c121SKalle Valo return true; 810e705c121SKalle Valo 811e705c121SKalle Valo IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n", 812e705c121SKalle Valo ctx->active.channel); 813e705c121SKalle Valo for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 814e705c121SKalle Valo if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & 815e705c121SKalle Valo RATE_MCS_HT_MSK) { 816e705c121SKalle Valo IWL_DEBUG_INFO(priv, 817e705c121SKalle Valo "index %d of LQ expects HT channel\n", 818e705c121SKalle Valo i); 819e705c121SKalle Valo return false; 820e705c121SKalle Valo } 821e705c121SKalle Valo } 822e705c121SKalle Valo return true; 823e705c121SKalle Valo } 824e705c121SKalle Valo 825e705c121SKalle Valo /** 826e705c121SKalle Valo * iwl_send_lq_cmd() - Send link quality command 827e705c121SKalle Valo * @init: This command is sent as part of station initialization right 828e705c121SKalle Valo * after station has been added. 829e705c121SKalle Valo * 830e705c121SKalle Valo * The link quality command is sent as the last step of station creation. 831e705c121SKalle Valo * This is the special case in which init is set and we call a callback in 832e705c121SKalle Valo * this case to clear the state indicating that station creation is in 833e705c121SKalle Valo * progress. 834e705c121SKalle Valo */ 835e705c121SKalle Valo int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 836e705c121SKalle Valo struct iwl_link_quality_cmd *lq, u8 flags, bool init) 837e705c121SKalle Valo { 838e705c121SKalle Valo int ret = 0; 839e705c121SKalle Valo struct iwl_host_cmd cmd = { 840e705c121SKalle Valo .id = REPLY_TX_LINK_QUALITY_CMD, 841e705c121SKalle Valo .len = { sizeof(struct iwl_link_quality_cmd), }, 842e705c121SKalle Valo .flags = flags, 843e705c121SKalle Valo .data = { lq, }, 844e705c121SKalle Valo }; 845e705c121SKalle Valo 846e705c121SKalle Valo if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) 847e705c121SKalle Valo return -EINVAL; 848e705c121SKalle Valo 849e705c121SKalle Valo 850e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 851e705c121SKalle Valo if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { 852e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 853e705c121SKalle Valo return -EINVAL; 854e705c121SKalle Valo } 855e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 856e705c121SKalle Valo 857e705c121SKalle Valo iwl_dump_lq_cmd(priv, lq); 858e705c121SKalle Valo if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) 859e705c121SKalle Valo return -EINVAL; 860e705c121SKalle Valo 861e705c121SKalle Valo if (is_lq_table_valid(priv, ctx, lq)) 862e705c121SKalle Valo ret = iwl_dvm_send_cmd(priv, &cmd); 863e705c121SKalle Valo else 864e705c121SKalle Valo ret = -EINVAL; 865e705c121SKalle Valo 866e705c121SKalle Valo if (cmd.flags & CMD_ASYNC) 867e705c121SKalle Valo return ret; 868e705c121SKalle Valo 869e705c121SKalle Valo if (init) { 870e705c121SKalle Valo IWL_DEBUG_INFO(priv, "init LQ command complete, " 871e705c121SKalle Valo "clearing sta addition status for sta %d\n", 872e705c121SKalle Valo lq->sta_id); 873e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 874e705c121SKalle Valo priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; 875e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 876e705c121SKalle Valo } 877e705c121SKalle Valo return ret; 878e705c121SKalle Valo } 879e705c121SKalle Valo 880e705c121SKalle Valo 881e705c121SKalle Valo static struct iwl_link_quality_cmd * 882e705c121SKalle Valo iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 883e705c121SKalle Valo u8 sta_id) 884e705c121SKalle Valo { 885e705c121SKalle Valo struct iwl_link_quality_cmd *link_cmd; 886e705c121SKalle Valo 887e705c121SKalle Valo link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL); 888e705c121SKalle Valo if (!link_cmd) { 889e705c121SKalle Valo IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); 890e705c121SKalle Valo return NULL; 891e705c121SKalle Valo } 892e705c121SKalle Valo 893e705c121SKalle Valo iwl_sta_fill_lq(priv, ctx, sta_id, link_cmd); 894e705c121SKalle Valo 895e705c121SKalle Valo return link_cmd; 896e705c121SKalle Valo } 897e705c121SKalle Valo 898e705c121SKalle Valo /* 899e705c121SKalle Valo * iwlagn_add_bssid_station - Add the special IBSS BSSID station 900e705c121SKalle Valo * 901e705c121SKalle Valo * Function sleeps. 902e705c121SKalle Valo */ 903e705c121SKalle Valo int iwlagn_add_bssid_station(struct iwl_priv *priv, 904e705c121SKalle Valo struct iwl_rxon_context *ctx, 905e705c121SKalle Valo const u8 *addr, u8 *sta_id_r) 906e705c121SKalle Valo { 907e705c121SKalle Valo int ret; 908e705c121SKalle Valo u8 sta_id; 909e705c121SKalle Valo struct iwl_link_quality_cmd *link_cmd; 910e705c121SKalle Valo 911e705c121SKalle Valo if (sta_id_r) 912e705c121SKalle Valo *sta_id_r = IWL_INVALID_STATION; 913e705c121SKalle Valo 914e705c121SKalle Valo ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); 915e705c121SKalle Valo if (ret) { 916e705c121SKalle Valo IWL_ERR(priv, "Unable to add station %pM\n", addr); 917e705c121SKalle Valo return ret; 918e705c121SKalle Valo } 919e705c121SKalle Valo 920e705c121SKalle Valo if (sta_id_r) 921e705c121SKalle Valo *sta_id_r = sta_id; 922e705c121SKalle Valo 923e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 924e705c121SKalle Valo priv->stations[sta_id].used |= IWL_STA_LOCAL; 925e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 926e705c121SKalle Valo 927e705c121SKalle Valo /* Set up default rate scaling table in device's station table */ 928e705c121SKalle Valo link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); 929e705c121SKalle Valo if (!link_cmd) { 930e705c121SKalle Valo IWL_ERR(priv, 931e705c121SKalle Valo "Unable to initialize rate scaling for station %pM.\n", 932e705c121SKalle Valo addr); 933e705c121SKalle Valo return -ENOMEM; 934e705c121SKalle Valo } 935e705c121SKalle Valo 936e705c121SKalle Valo ret = iwl_send_lq_cmd(priv, ctx, link_cmd, 0, true); 937e705c121SKalle Valo if (ret) 938e705c121SKalle Valo IWL_ERR(priv, "Link quality command failed (%d)\n", ret); 939e705c121SKalle Valo 940e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 941e705c121SKalle Valo priv->stations[sta_id].lq = link_cmd; 942e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 943e705c121SKalle Valo 944e705c121SKalle Valo return 0; 945e705c121SKalle Valo } 946e705c121SKalle Valo 947e705c121SKalle Valo /* 948e705c121SKalle Valo * static WEP keys 949e705c121SKalle Valo * 950e705c121SKalle Valo * For each context, the device has a table of 4 static WEP keys 951e705c121SKalle Valo * (one for each key index) that is updated with the following 952e705c121SKalle Valo * commands. 953e705c121SKalle Valo */ 954e705c121SKalle Valo 955e705c121SKalle Valo static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, 956e705c121SKalle Valo struct iwl_rxon_context *ctx, 957e705c121SKalle Valo bool send_if_empty) 958e705c121SKalle Valo { 959e705c121SKalle Valo int i, not_empty = 0; 960e705c121SKalle Valo u8 buff[sizeof(struct iwl_wep_cmd) + 961e705c121SKalle Valo sizeof(struct iwl_wep_key) * WEP_KEYS_MAX]; 962e705c121SKalle Valo struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff; 963e705c121SKalle Valo size_t cmd_size = sizeof(struct iwl_wep_cmd); 964e705c121SKalle Valo struct iwl_host_cmd cmd = { 965e705c121SKalle Valo .id = ctx->wep_key_cmd, 966e705c121SKalle Valo .data = { wep_cmd, }, 967e705c121SKalle Valo }; 968e705c121SKalle Valo 969e705c121SKalle Valo might_sleep(); 970e705c121SKalle Valo 971e705c121SKalle Valo memset(wep_cmd, 0, cmd_size + 972e705c121SKalle Valo (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); 973e705c121SKalle Valo 974e705c121SKalle Valo for (i = 0; i < WEP_KEYS_MAX ; i++) { 975e705c121SKalle Valo wep_cmd->key[i].key_index = i; 976e705c121SKalle Valo if (ctx->wep_keys[i].key_size) { 977e705c121SKalle Valo wep_cmd->key[i].key_offset = i; 978e705c121SKalle Valo not_empty = 1; 979e705c121SKalle Valo } else { 980e705c121SKalle Valo wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; 981e705c121SKalle Valo } 982e705c121SKalle Valo 983e705c121SKalle Valo wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size; 984e705c121SKalle Valo memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key, 985e705c121SKalle Valo ctx->wep_keys[i].key_size); 986e705c121SKalle Valo } 987e705c121SKalle Valo 988e705c121SKalle Valo wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; 989e705c121SKalle Valo wep_cmd->num_keys = WEP_KEYS_MAX; 990e705c121SKalle Valo 991e705c121SKalle Valo cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; 992e705c121SKalle Valo 993e705c121SKalle Valo cmd.len[0] = cmd_size; 994e705c121SKalle Valo 995e705c121SKalle Valo if (not_empty || send_if_empty) 996e705c121SKalle Valo return iwl_dvm_send_cmd(priv, &cmd); 997e705c121SKalle Valo else 998e705c121SKalle Valo return 0; 999e705c121SKalle Valo } 1000e705c121SKalle Valo 1001e705c121SKalle Valo int iwl_restore_default_wep_keys(struct iwl_priv *priv, 1002e705c121SKalle Valo struct iwl_rxon_context *ctx) 1003e705c121SKalle Valo { 1004e705c121SKalle Valo lockdep_assert_held(&priv->mutex); 1005e705c121SKalle Valo 1006e705c121SKalle Valo return iwl_send_static_wepkey_cmd(priv, ctx, false); 1007e705c121SKalle Valo } 1008e705c121SKalle Valo 1009e705c121SKalle Valo int iwl_remove_default_wep_key(struct iwl_priv *priv, 1010e705c121SKalle Valo struct iwl_rxon_context *ctx, 1011e705c121SKalle Valo struct ieee80211_key_conf *keyconf) 1012e705c121SKalle Valo { 1013e705c121SKalle Valo int ret; 1014e705c121SKalle Valo 1015e705c121SKalle Valo lockdep_assert_held(&priv->mutex); 1016e705c121SKalle Valo 1017e705c121SKalle Valo IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", 1018e705c121SKalle Valo keyconf->keyidx); 1019e705c121SKalle Valo 1020e705c121SKalle Valo memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); 1021e705c121SKalle Valo if (iwl_is_rfkill(priv)) { 1022e705c121SKalle Valo IWL_DEBUG_WEP(priv, 1023e705c121SKalle Valo "Not sending REPLY_WEPKEY command due to RFKILL.\n"); 1024e705c121SKalle Valo /* but keys in device are clear anyway so return success */ 1025e705c121SKalle Valo return 0; 1026e705c121SKalle Valo } 1027e705c121SKalle Valo ret = iwl_send_static_wepkey_cmd(priv, ctx, 1); 1028e705c121SKalle Valo IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", 1029e705c121SKalle Valo keyconf->keyidx, ret); 1030e705c121SKalle Valo 1031e705c121SKalle Valo return ret; 1032e705c121SKalle Valo } 1033e705c121SKalle Valo 1034e705c121SKalle Valo int iwl_set_default_wep_key(struct iwl_priv *priv, 1035e705c121SKalle Valo struct iwl_rxon_context *ctx, 1036e705c121SKalle Valo struct ieee80211_key_conf *keyconf) 1037e705c121SKalle Valo { 1038e705c121SKalle Valo int ret; 1039e705c121SKalle Valo 1040e705c121SKalle Valo lockdep_assert_held(&priv->mutex); 1041e705c121SKalle Valo 1042e705c121SKalle Valo if (keyconf->keylen != WEP_KEY_LEN_128 && 1043e705c121SKalle Valo keyconf->keylen != WEP_KEY_LEN_64) { 1044e705c121SKalle Valo IWL_DEBUG_WEP(priv, 1045e705c121SKalle Valo "Bad WEP key length %d\n", keyconf->keylen); 1046e705c121SKalle Valo return -EINVAL; 1047e705c121SKalle Valo } 1048e705c121SKalle Valo 1049e705c121SKalle Valo keyconf->hw_key_idx = IWLAGN_HW_KEY_DEFAULT; 1050e705c121SKalle Valo 1051e705c121SKalle Valo ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; 1052e705c121SKalle Valo memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key, 1053e705c121SKalle Valo keyconf->keylen); 1054e705c121SKalle Valo 1055e705c121SKalle Valo ret = iwl_send_static_wepkey_cmd(priv, ctx, false); 1056e705c121SKalle Valo IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", 1057e705c121SKalle Valo keyconf->keylen, keyconf->keyidx, ret); 1058e705c121SKalle Valo 1059e705c121SKalle Valo return ret; 1060e705c121SKalle Valo } 1061e705c121SKalle Valo 1062e705c121SKalle Valo /* 1063e705c121SKalle Valo * dynamic (per-station) keys 1064e705c121SKalle Valo * 1065e705c121SKalle Valo * The dynamic keys are a little more complicated. The device has 1066e705c121SKalle Valo * a key cache of up to STA_KEY_MAX_NUM/STA_KEY_MAX_NUM_PAN keys. 1067e705c121SKalle Valo * These are linked to stations by a table that contains an index 1068e705c121SKalle Valo * into the key table for each station/key index/{mcast,unicast}, 1069e705c121SKalle Valo * i.e. it's basically an array of pointers like this: 1070e705c121SKalle Valo * key_offset_t key_mapping[NUM_STATIONS][4][2]; 1071e705c121SKalle Valo * (it really works differently, but you can think of it as such) 1072e705c121SKalle Valo * 1073e705c121SKalle Valo * The key uploading and linking happens in the same command, the 1074e705c121SKalle Valo * add station command with STA_MODIFY_KEY_MASK. 1075e705c121SKalle Valo */ 1076e705c121SKalle Valo 1077e705c121SKalle Valo static u8 iwlagn_key_sta_id(struct iwl_priv *priv, 1078e705c121SKalle Valo struct ieee80211_vif *vif, 1079e705c121SKalle Valo struct ieee80211_sta *sta) 1080e705c121SKalle Valo { 1081e705c121SKalle Valo struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 1082e705c121SKalle Valo 1083e705c121SKalle Valo if (sta) 1084e705c121SKalle Valo return iwl_sta_id(sta); 1085e705c121SKalle Valo 1086e705c121SKalle Valo /* 1087e705c121SKalle Valo * The device expects GTKs for station interfaces to be 1088e705c121SKalle Valo * installed as GTKs for the AP station. If we have no 1089e705c121SKalle Valo * station ID, then use the ap_sta_id in that case. 1090e705c121SKalle Valo */ 1091e705c121SKalle Valo if (vif->type == NL80211_IFTYPE_STATION && vif_priv->ctx) 1092e705c121SKalle Valo return vif_priv->ctx->ap_sta_id; 1093e705c121SKalle Valo 1094e705c121SKalle Valo return IWL_INVALID_STATION; 1095e705c121SKalle Valo } 1096e705c121SKalle Valo 1097e705c121SKalle Valo static int iwlagn_send_sta_key(struct iwl_priv *priv, 1098e705c121SKalle Valo struct ieee80211_key_conf *keyconf, 1099e705c121SKalle Valo u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k, 1100e705c121SKalle Valo u32 cmd_flags) 1101e705c121SKalle Valo { 1102e705c121SKalle Valo __le16 key_flags; 1103e705c121SKalle Valo struct iwl_addsta_cmd sta_cmd; 1104e705c121SKalle Valo int i; 1105e705c121SKalle Valo 1106e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 1107e705c121SKalle Valo memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); 1108e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 1109e705c121SKalle Valo 1110e705c121SKalle Valo key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); 1111e705c121SKalle Valo key_flags |= STA_KEY_FLG_MAP_KEY_MSK; 1112e705c121SKalle Valo 1113e705c121SKalle Valo switch (keyconf->cipher) { 1114e705c121SKalle Valo case WLAN_CIPHER_SUITE_CCMP: 1115e705c121SKalle Valo key_flags |= STA_KEY_FLG_CCMP; 1116e705c121SKalle Valo memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen); 1117e705c121SKalle Valo break; 1118e705c121SKalle Valo case WLAN_CIPHER_SUITE_TKIP: 1119e705c121SKalle Valo key_flags |= STA_KEY_FLG_TKIP; 1120e705c121SKalle Valo sta_cmd.key.tkip_rx_tsc_byte2 = tkip_iv32; 1121e705c121SKalle Valo for (i = 0; i < 5; i++) 1122e705c121SKalle Valo sta_cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]); 1123e705c121SKalle Valo memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen); 1124e705c121SKalle Valo break; 1125e705c121SKalle Valo case WLAN_CIPHER_SUITE_WEP104: 1126e705c121SKalle Valo key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; 1127e705c121SKalle Valo /* fall through */ 1128e705c121SKalle Valo case WLAN_CIPHER_SUITE_WEP40: 1129e705c121SKalle Valo key_flags |= STA_KEY_FLG_WEP; 1130e705c121SKalle Valo memcpy(&sta_cmd.key.key[3], keyconf->key, keyconf->keylen); 1131e705c121SKalle Valo break; 1132e705c121SKalle Valo default: 1133e705c121SKalle Valo WARN_ON(1); 1134e705c121SKalle Valo return -EINVAL; 1135e705c121SKalle Valo } 1136e705c121SKalle Valo 1137e705c121SKalle Valo if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 1138e705c121SKalle Valo key_flags |= STA_KEY_MULTICAST_MSK; 1139e705c121SKalle Valo 1140e705c121SKalle Valo /* key pointer (offset) */ 1141e705c121SKalle Valo sta_cmd.key.key_offset = keyconf->hw_key_idx; 1142e705c121SKalle Valo 1143e705c121SKalle Valo sta_cmd.key.key_flags = key_flags; 1144e705c121SKalle Valo sta_cmd.mode = STA_CONTROL_MODIFY_MSK; 1145e705c121SKalle Valo sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK; 1146e705c121SKalle Valo 1147e705c121SKalle Valo return iwl_send_add_sta(priv, &sta_cmd, cmd_flags); 1148e705c121SKalle Valo } 1149e705c121SKalle Valo 1150e705c121SKalle Valo void iwl_update_tkip_key(struct iwl_priv *priv, 1151e705c121SKalle Valo struct ieee80211_vif *vif, 1152e705c121SKalle Valo struct ieee80211_key_conf *keyconf, 1153e705c121SKalle Valo struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) 1154e705c121SKalle Valo { 1155e705c121SKalle Valo u8 sta_id = iwlagn_key_sta_id(priv, vif, sta); 1156e705c121SKalle Valo 1157e705c121SKalle Valo if (sta_id == IWL_INVALID_STATION) 1158e705c121SKalle Valo return; 1159e705c121SKalle Valo 1160e705c121SKalle Valo if (iwl_scan_cancel(priv)) { 1161e705c121SKalle Valo /* cancel scan failed, just live w/ bad key and rely 1162e705c121SKalle Valo briefly on SW decryption */ 1163e705c121SKalle Valo return; 1164e705c121SKalle Valo } 1165e705c121SKalle Valo 1166e705c121SKalle Valo iwlagn_send_sta_key(priv, keyconf, sta_id, 1167e705c121SKalle Valo iv32, phase1key, CMD_ASYNC); 1168e705c121SKalle Valo } 1169e705c121SKalle Valo 1170e705c121SKalle Valo int iwl_remove_dynamic_key(struct iwl_priv *priv, 1171e705c121SKalle Valo struct iwl_rxon_context *ctx, 1172e705c121SKalle Valo struct ieee80211_key_conf *keyconf, 1173e705c121SKalle Valo struct ieee80211_sta *sta) 1174e705c121SKalle Valo { 1175e705c121SKalle Valo struct iwl_addsta_cmd sta_cmd; 1176e705c121SKalle Valo u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); 1177e705c121SKalle Valo __le16 key_flags; 1178e705c121SKalle Valo 1179e705c121SKalle Valo /* if station isn't there, neither is the key */ 1180e705c121SKalle Valo if (sta_id == IWL_INVALID_STATION) 1181e705c121SKalle Valo return -ENOENT; 1182e705c121SKalle Valo 1183e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 1184e705c121SKalle Valo memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); 1185e705c121SKalle Valo if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) 1186e705c121SKalle Valo sta_id = IWL_INVALID_STATION; 1187e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 1188e705c121SKalle Valo 1189e705c121SKalle Valo if (sta_id == IWL_INVALID_STATION) 1190e705c121SKalle Valo return 0; 1191e705c121SKalle Valo 1192e705c121SKalle Valo lockdep_assert_held(&priv->mutex); 1193e705c121SKalle Valo 1194e705c121SKalle Valo ctx->key_mapping_keys--; 1195e705c121SKalle Valo 1196e705c121SKalle Valo IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n", 1197e705c121SKalle Valo keyconf->keyidx, sta_id); 1198e705c121SKalle Valo 1199e705c121SKalle Valo if (!test_and_clear_bit(keyconf->hw_key_idx, &priv->ucode_key_table)) 1200e705c121SKalle Valo IWL_ERR(priv, "offset %d not used in uCode key table.\n", 1201e705c121SKalle Valo keyconf->hw_key_idx); 1202e705c121SKalle Valo 1203e705c121SKalle Valo key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); 1204e705c121SKalle Valo key_flags |= STA_KEY_FLG_MAP_KEY_MSK | STA_KEY_FLG_NO_ENC | 1205e705c121SKalle Valo STA_KEY_FLG_INVALID; 1206e705c121SKalle Valo 1207e705c121SKalle Valo if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 1208e705c121SKalle Valo key_flags |= STA_KEY_MULTICAST_MSK; 1209e705c121SKalle Valo 1210e705c121SKalle Valo sta_cmd.key.key_flags = key_flags; 1211e705c121SKalle Valo sta_cmd.key.key_offset = keyconf->hw_key_idx; 1212e705c121SKalle Valo sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK; 1213e705c121SKalle Valo sta_cmd.mode = STA_CONTROL_MODIFY_MSK; 1214e705c121SKalle Valo 1215e705c121SKalle Valo return iwl_send_add_sta(priv, &sta_cmd, 0); 1216e705c121SKalle Valo } 1217e705c121SKalle Valo 1218e705c121SKalle Valo int iwl_set_dynamic_key(struct iwl_priv *priv, 1219e705c121SKalle Valo struct iwl_rxon_context *ctx, 1220e705c121SKalle Valo struct ieee80211_key_conf *keyconf, 1221e705c121SKalle Valo struct ieee80211_sta *sta) 1222e705c121SKalle Valo { 1223e705c121SKalle Valo struct ieee80211_key_seq seq; 1224e705c121SKalle Valo u16 p1k[5]; 1225e705c121SKalle Valo int ret; 1226e705c121SKalle Valo u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); 1227e705c121SKalle Valo const u8 *addr; 1228e705c121SKalle Valo 1229e705c121SKalle Valo if (sta_id == IWL_INVALID_STATION) 1230e705c121SKalle Valo return -EINVAL; 1231e705c121SKalle Valo 1232e705c121SKalle Valo lockdep_assert_held(&priv->mutex); 1233e705c121SKalle Valo 1234e705c121SKalle Valo keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv); 1235e705c121SKalle Valo if (keyconf->hw_key_idx == WEP_INVALID_OFFSET) 1236e705c121SKalle Valo return -ENOSPC; 1237e705c121SKalle Valo 1238e705c121SKalle Valo ctx->key_mapping_keys++; 1239e705c121SKalle Valo 1240e705c121SKalle Valo switch (keyconf->cipher) { 1241e705c121SKalle Valo case WLAN_CIPHER_SUITE_TKIP: 1242e705c121SKalle Valo if (sta) 1243e705c121SKalle Valo addr = sta->addr; 1244e705c121SKalle Valo else /* station mode case only */ 1245e705c121SKalle Valo addr = ctx->active.bssid_addr; 1246e705c121SKalle Valo 1247e705c121SKalle Valo /* pre-fill phase 1 key into device cache */ 1248e705c121SKalle Valo ieee80211_get_key_rx_seq(keyconf, 0, &seq); 1249e705c121SKalle Valo ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k); 1250e705c121SKalle Valo ret = iwlagn_send_sta_key(priv, keyconf, sta_id, 1251e705c121SKalle Valo seq.tkip.iv32, p1k, 0); 1252e705c121SKalle Valo break; 1253e705c121SKalle Valo case WLAN_CIPHER_SUITE_CCMP: 1254e705c121SKalle Valo case WLAN_CIPHER_SUITE_WEP40: 1255e705c121SKalle Valo case WLAN_CIPHER_SUITE_WEP104: 1256e705c121SKalle Valo ret = iwlagn_send_sta_key(priv, keyconf, sta_id, 1257e705c121SKalle Valo 0, NULL, 0); 1258e705c121SKalle Valo break; 1259e705c121SKalle Valo default: 1260e705c121SKalle Valo IWL_ERR(priv, "Unknown cipher %x\n", keyconf->cipher); 1261e705c121SKalle Valo ret = -EINVAL; 1262e705c121SKalle Valo } 1263e705c121SKalle Valo 1264e705c121SKalle Valo if (ret) { 1265e705c121SKalle Valo ctx->key_mapping_keys--; 1266e705c121SKalle Valo clear_bit(keyconf->hw_key_idx, &priv->ucode_key_table); 1267e705c121SKalle Valo } 1268e705c121SKalle Valo 1269e705c121SKalle Valo IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n", 1270e705c121SKalle Valo keyconf->cipher, keyconf->keylen, keyconf->keyidx, 1271e705c121SKalle Valo sta ? sta->addr : NULL, ret); 1272e705c121SKalle Valo 1273e705c121SKalle Valo return ret; 1274e705c121SKalle Valo } 1275e705c121SKalle Valo 1276e705c121SKalle Valo /** 1277e705c121SKalle Valo * iwlagn_alloc_bcast_station - add broadcast station into driver's station table. 1278e705c121SKalle Valo * 1279e705c121SKalle Valo * This adds the broadcast station into the driver's station table 1280e705c121SKalle Valo * and marks it driver active, so that it will be restored to the 1281e705c121SKalle Valo * device at the next best time. 1282e705c121SKalle Valo */ 1283e705c121SKalle Valo int iwlagn_alloc_bcast_station(struct iwl_priv *priv, 1284e705c121SKalle Valo struct iwl_rxon_context *ctx) 1285e705c121SKalle Valo { 1286e705c121SKalle Valo struct iwl_link_quality_cmd *link_cmd; 1287e705c121SKalle Valo u8 sta_id; 1288e705c121SKalle Valo 1289e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 1290e705c121SKalle Valo sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); 1291e705c121SKalle Valo if (sta_id == IWL_INVALID_STATION) { 1292e705c121SKalle Valo IWL_ERR(priv, "Unable to prepare broadcast station\n"); 1293e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 1294e705c121SKalle Valo 1295e705c121SKalle Valo return -EINVAL; 1296e705c121SKalle Valo } 1297e705c121SKalle Valo 1298e705c121SKalle Valo priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; 1299e705c121SKalle Valo priv->stations[sta_id].used |= IWL_STA_BCAST; 1300e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 1301e705c121SKalle Valo 1302e705c121SKalle Valo link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); 1303e705c121SKalle Valo if (!link_cmd) { 1304e705c121SKalle Valo IWL_ERR(priv, 1305e705c121SKalle Valo "Unable to initialize rate scaling for bcast station.\n"); 1306e705c121SKalle Valo return -ENOMEM; 1307e705c121SKalle Valo } 1308e705c121SKalle Valo 1309e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 1310e705c121SKalle Valo priv->stations[sta_id].lq = link_cmd; 1311e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 1312e705c121SKalle Valo 1313e705c121SKalle Valo return 0; 1314e705c121SKalle Valo } 1315e705c121SKalle Valo 1316e705c121SKalle Valo /** 1317e705c121SKalle Valo * iwl_update_bcast_station - update broadcast station's LQ command 1318e705c121SKalle Valo * 1319e705c121SKalle Valo * Only used by iwlagn. Placed here to have all bcast station management 1320e705c121SKalle Valo * code together. 1321e705c121SKalle Valo */ 1322e705c121SKalle Valo int iwl_update_bcast_station(struct iwl_priv *priv, 1323e705c121SKalle Valo struct iwl_rxon_context *ctx) 1324e705c121SKalle Valo { 1325e705c121SKalle Valo struct iwl_link_quality_cmd *link_cmd; 1326e705c121SKalle Valo u8 sta_id = ctx->bcast_sta_id; 1327e705c121SKalle Valo 1328e705c121SKalle Valo link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); 1329e705c121SKalle Valo if (!link_cmd) { 1330e705c121SKalle Valo IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); 1331e705c121SKalle Valo return -ENOMEM; 1332e705c121SKalle Valo } 1333e705c121SKalle Valo 1334e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 1335e705c121SKalle Valo if (priv->stations[sta_id].lq) 1336e705c121SKalle Valo kfree(priv->stations[sta_id].lq); 1337e705c121SKalle Valo else 1338e705c121SKalle Valo IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); 1339e705c121SKalle Valo priv->stations[sta_id].lq = link_cmd; 1340e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 1341e705c121SKalle Valo 1342e705c121SKalle Valo return 0; 1343e705c121SKalle Valo } 1344e705c121SKalle Valo 1345e705c121SKalle Valo int iwl_update_bcast_stations(struct iwl_priv *priv) 1346e705c121SKalle Valo { 1347e705c121SKalle Valo struct iwl_rxon_context *ctx; 1348e705c121SKalle Valo int ret = 0; 1349e705c121SKalle Valo 1350e705c121SKalle Valo for_each_context(priv, ctx) { 1351e705c121SKalle Valo ret = iwl_update_bcast_station(priv, ctx); 1352e705c121SKalle Valo if (ret) 1353e705c121SKalle Valo break; 1354e705c121SKalle Valo } 1355e705c121SKalle Valo 1356e705c121SKalle Valo return ret; 1357e705c121SKalle Valo } 1358e705c121SKalle Valo 1359e705c121SKalle Valo /** 1360e705c121SKalle Valo * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table 1361e705c121SKalle Valo */ 1362e705c121SKalle Valo int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) 1363e705c121SKalle Valo { 1364e705c121SKalle Valo struct iwl_addsta_cmd sta_cmd; 1365e705c121SKalle Valo 1366e705c121SKalle Valo lockdep_assert_held(&priv->mutex); 1367e705c121SKalle Valo 1368e705c121SKalle Valo /* Remove "disable" flag, to enable Tx for this TID */ 1369e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 1370e705c121SKalle Valo priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; 1371e705c121SKalle Valo priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); 1372e705c121SKalle Valo priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1373e705c121SKalle Valo memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); 1374e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 1375e705c121SKalle Valo 1376e705c121SKalle Valo return iwl_send_add_sta(priv, &sta_cmd, 0); 1377e705c121SKalle Valo } 1378e705c121SKalle Valo 1379e705c121SKalle Valo int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, 1380e705c121SKalle Valo int tid, u16 ssn) 1381e705c121SKalle Valo { 1382e705c121SKalle Valo int sta_id; 1383e705c121SKalle Valo struct iwl_addsta_cmd sta_cmd; 1384e705c121SKalle Valo 1385e705c121SKalle Valo lockdep_assert_held(&priv->mutex); 1386e705c121SKalle Valo 1387e705c121SKalle Valo sta_id = iwl_sta_id(sta); 1388e705c121SKalle Valo if (sta_id == IWL_INVALID_STATION) 1389e705c121SKalle Valo return -ENXIO; 1390e705c121SKalle Valo 1391e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 1392e705c121SKalle Valo priv->stations[sta_id].sta.station_flags_msk = 0; 1393e705c121SKalle Valo priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; 1394e705c121SKalle Valo priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; 1395e705c121SKalle Valo priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); 1396e705c121SKalle Valo priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1397e705c121SKalle Valo memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); 1398e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 1399e705c121SKalle Valo 1400e705c121SKalle Valo return iwl_send_add_sta(priv, &sta_cmd, 0); 1401e705c121SKalle Valo } 1402e705c121SKalle Valo 1403e705c121SKalle Valo int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, 1404e705c121SKalle Valo int tid) 1405e705c121SKalle Valo { 1406e705c121SKalle Valo int sta_id; 1407e705c121SKalle Valo struct iwl_addsta_cmd sta_cmd; 1408e705c121SKalle Valo 1409e705c121SKalle Valo lockdep_assert_held(&priv->mutex); 1410e705c121SKalle Valo 1411e705c121SKalle Valo sta_id = iwl_sta_id(sta); 1412e705c121SKalle Valo if (sta_id == IWL_INVALID_STATION) { 1413e705c121SKalle Valo IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); 1414e705c121SKalle Valo return -ENXIO; 1415e705c121SKalle Valo } 1416e705c121SKalle Valo 1417e705c121SKalle Valo spin_lock_bh(&priv->sta_lock); 1418e705c121SKalle Valo priv->stations[sta_id].sta.station_flags_msk = 0; 1419e705c121SKalle Valo priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; 1420e705c121SKalle Valo priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; 1421e705c121SKalle Valo priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1422e705c121SKalle Valo memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); 1423e705c121SKalle Valo spin_unlock_bh(&priv->sta_lock); 1424e705c121SKalle Valo 1425e705c121SKalle Valo return iwl_send_add_sta(priv, &sta_cmd, 0); 1426e705c121SKalle Valo } 1427e705c121SKalle Valo 1428e705c121SKalle Valo 1429e705c121SKalle Valo 1430e705c121SKalle Valo void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) 1431e705c121SKalle Valo { 1432e705c121SKalle Valo struct iwl_addsta_cmd cmd = { 1433e705c121SKalle Valo .mode = STA_CONTROL_MODIFY_MSK, 1434e705c121SKalle Valo .station_flags = STA_FLG_PWR_SAVE_MSK, 1435e705c121SKalle Valo .station_flags_msk = STA_FLG_PWR_SAVE_MSK, 1436e705c121SKalle Valo .sta.sta_id = sta_id, 1437e705c121SKalle Valo .sta.modify_mask = STA_MODIFY_SLEEP_TX_COUNT_MSK, 1438e705c121SKalle Valo .sleep_tx_count = cpu_to_le16(cnt), 1439e705c121SKalle Valo }; 1440e705c121SKalle Valo 1441e705c121SKalle Valo iwl_send_add_sta(priv, &cmd, CMD_ASYNC); 1442e705c121SKalle Valo } 1443