diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 1451 |
1 files changed, 205 insertions, 1246 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index ff4d0e41d7c4..83d31606dd00 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -95,188 +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 | */ | ||
110 | static 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 | |||
141 | out: | ||
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 | */ | ||
152 | static void 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 | */ | ||
167 | u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) | ||
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 | static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) | ||
237 | { | ||
238 | int rc = 0; | ||
239 | struct iwl_rx_packet *res = NULL; | ||
240 | struct iwl3945_rxon_assoc_cmd rxon_assoc; | ||
241 | struct iwl_host_cmd cmd = { | ||
242 | .id = REPLY_RXON_ASSOC, | ||
243 | .len = sizeof(rxon_assoc), | ||
244 | .meta.flags = CMD_WANT_SKB, | ||
245 | .data = &rxon_assoc, | ||
246 | }; | ||
247 | const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; | ||
248 | const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; | ||
249 | |||
250 | if ((rxon1->flags == rxon2->flags) && | ||
251 | (rxon1->filter_flags == rxon2->filter_flags) && | ||
252 | (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && | ||
253 | (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { | ||
254 | IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | rxon_assoc.flags = priv->staging_rxon.flags; | ||
259 | rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; | ||
260 | rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; | ||
261 | rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; | ||
262 | rxon_assoc.reserved = 0; | ||
263 | |||
264 | rc = iwl_send_cmd_sync(priv, &cmd); | ||
265 | if (rc) | ||
266 | return rc; | ||
267 | |||
268 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; | ||
269 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
270 | IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); | ||
271 | rc = -EIO; | ||
272 | } | ||
273 | |||
274 | priv->alloc_rxb_skb--; | ||
275 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
276 | |||
277 | return rc; | ||
278 | } | ||
279 | |||
280 | /** | 98 | /** |
281 | * iwl3945_get_antenna_flags - Get antenna flags for RXON command | 99 | * iwl3945_get_antenna_flags - Get antenna flags for RXON command |
282 | * @priv: eeprom and antenna fields are used to determine antenna flags | 100 | * @priv: eeprom and antenna fields are used to determine antenna flags |
@@ -314,150 +132,6 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv) | |||
314 | return 0; /* "diversity" is default if error */ | 132 | return 0; /* "diversity" is default if error */ |
315 | } | 133 | } |
316 | 134 | ||
317 | /** | ||
318 | * iwl3945_commit_rxon - commit staging_rxon to hardware | ||
319 | * | ||
320 | * The RXON command in staging_rxon is committed to the hardware and | ||
321 | * the active_rxon structure is updated with the new data. This | ||
322 | * function correctly transitions out of the RXON_ASSOC_MSK state if | ||
323 | * a HW tune is required based on the RXON structure changes. | ||
324 | */ | ||
325 | static int iwl3945_commit_rxon(struct iwl_priv *priv) | ||
326 | { | ||
327 | /* cast away the const for active_rxon in this function */ | ||
328 | struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon; | ||
329 | struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon; | ||
330 | int rc = 0; | ||
331 | bool new_assoc = | ||
332 | !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); | ||
333 | |||
334 | if (!iwl_is_alive(priv)) | ||
335 | return -1; | ||
336 | |||
337 | /* always get timestamp with Rx frame */ | ||
338 | staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK; | ||
339 | |||
340 | /* select antenna */ | ||
341 | staging_rxon->flags &= | ||
342 | ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); | ||
343 | staging_rxon->flags |= iwl3945_get_antenna_flags(priv); | ||
344 | |||
345 | rc = iwl_check_rxon_cmd(priv); | ||
346 | if (rc) { | ||
347 | IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); | ||
348 | return -EINVAL; | ||
349 | } | ||
350 | |||
351 | /* If we don't need to send a full RXON, we can use | ||
352 | * iwl3945_rxon_assoc_cmd which is used to reconfigure filter | ||
353 | * and other flags for the current radio configuration. */ | ||
354 | if (!iwl_full_rxon_required(priv)) { | ||
355 | rc = iwl3945_send_rxon_assoc(priv); | ||
356 | if (rc) { | ||
357 | IWL_ERR(priv, "Error setting RXON_ASSOC " | ||
358 | "configuration (%d).\n", rc); | ||
359 | return rc; | ||
360 | } | ||
361 | |||
362 | memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | /* If we are currently associated and the new config requires | ||
368 | * an RXON_ASSOC and the new config wants the associated mask enabled, | ||
369 | * we must clear the associated from the active configuration | ||
370 | * before we apply the new config */ | ||
371 | if (iwl_is_associated(priv) && new_assoc) { | ||
372 | IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); | ||
373 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
374 | |||
375 | /* | ||
376 | * reserved4 and 5 could have been filled by the iwlcore code. | ||
377 | * Let's clear them before pushing to the 3945. | ||
378 | */ | ||
379 | active_rxon->reserved4 = 0; | ||
380 | active_rxon->reserved5 = 0; | ||
381 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, | ||
382 | sizeof(struct iwl3945_rxon_cmd), | ||
383 | &priv->active_rxon); | ||
384 | |||
385 | /* If the mask clearing failed then we set | ||
386 | * active_rxon back to what it was previously */ | ||
387 | if (rc) { | ||
388 | active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; | ||
389 | IWL_ERR(priv, "Error clearing ASSOC_MSK on current " | ||
390 | "configuration (%d).\n", rc); | ||
391 | return rc; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | IWL_DEBUG_INFO(priv, "Sending RXON\n" | ||
396 | "* with%s RXON_FILTER_ASSOC_MSK\n" | ||
397 | "* channel = %d\n" | ||
398 | "* bssid = %pM\n", | ||
399 | (new_assoc ? "" : "out"), | ||
400 | le16_to_cpu(staging_rxon->channel), | ||
401 | staging_rxon->bssid_addr); | ||
402 | |||
403 | /* | ||
404 | * reserved4 and 5 could have been filled by the iwlcore code. | ||
405 | * Let's clear them before pushing to the 3945. | ||
406 | */ | ||
407 | staging_rxon->reserved4 = 0; | ||
408 | staging_rxon->reserved5 = 0; | ||
409 | |||
410 | iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto); | ||
411 | |||
412 | /* Apply the new configuration */ | ||
413 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, | ||
414 | sizeof(struct iwl3945_rxon_cmd), | ||
415 | staging_rxon); | ||
416 | if (rc) { | ||
417 | IWL_ERR(priv, "Error setting new configuration (%d).\n", rc); | ||
418 | return rc; | ||
419 | } | ||
420 | |||
421 | memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); | ||
422 | |||
423 | iwl3945_clear_stations_table(priv); | ||
424 | |||
425 | /* If we issue a new RXON command which required a tune then we must | ||
426 | * send a new TXPOWER command or we won't be able to Tx any frames */ | ||
427 | rc = priv->cfg->ops->lib->send_tx_power(priv); | ||
428 | if (rc) { | ||
429 | IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); | ||
430 | return rc; | ||
431 | } | ||
432 | |||
433 | /* Add the broadcast address so we can send broadcast frames */ | ||
434 | if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) == | ||
435 | IWL_INVALID_STATION) { | ||
436 | IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); | ||
437 | return -EIO; | ||
438 | } | ||
439 | |||
440 | /* If we have set the ASSOC_MSK and we are in BSS mode then | ||
441 | * add the IWL_AP_ID to the station rate table */ | ||
442 | if (iwl_is_associated(priv) && | ||
443 | (priv->iw_mode == NL80211_IFTYPE_STATION)) | ||
444 | if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, | ||
445 | 1, 0) | ||
446 | == IWL_INVALID_STATION) { | ||
447 | IWL_ERR(priv, "Error adding AP address for transmit\n"); | ||
448 | return -EIO; | ||
449 | } | ||
450 | |||
451 | /* Init the hardware's rate fallback order based on the band */ | ||
452 | rc = iwl3945_init_hw_rate_table(priv); | ||
453 | if (rc) { | ||
454 | IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc); | ||
455 | return -EIO; | ||
456 | } | ||
457 | |||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | 135 | static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, |
462 | struct ieee80211_key_conf *keyconf, | 136 | struct ieee80211_key_conf *keyconf, |
463 | u8 sta_id) | 137 | u8 sta_id) |
@@ -477,32 +151,31 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | |||
477 | key_flags &= ~STA_KEY_FLG_INVALID; | 151 | key_flags &= ~STA_KEY_FLG_INVALID; |
478 | 152 | ||
479 | spin_lock_irqsave(&priv->sta_lock, flags); | 153 | spin_lock_irqsave(&priv->sta_lock, flags); |
480 | priv->stations_39[sta_id].keyinfo.alg = keyconf->alg; | 154 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; |
481 | priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen; | 155 | priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; |
482 | memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key, | 156 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, |
483 | keyconf->keylen); | 157 | keyconf->keylen); |
484 | 158 | ||
485 | memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key, | 159 | memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, |
486 | keyconf->keylen); | 160 | keyconf->keylen); |
487 | 161 | ||
488 | 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) |
489 | == STA_KEY_FLG_NO_ENC) | 163 | == STA_KEY_FLG_NO_ENC) |
490 | priv->stations_39[sta_id].sta.key.key_offset = | 164 | priv->stations[sta_id].sta.key.key_offset = |
491 | iwl_get_free_ucode_key_index(priv); | 165 | iwl_get_free_ucode_key_index(priv); |
492 | /* 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 |
493 | * in uCode. */ | 167 | * in uCode. */ |
494 | 168 | ||
495 | 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, |
496 | "no space for a new key"); | 170 | "no space for a new key"); |
497 | 171 | ||
498 | priv->stations_39[sta_id].sta.key.key_flags = key_flags; | 172 | priv->stations[sta_id].sta.key.key_flags = key_flags; |
499 | 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; |
500 | priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 174 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
501 | 175 | ||
502 | IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); | 176 | IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); |
503 | 177 | ||
504 | ret = iwl_send_add_sta(priv, | 178 | ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
505 | (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC); | ||
506 | 179 | ||
507 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 180 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
508 | 181 | ||
@@ -528,17 +201,16 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) | |||
528 | unsigned long flags; | 201 | unsigned long flags; |
529 | 202 | ||
530 | spin_lock_irqsave(&priv->sta_lock, flags); | 203 | spin_lock_irqsave(&priv->sta_lock, flags); |
531 | memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key)); | 204 | memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); |
532 | memset(&priv->stations_39[sta_id].sta.key, 0, | 205 | memset(&priv->stations[sta_id].sta.key, 0, |
533 | sizeof(struct iwl4965_keyinfo)); | 206 | sizeof(struct iwl4965_keyinfo)); |
534 | 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; |
535 | 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; |
536 | priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 209 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
537 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 210 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
538 | 211 | ||
539 | IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); | 212 | IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); |
540 | iwl_send_add_sta(priv, | 213 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); |
541 | (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0); | ||
542 | return 0; | 214 | return 0; |
543 | } | 215 | } |
544 | 216 | ||
@@ -739,7 +411,8 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv) | |||
739 | priv->rxon_timing.atim_window = 0; | 411 | priv->rxon_timing.atim_window = 0; |
740 | } else { | 412 | } else { |
741 | priv->rxon_timing.beacon_interval = | 413 | priv->rxon_timing.beacon_interval = |
742 | iwl3945_adjust_beacon_interval(conf->beacon_int); | 414 | iwl3945_adjust_beacon_interval( |
415 | priv->vif->bss_conf.beacon_int); | ||
743 | /* TODO: we need to get atim_window from upper stack | 416 | /* TODO: we need to get atim_window from upper stack |
744 | * for now we set to 0 */ | 417 | * for now we set to 0 */ |
745 | priv->rxon_timing.atim_window = 0; | 418 | priv->rxon_timing.atim_window = 0; |
@@ -758,35 +431,6 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv) | |||
758 | le16_to_cpu(priv->rxon_timing.atim_window)); | 431 | le16_to_cpu(priv->rxon_timing.atim_window)); |
759 | } | 432 | } |
760 | 433 | ||
761 | static int iwl3945_set_mode(struct iwl_priv *priv, int mode) | ||
762 | { | ||
763 | if (mode == NL80211_IFTYPE_ADHOC) { | ||
764 | const struct iwl_channel_info *ch_info; | ||
765 | |||
766 | ch_info = iwl_get_channel_info(priv, | ||
767 | priv->band, | ||
768 | le16_to_cpu(priv->staging_rxon.channel)); | ||
769 | |||
770 | if (!ch_info || !is_channel_ibss(ch_info)) { | ||
771 | IWL_ERR(priv, "channel %d not IBSS channel\n", | ||
772 | le16_to_cpu(priv->staging_rxon.channel)); | ||
773 | return -EINVAL; | ||
774 | } | ||
775 | } | ||
776 | |||
777 | iwl_connection_init_rx_config(priv, mode); | ||
778 | |||
779 | iwl3945_clear_stations_table(priv); | ||
780 | |||
781 | /* don't commit rxon if rf-kill is on*/ | ||
782 | if (!iwl_is_ready_rf(priv)) | ||
783 | return -EAGAIN; | ||
784 | |||
785 | iwl3945_commit_rxon(priv); | ||
786 | |||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | 434 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, |
791 | struct ieee80211_tx_info *info, | 435 | struct ieee80211_tx_info *info, |
792 | struct iwl_cmd *cmd, | 436 | struct iwl_cmd *cmd, |
@@ -794,8 +438,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | |||
794 | int sta_id) | 438 | int sta_id) |
795 | { | 439 | { |
796 | 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; |
797 | struct iwl3945_hw_key *keyinfo = | 441 | struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; |
798 | &priv->stations_39[sta_id].keyinfo; | ||
799 | 442 | ||
800 | switch (keyinfo->alg) { | 443 | switch (keyinfo->alg) { |
801 | case ALG_CCMP: | 444 | case ALG_CCMP: |
@@ -893,64 +536,6 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, | |||
893 | tx->next_frame_len = 0; | 536 | tx->next_frame_len = 0; |
894 | } | 537 | } |
895 | 538 | ||
896 | /** | ||
897 | * iwl3945_get_sta_id - Find station's index within station table | ||
898 | */ | ||
899 | static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) | ||
900 | { | ||
901 | int sta_id; | ||
902 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
903 | |||
904 | /* If this frame is broadcast or management, use broadcast station id */ | ||
905 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || | ||
906 | is_multicast_ether_addr(hdr->addr1)) | ||
907 | return priv->hw_params.bcast_sta_id; | ||
908 | |||
909 | switch (priv->iw_mode) { | ||
910 | |||
911 | /* If we are a client station in a BSS network, use the special | ||
912 | * AP station entry (that's the only station we communicate with) */ | ||
913 | case NL80211_IFTYPE_STATION: | ||
914 | return IWL_AP_ID; | ||
915 | |||
916 | /* If we are an AP, then find the station, or use BCAST */ | ||
917 | case NL80211_IFTYPE_AP: | ||
918 | sta_id = iwl3945_hw_find_station(priv, hdr->addr1); | ||
919 | if (sta_id != IWL_INVALID_STATION) | ||
920 | return sta_id; | ||
921 | return priv->hw_params.bcast_sta_id; | ||
922 | |||
923 | /* If this frame is going out to an IBSS network, find the station, | ||
924 | * or create a new station table entry */ | ||
925 | case NL80211_IFTYPE_ADHOC: { | ||
926 | /* Create new station table entry */ | ||
927 | sta_id = iwl3945_hw_find_station(priv, hdr->addr1); | ||
928 | if (sta_id != IWL_INVALID_STATION) | ||
929 | return sta_id; | ||
930 | |||
931 | sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC); | ||
932 | |||
933 | if (sta_id != IWL_INVALID_STATION) | ||
934 | return sta_id; | ||
935 | |||
936 | IWL_DEBUG_DROP(priv, "Station %pM not in station map. " | ||
937 | "Defaulting to broadcast...\n", | ||
938 | hdr->addr1); | ||
939 | iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | ||
940 | return priv->hw_params.bcast_sta_id; | ||
941 | } | ||
942 | /* If we are in monitor mode, use BCAST. This is required for | ||
943 | * packet injection. */ | ||
944 | case NL80211_IFTYPE_MONITOR: | ||
945 | return priv->hw_params.bcast_sta_id; | ||
946 | |||
947 | default: | ||
948 | IWL_WARN(priv, "Unknown mode of operation: %d\n", | ||
949 | priv->iw_mode); | ||
950 | return priv->hw_params.bcast_sta_id; | ||
951 | } | ||
952 | } | ||
953 | |||
954 | /* | 539 | /* |
955 | * start REPLY_TX command process | 540 | * start REPLY_TX command process |
956 | */ | 541 | */ |
@@ -1004,7 +589,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
1004 | 589 | ||
1005 | /* drop all data frame if we are not associated */ | 590 | /* drop all data frame if we are not associated */ |
1006 | if (ieee80211_is_data(fc) && | 591 | if (ieee80211_is_data(fc) && |
1007 | (priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */ | 592 | (!iwl_is_monitor_mode(priv)) && /* packet injection */ |
1008 | (!iwl_is_associated(priv) || | 593 | (!iwl_is_associated(priv) || |
1009 | ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) { | 594 | ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) { |
1010 | IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n"); | 595 | IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n"); |
@@ -1016,7 +601,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
1016 | hdr_len = ieee80211_hdrlen(fc); | 601 | hdr_len = ieee80211_hdrlen(fc); |
1017 | 602 | ||
1018 | /* Find (or create) index into station table for destination station */ | 603 | /* Find (or create) index into station table for destination station */ |
1019 | sta_id = iwl3945_get_sta_id(priv, hdr); | 604 | sta_id = iwl_get_sta_id(priv, hdr); |
1020 | if (sta_id == IWL_INVALID_STATION) { | 605 | if (sta_id == IWL_INVALID_STATION) { |
1021 | IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", | 606 | IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", |
1022 | hdr->addr1); | 607 | hdr->addr1); |
@@ -1028,7 +613,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
1028 | if (ieee80211_is_data_qos(fc)) { | 613 | if (ieee80211_is_data_qos(fc)) { |
1029 | qc = ieee80211_get_qos_ctl(hdr); | 614 | qc = ieee80211_get_qos_ctl(hdr); |
1030 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 615 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; |
1031 | seq_number = priv->stations_39[sta_id].tid[tid].seq_number & | 616 | seq_number = priv->stations[sta_id].tid[tid].seq_number & |
1032 | IEEE80211_SCTL_SEQ; | 617 | IEEE80211_SCTL_SEQ; |
1033 | hdr->seq_ctrl = cpu_to_le16(seq_number) | | 618 | hdr->seq_ctrl = cpu_to_le16(seq_number) | |
1034 | (hdr->seq_ctrl & | 619 | (hdr->seq_ctrl & |
@@ -1088,7 +673,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
1088 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | 673 | if (!ieee80211_has_morefrags(hdr->frame_control)) { |
1089 | txq->need_update = 1; | 674 | txq->need_update = 1; |
1090 | if (qc) | 675 | if (qc) |
1091 | priv->stations_39[sta_id].tid[tid].seq_number = seq_number; | 676 | priv->stations[sta_id].tid[tid].seq_number = seq_number; |
1092 | } else { | 677 | } else { |
1093 | wait_write_ptr = 1; | 678 | wait_write_ptr = 1; |
1094 | txq->need_update = 0; | 679 | txq->need_update = 0; |
@@ -1424,18 +1009,12 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, | |||
1424 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1009 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1425 | 1010 | ||
1426 | 1011 | ||
1427 | if (flags & SW_CARD_DISABLED) | ||
1428 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1429 | else | ||
1430 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1431 | |||
1432 | iwl_scan_cancel(priv); | 1012 | iwl_scan_cancel(priv); |
1433 | 1013 | ||
1434 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 1014 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
1435 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 1015 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
1436 | (test_bit(STATUS_RF_KILL_SW, &status) != | 1016 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
1437 | test_bit(STATUS_RF_KILL_SW, &priv->status))) | 1017 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
1438 | queue_work(priv->workqueue, &priv->rf_kill); | ||
1439 | else | 1018 | else |
1440 | wake_up_interruptible(&priv->wait_command_queue); | 1019 | wake_up_interruptible(&priv->wait_command_queue); |
1441 | } | 1020 | } |
@@ -1591,7 +1170,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) | |||
1591 | 1170 | ||
1592 | /* If we've added more space for the firmware to place data, tell it. | 1171 | /* If we've added more space for the firmware to place data, tell it. |
1593 | * Increment device's write pointer in multiples of 8. */ | 1172 | * Increment device's write pointer in multiples of 8. */ |
1594 | if ((write != (rxq->write & ~0x7)) | 1173 | if ((rxq->write_actual != (rxq->write & ~0x7)) |
1595 | || (abs(rxq->write - rxq->read) > 7)) { | 1174 | || (abs(rxq->write - rxq->read) > 7)) { |
1596 | spin_lock_irqsave(&rxq->lock, flags); | 1175 | spin_lock_irqsave(&rxq->lock, flags); |
1597 | rxq->need_update = 1; | 1176 | rxq->need_update = 1; |
@@ -1612,21 +1191,30 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) | |||
1612 | * Also restock the Rx queue via iwl3945_rx_queue_restock. | 1191 | * Also restock the Rx queue via iwl3945_rx_queue_restock. |
1613 | * This is called as a scheduled work item (except for during initialization) | 1192 | * This is called as a scheduled work item (except for during initialization) |
1614 | */ | 1193 | */ |
1615 | static void iwl3945_rx_allocate(struct iwl_priv *priv) | 1194 | static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) |
1616 | { | 1195 | { |
1617 | struct iwl_rx_queue *rxq = &priv->rxq; | 1196 | struct iwl_rx_queue *rxq = &priv->rxq; |
1618 | struct list_head *element; | 1197 | struct list_head *element; |
1619 | struct iwl_rx_mem_buffer *rxb; | 1198 | struct iwl_rx_mem_buffer *rxb; |
1620 | unsigned long flags; | 1199 | unsigned long flags; |
1621 | spin_lock_irqsave(&rxq->lock, flags); | 1200 | |
1622 | while (!list_empty(&rxq->rx_used)) { | 1201 | while (1) { |
1202 | spin_lock_irqsave(&rxq->lock, flags); | ||
1203 | |||
1204 | if (list_empty(&rxq->rx_used)) { | ||
1205 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
1206 | return; | ||
1207 | } | ||
1208 | |||
1623 | element = rxq->rx_used.next; | 1209 | element = rxq->rx_used.next; |
1624 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | 1210 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); |
1211 | list_del(element); | ||
1212 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
1625 | 1213 | ||
1626 | /* Alloc a new receive buffer */ | 1214 | /* Alloc a new receive buffer */ |
1627 | rxb->skb = | 1215 | rxb->skb = |
1628 | alloc_skb(priv->hw_params.rx_buf_size, | 1216 | alloc_skb(priv->hw_params.rx_buf_size, |
1629 | __GFP_NOWARN | GFP_ATOMIC); | 1217 | priority); |
1630 | if (!rxb->skb) { | 1218 | if (!rxb->skb) { |
1631 | if (net_ratelimit()) | 1219 | if (net_ratelimit()) |
1632 | IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); | 1220 | IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); |
@@ -1644,18 +1232,18 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv) | |||
1644 | */ | 1232 | */ |
1645 | skb_reserve(rxb->skb, 4); | 1233 | skb_reserve(rxb->skb, 4); |
1646 | 1234 | ||
1647 | priv->alloc_rxb_skb++; | ||
1648 | list_del(element); | ||
1649 | |||
1650 | /* Get physical address of RB/SKB */ | 1235 | /* Get physical address of RB/SKB */ |
1651 | rxb->real_dma_addr = pci_map_single(priv->pci_dev, | 1236 | rxb->real_dma_addr = pci_map_single(priv->pci_dev, |
1652 | rxb->skb->data, | 1237 | rxb->skb->data, |
1653 | priv->hw_params.rx_buf_size, | 1238 | priv->hw_params.rx_buf_size, |
1654 | PCI_DMA_FROMDEVICE); | 1239 | PCI_DMA_FROMDEVICE); |
1240 | |||
1241 | spin_lock_irqsave(&rxq->lock, flags); | ||
1655 | list_add_tail(&rxb->list, &rxq->rx_free); | 1242 | list_add_tail(&rxb->list, &rxq->rx_free); |
1243 | priv->alloc_rxb_skb++; | ||
1656 | rxq->free_count++; | 1244 | rxq->free_count++; |
1245 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
1657 | } | 1246 | } |
1658 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
1659 | } | 1247 | } |
1660 | 1248 | ||
1661 | void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | 1249 | void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) |
@@ -1685,33 +1273,30 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
1685 | * not restocked the Rx queue with fresh buffers */ | 1273 | * not restocked the Rx queue with fresh buffers */ |
1686 | rxq->read = rxq->write = 0; | 1274 | rxq->read = rxq->write = 0; |
1687 | rxq->free_count = 0; | 1275 | rxq->free_count = 0; |
1276 | rxq->write_actual = 0; | ||
1688 | spin_unlock_irqrestore(&rxq->lock, flags); | 1277 | spin_unlock_irqrestore(&rxq->lock, flags); |
1689 | } | 1278 | } |
1690 | 1279 | ||
1691 | /* | ||
1692 | * this should be called while priv->lock is locked | ||
1693 | */ | ||
1694 | static void __iwl3945_rx_replenish(void *data) | ||
1695 | { | ||
1696 | struct iwl_priv *priv = data; | ||
1697 | |||
1698 | iwl3945_rx_allocate(priv); | ||
1699 | iwl3945_rx_queue_restock(priv); | ||
1700 | } | ||
1701 | |||
1702 | |||
1703 | void iwl3945_rx_replenish(void *data) | 1280 | void iwl3945_rx_replenish(void *data) |
1704 | { | 1281 | { |
1705 | struct iwl_priv *priv = data; | 1282 | struct iwl_priv *priv = data; |
1706 | unsigned long flags; | 1283 | unsigned long flags; |
1707 | 1284 | ||
1708 | iwl3945_rx_allocate(priv); | 1285 | iwl3945_rx_allocate(priv, GFP_KERNEL); |
1709 | 1286 | ||
1710 | spin_lock_irqsave(&priv->lock, flags); | 1287 | spin_lock_irqsave(&priv->lock, flags); |
1711 | iwl3945_rx_queue_restock(priv); | 1288 | iwl3945_rx_queue_restock(priv); |
1712 | spin_unlock_irqrestore(&priv->lock, flags); | 1289 | spin_unlock_irqrestore(&priv->lock, flags); |
1713 | } | 1290 | } |
1714 | 1291 | ||
1292 | static void iwl3945_rx_replenish_now(struct iwl_priv *priv) | ||
1293 | { | ||
1294 | iwl3945_rx_allocate(priv, GFP_ATOMIC); | ||
1295 | |||
1296 | iwl3945_rx_queue_restock(priv); | ||
1297 | } | ||
1298 | |||
1299 | |||
1715 | /* Assumes that the skb field of the buffers in 'pool' is kept accurate. | 1300 | /* Assumes that the skb field of the buffers in 'pool' is kept accurate. |
1716 | * If an SKB has been detached, the POOL needs to have its SKB set to NULL | 1301 | * If an SKB has been detached, the POOL needs to have its SKB set to NULL |
1717 | * This free routine walks the list of POOL entries and if SKB is set to | 1302 | * This free routine walks the list of POOL entries and if SKB is set to |
@@ -1834,13 +1419,19 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1834 | unsigned long flags; | 1419 | unsigned long flags; |
1835 | u8 fill_rx = 0; | 1420 | u8 fill_rx = 0; |
1836 | u32 count = 8; | 1421 | u32 count = 8; |
1422 | int total_empty = 0; | ||
1837 | 1423 | ||
1838 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 1424 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
1839 | * buffer that the driver may process (last buffer filled by ucode). */ | 1425 | * buffer that the driver may process (last buffer filled by ucode). */ |
1840 | r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; | 1426 | r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; |
1841 | i = rxq->read; | 1427 | i = rxq->read; |
1842 | 1428 | ||
1843 | if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) | 1429 | /* calculate total frames need to be restock after handling RX */ |
1430 | total_empty = r - priv->rxq.write_actual; | ||
1431 | if (total_empty < 0) | ||
1432 | total_empty += RX_QUEUE_SIZE; | ||
1433 | |||
1434 | if (total_empty > (RX_QUEUE_SIZE / 2)) | ||
1844 | fill_rx = 1; | 1435 | fill_rx = 1; |
1845 | /* Rx interrupt, but nothing sent from uCode */ | 1436 | /* Rx interrupt, but nothing sent from uCode */ |
1846 | if (i == r) | 1437 | if (i == r) |
@@ -1879,6 +1470,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1879 | "r = %d, i = %d, %s, 0x%02x\n", r, i, | 1470 | "r = %d, i = %d, %s, 0x%02x\n", r, i, |
1880 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | 1471 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
1881 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | 1472 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); |
1473 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | ||
1882 | } else { | 1474 | } else { |
1883 | /* No handling needed */ | 1475 | /* No handling needed */ |
1884 | IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR, | 1476 | IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR, |
@@ -1916,7 +1508,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1916 | count++; | 1508 | count++; |
1917 | if (count >= 8) { | 1509 | if (count >= 8) { |
1918 | priv->rxq.read = i; | 1510 | priv->rxq.read = i; |
1919 | __iwl3945_rx_replenish(priv); | 1511 | iwl3945_rx_replenish_now(priv); |
1920 | count = 0; | 1512 | count = 0; |
1921 | } | 1513 | } |
1922 | } | 1514 | } |
@@ -1924,7 +1516,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1924 | 1516 | ||
1925 | /* Backtrack one entry */ | 1517 | /* Backtrack one entry */ |
1926 | priv->rxq.read = i; | 1518 | priv->rxq.read = i; |
1927 | iwl3945_rx_queue_restock(priv); | 1519 | if (fill_rx) |
1520 | iwl3945_rx_replenish_now(priv); | ||
1521 | else | ||
1522 | iwl3945_rx_queue_restock(priv); | ||
1928 | } | 1523 | } |
1929 | 1524 | ||
1930 | /* call this function to flush any scheduled tasklet */ | 1525 | /* call this function to flush any scheduled tasklet */ |
@@ -1963,7 +1558,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv) | |||
1963 | u32 i; | 1558 | u32 i; |
1964 | u32 desc, time, count, base, data1; | 1559 | u32 desc, time, count, base, data1; |
1965 | u32 blink1, blink2, ilink1, ilink2; | 1560 | u32 blink1, blink2, ilink1, ilink2; |
1966 | int rc; | ||
1967 | 1561 | ||
1968 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); | 1562 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); |
1969 | 1563 | ||
@@ -1972,11 +1566,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv) | |||
1972 | return; | 1566 | return; |
1973 | } | 1567 | } |
1974 | 1568 | ||
1975 | rc = iwl_grab_nic_access(priv); | ||
1976 | if (rc) { | ||
1977 | IWL_WARN(priv, "Can not read from adapter at this time.\n"); | ||
1978 | return; | ||
1979 | } | ||
1980 | 1569 | ||
1981 | count = iwl_read_targ_mem(priv, base); | 1570 | count = iwl_read_targ_mem(priv, base); |
1982 | 1571 | ||
@@ -2011,8 +1600,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv) | |||
2011 | ilink1, ilink2, data1); | 1600 | ilink1, ilink2, data1); |
2012 | } | 1601 | } |
2013 | 1602 | ||
2014 | iwl_release_nic_access(priv); | ||
2015 | |||
2016 | } | 1603 | } |
2017 | 1604 | ||
2018 | #define EVENT_START_OFFSET (6 * sizeof(u32)) | 1605 | #define EVENT_START_OFFSET (6 * sizeof(u32)) |
@@ -2020,7 +1607,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv) | |||
2020 | /** | 1607 | /** |
2021 | * iwl3945_print_event_log - Dump error event log to syslog | 1608 | * iwl3945_print_event_log - Dump error event log to syslog |
2022 | * | 1609 | * |
2023 | * NOTE: Must be called with iwl_grab_nic_access() already obtained! | ||
2024 | */ | 1610 | */ |
2025 | static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | 1611 | static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, |
2026 | u32 num_events, u32 mode) | 1612 | u32 num_events, u32 mode) |
@@ -2063,7 +1649,6 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
2063 | 1649 | ||
2064 | static void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | 1650 | static void iwl3945_dump_nic_event_log(struct iwl_priv *priv) |
2065 | { | 1651 | { |
2066 | int rc; | ||
2067 | u32 base; /* SRAM byte address of event log header */ | 1652 | u32 base; /* SRAM byte address of event log header */ |
2068 | u32 capacity; /* event log capacity in # entries */ | 1653 | u32 capacity; /* event log capacity in # entries */ |
2069 | u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ | 1654 | u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ |
@@ -2077,12 +1662,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | |||
2077 | return; | 1662 | return; |
2078 | } | 1663 | } |
2079 | 1664 | ||
2080 | rc = iwl_grab_nic_access(priv); | ||
2081 | if (rc) { | ||
2082 | IWL_WARN(priv, "Can not read from adapter at this time.\n"); | ||
2083 | return; | ||
2084 | } | ||
2085 | |||
2086 | /* event log header */ | 1665 | /* event log header */ |
2087 | capacity = iwl_read_targ_mem(priv, base); | 1666 | capacity = iwl_read_targ_mem(priv, base); |
2088 | mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32))); | 1667 | mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32))); |
@@ -2094,7 +1673,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | |||
2094 | /* bail out if nothing in log */ | 1673 | /* bail out if nothing in log */ |
2095 | if (size == 0) { | 1674 | if (size == 0) { |
2096 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); | 1675 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); |
2097 | iwl_release_nic_access(priv); | ||
2098 | return; | 1676 | return; |
2099 | } | 1677 | } |
2100 | 1678 | ||
@@ -2110,24 +1688,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | |||
2110 | /* (then/else) start at top of log */ | 1688 | /* (then/else) start at top of log */ |
2111 | iwl3945_print_event_log(priv, 0, next_entry, mode); | 1689 | iwl3945_print_event_log(priv, 0, next_entry, mode); |
2112 | 1690 | ||
2113 | iwl_release_nic_access(priv); | ||
2114 | } | ||
2115 | |||
2116 | static void iwl3945_error_recovery(struct iwl_priv *priv) | ||
2117 | { | ||
2118 | unsigned long flags; | ||
2119 | |||
2120 | memcpy(&priv->staging_rxon, &priv->recovery_rxon, | ||
2121 | sizeof(priv->staging_rxon)); | ||
2122 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
2123 | iwl3945_commit_rxon(priv); | ||
2124 | |||
2125 | iwl3945_add_station(priv, priv->bssid, 1, 0); | ||
2126 | |||
2127 | spin_lock_irqsave(&priv->lock, flags); | ||
2128 | priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); | ||
2129 | priv->error_recovering = 0; | ||
2130 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2131 | } | 1691 | } |
2132 | 1692 | ||
2133 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) | 1693 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) |
@@ -2178,6 +1738,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
2178 | /* Tell the device to stop sending interrupts */ | 1738 | /* Tell the device to stop sending interrupts */ |
2179 | iwl_disable_interrupts(priv); | 1739 | iwl_disable_interrupts(priv); |
2180 | 1740 | ||
1741 | priv->isr_stats.hw++; | ||
2181 | iwl_irq_handle_error(priv); | 1742 | iwl_irq_handle_error(priv); |
2182 | 1743 | ||
2183 | handled |= CSR_INT_BIT_HW_ERR; | 1744 | handled |= CSR_INT_BIT_HW_ERR; |
@@ -2190,13 +1751,17 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
2190 | #ifdef CONFIG_IWLWIFI_DEBUG | 1751 | #ifdef CONFIG_IWLWIFI_DEBUG |
2191 | if (priv->debug_level & (IWL_DL_ISR)) { | 1752 | if (priv->debug_level & (IWL_DL_ISR)) { |
2192 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | 1753 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ |
2193 | if (inta & CSR_INT_BIT_SCD) | 1754 | if (inta & CSR_INT_BIT_SCD) { |
2194 | IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " | 1755 | IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " |
2195 | "the frame/frames.\n"); | 1756 | "the frame/frames.\n"); |
1757 | priv->isr_stats.sch++; | ||
1758 | } | ||
2196 | 1759 | ||
2197 | /* Alive notification via Rx interrupt will do the real work */ | 1760 | /* Alive notification via Rx interrupt will do the real work */ |
2198 | if (inta & CSR_INT_BIT_ALIVE) | 1761 | if (inta & CSR_INT_BIT_ALIVE) { |
2199 | IWL_DEBUG_ISR(priv, "Alive interrupt\n"); | 1762 | IWL_DEBUG_ISR(priv, "Alive interrupt\n"); |
1763 | priv->isr_stats.alive++; | ||
1764 | } | ||
2200 | } | 1765 | } |
2201 | #endif | 1766 | #endif |
2202 | /* Safely ignore these bits for debug checks below */ | 1767 | /* Safely ignore these bits for debug checks below */ |
@@ -2206,6 +1771,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
2206 | if (inta & CSR_INT_BIT_SW_ERR) { | 1771 | if (inta & CSR_INT_BIT_SW_ERR) { |
2207 | IWL_ERR(priv, "Microcode SW error detected. " | 1772 | IWL_ERR(priv, "Microcode SW error detected. " |
2208 | "Restarting 0x%X.\n", inta); | 1773 | "Restarting 0x%X.\n", inta); |
1774 | priv->isr_stats.sw++; | ||
1775 | priv->isr_stats.sw_err = inta; | ||
2209 | iwl_irq_handle_error(priv); | 1776 | iwl_irq_handle_error(priv); |
2210 | handled |= CSR_INT_BIT_SW_ERR; | 1777 | handled |= CSR_INT_BIT_SW_ERR; |
2211 | } | 1778 | } |
@@ -2221,6 +1788,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
2221 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); | 1788 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); |
2222 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); | 1789 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); |
2223 | 1790 | ||
1791 | priv->isr_stats.wakeup++; | ||
2224 | handled |= CSR_INT_BIT_WAKEUP; | 1792 | handled |= CSR_INT_BIT_WAKEUP; |
2225 | } | 1793 | } |
2226 | 1794 | ||
@@ -2229,27 +1797,28 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
2229 | * notifications from uCode come through here*/ | 1797 | * notifications from uCode come through here*/ |
2230 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | 1798 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { |
2231 | iwl3945_rx_handle(priv); | 1799 | iwl3945_rx_handle(priv); |
1800 | priv->isr_stats.rx++; | ||
2232 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 1801 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
2233 | } | 1802 | } |
2234 | 1803 | ||
2235 | if (inta & CSR_INT_BIT_FH_TX) { | 1804 | if (inta & CSR_INT_BIT_FH_TX) { |
2236 | IWL_DEBUG_ISR(priv, "Tx interrupt\n"); | 1805 | IWL_DEBUG_ISR(priv, "Tx interrupt\n"); |
1806 | priv->isr_stats.tx++; | ||
2237 | 1807 | ||
2238 | iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); | 1808 | iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); |
2239 | if (!iwl_grab_nic_access(priv)) { | 1809 | iwl_write_direct32(priv, FH39_TCSR_CREDIT |
2240 | iwl_write_direct32(priv, FH39_TCSR_CREDIT | 1810 | (FH39_SRVC_CHNL), 0x0); |
2241 | (FH39_SRVC_CHNL), 0x0); | ||
2242 | iwl_release_nic_access(priv); | ||
2243 | } | ||
2244 | handled |= CSR_INT_BIT_FH_TX; | 1811 | handled |= CSR_INT_BIT_FH_TX; |
2245 | } | 1812 | } |
2246 | 1813 | ||
2247 | if (inta & ~handled) | 1814 | if (inta & ~handled) { |
2248 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); | 1815 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); |
1816 | priv->isr_stats.unhandled++; | ||
1817 | } | ||
2249 | 1818 | ||
2250 | if (inta & ~CSR_INI_SET_MASK) { | 1819 | if (inta & ~priv->inta_mask) { |
2251 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", | 1820 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", |
2252 | inta & ~CSR_INI_SET_MASK); | 1821 | inta & ~priv->inta_mask); |
2253 | IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); | 1822 | IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); |
2254 | } | 1823 | } |
2255 | 1824 | ||
@@ -2413,10 +1982,6 @@ static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 le | |||
2413 | 1982 | ||
2414 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); | 1983 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); |
2415 | 1984 | ||
2416 | rc = iwl_grab_nic_access(priv); | ||
2417 | if (rc) | ||
2418 | return rc; | ||
2419 | |||
2420 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, | 1985 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, |
2421 | IWL39_RTC_INST_LOWER_BOUND); | 1986 | IWL39_RTC_INST_LOWER_BOUND); |
2422 | 1987 | ||
@@ -2437,7 +2002,6 @@ static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 le | |||
2437 | } | 2002 | } |
2438 | } | 2003 | } |
2439 | 2004 | ||
2440 | iwl_release_nic_access(priv); | ||
2441 | 2005 | ||
2442 | if (!errcnt) | 2006 | if (!errcnt) |
2443 | IWL_DEBUG_INFO(priv, | 2007 | IWL_DEBUG_INFO(priv, |
@@ -2461,10 +2025,6 @@ static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 | |||
2461 | 2025 | ||
2462 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); | 2026 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); |
2463 | 2027 | ||
2464 | rc = iwl_grab_nic_access(priv); | ||
2465 | if (rc) | ||
2466 | return rc; | ||
2467 | |||
2468 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | 2028 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { |
2469 | /* read data comes through single port, auto-incr addr */ | 2029 | /* read data comes through single port, auto-incr addr */ |
2470 | /* NOTE: Use the debugless read so we don't flood kernel log | 2030 | /* NOTE: Use the debugless read so we don't flood kernel log |
@@ -2485,8 +2045,6 @@ static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 | |||
2485 | } | 2045 | } |
2486 | } | 2046 | } |
2487 | 2047 | ||
2488 | iwl_release_nic_access(priv); | ||
2489 | |||
2490 | return rc; | 2048 | return rc; |
2491 | } | 2049 | } |
2492 | 2050 | ||
@@ -2810,20 +2368,11 @@ static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv) | |||
2810 | { | 2368 | { |
2811 | dma_addr_t pinst; | 2369 | dma_addr_t pinst; |
2812 | dma_addr_t pdata; | 2370 | dma_addr_t pdata; |
2813 | int rc = 0; | ||
2814 | unsigned long flags; | ||
2815 | 2371 | ||
2816 | /* bits 31:0 for 3945 */ | 2372 | /* bits 31:0 for 3945 */ |
2817 | pinst = priv->ucode_code.p_addr; | 2373 | pinst = priv->ucode_code.p_addr; |
2818 | pdata = priv->ucode_data_backup.p_addr; | 2374 | pdata = priv->ucode_data_backup.p_addr; |
2819 | 2375 | ||
2820 | spin_lock_irqsave(&priv->lock, flags); | ||
2821 | rc = iwl_grab_nic_access(priv); | ||
2822 | if (rc) { | ||
2823 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2824 | return rc; | ||
2825 | } | ||
2826 | |||
2827 | /* Tell bootstrap uCode where to find image to load */ | 2376 | /* Tell bootstrap uCode where to find image to load */ |
2828 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | 2377 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); |
2829 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | 2378 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); |
@@ -2835,13 +2384,9 @@ static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv) | |||
2835 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, | 2384 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, |
2836 | priv->ucode_code.len | BSM_DRAM_INST_LOAD); | 2385 | priv->ucode_code.len | BSM_DRAM_INST_LOAD); |
2837 | 2386 | ||
2838 | iwl_release_nic_access(priv); | ||
2839 | |||
2840 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2841 | |||
2842 | IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); | 2387 | IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); |
2843 | 2388 | ||
2844 | return rc; | 2389 | return 0; |
2845 | } | 2390 | } |
2846 | 2391 | ||
2847 | /** | 2392 | /** |
@@ -2887,11 +2432,6 @@ static void iwl3945_init_alive_start(struct iwl_priv *priv) | |||
2887 | queue_work(priv->workqueue, &priv->restart); | 2432 | queue_work(priv->workqueue, &priv->restart); |
2888 | } | 2433 | } |
2889 | 2434 | ||
2890 | |||
2891 | /* temporary */ | ||
2892 | static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, | ||
2893 | struct sk_buff *skb); | ||
2894 | |||
2895 | /** | 2435 | /** |
2896 | * iwl3945_alive_start - called after REPLY_ALIVE notification received | 2436 | * iwl3945_alive_start - called after REPLY_ALIVE notification received |
2897 | * from protocol/runtime uCode (initialization uCode's | 2437 | * from protocol/runtime uCode (initialization uCode's |
@@ -2899,7 +2439,6 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, | |||
2899 | */ | 2439 | */ |
2900 | static void iwl3945_alive_start(struct iwl_priv *priv) | 2440 | static void iwl3945_alive_start(struct iwl_priv *priv) |
2901 | { | 2441 | { |
2902 | int rc = 0; | ||
2903 | int thermal_spin = 0; | 2442 | int thermal_spin = 0; |
2904 | u32 rfkill; | 2443 | u32 rfkill; |
2905 | 2444 | ||
@@ -2922,17 +2461,10 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2922 | goto restart; | 2461 | goto restart; |
2923 | } | 2462 | } |
2924 | 2463 | ||
2925 | iwl3945_clear_stations_table(priv); | 2464 | iwl_clear_stations_table(priv); |
2926 | |||
2927 | rc = iwl_grab_nic_access(priv); | ||
2928 | if (rc) { | ||
2929 | IWL_WARN(priv, "Can not read RFKILL status from adapter\n"); | ||
2930 | return; | ||
2931 | } | ||
2932 | 2465 | ||
2933 | rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); | 2466 | rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); |
2934 | IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); | 2467 | IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); |
2935 | iwl_release_nic_access(priv); | ||
2936 | 2468 | ||
2937 | if (rfkill & 0x1) { | 2469 | if (rfkill & 0x1) { |
2938 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 2470 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
@@ -2952,9 +2484,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2952 | /* After the ALIVE response, we can send commands to 3945 uCode */ | 2484 | /* After the ALIVE response, we can send commands to 3945 uCode */ |
2953 | set_bit(STATUS_ALIVE, &priv->status); | 2485 | set_bit(STATUS_ALIVE, &priv->status); |
2954 | 2486 | ||
2955 | /* Clear out the uCode error bit if it is set */ | ||
2956 | clear_bit(STATUS_FW_ERROR, &priv->status); | ||
2957 | |||
2958 | if (iwl_is_rfkill(priv)) | 2487 | if (iwl_is_rfkill(priv)) |
2959 | return; | 2488 | return; |
2960 | 2489 | ||
@@ -2981,7 +2510,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2981 | iwl_send_bt_config(priv); | 2510 | iwl_send_bt_config(priv); |
2982 | 2511 | ||
2983 | /* Configure the adapter for unassociated operation */ | 2512 | /* Configure the adapter for unassociated operation */ |
2984 | iwl3945_commit_rxon(priv); | 2513 | iwlcore_commit_rxon(priv); |
2985 | 2514 | ||
2986 | iwl3945_reg_txpower_periodic(priv); | 2515 | iwl3945_reg_txpower_periodic(priv); |
2987 | 2516 | ||
@@ -2991,17 +2520,17 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2991 | set_bit(STATUS_READY, &priv->status); | 2520 | set_bit(STATUS_READY, &priv->status); |
2992 | wake_up_interruptible(&priv->wait_command_queue); | 2521 | wake_up_interruptible(&priv->wait_command_queue); |
2993 | 2522 | ||
2994 | if (priv->error_recovering) | ||
2995 | iwl3945_error_recovery(priv); | ||
2996 | |||
2997 | /* reassociate for ADHOC mode */ | 2523 | /* reassociate for ADHOC mode */ |
2998 | if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) { | 2524 | if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) { |
2999 | struct sk_buff *beacon = ieee80211_beacon_get(priv->hw, | 2525 | struct sk_buff *beacon = ieee80211_beacon_get(priv->hw, |
3000 | priv->vif); | 2526 | priv->vif); |
3001 | if (beacon) | 2527 | if (beacon) |
3002 | iwl3945_mac_beacon_update(priv->hw, beacon); | 2528 | iwl_mac_beacon_update(priv->hw, beacon); |
3003 | } | 2529 | } |
3004 | 2530 | ||
2531 | if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) | ||
2532 | iwl_set_mode(priv, priv->iw_mode); | ||
2533 | |||
3005 | return; | 2534 | return; |
3006 | 2535 | ||
3007 | restart: | 2536 | restart: |
@@ -3024,7 +2553,7 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
3024 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2553 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
3025 | 2554 | ||
3026 | iwl3945_led_unregister(priv); | 2555 | iwl3945_led_unregister(priv); |
3027 | iwl3945_clear_stations_table(priv); | 2556 | iwl_clear_stations_table(priv); |
3028 | 2557 | ||
3029 | /* Unblock any waiting calls */ | 2558 | /* Unblock any waiting calls */ |
3030 | wake_up_interruptible_all(&priv->wait_command_queue); | 2559 | wake_up_interruptible_all(&priv->wait_command_queue); |
@@ -3047,31 +2576,23 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
3047 | ieee80211_stop_queues(priv->hw); | 2576 | ieee80211_stop_queues(priv->hw); |
3048 | 2577 | ||
3049 | /* If we have not previously called iwl3945_init() then | 2578 | /* If we have not previously called iwl3945_init() then |
3050 | * clear all bits but the RF Kill and SUSPEND bits and return */ | 2579 | * clear all bits but the RF Kill bits and return */ |
3051 | if (!iwl_is_init(priv)) { | 2580 | if (!iwl_is_init(priv)) { |
3052 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | 2581 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << |
3053 | STATUS_RF_KILL_HW | | 2582 | STATUS_RF_KILL_HW | |
3054 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
3055 | STATUS_RF_KILL_SW | | ||
3056 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2583 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
3057 | STATUS_GEO_CONFIGURED | | 2584 | STATUS_GEO_CONFIGURED | |
3058 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | ||
3059 | STATUS_IN_SUSPEND | | ||
3060 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 2585 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
3061 | STATUS_EXIT_PENDING; | 2586 | STATUS_EXIT_PENDING; |
3062 | goto exit; | 2587 | goto exit; |
3063 | } | 2588 | } |
3064 | 2589 | ||
3065 | /* ...otherwise clear out all the status bits but the RF Kill and | 2590 | /* ...otherwise clear out all the status bits but the RF Kill |
3066 | * SUSPEND bits and continue taking the NIC down. */ | 2591 | * bit and continue taking the NIC down. */ |
3067 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 2592 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
3068 | STATUS_RF_KILL_HW | | 2593 | STATUS_RF_KILL_HW | |
3069 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
3070 | STATUS_RF_KILL_SW | | ||
3071 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2594 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
3072 | STATUS_GEO_CONFIGURED | | 2595 | STATUS_GEO_CONFIGURED | |
3073 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | ||
3074 | STATUS_IN_SUSPEND | | ||
3075 | test_bit(STATUS_FW_ERROR, &priv->status) << | 2596 | test_bit(STATUS_FW_ERROR, &priv->status) << |
3076 | STATUS_FW_ERROR | | 2597 | STATUS_FW_ERROR | |
3077 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 2598 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
@@ -3085,17 +2606,12 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
3085 | iwl3945_hw_txq_ctx_stop(priv); | 2606 | iwl3945_hw_txq_ctx_stop(priv); |
3086 | iwl3945_hw_rxq_stop(priv); | 2607 | iwl3945_hw_rxq_stop(priv); |
3087 | 2608 | ||
3088 | spin_lock_irqsave(&priv->lock, flags); | 2609 | iwl_write_prph(priv, APMG_CLK_DIS_REG, |
3089 | if (!iwl_grab_nic_access(priv)) { | 2610 | APMG_CLK_VAL_DMA_CLK_RQT); |
3090 | iwl_write_prph(priv, APMG_CLK_DIS_REG, | ||
3091 | APMG_CLK_VAL_DMA_CLK_RQT); | ||
3092 | iwl_release_nic_access(priv); | ||
3093 | } | ||
3094 | spin_unlock_irqrestore(&priv->lock, flags); | ||
3095 | 2611 | ||
3096 | udelay(5); | 2612 | udelay(5); |
3097 | 2613 | ||
3098 | if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) | 2614 | if (exit_pending) |
3099 | priv->cfg->ops->lib->apm_ops.stop(priv); | 2615 | priv->cfg->ops->lib->apm_ops.stop(priv); |
3100 | else | 2616 | else |
3101 | priv->cfg->ops->lib->apm_ops.reset(priv); | 2617 | priv->cfg->ops->lib->apm_ops.reset(priv); |
@@ -3131,12 +2647,6 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
3131 | return -EIO; | 2647 | return -EIO; |
3132 | } | 2648 | } |
3133 | 2649 | ||
3134 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { | ||
3135 | IWL_WARN(priv, "Radio disabled by SW RF kill (module " | ||
3136 | "parameter)\n"); | ||
3137 | return -ENODEV; | ||
3138 | } | ||
3139 | |||
3140 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { | 2650 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { |
3141 | IWL_ERR(priv, "ucode not available for device bring up\n"); | 2651 | IWL_ERR(priv, "ucode not available for device bring up\n"); |
3142 | return -EIO; | 2652 | return -EIO; |
@@ -3148,10 +2658,8 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
3148 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 2658 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
3149 | else { | 2659 | else { |
3150 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 2660 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
3151 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { | 2661 | IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); |
3152 | IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); | 2662 | return -ENODEV; |
3153 | return -ENODEV; | ||
3154 | } | ||
3155 | } | 2663 | } |
3156 | 2664 | ||
3157 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | 2665 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
@@ -3187,7 +2695,7 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
3187 | 2695 | ||
3188 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | 2696 | for (i = 0; i < MAX_HW_RESTARTS; i++) { |
3189 | 2697 | ||
3190 | iwl3945_clear_stations_table(priv); | 2698 | iwl_clear_stations_table(priv); |
3191 | 2699 | ||
3192 | /* load bootstrap state machine, | 2700 | /* load bootstrap state machine, |
3193 | * load bootstrap program into processor's memory, | 2701 | * load bootstrap program into processor's memory, |
@@ -3255,15 +2763,14 @@ static void iwl3945_rfkill_poll(struct work_struct *data) | |||
3255 | { | 2763 | { |
3256 | struct iwl_priv *priv = | 2764 | struct iwl_priv *priv = |
3257 | container_of(data, struct iwl_priv, rfkill_poll.work); | 2765 | container_of(data, struct iwl_priv, rfkill_poll.work); |
3258 | unsigned long status = priv->status; | ||
3259 | 2766 | ||
3260 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 2767 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
3261 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 2768 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
3262 | else | 2769 | else |
3263 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 2770 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
3264 | 2771 | ||
3265 | if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) | 2772 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
3266 | queue_work(priv->workqueue, &priv->rf_kill); | 2773 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
3267 | 2774 | ||
3268 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 2775 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
3269 | round_jiffies_relative(2 * HZ)); | 2776 | round_jiffies_relative(2 * HZ)); |
@@ -3283,9 +2790,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
3283 | int rc = 0; | 2790 | int rc = 0; |
3284 | struct iwl3945_scan_cmd *scan; | 2791 | struct iwl3945_scan_cmd *scan; |
3285 | struct ieee80211_conf *conf = NULL; | 2792 | struct ieee80211_conf *conf = NULL; |
3286 | u8 n_probes = 2; | 2793 | u8 n_probes = 0; |
3287 | enum ieee80211_band band; | 2794 | enum ieee80211_band band; |
3288 | DECLARE_SSID_BUF(ssid); | 2795 | bool is_active = false; |
3289 | 2796 | ||
3290 | conf = ieee80211_get_hw_conf(priv->hw); | 2797 | conf = ieee80211_get_hw_conf(priv->hw); |
3291 | 2798 | ||
@@ -3386,18 +2893,25 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
3386 | scan_suspend_time, interval); | 2893 | scan_suspend_time, interval); |
3387 | } | 2894 | } |
3388 | 2895 | ||
3389 | /* We should add the ability for user to lock to PASSIVE ONLY */ | 2896 | if (priv->scan_request->n_ssids) { |
3390 | if (priv->one_direct_scan) { | 2897 | int i, p = 0; |
3391 | IWL_DEBUG_SCAN(priv, "Kicking off one direct scan for '%s'\n", | 2898 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); |
3392 | print_ssid(ssid, priv->direct_ssid, | 2899 | for (i = 0; i < priv->scan_request->n_ssids; i++) { |
3393 | priv->direct_ssid_len)); | 2900 | /* always does wildcard anyway */ |
3394 | scan->direct_scan[0].id = WLAN_EID_SSID; | 2901 | if (!priv->scan_request->ssids[i].ssid_len) |
3395 | scan->direct_scan[0].len = priv->direct_ssid_len; | 2902 | continue; |
3396 | memcpy(scan->direct_scan[0].ssid, | 2903 | scan->direct_scan[p].id = WLAN_EID_SSID; |
3397 | priv->direct_ssid, priv->direct_ssid_len); | 2904 | scan->direct_scan[p].len = |
3398 | n_probes++; | 2905 | priv->scan_request->ssids[i].ssid_len; |
2906 | memcpy(scan->direct_scan[p].ssid, | ||
2907 | priv->scan_request->ssids[i].ssid, | ||
2908 | priv->scan_request->ssids[i].ssid_len); | ||
2909 | n_probes++; | ||
2910 | p++; | ||
2911 | } | ||
2912 | is_active = true; | ||
3399 | } else | 2913 | } else |
3400 | IWL_DEBUG_SCAN(priv, "Kicking off one indirect scan.\n"); | 2914 | IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n"); |
3401 | 2915 | ||
3402 | /* We don't build a direct scan probe request; the uCode will do | 2916 | /* We don't build a direct scan probe request; the uCode will do |
3403 | * that based on the direct_mask added to each channel entry */ | 2917 | * that based on the direct_mask added to each channel entry */ |
@@ -3414,7 +2928,12 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
3414 | band = IEEE80211_BAND_2GHZ; | 2928 | band = IEEE80211_BAND_2GHZ; |
3415 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { | 2929 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { |
3416 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; | 2930 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; |
3417 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 2931 | /* |
2932 | * If active scaning is requested but a certain channel | ||
2933 | * is marked passive, we can do active scanning if we | ||
2934 | * detect transmissions. | ||
2935 | */ | ||
2936 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; | ||
3418 | band = IEEE80211_BAND_5GHZ; | 2937 | band = IEEE80211_BAND_5GHZ; |
3419 | } else { | 2938 | } else { |
3420 | IWL_WARN(priv, "Invalid scan band count\n"); | 2939 | IWL_WARN(priv, "Invalid scan band count\n"); |
@@ -3422,19 +2941,20 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
3422 | } | 2941 | } |
3423 | 2942 | ||
3424 | scan->tx_cmd.len = cpu_to_le16( | 2943 | scan->tx_cmd.len = cpu_to_le16( |
3425 | iwl_fill_probe_req(priv, band, | 2944 | iwl_fill_probe_req(priv, |
3426 | (struct ieee80211_mgmt *)scan->data, | 2945 | (struct ieee80211_mgmt *)scan->data, |
3427 | IWL_MAX_SCAN_SIZE - sizeof(*scan))); | 2946 | priv->scan_request->ie, |
2947 | priv->scan_request->ie_len, | ||
2948 | IWL_MAX_SCAN_SIZE - sizeof(*scan))); | ||
3428 | 2949 | ||
3429 | /* select Rx antennas */ | 2950 | /* select Rx antennas */ |
3430 | scan->flags |= iwl3945_get_antenna_flags(priv); | 2951 | scan->flags |= iwl3945_get_antenna_flags(priv); |
3431 | 2952 | ||
3432 | if (priv->iw_mode == NL80211_IFTYPE_MONITOR) | 2953 | if (iwl_is_monitor_mode(priv)) |
3433 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; | 2954 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; |
3434 | 2955 | ||
3435 | scan->channel_count = | 2956 | scan->channel_count = |
3436 | iwl3945_get_channels_for_scan(priv, band, 1, /* active */ | 2957 | iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, |
3437 | n_probes, | ||
3438 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 2958 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
3439 | 2959 | ||
3440 | if (scan->channel_count == 0) { | 2960 | if (scan->channel_count == 0) { |
@@ -3482,7 +3002,6 @@ static void iwl3945_bg_up(struct work_struct *data) | |||
3482 | mutex_lock(&priv->mutex); | 3002 | mutex_lock(&priv->mutex); |
3483 | __iwl3945_up(priv); | 3003 | __iwl3945_up(priv); |
3484 | mutex_unlock(&priv->mutex); | 3004 | mutex_unlock(&priv->mutex); |
3485 | iwl_rfkill_set_hw_state(priv); | ||
3486 | } | 3005 | } |
3487 | 3006 | ||
3488 | static void iwl3945_bg_restart(struct work_struct *data) | 3007 | static void iwl3945_bg_restart(struct work_struct *data) |
@@ -3492,8 +3011,17 @@ static void iwl3945_bg_restart(struct work_struct *data) | |||
3492 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 3011 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
3493 | return; | 3012 | return; |
3494 | 3013 | ||
3495 | iwl3945_down(priv); | 3014 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { |
3496 | queue_work(priv->workqueue, &priv->up); | 3015 | mutex_lock(&priv->mutex); |
3016 | priv->vif = NULL; | ||
3017 | priv->is_open = 0; | ||
3018 | mutex_unlock(&priv->mutex); | ||
3019 | iwl3945_down(priv); | ||
3020 | ieee80211_restart_hw(priv->hw); | ||
3021 | } else { | ||
3022 | iwl3945_down(priv); | ||
3023 | queue_work(priv->workqueue, &priv->up); | ||
3024 | } | ||
3497 | } | 3025 | } |
3498 | 3026 | ||
3499 | static void iwl3945_bg_rx_replenish(struct work_struct *data) | 3027 | static void iwl3945_bg_rx_replenish(struct work_struct *data) |
@@ -3511,7 +3039,7 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) | |||
3511 | 3039 | ||
3512 | #define IWL_DELAY_NEXT_SCAN (HZ*2) | 3040 | #define IWL_DELAY_NEXT_SCAN (HZ*2) |
3513 | 3041 | ||
3514 | static void iwl3945_post_associate(struct iwl_priv *priv) | 3042 | void iwl3945_post_associate(struct iwl_priv *priv) |
3515 | { | 3043 | { |
3516 | int rc = 0; | 3044 | int rc = 0; |
3517 | struct ieee80211_conf *conf = NULL; | 3045 | struct ieee80211_conf *conf = NULL; |
@@ -3536,7 +3064,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv) | |||
3536 | conf = ieee80211_get_hw_conf(priv->hw); | 3064 | conf = ieee80211_get_hw_conf(priv->hw); |
3537 | 3065 | ||
3538 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3066 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
3539 | iwl3945_commit_rxon(priv); | 3067 | iwlcore_commit_rxon(priv); |
3540 | 3068 | ||
3541 | memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); | 3069 | memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); |
3542 | iwl3945_setup_rxon_timing(priv); | 3070 | iwl3945_setup_rxon_timing(priv); |
@@ -3569,7 +3097,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv) | |||
3569 | 3097 | ||
3570 | } | 3098 | } |
3571 | 3099 | ||
3572 | iwl3945_commit_rxon(priv); | 3100 | iwlcore_commit_rxon(priv); |
3573 | 3101 | ||
3574 | switch (priv->iw_mode) { | 3102 | switch (priv->iw_mode) { |
3575 | case NL80211_IFTYPE_STATION: | 3103 | case NL80211_IFTYPE_STATION: |
@@ -3579,7 +3107,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv) | |||
3579 | case NL80211_IFTYPE_ADHOC: | 3107 | case NL80211_IFTYPE_ADHOC: |
3580 | 3108 | ||
3581 | priv->assoc_id = 1; | 3109 | priv->assoc_id = 1; |
3582 | iwl3945_add_station(priv, priv->bssid, 0, 0); | 3110 | iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL); |
3583 | iwl3945_sync_sta(priv, IWL_STA_ID, | 3111 | iwl3945_sync_sta(priv, IWL_STA_ID, |
3584 | (priv->band == IEEE80211_BAND_5GHZ) ? | 3112 | (priv->band == IEEE80211_BAND_5GHZ) ? |
3585 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, | 3113 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, |
@@ -3601,8 +3129,6 @@ static void iwl3945_post_associate(struct iwl_priv *priv) | |||
3601 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 3129 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
3602 | } | 3130 | } |
3603 | 3131 | ||
3604 | static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed); | ||
3605 | |||
3606 | /***************************************************************************** | 3132 | /***************************************************************************** |
3607 | * | 3133 | * |
3608 | * mac80211 entry point functions | 3134 | * mac80211 entry point functions |
@@ -3638,16 +3164,11 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
3638 | 3164 | ||
3639 | mutex_unlock(&priv->mutex); | 3165 | mutex_unlock(&priv->mutex); |
3640 | 3166 | ||
3641 | iwl_rfkill_set_hw_state(priv); | ||
3642 | |||
3643 | if (ret) | 3167 | if (ret) |
3644 | goto out_release_irq; | 3168 | goto out_release_irq; |
3645 | 3169 | ||
3646 | IWL_DEBUG_INFO(priv, "Start UP work.\n"); | 3170 | IWL_DEBUG_INFO(priv, "Start UP work.\n"); |
3647 | 3171 | ||
3648 | if (test_bit(STATUS_IN_SUSPEND, &priv->status)) | ||
3649 | return 0; | ||
3650 | |||
3651 | /* Wait for START_ALIVE from ucode. Otherwise callbacks from | 3172 | /* Wait for START_ALIVE from ucode. Otherwise callbacks from |
3652 | * mac80211 will not be run successfully. */ | 3173 | * mac80211 will not be run successfully. */ |
3653 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 3174 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, |
@@ -3726,144 +3247,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3726 | return NETDEV_TX_OK; | 3247 | return NETDEV_TX_OK; |
3727 | } | 3248 | } |
3728 | 3249 | ||
3729 | static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, | 3250 | void iwl3945_config_ap(struct iwl_priv *priv) |
3730 | struct ieee80211_if_init_conf *conf) | ||
3731 | { | ||
3732 | struct iwl_priv *priv = hw->priv; | ||
3733 | unsigned long flags; | ||
3734 | |||
3735 | IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type); | ||
3736 | |||
3737 | if (priv->vif) { | ||
3738 | IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); | ||
3739 | return -EOPNOTSUPP; | ||
3740 | } | ||
3741 | |||
3742 | spin_lock_irqsave(&priv->lock, flags); | ||
3743 | priv->vif = conf->vif; | ||
3744 | priv->iw_mode = conf->type; | ||
3745 | |||
3746 | spin_unlock_irqrestore(&priv->lock, flags); | ||
3747 | |||
3748 | mutex_lock(&priv->mutex); | ||
3749 | |||
3750 | if (conf->mac_addr) { | ||
3751 | IWL_DEBUG_MAC80211(priv, "Set: %pM\n", conf->mac_addr); | ||
3752 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); | ||
3753 | } | ||
3754 | |||
3755 | if (iwl_is_ready(priv)) | ||
3756 | iwl3945_set_mode(priv, conf->type); | ||
3757 | |||
3758 | mutex_unlock(&priv->mutex); | ||
3759 | |||
3760 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
3761 | return 0; | ||
3762 | } | ||
3763 | |||
3764 | /** | ||
3765 | * iwl3945_mac_config - mac80211 config callback | ||
3766 | * | ||
3767 | * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to | ||
3768 | * be set inappropriately and the driver currently sets the hardware up to | ||
3769 | * use it whenever needed. | ||
3770 | */ | ||
3771 | static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed) | ||
3772 | { | ||
3773 | struct iwl_priv *priv = hw->priv; | ||
3774 | const struct iwl_channel_info *ch_info; | ||
3775 | struct ieee80211_conf *conf = &hw->conf; | ||
3776 | unsigned long flags; | ||
3777 | int ret = 0; | ||
3778 | |||
3779 | mutex_lock(&priv->mutex); | ||
3780 | IWL_DEBUG_MAC80211(priv, "enter to channel %d\n", | ||
3781 | conf->channel->hw_value); | ||
3782 | |||
3783 | if (!iwl_is_ready(priv)) { | ||
3784 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | ||
3785 | ret = -EIO; | ||
3786 | goto out; | ||
3787 | } | ||
3788 | |||
3789 | if (unlikely(!iwl3945_mod_params.disable_hw_scan && | ||
3790 | test_bit(STATUS_SCANNING, &priv->status))) { | ||
3791 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | ||
3792 | set_bit(STATUS_CONF_PENDING, &priv->status); | ||
3793 | mutex_unlock(&priv->mutex); | ||
3794 | return 0; | ||
3795 | } | ||
3796 | |||
3797 | spin_lock_irqsave(&priv->lock, flags); | ||
3798 | |||
3799 | ch_info = iwl_get_channel_info(priv, conf->channel->band, | ||
3800 | conf->channel->hw_value); | ||
3801 | if (!is_channel_valid(ch_info)) { | ||
3802 | IWL_DEBUG_SCAN(priv, | ||
3803 | "Channel %d [%d] is INVALID for this band.\n", | ||
3804 | conf->channel->hw_value, conf->channel->band); | ||
3805 | IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); | ||
3806 | spin_unlock_irqrestore(&priv->lock, flags); | ||
3807 | ret = -EINVAL; | ||
3808 | goto out; | ||
3809 | } | ||
3810 | |||
3811 | iwl_set_rxon_channel(priv, conf->channel); | ||
3812 | |||
3813 | iwl_set_flags_for_band(priv, conf->channel->band); | ||
3814 | |||
3815 | /* The list of supported rates and rate mask can be different | ||
3816 | * for each phymode; since the phymode may have changed, reset | ||
3817 | * the rate mask to what mac80211 lists */ | ||
3818 | iwl_set_rate(priv); | ||
3819 | |||
3820 | spin_unlock_irqrestore(&priv->lock, flags); | ||
3821 | |||
3822 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH | ||
3823 | if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) { | ||
3824 | iwl3945_hw_channel_switch(priv, conf->channel); | ||
3825 | goto out; | ||
3826 | } | ||
3827 | #endif | ||
3828 | |||
3829 | if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { | ||
3830 | if (conf->radio_enabled && | ||
3831 | iwl_radio_kill_sw_enable_radio(priv)) { | ||
3832 | IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " | ||
3833 | "waiting for uCode\n"); | ||
3834 | goto out; | ||
3835 | } | ||
3836 | |||
3837 | if (!conf->radio_enabled) { | ||
3838 | iwl_radio_kill_sw_disable_radio(priv); | ||
3839 | IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); | ||
3840 | goto out; | ||
3841 | } | ||
3842 | } | ||
3843 | |||
3844 | if (iwl_is_rfkill(priv)) { | ||
3845 | IWL_DEBUG_MAC80211(priv, "leave - RF kill\n"); | ||
3846 | ret = -EIO; | ||
3847 | goto out; | ||
3848 | } | ||
3849 | |||
3850 | iwl_set_rate(priv); | ||
3851 | |||
3852 | if (memcmp(&priv->active_rxon, | ||
3853 | &priv->staging_rxon, sizeof(priv->staging_rxon))) | ||
3854 | iwl3945_commit_rxon(priv); | ||
3855 | else | ||
3856 | IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n"); | ||
3857 | |||
3858 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
3859 | |||
3860 | out: | ||
3861 | clear_bit(STATUS_CONF_PENDING, &priv->status); | ||
3862 | mutex_unlock(&priv->mutex); | ||
3863 | return ret; | ||
3864 | } | ||
3865 | |||
3866 | static void iwl3945_config_ap(struct iwl_priv *priv) | ||
3867 | { | 3251 | { |
3868 | int rc = 0; | 3252 | int rc = 0; |
3869 | 3253 | ||
@@ -3875,7 +3259,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv) | |||
3875 | 3259 | ||
3876 | /* RXON - unassoc (to set timing command) */ | 3260 | /* RXON - unassoc (to set timing command) */ |
3877 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3261 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
3878 | iwl3945_commit_rxon(priv); | 3262 | iwlcore_commit_rxon(priv); |
3879 | 3263 | ||
3880 | /* RXON Timing */ | 3264 | /* RXON Timing */ |
3881 | memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); | 3265 | memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); |
@@ -3911,8 +3295,8 @@ static void iwl3945_config_ap(struct iwl_priv *priv) | |||
3911 | } | 3295 | } |
3912 | /* restore RXON assoc */ | 3296 | /* restore RXON assoc */ |
3913 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 3297 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
3914 | iwl3945_commit_rxon(priv); | 3298 | iwlcore_commit_rxon(priv); |
3915 | iwl3945_add_station(priv, iwl_bcast_addr, 0, 0); | 3299 | iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL); |
3916 | } | 3300 | } |
3917 | iwl3945_send_beacon_cmd(priv); | 3301 | iwl3945_send_beacon_cmd(priv); |
3918 | 3302 | ||
@@ -3921,189 +3305,6 @@ static void iwl3945_config_ap(struct iwl_priv *priv) | |||
3921 | * clear sta table, add BCAST sta... */ | 3305 | * clear sta table, add BCAST sta... */ |
3922 | } | 3306 | } |
3923 | 3307 | ||
3924 | static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | ||
3925 | struct ieee80211_vif *vif, | ||
3926 | struct ieee80211_if_conf *conf) | ||
3927 | { | ||
3928 | struct iwl_priv *priv = hw->priv; | ||
3929 | int rc; | ||
3930 | |||
3931 | if (conf == NULL) | ||
3932 | return -EIO; | ||
3933 | |||
3934 | if (priv->vif != vif) { | ||
3935 | IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n"); | ||
3936 | return 0; | ||
3937 | } | ||
3938 | |||
3939 | /* handle this temporarily here */ | ||
3940 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | ||
3941 | conf->changed & IEEE80211_IFCC_BEACON) { | ||
3942 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | ||
3943 | if (!beacon) | ||
3944 | return -ENOMEM; | ||
3945 | mutex_lock(&priv->mutex); | ||
3946 | rc = iwl3945_mac_beacon_update(hw, beacon); | ||
3947 | mutex_unlock(&priv->mutex); | ||
3948 | if (rc) | ||
3949 | return rc; | ||
3950 | } | ||
3951 | |||
3952 | if (!iwl_is_alive(priv)) | ||
3953 | return -EAGAIN; | ||
3954 | |||
3955 | mutex_lock(&priv->mutex); | ||
3956 | |||
3957 | if (conf->bssid) | ||
3958 | IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid); | ||
3959 | |||
3960 | /* | ||
3961 | * very dubious code was here; the probe filtering flag is never set: | ||
3962 | * | ||
3963 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && | ||
3964 | !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { | ||
3965 | */ | ||
3966 | |||
3967 | if (priv->iw_mode == NL80211_IFTYPE_AP) { | ||
3968 | if (!conf->bssid) { | ||
3969 | conf->bssid = priv->mac_addr; | ||
3970 | memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); | ||
3971 | IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n", | ||
3972 | conf->bssid); | ||
3973 | } | ||
3974 | if (priv->ibss_beacon) | ||
3975 | dev_kfree_skb(priv->ibss_beacon); | ||
3976 | |||
3977 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); | ||
3978 | } | ||
3979 | |||
3980 | if (iwl_is_rfkill(priv)) | ||
3981 | goto done; | ||
3982 | |||
3983 | if (conf->bssid && !is_zero_ether_addr(conf->bssid) && | ||
3984 | !is_multicast_ether_addr(conf->bssid)) { | ||
3985 | /* If there is currently a HW scan going on in the background | ||
3986 | * then we need to cancel it else the RXON below will fail. */ | ||
3987 | if (iwl_scan_cancel_timeout(priv, 100)) { | ||
3988 | IWL_WARN(priv, "Aborted scan still in progress " | ||
3989 | "after 100ms\n"); | ||
3990 | IWL_DEBUG_MAC80211(priv, "leaving:scan abort failed\n"); | ||
3991 | mutex_unlock(&priv->mutex); | ||
3992 | return -EAGAIN; | ||
3993 | } | ||
3994 | memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN); | ||
3995 | |||
3996 | /* TODO: Audit driver for usage of these members and see | ||
3997 | * if mac80211 deprecates them (priv->bssid looks like it | ||
3998 | * shouldn't be there, but I haven't scanned the IBSS code | ||
3999 | * to verify) - jpk */ | ||
4000 | memcpy(priv->bssid, conf->bssid, ETH_ALEN); | ||
4001 | |||
4002 | if (priv->iw_mode == NL80211_IFTYPE_AP) | ||
4003 | iwl3945_config_ap(priv); | ||
4004 | else { | ||
4005 | rc = iwl3945_commit_rxon(priv); | ||
4006 | if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) | ||
4007 | iwl3945_add_station(priv, | ||
4008 | priv->active_rxon.bssid_addr, 1, 0); | ||
4009 | } | ||
4010 | |||
4011 | } else { | ||
4012 | iwl_scan_cancel_timeout(priv, 100); | ||
4013 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
4014 | iwl3945_commit_rxon(priv); | ||
4015 | } | ||
4016 | |||
4017 | done: | ||
4018 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
4019 | mutex_unlock(&priv->mutex); | ||
4020 | |||
4021 | return 0; | ||
4022 | } | ||
4023 | |||
4024 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, | ||
4025 | struct ieee80211_if_init_conf *conf) | ||
4026 | { | ||
4027 | struct iwl_priv *priv = hw->priv; | ||
4028 | |||
4029 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
4030 | |||
4031 | mutex_lock(&priv->mutex); | ||
4032 | |||
4033 | if (iwl_is_ready_rf(priv)) { | ||
4034 | iwl_scan_cancel_timeout(priv, 100); | ||
4035 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
4036 | iwl3945_commit_rxon(priv); | ||
4037 | } | ||
4038 | if (priv->vif == conf->vif) { | ||
4039 | priv->vif = NULL; | ||
4040 | memset(priv->bssid, 0, ETH_ALEN); | ||
4041 | } | ||
4042 | mutex_unlock(&priv->mutex); | ||
4043 | |||
4044 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
4045 | } | ||
4046 | |||
4047 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | ||
4048 | |||
4049 | static void iwl3945_bss_info_changed(struct ieee80211_hw *hw, | ||
4050 | struct ieee80211_vif *vif, | ||
4051 | struct ieee80211_bss_conf *bss_conf, | ||
4052 | u32 changes) | ||
4053 | { | ||
4054 | struct iwl_priv *priv = hw->priv; | ||
4055 | |||
4056 | IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); | ||
4057 | |||
4058 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | ||
4059 | IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", | ||
4060 | bss_conf->use_short_preamble); | ||
4061 | if (bss_conf->use_short_preamble) | ||
4062 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | ||
4063 | else | ||
4064 | priv->staging_rxon.flags &= | ||
4065 | ~RXON_FLG_SHORT_PREAMBLE_MSK; | ||
4066 | } | ||
4067 | |||
4068 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { | ||
4069 | IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", | ||
4070 | bss_conf->use_cts_prot); | ||
4071 | if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) | ||
4072 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; | ||
4073 | else | ||
4074 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | ||
4075 | } | ||
4076 | |||
4077 | if (changes & BSS_CHANGED_ASSOC) { | ||
4078 | IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); | ||
4079 | /* This should never happen as this function should | ||
4080 | * never be called from interrupt context. */ | ||
4081 | if (WARN_ON_ONCE(in_interrupt())) | ||
4082 | return; | ||
4083 | if (bss_conf->assoc) { | ||
4084 | priv->assoc_id = bss_conf->aid; | ||
4085 | priv->beacon_int = bss_conf->beacon_int; | ||
4086 | priv->timestamp = bss_conf->timestamp; | ||
4087 | priv->assoc_capability = bss_conf->assoc_capability; | ||
4088 | priv->power_data.dtim_period = bss_conf->dtim_period; | ||
4089 | priv->next_scan_jiffies = jiffies + | ||
4090 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | ||
4091 | mutex_lock(&priv->mutex); | ||
4092 | iwl3945_post_associate(priv); | ||
4093 | mutex_unlock(&priv->mutex); | ||
4094 | } else { | ||
4095 | priv->assoc_id = 0; | ||
4096 | IWL_DEBUG_MAC80211(priv, | ||
4097 | "DISASSOC %d\n", bss_conf->assoc); | ||
4098 | } | ||
4099 | } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { | ||
4100 | IWL_DEBUG_MAC80211(priv, | ||
4101 | "Associated Changes %d\n", changes); | ||
4102 | iwl3945_send_rxon_assoc(priv); | ||
4103 | } | ||
4104 | |||
4105 | } | ||
4106 | |||
4107 | static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 3308 | static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
4108 | struct ieee80211_vif *vif, | 3309 | struct ieee80211_vif *vif, |
4109 | struct ieee80211_sta *sta, | 3310 | struct ieee80211_sta *sta, |
@@ -4126,7 +3327,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
4126 | static_key = !iwl_is_associated(priv); | 3327 | static_key = !iwl_is_associated(priv); |
4127 | 3328 | ||
4128 | if (!static_key) { | 3329 | if (!static_key) { |
4129 | sta_id = iwl3945_hw_find_station(priv, addr); | 3330 | sta_id = iwl_find_station(priv, addr); |
4130 | if (sta_id == IWL_INVALID_STATION) { | 3331 | if (sta_id == IWL_INVALID_STATION) { |
4131 | IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", | 3332 | IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", |
4132 | addr); | 3333 | addr); |
@@ -4162,185 +3363,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
4162 | return ret; | 3363 | return ret; |
4163 | } | 3364 | } |
4164 | 3365 | ||
4165 | static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | ||
4166 | const struct ieee80211_tx_queue_params *params) | ||
4167 | { | ||
4168 | struct iwl_priv *priv = hw->priv; | ||
4169 | unsigned long flags; | ||
4170 | int q; | ||
4171 | |||
4172 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
4173 | |||
4174 | if (!iwl_is_ready_rf(priv)) { | ||
4175 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
4176 | return -EIO; | ||
4177 | } | ||
4178 | |||
4179 | if (queue >= AC_NUM) { | ||
4180 | IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); | ||
4181 | return 0; | ||
4182 | } | ||
4183 | |||
4184 | q = AC_NUM - 1 - queue; | ||
4185 | |||
4186 | spin_lock_irqsave(&priv->lock, flags); | ||
4187 | |||
4188 | priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); | ||
4189 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); | ||
4190 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | ||
4191 | priv->qos_data.def_qos_parm.ac[q].edca_txop = | ||
4192 | cpu_to_le16((params->txop * 32)); | ||
4193 | |||
4194 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | ||
4195 | priv->qos_data.qos_active = 1; | ||
4196 | |||
4197 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4198 | |||
4199 | mutex_lock(&priv->mutex); | ||
4200 | if (priv->iw_mode == NL80211_IFTYPE_AP) | ||
4201 | iwl_activate_qos(priv, 1); | ||
4202 | else if (priv->assoc_id && iwl_is_associated(priv)) | ||
4203 | iwl_activate_qos(priv, 0); | ||
4204 | |||
4205 | mutex_unlock(&priv->mutex); | ||
4206 | |||
4207 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
4208 | return 0; | ||
4209 | } | ||
4210 | |||
4211 | static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw, | ||
4212 | struct ieee80211_tx_queue_stats *stats) | ||
4213 | { | ||
4214 | struct iwl_priv *priv = hw->priv; | ||
4215 | int i, avail; | ||
4216 | struct iwl_tx_queue *txq; | ||
4217 | struct iwl_queue *q; | ||
4218 | unsigned long flags; | ||
4219 | |||
4220 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
4221 | |||
4222 | if (!iwl_is_ready_rf(priv)) { | ||
4223 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
4224 | return -EIO; | ||
4225 | } | ||
4226 | |||
4227 | spin_lock_irqsave(&priv->lock, flags); | ||
4228 | |||
4229 | for (i = 0; i < AC_NUM; i++) { | ||
4230 | txq = &priv->txq[i]; | ||
4231 | q = &txq->q; | ||
4232 | avail = iwl_queue_space(q); | ||
4233 | |||
4234 | stats[i].len = q->n_window - avail; | ||
4235 | stats[i].limit = q->n_window - q->high_mark; | ||
4236 | stats[i].count = q->n_window; | ||
4237 | |||
4238 | } | ||
4239 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4240 | |||
4241 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
4242 | |||
4243 | return 0; | ||
4244 | } | ||
4245 | |||
4246 | static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | ||
4247 | { | ||
4248 | struct iwl_priv *priv = hw->priv; | ||
4249 | unsigned long flags; | ||
4250 | |||
4251 | mutex_lock(&priv->mutex); | ||
4252 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
4253 | |||
4254 | iwl_reset_qos(priv); | ||
4255 | |||
4256 | spin_lock_irqsave(&priv->lock, flags); | ||
4257 | priv->assoc_id = 0; | ||
4258 | priv->assoc_capability = 0; | ||
4259 | |||
4260 | /* new association get rid of ibss beacon skb */ | ||
4261 | if (priv->ibss_beacon) | ||
4262 | dev_kfree_skb(priv->ibss_beacon); | ||
4263 | |||
4264 | priv->ibss_beacon = NULL; | ||
4265 | |||
4266 | priv->beacon_int = priv->hw->conf.beacon_int; | ||
4267 | priv->timestamp = 0; | ||
4268 | if ((priv->iw_mode == NL80211_IFTYPE_STATION)) | ||
4269 | priv->beacon_int = 0; | ||
4270 | |||
4271 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4272 | |||
4273 | if (!iwl_is_ready_rf(priv)) { | ||
4274 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | ||
4275 | mutex_unlock(&priv->mutex); | ||
4276 | return; | ||
4277 | } | ||
4278 | |||
4279 | /* we are restarting association process | ||
4280 | * clear RXON_FILTER_ASSOC_MSK bit | ||
4281 | */ | ||
4282 | if (priv->iw_mode != NL80211_IFTYPE_AP) { | ||
4283 | iwl_scan_cancel_timeout(priv, 100); | ||
4284 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
4285 | iwl3945_commit_rxon(priv); | ||
4286 | } | ||
4287 | |||
4288 | /* Per mac80211.h: This is only used in IBSS mode... */ | ||
4289 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | ||
4290 | |||
4291 | IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); | ||
4292 | mutex_unlock(&priv->mutex); | ||
4293 | return; | ||
4294 | } | ||
4295 | |||
4296 | iwl_set_rate(priv); | ||
4297 | |||
4298 | mutex_unlock(&priv->mutex); | ||
4299 | |||
4300 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
4301 | |||
4302 | } | ||
4303 | |||
4304 | static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
4305 | { | ||
4306 | struct iwl_priv *priv = hw->priv; | ||
4307 | unsigned long flags; | ||
4308 | __le64 timestamp; | ||
4309 | |||
4310 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
4311 | |||
4312 | if (!iwl_is_ready_rf(priv)) { | ||
4313 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
4314 | return -EIO; | ||
4315 | } | ||
4316 | |||
4317 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | ||
4318 | IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n"); | ||
4319 | return -EIO; | ||
4320 | } | ||
4321 | |||
4322 | spin_lock_irqsave(&priv->lock, flags); | ||
4323 | |||
4324 | if (priv->ibss_beacon) | ||
4325 | dev_kfree_skb(priv->ibss_beacon); | ||
4326 | |||
4327 | priv->ibss_beacon = skb; | ||
4328 | |||
4329 | priv->assoc_id = 0; | ||
4330 | timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | ||
4331 | priv->timestamp = le64_to_cpu(timestamp); | ||
4332 | |||
4333 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
4334 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4335 | |||
4336 | iwl_reset_qos(priv); | ||
4337 | |||
4338 | iwl3945_post_associate(priv); | ||
4339 | |||
4340 | |||
4341 | return 0; | ||
4342 | } | ||
4343 | |||
4344 | /***************************************************************************** | 3366 | /***************************************************************************** |
4345 | * | 3367 | * |
4346 | * sysfs attributes | 3368 | * sysfs attributes |
@@ -4359,7 +3381,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
4359 | static ssize_t show_debug_level(struct device *d, | 3381 | static ssize_t show_debug_level(struct device *d, |
4360 | struct device_attribute *attr, char *buf) | 3382 | struct device_attribute *attr, char *buf) |
4361 | { | 3383 | { |
4362 | struct iwl_priv *priv = d->driver_data; | 3384 | struct iwl_priv *priv = dev_get_drvdata(d); |
4363 | 3385 | ||
4364 | return sprintf(buf, "0x%08X\n", priv->debug_level); | 3386 | return sprintf(buf, "0x%08X\n", priv->debug_level); |
4365 | } | 3387 | } |
@@ -4367,7 +3389,7 @@ static ssize_t store_debug_level(struct device *d, | |||
4367 | struct device_attribute *attr, | 3389 | struct device_attribute *attr, |
4368 | const char *buf, size_t count) | 3390 | const char *buf, size_t count) |
4369 | { | 3391 | { |
4370 | struct iwl_priv *priv = d->driver_data; | 3392 | struct iwl_priv *priv = dev_get_drvdata(d); |
4371 | unsigned long val; | 3393 | unsigned long val; |
4372 | int ret; | 3394 | int ret; |
4373 | 3395 | ||
@@ -4388,7 +3410,7 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, | |||
4388 | static ssize_t show_temperature(struct device *d, | 3410 | static ssize_t show_temperature(struct device *d, |
4389 | struct device_attribute *attr, char *buf) | 3411 | struct device_attribute *attr, char *buf) |
4390 | { | 3412 | { |
4391 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3413 | struct iwl_priv *priv = dev_get_drvdata(d); |
4392 | 3414 | ||
4393 | if (!iwl_is_alive(priv)) | 3415 | if (!iwl_is_alive(priv)) |
4394 | return -EAGAIN; | 3416 | return -EAGAIN; |
@@ -4401,7 +3423,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); | |||
4401 | static ssize_t show_tx_power(struct device *d, | 3423 | static ssize_t show_tx_power(struct device *d, |
4402 | struct device_attribute *attr, char *buf) | 3424 | struct device_attribute *attr, char *buf) |
4403 | { | 3425 | { |
4404 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3426 | struct iwl_priv *priv = dev_get_drvdata(d); |
4405 | return sprintf(buf, "%d\n", priv->tx_power_user_lmt); | 3427 | return sprintf(buf, "%d\n", priv->tx_power_user_lmt); |
4406 | } | 3428 | } |
4407 | 3429 | ||
@@ -4409,7 +3431,7 @@ static ssize_t store_tx_power(struct device *d, | |||
4409 | struct device_attribute *attr, | 3431 | struct device_attribute *attr, |
4410 | const char *buf, size_t count) | 3432 | const char *buf, size_t count) |
4411 | { | 3433 | { |
4412 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3434 | struct iwl_priv *priv = dev_get_drvdata(d); |
4413 | char *p = (char *)buf; | 3435 | char *p = (char *)buf; |
4414 | u32 val; | 3436 | u32 val; |
4415 | 3437 | ||
@@ -4427,7 +3449,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); | |||
4427 | static ssize_t show_flags(struct device *d, | 3449 | static ssize_t show_flags(struct device *d, |
4428 | struct device_attribute *attr, char *buf) | 3450 | struct device_attribute *attr, char *buf) |
4429 | { | 3451 | { |
4430 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3452 | struct iwl_priv *priv = dev_get_drvdata(d); |
4431 | 3453 | ||
4432 | return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); | 3454 | return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); |
4433 | } | 3455 | } |
@@ -4436,7 +3458,7 @@ static ssize_t store_flags(struct device *d, | |||
4436 | struct device_attribute *attr, | 3458 | struct device_attribute *attr, |
4437 | const char *buf, size_t count) | 3459 | const char *buf, size_t count) |
4438 | { | 3460 | { |
4439 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3461 | struct iwl_priv *priv = dev_get_drvdata(d); |
4440 | u32 flags = simple_strtoul(buf, NULL, 0); | 3462 | u32 flags = simple_strtoul(buf, NULL, 0); |
4441 | 3463 | ||
4442 | mutex_lock(&priv->mutex); | 3464 | mutex_lock(&priv->mutex); |
@@ -4448,7 +3470,7 @@ static ssize_t store_flags(struct device *d, | |||
4448 | IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", | 3470 | IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", |
4449 | flags); | 3471 | flags); |
4450 | priv->staging_rxon.flags = cpu_to_le32(flags); | 3472 | priv->staging_rxon.flags = cpu_to_le32(flags); |
4451 | iwl3945_commit_rxon(priv); | 3473 | iwlcore_commit_rxon(priv); |
4452 | } | 3474 | } |
4453 | } | 3475 | } |
4454 | mutex_unlock(&priv->mutex); | 3476 | mutex_unlock(&priv->mutex); |
@@ -4461,7 +3483,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags); | |||
4461 | static ssize_t show_filter_flags(struct device *d, | 3483 | static ssize_t show_filter_flags(struct device *d, |
4462 | struct device_attribute *attr, char *buf) | 3484 | struct device_attribute *attr, char *buf) |
4463 | { | 3485 | { |
4464 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3486 | struct iwl_priv *priv = dev_get_drvdata(d); |
4465 | 3487 | ||
4466 | return sprintf(buf, "0x%04X\n", | 3488 | return sprintf(buf, "0x%04X\n", |
4467 | le32_to_cpu(priv->active_rxon.filter_flags)); | 3489 | le32_to_cpu(priv->active_rxon.filter_flags)); |
@@ -4471,7 +3493,7 @@ static ssize_t store_filter_flags(struct device *d, | |||
4471 | struct device_attribute *attr, | 3493 | struct device_attribute *attr, |
4472 | const char *buf, size_t count) | 3494 | const char *buf, size_t count) |
4473 | { | 3495 | { |
4474 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3496 | struct iwl_priv *priv = dev_get_drvdata(d); |
4475 | u32 filter_flags = simple_strtoul(buf, NULL, 0); | 3497 | u32 filter_flags = simple_strtoul(buf, NULL, 0); |
4476 | 3498 | ||
4477 | mutex_lock(&priv->mutex); | 3499 | mutex_lock(&priv->mutex); |
@@ -4484,7 +3506,7 @@ static ssize_t store_filter_flags(struct device *d, | |||
4484 | "0x%04X\n", filter_flags); | 3506 | "0x%04X\n", filter_flags); |
4485 | priv->staging_rxon.filter_flags = | 3507 | priv->staging_rxon.filter_flags = |
4486 | cpu_to_le32(filter_flags); | 3508 | cpu_to_le32(filter_flags); |
4487 | iwl3945_commit_rxon(priv); | 3509 | iwlcore_commit_rxon(priv); |
4488 | } | 3510 | } |
4489 | } | 3511 | } |
4490 | mutex_unlock(&priv->mutex); | 3512 | mutex_unlock(&priv->mutex); |
@@ -4624,26 +3646,11 @@ static ssize_t show_power_level(struct device *d, | |||
4624 | { | 3646 | { |
4625 | struct iwl_priv *priv = dev_get_drvdata(d); | 3647 | struct iwl_priv *priv = dev_get_drvdata(d); |
4626 | int mode = priv->power_data.user_power_setting; | 3648 | int mode = priv->power_data.user_power_setting; |
4627 | int system = priv->power_data.system_power_setting; | ||
4628 | int level = priv->power_data.power_mode; | 3649 | int level = priv->power_data.power_mode; |
4629 | char *p = buf; | 3650 | char *p = buf; |
4630 | 3651 | ||
4631 | switch (system) { | 3652 | p += sprintf(p, "INDEX:%d\t", level); |
4632 | case IWL_POWER_SYS_AUTO: | 3653 | p += sprintf(p, "USER:%d\n", mode); |
4633 | p += sprintf(p, "SYSTEM:auto"); | ||
4634 | break; | ||
4635 | case IWL_POWER_SYS_AC: | ||
4636 | p += sprintf(p, "SYSTEM:ac"); | ||
4637 | break; | ||
4638 | case IWL_POWER_SYS_BATTERY: | ||
4639 | p += sprintf(p, "SYSTEM:battery"); | ||
4640 | break; | ||
4641 | } | ||
4642 | |||
4643 | p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ? | ||
4644 | "fixed" : "auto"); | ||
4645 | p += sprintf(p, "\tINDEX:%d", level); | ||
4646 | p += sprintf(p, "\n"); | ||
4647 | return p - buf + 1; | 3654 | return p - buf + 1; |
4648 | } | 3655 | } |
4649 | 3656 | ||
@@ -4756,7 +3763,7 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna); | |||
4756 | static ssize_t show_status(struct device *d, | 3763 | static ssize_t show_status(struct device *d, |
4757 | struct device_attribute *attr, char *buf) | 3764 | struct device_attribute *attr, char *buf) |
4758 | { | 3765 | { |
4759 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3766 | struct iwl_priv *priv = dev_get_drvdata(d); |
4760 | if (!iwl_is_alive(priv)) | 3767 | if (!iwl_is_alive(priv)) |
4761 | return -EAGAIN; | 3768 | return -EAGAIN; |
4762 | return sprintf(buf, "0x%08x\n", (int)priv->status); | 3769 | return sprintf(buf, "0x%08x\n", (int)priv->status); |
@@ -4768,10 +3775,11 @@ static ssize_t dump_error_log(struct device *d, | |||
4768 | struct device_attribute *attr, | 3775 | struct device_attribute *attr, |
4769 | const char *buf, size_t count) | 3776 | const char *buf, size_t count) |
4770 | { | 3777 | { |
3778 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
4771 | char *p = (char *)buf; | 3779 | char *p = (char *)buf; |
4772 | 3780 | ||
4773 | if (p[0] == '1') | 3781 | if (p[0] == '1') |
4774 | iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data); | 3782 | iwl3945_dump_nic_error_log(priv); |
4775 | 3783 | ||
4776 | return strnlen(buf, count); | 3784 | return strnlen(buf, count); |
4777 | } | 3785 | } |
@@ -4782,10 +3790,11 @@ static ssize_t dump_event_log(struct device *d, | |||
4782 | struct device_attribute *attr, | 3790 | struct device_attribute *attr, |
4783 | const char *buf, size_t count) | 3791 | const char *buf, size_t count) |
4784 | { | 3792 | { |
3793 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
4785 | char *p = (char *)buf; | 3794 | char *p = (char *)buf; |
4786 | 3795 | ||
4787 | if (p[0] == '1') | 3796 | if (p[0] == '1') |
4788 | iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data); | 3797 | iwl3945_dump_nic_event_log(priv); |
4789 | 3798 | ||
4790 | return strnlen(buf, count); | 3799 | return strnlen(buf, count); |
4791 | } | 3800 | } |
@@ -4807,7 +3816,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) | |||
4807 | INIT_WORK(&priv->up, iwl3945_bg_up); | 3816 | INIT_WORK(&priv->up, iwl3945_bg_up); |
4808 | INIT_WORK(&priv->restart, iwl3945_bg_restart); | 3817 | INIT_WORK(&priv->restart, iwl3945_bg_restart); |
4809 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); | 3818 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); |
4810 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); | ||
4811 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); | 3819 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); |
4812 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); | 3820 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); |
4813 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 3821 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
@@ -4864,16 +3872,15 @@ static struct ieee80211_ops iwl3945_hw_ops = { | |||
4864 | .tx = iwl3945_mac_tx, | 3872 | .tx = iwl3945_mac_tx, |
4865 | .start = iwl3945_mac_start, | 3873 | .start = iwl3945_mac_start, |
4866 | .stop = iwl3945_mac_stop, | 3874 | .stop = iwl3945_mac_stop, |
4867 | .add_interface = iwl3945_mac_add_interface, | 3875 | .add_interface = iwl_mac_add_interface, |
4868 | .remove_interface = iwl3945_mac_remove_interface, | 3876 | .remove_interface = iwl_mac_remove_interface, |
4869 | .config = iwl3945_mac_config, | 3877 | .config = iwl_mac_config, |
4870 | .config_interface = iwl3945_mac_config_interface, | ||
4871 | .configure_filter = iwl_configure_filter, | 3878 | .configure_filter = iwl_configure_filter, |
4872 | .set_key = iwl3945_mac_set_key, | 3879 | .set_key = iwl3945_mac_set_key, |
4873 | .get_tx_stats = iwl3945_mac_get_tx_stats, | 3880 | .get_tx_stats = iwl_mac_get_tx_stats, |
4874 | .conf_tx = iwl3945_mac_conf_tx, | 3881 | .conf_tx = iwl_mac_conf_tx, |
4875 | .reset_tsf = iwl3945_mac_reset_tsf, | 3882 | .reset_tsf = iwl_mac_reset_tsf, |
4876 | .bss_info_changed = iwl3945_bss_info_changed, | 3883 | .bss_info_changed = iwl_bss_info_changed, |
4877 | .hw_scan = iwl_mac_hw_scan | 3884 | .hw_scan = iwl_mac_hw_scan |
4878 | }; | 3885 | }; |
4879 | 3886 | ||
@@ -4886,7 +3893,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
4886 | priv->ibss_beacon = NULL; | 3893 | priv->ibss_beacon = NULL; |
4887 | 3894 | ||
4888 | spin_lock_init(&priv->lock); | 3895 | spin_lock_init(&priv->lock); |
4889 | spin_lock_init(&priv->power_data.lock); | ||
4890 | spin_lock_init(&priv->sta_lock); | 3896 | spin_lock_init(&priv->sta_lock); |
4891 | spin_lock_init(&priv->hcmd_lock); | 3897 | spin_lock_init(&priv->hcmd_lock); |
4892 | 3898 | ||
@@ -4895,7 +3901,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
4895 | mutex_init(&priv->mutex); | 3901 | mutex_init(&priv->mutex); |
4896 | 3902 | ||
4897 | /* Clear the driver's (not device's) station table */ | 3903 | /* Clear the driver's (not device's) station table */ |
4898 | iwl3945_clear_stations_table(priv); | 3904 | iwl_clear_stations_table(priv); |
4899 | 3905 | ||
4900 | priv->data_retry_limit = -1; | 3906 | priv->data_retry_limit = -1; |
4901 | priv->ieee_channels = NULL; | 3907 | priv->ieee_channels = NULL; |
@@ -4966,13 +3972,13 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
4966 | 3972 | ||
4967 | hw->wiphy->custom_regulatory = true; | 3973 | hw->wiphy->custom_regulatory = true; |
4968 | 3974 | ||
4969 | hw->wiphy->max_scan_ssids = 1; /* WILL FIX */ | 3975 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; |
3976 | /* we create the 802.11 header and a zero-length SSID element */ | ||
3977 | hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; | ||
4970 | 3978 | ||
4971 | /* Default value; 4 EDCA QOS priorities */ | 3979 | /* Default value; 4 EDCA QOS priorities */ |
4972 | hw->queues = 4; | 3980 | hw->queues = 4; |
4973 | 3981 | ||
4974 | hw->conf.beacon_int = 100; | ||
4975 | |||
4976 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | 3982 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) |
4977 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | 3983 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
4978 | &priv->bands[IEEE80211_BAND_2GHZ]; | 3984 | &priv->bands[IEEE80211_BAND_2GHZ]; |
@@ -5037,6 +4043,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5037 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); | 4043 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); |
5038 | priv->cfg = cfg; | 4044 | priv->cfg = cfg; |
5039 | priv->pci_dev = pdev; | 4045 | priv->pci_dev = pdev; |
4046 | priv->inta_mask = CSR_INI_SET_MASK; | ||
5040 | 4047 | ||
5041 | #ifdef CONFIG_IWLWIFI_DEBUG | 4048 | #ifdef CONFIG_IWLWIFI_DEBUG |
5042 | priv->debug_level = iwl3945_mod_params.debug; | 4049 | priv->debug_level = iwl3945_mod_params.debug; |
@@ -5083,6 +4090,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5083 | * PCI Tx retries from interfering with C3 CPU state */ | 4090 | * PCI Tx retries from interfering with C3 CPU state */ |
5084 | pci_write_config_byte(pdev, 0x41, 0x00); | 4091 | pci_write_config_byte(pdev, 0x41, 0x00); |
5085 | 4092 | ||
4093 | /* this spin lock will be used in apm_ops.init and EEPROM access | ||
4094 | * we should init now | ||
4095 | */ | ||
4096 | spin_lock_init(&priv->reg_lock); | ||
4097 | |||
5086 | /* amp init */ | 4098 | /* amp init */ |
5087 | err = priv->cfg->ops->lib->apm_ops.init(priv); | 4099 | err = priv->cfg->ops->lib->apm_ops.init(priv); |
5088 | if (err < 0) { | 4100 | if (err < 0) { |
@@ -5128,20 +4140,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5128 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n", | 4140 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n", |
5129 | priv->cfg->name); | 4141 | priv->cfg->name); |
5130 | 4142 | ||
5131 | /*********************************** | ||
5132 | * 7. Initialize Module Parameters | ||
5133 | * **********************************/ | ||
5134 | |||
5135 | /* Initialize module parameter values here */ | ||
5136 | /* Disable radio (SW RF KILL) via parameter when loading driver */ | ||
5137 | if (iwl3945_mod_params.disable) { | ||
5138 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
5139 | IWL_DEBUG_INFO(priv, "Radio disabled.\n"); | ||
5140 | } | ||
5141 | |||
5142 | |||
5143 | /*********************** | 4143 | /*********************** |
5144 | * 8. Setup Services | 4144 | * 7. Setup Services |
5145 | * ********************/ | 4145 | * ********************/ |
5146 | 4146 | ||
5147 | spin_lock_irqsave(&priv->lock, flags); | 4147 | spin_lock_irqsave(&priv->lock, flags); |
@@ -5150,8 +4150,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5150 | 4150 | ||
5151 | pci_enable_msi(priv->pci_dev); | 4151 | pci_enable_msi(priv->pci_dev); |
5152 | 4152 | ||
5153 | err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED, | 4153 | err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr, |
5154 | DRV_NAME, priv); | 4154 | IRQF_SHARED, DRV_NAME, priv); |
5155 | if (err) { | 4155 | if (err) { |
5156 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); | 4156 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); |
5157 | goto out_disable_msi; | 4157 | goto out_disable_msi; |
@@ -5169,7 +4169,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5169 | iwl3945_setup_rx_handlers(priv); | 4169 | iwl3945_setup_rx_handlers(priv); |
5170 | 4170 | ||
5171 | /********************************* | 4171 | /********************************* |
5172 | * 9. Setup and Register mac80211 | 4172 | * 8. Setup and Register mac80211 |
5173 | * *******************************/ | 4173 | * *******************************/ |
5174 | 4174 | ||
5175 | iwl_enable_interrupts(priv); | 4175 | iwl_enable_interrupts(priv); |
@@ -5178,12 +4178,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5178 | if (err) | 4178 | if (err) |
5179 | goto out_remove_sysfs; | 4179 | goto out_remove_sysfs; |
5180 | 4180 | ||
5181 | err = iwl_rfkill_init(priv); | 4181 | err = iwl_dbgfs_register(priv, DRV_NAME); |
5182 | if (err) | 4182 | if (err) |
5183 | IWL_ERR(priv, "Unable to initialize RFKILL system. " | 4183 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); |
5184 | "Ignoring error: %d\n", err); | ||
5185 | else | ||
5186 | iwl_rfkill_set_hw_state(priv); | ||
5187 | 4184 | ||
5188 | /* Start monitoring the killswitch */ | 4185 | /* Start monitoring the killswitch */ |
5189 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 4186 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
@@ -5228,6 +4225,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
5228 | 4225 | ||
5229 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); | 4226 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); |
5230 | 4227 | ||
4228 | iwl_dbgfs_unregister(priv); | ||
4229 | |||
5231 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 4230 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
5232 | 4231 | ||
5233 | if (priv->mac80211_registered) { | 4232 | if (priv->mac80211_registered) { |
@@ -5248,7 +4247,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
5248 | 4247 | ||
5249 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 4248 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
5250 | 4249 | ||
5251 | iwl_rfkill_unregister(priv); | ||
5252 | cancel_delayed_work_sync(&priv->rfkill_poll); | 4250 | cancel_delayed_work_sync(&priv->rfkill_poll); |
5253 | 4251 | ||
5254 | iwl3945_dealloc_ucode_pci(priv); | 4252 | iwl3945_dealloc_ucode_pci(priv); |
@@ -5258,7 +4256,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
5258 | iwl3945_hw_txq_ctx_free(priv); | 4256 | iwl3945_hw_txq_ctx_free(priv); |
5259 | 4257 | ||
5260 | iwl3945_unset_hw_params(priv); | 4258 | iwl3945_unset_hw_params(priv); |
5261 | iwl3945_clear_stations_table(priv); | 4259 | iwl_clear_stations_table(priv); |
5262 | 4260 | ||
5263 | /*netif_stop_queue(dev); */ | 4261 | /*netif_stop_queue(dev); */ |
5264 | flush_workqueue(priv->workqueue); | 4262 | flush_workqueue(priv->workqueue); |
@@ -5286,43 +4284,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
5286 | ieee80211_free_hw(priv->hw); | 4284 | ieee80211_free_hw(priv->hw); |
5287 | } | 4285 | } |
5288 | 4286 | ||
5289 | #ifdef CONFIG_PM | ||
5290 | |||
5291 | static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
5292 | { | ||
5293 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
5294 | |||
5295 | if (priv->is_open) { | ||
5296 | set_bit(STATUS_IN_SUSPEND, &priv->status); | ||
5297 | iwl3945_mac_stop(priv->hw); | ||
5298 | priv->is_open = 1; | ||
5299 | } | ||
5300 | pci_save_state(pdev); | ||
5301 | pci_disable_device(pdev); | ||
5302 | pci_set_power_state(pdev, PCI_D3hot); | ||
5303 | |||
5304 | return 0; | ||
5305 | } | ||
5306 | |||
5307 | static int iwl3945_pci_resume(struct pci_dev *pdev) | ||
5308 | { | ||
5309 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
5310 | int ret; | ||
5311 | |||
5312 | pci_set_power_state(pdev, PCI_D0); | ||
5313 | ret = pci_enable_device(pdev); | ||
5314 | if (ret) | ||
5315 | return ret; | ||
5316 | pci_restore_state(pdev); | ||
5317 | |||
5318 | if (priv->is_open) | ||
5319 | iwl3945_mac_start(priv->hw); | ||
5320 | |||
5321 | clear_bit(STATUS_IN_SUSPEND, &priv->status); | ||
5322 | return 0; | ||
5323 | } | ||
5324 | |||
5325 | #endif /* CONFIG_PM */ | ||
5326 | 4287 | ||
5327 | /***************************************************************************** | 4288 | /***************************************************************************** |
5328 | * | 4289 | * |
@@ -5336,8 +4297,8 @@ static struct pci_driver iwl3945_driver = { | |||
5336 | .probe = iwl3945_pci_probe, | 4297 | .probe = iwl3945_pci_probe, |
5337 | .remove = __devexit_p(iwl3945_pci_remove), | 4298 | .remove = __devexit_p(iwl3945_pci_remove), |
5338 | #ifdef CONFIG_PM | 4299 | #ifdef CONFIG_PM |
5339 | .suspend = iwl3945_pci_suspend, | 4300 | .suspend = iwl_pci_suspend, |
5340 | .resume = iwl3945_pci_resume, | 4301 | .resume = iwl_pci_resume, |
5341 | #endif | 4302 | #endif |
5342 | }; | 4303 | }; |
5343 | 4304 | ||
@@ -5378,8 +4339,6 @@ MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX)); | |||
5378 | 4339 | ||
5379 | module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444); | 4340 | module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444); |
5380 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); | 4341 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); |
5381 | module_param_named(disable, iwl3945_mod_params.disable, int, 0444); | ||
5382 | MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); | ||
5383 | module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444); | 4342 | module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444); |
5384 | MODULE_PARM_DESC(swcrypto, | 4343 | MODULE_PARM_DESC(swcrypto, |
5385 | "using software crypto (default 1 [software])\n"); | 4344 | "using software crypto (default 1 [software])\n"); |