aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-3945.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c125
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 */
269int 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
757u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) 794u8 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
2468static struct iwl_3945_cfg iwl3945_bg_cfg = { 2521static 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
2474static struct iwl_3945_cfg iwl3945_abg_cfg = { 2529static 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