aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-sta.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-11-12 16:14:05 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-11-25 16:41:06 -0500
commit9f58671e8d4f4896acea30020308ce72bf94ec6e (patch)
tree8c8df09be1ed592ef0640e8f1b9a681e358c571c /drivers/net/wireless/iwlwifi/iwl-sta.c
parentcee53ddb46eb520079335d0868d0e81c8d311089 (diff)
iwlwifi: consolidate station management code
This patch moves code around and group most of the station management code into iwl-sta.c No functional changes (yet) Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-sta.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c134
1 files changed, 129 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 0c5f1221b8f3..109136a09c54 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -132,7 +132,7 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
132 return 1; 132 return 1;
133} 133}
134 134
135int iwl_send_add_sta(struct iwl_priv *priv, 135static int iwl_send_add_sta(struct iwl_priv *priv,
136 struct iwl_addsta_cmd *sta, u8 flags) 136 struct iwl_addsta_cmd *sta, u8 flags)
137{ 137{
138 struct iwl_rx_packet *res = NULL; 138 struct iwl_rx_packet *res = NULL;
@@ -180,7 +180,6 @@ int iwl_send_add_sta(struct iwl_priv *priv,
180 180
181 return ret; 181 return ret;
182} 182}
183EXPORT_SYMBOL(iwl_send_add_sta);
184 183
185static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, 184static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
186 struct ieee80211_sta_ht_cap *sta_ht_inf) 185 struct ieee80211_sta_ht_cap *sta_ht_inf)
@@ -703,6 +702,55 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
703 return ret; 702 return ret;
704} 703}
705 704
705void iwl_update_tkip_key(struct iwl_priv *priv,
706 struct ieee80211_key_conf *keyconf,
707 const u8 *addr, u32 iv32, u16 *phase1key)
708{
709 u8 sta_id = IWL_INVALID_STATION;
710 unsigned long flags;
711 __le16 key_flags = 0;
712 int i;
713 DECLARE_MAC_BUF(mac);
714
715 sta_id = iwl_find_station(priv, addr);
716 if (sta_id == IWL_INVALID_STATION) {
717 IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
718 addr);
719 return;
720 }
721
722 if (iwl_scan_cancel(priv)) {
723 /* cancel scan failed, just live w/ bad key and rely
724 briefly on SW decryption */
725 return;
726 }
727
728 key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
729 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
730 key_flags &= ~STA_KEY_FLG_INVALID;
731
732 if (sta_id == priv->hw_params.bcast_sta_id)
733 key_flags |= STA_KEY_MULTICAST_MSK;
734
735 spin_lock_irqsave(&priv->sta_lock, flags);
736
737 priv->stations[sta_id].sta.key.key_flags = key_flags;
738 priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
739
740 for (i = 0; i < 5; i++)
741 priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
742 cpu_to_le16(phase1key[i]);
743
744 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
745 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
746
747 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
748
749 spin_unlock_irqrestore(&priv->sta_lock, flags);
750
751}
752EXPORT_SYMBOL(iwl_update_tkip_key);
753
706int iwl_remove_dynamic_key(struct iwl_priv *priv, 754int iwl_remove_dynamic_key(struct iwl_priv *priv,
707 struct ieee80211_key_conf *keyconf, 755 struct ieee80211_key_conf *keyconf,
708 u8 sta_id) 756 u8 sta_id)
@@ -989,9 +1037,9 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
989EXPORT_SYMBOL(iwl_get_sta_id); 1037EXPORT_SYMBOL(iwl_get_sta_id);
990 1038
991/** 1039/**
992 * iwl_sta_modify_enable_tid_tx - Enable Tx for this TID in station table 1040 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
993 */ 1041 */
994void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid) 1042void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
995{ 1043{
996 unsigned long flags; 1044 unsigned long flags;
997 1045
@@ -1004,5 +1052,81 @@ void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid)
1004 1052
1005 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1053 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1006} 1054}
1007EXPORT_SYMBOL(iwl_sta_modify_enable_tid_tx); 1055EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
1056
1057int iwl_sta_rx_agg_start(struct iwl_priv *priv,
1058 const u8 *addr, int tid, u16 ssn)
1059{
1060 unsigned long flags;
1061 int sta_id;
1062
1063 sta_id = iwl_find_station(priv, addr);
1064 if (sta_id == IWL_INVALID_STATION)
1065 return -ENXIO;
1066
1067 spin_lock_irqsave(&priv->sta_lock, flags);
1068 priv->stations[sta_id].sta.station_flags_msk = 0;
1069 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
1070 priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
1071 priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
1072 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1073 spin_unlock_irqrestore(&priv->sta_lock, flags);
1074
1075 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta,
1076 CMD_ASYNC);
1077}
1078EXPORT_SYMBOL(iwl_sta_rx_agg_start);
1079
1080int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid)
1081{
1082 unsigned long flags;
1083 int sta_id;
1084
1085 sta_id = iwl_find_station(priv, addr);
1086 if (sta_id == IWL_INVALID_STATION)
1087 return -ENXIO;
1088
1089 spin_lock_irqsave(&priv->sta_lock, flags);
1090 priv->stations[sta_id].sta.station_flags_msk = 0;
1091 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
1092 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
1093 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1094 spin_unlock_irqrestore(&priv->sta_lock, flags);
1095
1096 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta,
1097 CMD_ASYNC);
1098}
1099EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
1100
1101static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1102{
1103 unsigned long flags;
1104
1105 spin_lock_irqsave(&priv->sta_lock, flags);
1106 priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
1107 priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
1108 priv->stations[sta_id].sta.sta.modify_mask = 0;
1109 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1110 spin_unlock_irqrestore(&priv->sta_lock, flags);
1111
1112 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1113}
1114
1115void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
1116{
1117 /* FIXME: need locking over ps_status ??? */
1118 u8 sta_id = iwl_find_station(priv, addr);
1119
1120 if (sta_id != IWL_INVALID_STATION) {
1121 u8 sta_awake = priv->stations[sta_id].
1122 ps_status == STA_PS_STATUS_WAKE;
1123
1124 if (sta_awake && ps_bit)
1125 priv->stations[sta_id].ps_status = STA_PS_STATUS_SLEEP;
1126 else if (!sta_awake && !ps_bit) {
1127 iwl_sta_modify_ps_wake(priv, sta_id);
1128 priv->stations[sta_id].ps_status = STA_PS_STATUS_WAKE;
1129 }
1130 }
1131}
1008 1132