diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 125 |
1 files changed, 91 insertions, 34 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 7ca5627cc078..8fdb34222c0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * file called LICENSE. | 19 | * file called LICENSE. |
20 | * | 20 | * |
21 | * Contact Information: | 21 | * Contact Information: |
22 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> | 22 | * Intel Linux Wireless <ilw@linux.intel.com> |
23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
24 | * | 24 | * |
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
@@ -200,7 +200,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp) | |||
200 | * priv->eeprom is used to determine if antenna AUX/MAIN are reversed | 200 | * priv->eeprom is used to determine if antenna AUX/MAIN are reversed |
201 | * priv->antenna specifies the antenna diversity mode: | 201 | * priv->antenna specifies the antenna diversity mode: |
202 | * | 202 | * |
203 | * IWL_ANTENNA_DIVERISTY - NIC selects best antenna by itself | 203 | * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself |
204 | * IWL_ANTENNA_MAIN - Force MAIN antenna | 204 | * IWL_ANTENNA_MAIN - Force MAIN antenna |
205 | * IWL_ANTENNA_AUX - Force AUX antenna | 205 | * IWL_ANTENNA_AUX - Force AUX antenna |
206 | */ | 206 | */ |
@@ -261,6 +261,37 @@ static inline const char *iwl3945_get_tx_fail_reason(u32 status) | |||
261 | } | 261 | } |
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | /* | ||
265 | * get ieee prev rate from rate scale table. | ||
266 | * for A and B mode we need to overright prev | ||
267 | * value | ||
268 | */ | ||
269 | int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate) | ||
270 | { | ||
271 | int next_rate = iwl3945_get_prev_ieee_rate(rate); | ||
272 | |||
273 | switch (priv->band) { | ||
274 | case IEEE80211_BAND_5GHZ: | ||
275 | if (rate == IWL_RATE_12M_INDEX) | ||
276 | next_rate = IWL_RATE_9M_INDEX; | ||
277 | else if (rate == IWL_RATE_6M_INDEX) | ||
278 | next_rate = IWL_RATE_6M_INDEX; | ||
279 | break; | ||
280 | case IEEE80211_BAND_2GHZ: | ||
281 | if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && | ||
282 | iwl3945_is_associated(priv)) { | ||
283 | if (rate == IWL_RATE_11M_INDEX) | ||
284 | next_rate = IWL_RATE_5M_INDEX; | ||
285 | } | ||
286 | break; | ||
287 | |||
288 | default: | ||
289 | break; | ||
290 | } | ||
291 | |||
292 | return next_rate; | ||
293 | } | ||
294 | |||
264 | 295 | ||
265 | /** | 296 | /** |
266 | * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd | 297 | * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd |
@@ -308,6 +339,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
308 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 339 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
309 | u32 status = le32_to_cpu(tx_resp->status); | 340 | u32 status = le32_to_cpu(tx_resp->status); |
310 | int rate_idx; | 341 | int rate_idx; |
342 | int fail; | ||
311 | 343 | ||
312 | if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { | 344 | if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { |
313 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 345 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " |
@@ -318,9 +350,18 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
318 | } | 350 | } |
319 | 351 | ||
320 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); | 352 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); |
321 | memset(&info->status, 0, sizeof(info->status)); | 353 | ieee80211_tx_info_clear_status(info); |
354 | |||
355 | /* Fill the MRR chain with some info about on-chip retransmissions */ | ||
356 | rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); | ||
357 | if (info->band == IEEE80211_BAND_5GHZ) | ||
358 | rate_idx -= IWL_FIRST_OFDM_RATE; | ||
359 | |||
360 | fail = tx_resp->failure_frame; | ||
361 | |||
362 | info->status.rates[0].idx = rate_idx; | ||
363 | info->status.rates[0].count = fail + 1; /* add final attempt */ | ||
322 | 364 | ||
323 | info->status.retry_count = tx_resp->failure_frame; | ||
324 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ | 365 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ |
325 | info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? | 366 | info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? |
326 | IEEE80211_TX_STAT_ACK : 0; | 367 | IEEE80211_TX_STAT_ACK : 0; |
@@ -329,10 +370,6 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
329 | txq_id, iwl3945_get_tx_fail_reason(status), status, | 370 | txq_id, iwl3945_get_tx_fail_reason(status), status, |
330 | tx_resp->rate, tx_resp->failure_frame); | 371 | tx_resp->rate, tx_resp->failure_frame); |
331 | 372 | ||
332 | rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); | ||
333 | if (info->band == IEEE80211_BAND_5GHZ) | ||
334 | rate_idx -= IWL_FIRST_OFDM_RATE; | ||
335 | info->tx_rate_idx = rate_idx; | ||
336 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 373 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
337 | iwl3945_tx_queue_reclaim(priv, txq_id, index); | 374 | iwl3945_tx_queue_reclaim(priv, txq_id, index); |
338 | 375 | ||
@@ -756,13 +793,19 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue * | |||
756 | 793 | ||
757 | u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) | 794 | u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) |
758 | { | 795 | { |
759 | int i; | 796 | int i, start = IWL_AP_ID; |
760 | int ret = IWL_INVALID_STATION; | 797 | int ret = IWL_INVALID_STATION; |
761 | unsigned long flags; | 798 | unsigned long flags; |
762 | DECLARE_MAC_BUF(mac); | 799 | |
800 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) || | ||
801 | (priv->iw_mode == NL80211_IFTYPE_AP)) | ||
802 | start = IWL_STA_ID; | ||
803 | |||
804 | if (is_broadcast_ether_addr(addr)) | ||
805 | return priv->hw_setting.bcast_sta_id; | ||
763 | 806 | ||
764 | spin_lock_irqsave(&priv->sta_lock, flags); | 807 | spin_lock_irqsave(&priv->sta_lock, flags); |
765 | for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) | 808 | for (i = start; i < priv->hw_setting.max_stations; i++) |
766 | if ((priv->stations[i].used) && | 809 | if ((priv->stations[i].used) && |
767 | (!compare_ether_addr | 810 | (!compare_ether_addr |
768 | (priv->stations[i].sta.sta.addr, addr))) { | 811 | (priv->stations[i].sta.sta.addr, addr))) { |
@@ -770,8 +813,8 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) | |||
770 | goto out; | 813 | goto out; |
771 | } | 814 | } |
772 | 815 | ||
773 | IWL_DEBUG_INFO("can not find STA %s (total %d)\n", | 816 | IWL_DEBUG_INFO("can not find STA %pM (total %d)\n", |
774 | print_mac(mac, addr), priv->num_stations); | 817 | addr, priv->num_stations); |
775 | out: | 818 | out: |
776 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 819 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
777 | return ret; | 820 | return ret; |
@@ -1060,9 +1103,8 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv) | |||
1060 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | 1103 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); |
1061 | 1104 | ||
1062 | iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 1105 | iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
1063 | rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL, | 1106 | rc = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL, |
1064 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 1107 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); |
1065 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
1066 | if (rc < 0) { | 1108 | if (rc < 0) { |
1067 | spin_unlock_irqrestore(&priv->lock, flags); | 1109 | spin_unlock_irqrestore(&priv->lock, flags); |
1068 | IWL_DEBUG_INFO("Failed to init the card\n"); | 1110 | IWL_DEBUG_INFO("Failed to init the card\n"); |
@@ -1243,8 +1285,7 @@ int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv) | |||
1243 | IWL_DEBUG_INFO("Card in power save, master is already " | 1285 | IWL_DEBUG_INFO("Card in power save, master is already " |
1244 | "stopped\n"); | 1286 | "stopped\n"); |
1245 | else { | 1287 | else { |
1246 | rc = iwl3945_poll_bit(priv, CSR_RESET, | 1288 | rc = iwl3945_poll_direct_bit(priv, CSR_RESET, |
1247 | CSR_RESET_REG_FLAG_MASTER_DISABLED, | ||
1248 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); | 1289 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); |
1249 | if (rc < 0) { | 1290 | if (rc < 0) { |
1250 | spin_unlock_irqrestore(&priv->lock, flags); | 1291 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -1269,9 +1310,8 @@ int iwl3945_hw_nic_reset(struct iwl3945_priv *priv) | |||
1269 | 1310 | ||
1270 | iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | 1311 | iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); |
1271 | 1312 | ||
1272 | rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL, | 1313 | iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL, |
1273 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 1314 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); |
1274 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
1275 | 1315 | ||
1276 | rc = iwl3945_grab_nic_access(priv); | 1316 | rc = iwl3945_grab_nic_access(priv); |
1277 | if (!rc) { | 1317 | if (!rc) { |
@@ -1830,7 +1870,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv) | |||
1830 | ref_temp = (s16)priv->eeprom.groups[ch_info->group_index]. | 1870 | ref_temp = (s16)priv->eeprom.groups[ch_info->group_index]. |
1831 | temperature; | 1871 | temperature; |
1832 | 1872 | ||
1833 | /* get power index adjustment based on curr and factory | 1873 | /* get power index adjustment based on current and factory |
1834 | * temps */ | 1874 | * temps */ |
1835 | delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, | 1875 | delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, |
1836 | ref_temp); | 1876 | ref_temp); |
@@ -2268,7 +2308,8 @@ int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv) | |||
2268 | } | 2308 | } |
2269 | 2309 | ||
2270 | iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0); | 2310 | iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0); |
2271 | rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS, (1 << 24), 1000); | 2311 | rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS, |
2312 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); | ||
2272 | if (rc < 0) | 2313 | if (rc < 0) |
2273 | IWL_ERROR("Can't stop Rx DMA.\n"); | 2314 | IWL_ERROR("Can't stop Rx DMA.\n"); |
2274 | 2315 | ||
@@ -2337,7 +2378,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2337 | iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0); | 2378 | iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0); |
2338 | table[index].try_cnt = priv->retry_rate; | 2379 | table[index].try_cnt = priv->retry_rate; |
2339 | prev_index = iwl3945_get_prev_ieee_rate(i); | 2380 | prev_index = iwl3945_get_prev_ieee_rate(i); |
2340 | table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index; | 2381 | table[index].next_rate_index = |
2382 | iwl3945_rates[prev_index].table_rs_index; | ||
2341 | } | 2383 | } |
2342 | 2384 | ||
2343 | switch (priv->band) { | 2385 | switch (priv->band) { |
@@ -2345,11 +2387,14 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2345 | IWL_DEBUG_RATE("Select A mode rate scale\n"); | 2387 | IWL_DEBUG_RATE("Select A mode rate scale\n"); |
2346 | /* If one of the following CCK rates is used, | 2388 | /* If one of the following CCK rates is used, |
2347 | * have it fall back to the 6M OFDM rate */ | 2389 | * have it fall back to the 6M OFDM rate */ |
2348 | for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) | 2390 | for (i = IWL_RATE_1M_INDEX_TABLE; |
2349 | table[i].next_rate_index = iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; | 2391 | i <= IWL_RATE_11M_INDEX_TABLE; i++) |
2392 | table[i].next_rate_index = | ||
2393 | iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; | ||
2350 | 2394 | ||
2351 | /* Don't fall back to CCK rates */ | 2395 | /* Don't fall back to CCK rates */ |
2352 | table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE; | 2396 | table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = |
2397 | IWL_RATE_9M_INDEX_TABLE; | ||
2353 | 2398 | ||
2354 | /* Don't drop out of OFDM rates */ | 2399 | /* Don't drop out of OFDM rates */ |
2355 | table[IWL_RATE_6M_INDEX_TABLE].next_rate_index = | 2400 | table[IWL_RATE_6M_INDEX_TABLE].next_rate_index = |
@@ -2360,11 +2405,20 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2360 | IWL_DEBUG_RATE("Select B/G mode rate scale\n"); | 2405 | IWL_DEBUG_RATE("Select B/G mode rate scale\n"); |
2361 | /* If an OFDM rate is used, have it fall back to the | 2406 | /* If an OFDM rate is used, have it fall back to the |
2362 | * 1M CCK rates */ | 2407 | * 1M CCK rates */ |
2363 | for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++) | ||
2364 | table[i].next_rate_index = iwl3945_rates[IWL_FIRST_CCK_RATE].table_rs_index; | ||
2365 | 2408 | ||
2366 | /* CCK shouldn't fall back to OFDM... */ | 2409 | if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && |
2367 | table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE; | 2410 | iwl3945_is_associated(priv)) { |
2411 | |||
2412 | index = IWL_FIRST_CCK_RATE; | ||
2413 | for (i = IWL_RATE_6M_INDEX_TABLE; | ||
2414 | i <= IWL_RATE_54M_INDEX_TABLE; i++) | ||
2415 | table[i].next_rate_index = | ||
2416 | iwl3945_rates[index].table_rs_index; | ||
2417 | |||
2418 | index = IWL_RATE_11M_INDEX_TABLE; | ||
2419 | /* CCK shouldn't fall back to OFDM... */ | ||
2420 | table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE; | ||
2421 | } | ||
2368 | break; | 2422 | break; |
2369 | 2423 | ||
2370 | default: | 2424 | default: |
@@ -2428,7 +2482,6 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv, | |||
2428 | 2482 | ||
2429 | frame_size = iwl3945_fill_beacon_frame(priv, | 2483 | frame_size = iwl3945_fill_beacon_frame(priv, |
2430 | tx_beacon_cmd->frame, | 2484 | tx_beacon_cmd->frame, |
2431 | iwl3945_broadcast_addr, | ||
2432 | sizeof(frame->u) - sizeof(*tx_beacon_cmd)); | 2485 | sizeof(frame->u) - sizeof(*tx_beacon_cmd)); |
2433 | 2486 | ||
2434 | BUG_ON(frame_size > MAX_MPDU_SIZE); | 2487 | BUG_ON(frame_size > MAX_MPDU_SIZE); |
@@ -2467,13 +2520,17 @@ void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv) | |||
2467 | 2520 | ||
2468 | static struct iwl_3945_cfg iwl3945_bg_cfg = { | 2521 | static struct iwl_3945_cfg iwl3945_bg_cfg = { |
2469 | .name = "3945BG", | 2522 | .name = "3945BG", |
2470 | .fw_name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode", | 2523 | .fw_name_pre = IWL3945_FW_PRE, |
2524 | .ucode_api_max = IWL3945_UCODE_API_MAX, | ||
2525 | .ucode_api_min = IWL3945_UCODE_API_MIN, | ||
2471 | .sku = IWL_SKU_G, | 2526 | .sku = IWL_SKU_G, |
2472 | }; | 2527 | }; |
2473 | 2528 | ||
2474 | static struct iwl_3945_cfg iwl3945_abg_cfg = { | 2529 | static struct iwl_3945_cfg iwl3945_abg_cfg = { |
2475 | .name = "3945ABG", | 2530 | .name = "3945ABG", |
2476 | .fw_name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode", | 2531 | .fw_name_pre = IWL3945_FW_PRE, |
2532 | .ucode_api_max = IWL3945_UCODE_API_MAX, | ||
2533 | .ucode_api_min = IWL3945_UCODE_API_MIN, | ||
2477 | .sku = IWL_SKU_A|IWL_SKU_G, | 2534 | .sku = IWL_SKU_A|IWL_SKU_G, |
2478 | }; | 2535 | }; |
2479 | 2536 | ||