diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-02-18 13:47:13 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-02-18 13:47:13 -0500 |
commit | 98d5fac2330779e6eea6431a90b44c7476260dcc (patch) | |
tree | 99870656d835fc6c12093bc67517956cc7b3d6ec /drivers/net/wireless/iwlwifi/mvm/sta.c | |
parent | 4153577a8d318ae02b3791341e10e78416de402f (diff) | |
parent | 9e97d14b4923da524d202f2e005d5d30b70db9d6 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/ti/wlcore/sdio.c
drivers/net/wireless/ti/wlcore/spi.c
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/sta.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/sta.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 69603c3b2b39..a1eb692d7fad 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -81,8 +81,9 @@ static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm) return IWL_MVM_STATION_COUNT; } -/* add a NEW station to fw */ -int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta) +/* send station add/update command to firmware */ +int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + bool update) { struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; struct iwl_mvm_add_sta_cmd add_sta_cmd; @@ -94,8 +95,11 @@ int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta) add_sta_cmd.sta_id = mvm_sta->sta_id; add_sta_cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); - add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk); - memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN); + if (!update) { + add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk); + memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN); + } + add_sta_cmd.add_modify = update ? 1 : 0; /* STA_FLG_FAT_EN_MSK ? */ /* STA_FLG_MIMO_EN_MSK ? */ @@ -181,7 +185,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, /* for HW restart - need to reset the seq_number etc... */ memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data)); - ret = iwl_mvm_sta_add_to_fw(mvm, sta); + ret = iwl_mvm_sta_send_to_fw(mvm, sta, false); if (ret) return ret; @@ -195,6 +199,13 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, return 0; } +int iwl_mvm_update_sta(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + return iwl_mvm_sta_send_to_fw(mvm, sta, true); +} + int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, bool drain) { @@ -1116,7 +1127,8 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, if (WARN_ON_ONCE(mvm_sta->vif != vif)) return -EINVAL; - key_flags = cpu_to_le16(keyconf->keyidx & STA_KEY_FLG_KEYID_MSK); + key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & + STA_KEY_FLG_KEYID_MSK); key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP); key_flags |= cpu_to_le16(STA_KEY_NOT_VALID); @@ -1154,14 +1166,26 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) { - struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; + struct iwl_mvm_sta *mvm_sta; u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); - if (sta_id == IWL_INVALID_STATION) + if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) return; + rcu_read_lock(); + + if (!sta) { + sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); + if (WARN_ON(IS_ERR_OR_NULL(sta))) { + rcu_read_unlock(); + return; + } + } + + mvm_sta = (void *)sta->drv_priv; iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id, iv32, phase1key, CMD_ASYNC); + rcu_read_unlock(); } void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id) |