aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2009-06-03 14:44:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-06-04 10:56:20 -0400
commitc587de0b8d6e194f7a1719fc6af8a81b4e8916d2 (patch)
tree1537752cd44caa46883d1bdc2c6b7f40b3ef2600 /drivers/net/wireless/iwlwifi/iwl3945-base.c
parent0aa8204b46e0fb155a98074d53f8b31ca04269b2 (diff)
iwlwifi: unify station management
This patch unifies 3945 and AGN station management It also removes useless struct iwl_station_mgmt ops and cleanups a bit the interface Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Tested-by: Abhijeet Kolekar <abhijeet.kolekar@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/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c196
1 files changed, 28 insertions, 168 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5c10b87d0336..745eaaec5954 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -95,144 +95,6 @@ struct iwl_mod_params iwl3945_mod_params = {
95 /* the rest are 0 by default */ 95 /* the rest are 0 by default */
96}; 96};
97 97
98/*************** STATION TABLE MANAGEMENT ****
99 * mac80211 should be examined to determine if sta_info is duplicating
100 * the functionality provided here
101 */
102
103/**************************************************************/
104#if 0 /* temporary disable till we add real remove station */
105/**
106 * iwl3945_remove_station - Remove driver's knowledge of station.
107 *
108 * NOTE: This does not remove station from device's station table.
109 */
110static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
111{
112 int index = IWL_INVALID_STATION;
113 int i;
114 unsigned long flags;
115
116 spin_lock_irqsave(&priv->sta_lock, flags);
117
118 if (is_ap)
119 index = IWL_AP_ID;
120 else if (is_broadcast_ether_addr(addr))
121 index = priv->hw_params.bcast_sta_id;
122 else
123 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
124 if (priv->stations_39[i].used &&
125 !compare_ether_addr(priv->stations_39[i].sta.sta.addr,
126 addr)) {
127 index = i;
128 break;
129 }
130
131 if (unlikely(index == IWL_INVALID_STATION))
132 goto out;
133
134 if (priv->stations_39[index].used) {
135 priv->stations_39[index].used = 0;
136 priv->num_stations--;
137 }
138
139 BUG_ON(priv->num_stations < 0);
140
141out:
142 spin_unlock_irqrestore(&priv->sta_lock, flags);
143 return 0;
144}
145#endif
146
147/**
148 * iwl3945_clear_stations_table - Clear the driver's station table
149 *
150 * NOTE: This does not clear or otherwise alter the device's station table.
151 */
152void iwl3945_clear_stations_table(struct iwl_priv *priv)
153{
154 unsigned long flags;
155
156 spin_lock_irqsave(&priv->sta_lock, flags);
157
158 priv->num_stations = 0;
159 memset(priv->stations_39, 0, sizeof(priv->stations_39));
160
161 spin_unlock_irqrestore(&priv->sta_lock, flags);
162}
163
164/**
165 * iwl3945_add_station - Add station to station tables in driver and device
166 */
167u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info)
168{
169 int i;
170 int index = IWL_INVALID_STATION;
171 struct iwl3945_station_entry *station;
172 unsigned long flags_spin;
173 u8 rate;
174
175 spin_lock_irqsave(&priv->sta_lock, flags_spin);
176 if (is_ap)
177 index = IWL_AP_ID;
178 else if (is_broadcast_ether_addr(addr))
179 index = priv->hw_params.bcast_sta_id;
180 else
181 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
182 if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,
183 addr)) {
184 index = i;
185 break;
186 }
187
188 if (!priv->stations_39[i].used &&
189 index == IWL_INVALID_STATION)
190 index = i;
191 }
192
193 /* These two conditions has the same outcome but keep them separate
194 since they have different meaning */
195 if (unlikely(index == IWL_INVALID_STATION)) {
196 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
197 return index;
198 }
199
200 if (priv->stations_39[index].used &&
201 !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {
202 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
203 return index;
204 }
205
206 IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);
207 station = &priv->stations_39[index];
208 station->used = 1;
209 priv->num_stations++;
210
211 /* Set up the REPLY_ADD_STA command to send to device */
212 memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd));
213 memcpy(station->sta.sta.addr, addr, ETH_ALEN);
214 station->sta.mode = 0;
215 station->sta.sta.sta_id = index;
216 station->sta.station_flags = 0;
217
218 if (priv->band == IEEE80211_BAND_5GHZ)
219 rate = IWL_RATE_6M_PLCP;
220 else
221 rate = IWL_RATE_1M_PLCP;
222
223 /* Turn on both antennas for the station... */
224 station->sta.rate_n_flags =
225 iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
226
227 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
228
229 /* Add station to device's station table */
230 iwl_send_add_sta(priv,
231 (struct iwl_addsta_cmd *)&station->sta, flags);
232 return index;
233
234}
235
236/** 98/**
237 * iwl3945_get_antenna_flags - Get antenna flags for RXON command 99 * iwl3945_get_antenna_flags - Get antenna flags for RXON command
238 * @priv: eeprom and antenna fields are used to determine antenna flags 100 * @priv: eeprom and antenna fields are used to determine antenna flags
@@ -289,32 +151,31 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
289 key_flags &= ~STA_KEY_FLG_INVALID; 151 key_flags &= ~STA_KEY_FLG_INVALID;
290 152
291 spin_lock_irqsave(&priv->sta_lock, flags); 153 spin_lock_irqsave(&priv->sta_lock, flags);
292 priv->stations_39[sta_id].keyinfo.alg = keyconf->alg; 154 priv->stations[sta_id].keyinfo.alg = keyconf->alg;
293 priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen; 155 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
294 memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key, 156 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
295 keyconf->keylen); 157 keyconf->keylen);
296 158
297 memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key, 159 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
298 keyconf->keylen); 160 keyconf->keylen);
299 161
300 if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) 162 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
301 == STA_KEY_FLG_NO_ENC) 163 == STA_KEY_FLG_NO_ENC)
302 priv->stations_39[sta_id].sta.key.key_offset = 164 priv->stations[sta_id].sta.key.key_offset =
303 iwl_get_free_ucode_key_index(priv); 165 iwl_get_free_ucode_key_index(priv);
304 /* else, we are overriding an existing key => no need to allocated room 166 /* else, we are overriding an existing key => no need to allocated room
305 * in uCode. */ 167 * in uCode. */
306 168
307 WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, 169 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
308 "no space for a new key"); 170 "no space for a new key");
309 171
310 priv->stations_39[sta_id].sta.key.key_flags = key_flags; 172 priv->stations[sta_id].sta.key.key_flags = key_flags;
311 priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 173 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
312 priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 174 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
313 175
314 IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); 176 IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
315 177
316 ret = iwl_send_add_sta(priv, 178 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
317 (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
318 179
319 spin_unlock_irqrestore(&priv->sta_lock, flags); 180 spin_unlock_irqrestore(&priv->sta_lock, flags);
320 181
@@ -340,17 +201,16 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
340 unsigned long flags; 201 unsigned long flags;
341 202
342 spin_lock_irqsave(&priv->sta_lock, flags); 203 spin_lock_irqsave(&priv->sta_lock, flags);
343 memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); 204 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
344 memset(&priv->stations_39[sta_id].sta.key, 0, 205 memset(&priv->stations[sta_id].sta.key, 0,
345 sizeof(struct iwl4965_keyinfo)); 206 sizeof(struct iwl4965_keyinfo));
346 priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; 207 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
347 priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 208 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
348 priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 209 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
349 spin_unlock_irqrestore(&priv->sta_lock, flags); 210 spin_unlock_irqrestore(&priv->sta_lock, flags);
350 211
351 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); 212 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
352 iwl_send_add_sta(priv, 213 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0);
353 (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
354 return 0; 214 return 0;
355} 215}
356 216
@@ -578,7 +438,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
578 int sta_id) 438 int sta_id)
579{ 439{
580 struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; 440 struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
581 struct iwl_hw_key *keyinfo = &priv->stations_39[sta_id].keyinfo; 441 struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
582 442
583 switch (keyinfo->alg) { 443 switch (keyinfo->alg) {
584 case ALG_CCMP: 444 case ALG_CCMP:
@@ -753,7 +613,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
753 if (ieee80211_is_data_qos(fc)) { 613 if (ieee80211_is_data_qos(fc)) {
754 qc = ieee80211_get_qos_ctl(hdr); 614 qc = ieee80211_get_qos_ctl(hdr);
755 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 615 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
756 seq_number = priv->stations_39[sta_id].tid[tid].seq_number & 616 seq_number = priv->stations[sta_id].tid[tid].seq_number &
757 IEEE80211_SCTL_SEQ; 617 IEEE80211_SCTL_SEQ;
758 hdr->seq_ctrl = cpu_to_le16(seq_number) | 618 hdr->seq_ctrl = cpu_to_le16(seq_number) |
759 (hdr->seq_ctrl & 619 (hdr->seq_ctrl &
@@ -813,7 +673,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
813 if (!ieee80211_has_morefrags(hdr->frame_control)) { 673 if (!ieee80211_has_morefrags(hdr->frame_control)) {
814 txq->need_update = 1; 674 txq->need_update = 1;
815 if (qc) 675 if (qc)
816 priv->stations_39[sta_id].tid[tid].seq_number = seq_number; 676 priv->stations[sta_id].tid[tid].seq_number = seq_number;
817 } else { 677 } else {
818 wait_write_ptr = 1; 678 wait_write_ptr = 1;
819 txq->need_update = 0; 679 txq->need_update = 0;
@@ -2589,7 +2449,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2589 goto restart; 2449 goto restart;
2590 } 2450 }
2591 2451
2592 priv->cfg->ops->smgmt->clear_station_table(priv); 2452 iwl_clear_stations_table(priv);
2593 2453
2594 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); 2454 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
2595 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); 2455 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
@@ -2681,7 +2541,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
2681 set_bit(STATUS_EXIT_PENDING, &priv->status); 2541 set_bit(STATUS_EXIT_PENDING, &priv->status);
2682 2542
2683 iwl3945_led_unregister(priv); 2543 iwl3945_led_unregister(priv);
2684 priv->cfg->ops->smgmt->clear_station_table(priv); 2544 iwl_clear_stations_table(priv);
2685 2545
2686 /* Unblock any waiting calls */ 2546 /* Unblock any waiting calls */
2687 wake_up_interruptible_all(&priv->wait_command_queue); 2547 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2833,7 +2693,7 @@ static int __iwl3945_up(struct iwl_priv *priv)
2833 2693
2834 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2694 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2835 2695
2836 priv->cfg->ops->smgmt->clear_station_table(priv); 2696 iwl_clear_stations_table(priv);
2837 2697
2838 /* load bootstrap state machine, 2698 /* load bootstrap state machine,
2839 * load bootstrap program into processor's memory, 2699 * load bootstrap program into processor's memory,
@@ -3247,7 +3107,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3247 case NL80211_IFTYPE_ADHOC: 3107 case NL80211_IFTYPE_ADHOC:
3248 3108
3249 priv->assoc_id = 1; 3109 priv->assoc_id = 1;
3250 priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0, NULL); 3110 iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL);
3251 iwl3945_sync_sta(priv, IWL_STA_ID, 3111 iwl3945_sync_sta(priv, IWL_STA_ID,
3252 (priv->band == IEEE80211_BAND_5GHZ) ? 3112 (priv->band == IEEE80211_BAND_5GHZ) ?
3253 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, 3113 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
@@ -3438,7 +3298,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3438 /* restore RXON assoc */ 3298 /* restore RXON assoc */
3439 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3299 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3440 iwlcore_commit_rxon(priv); 3300 iwlcore_commit_rxon(priv);
3441 priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL); 3301 iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL);
3442 } 3302 }
3443 iwl3945_send_beacon_cmd(priv); 3303 iwl3945_send_beacon_cmd(priv);
3444 3304
@@ -3469,7 +3329,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3469 static_key = !iwl_is_associated(priv); 3329 static_key = !iwl_is_associated(priv);
3470 3330
3471 if (!static_key) { 3331 if (!static_key) {
3472 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 3332 sta_id = iwl_find_station(priv, addr);
3473 if (sta_id == IWL_INVALID_STATION) { 3333 if (sta_id == IWL_INVALID_STATION) {
3474 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 3334 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
3475 addr); 3335 addr);
@@ -4044,7 +3904,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
4044 mutex_init(&priv->mutex); 3904 mutex_init(&priv->mutex);
4045 3905
4046 /* Clear the driver's (not device's) station table */ 3906 /* Clear the driver's (not device's) station table */
4047 priv->cfg->ops->smgmt->clear_station_table(priv); 3907 iwl_clear_stations_table(priv);
4048 3908
4049 priv->data_retry_limit = -1; 3909 priv->data_retry_limit = -1;
4050 priv->ieee_channels = NULL; 3910 priv->ieee_channels = NULL;
@@ -4407,7 +4267,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4407 iwl3945_hw_txq_ctx_free(priv); 4267 iwl3945_hw_txq_ctx_free(priv);
4408 4268
4409 iwl3945_unset_hw_params(priv); 4269 iwl3945_unset_hw_params(priv);
4410 priv->cfg->ops->smgmt->clear_station_table(priv); 4270 iwl_clear_stations_table(priv);
4411 4271
4412 /*netif_stop_queue(dev); */ 4272 /*netif_stop_queue(dev); */
4413 flush_workqueue(priv->workqueue); 4273 flush_workqueue(priv->workqueue);