diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 218 |
1 files changed, 118 insertions, 100 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 0728054a22d4..99b876a2feb9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include "iwl-helpers.h" | 50 | #include "iwl-helpers.h" |
51 | #include "iwl-led.h" | 51 | #include "iwl-led.h" |
52 | #include "iwl-3945-led.h" | 52 | #include "iwl-3945-led.h" |
53 | #include "iwl-3945-debugfs.h" | ||
53 | 54 | ||
54 | #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ | 55 | #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ |
55 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ | 56 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ |
@@ -192,12 +193,12 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp) | |||
192 | } | 193 | } |
193 | 194 | ||
194 | #ifdef CONFIG_IWLWIFI_DEBUG | 195 | #ifdef CONFIG_IWLWIFI_DEBUG |
195 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 196 | #define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x |
196 | 197 | ||
197 | static const char *iwl3945_get_tx_fail_reason(u32 status) | 198 | static const char *iwl3945_get_tx_fail_reason(u32 status) |
198 | { | 199 | { |
199 | switch (status & TX_STATUS_MSK) { | 200 | switch (status & TX_STATUS_MSK) { |
200 | case TX_STATUS_SUCCESS: | 201 | case TX_3945_STATUS_SUCCESS: |
201 | return "SUCCESS"; | 202 | return "SUCCESS"; |
202 | TX_STATUS_ENTRY(SHORT_LIMIT); | 203 | TX_STATUS_ENTRY(SHORT_LIMIT); |
203 | TX_STATUS_ENTRY(LONG_LIMIT); | 204 | TX_STATUS_ENTRY(LONG_LIMIT); |
@@ -243,7 +244,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate) | |||
243 | next_rate = IWL_RATE_6M_INDEX; | 244 | next_rate = IWL_RATE_6M_INDEX; |
244 | break; | 245 | break; |
245 | case IEEE80211_BAND_2GHZ: | 246 | case IEEE80211_BAND_2GHZ: |
246 | if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && | 247 | if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && |
247 | iwl_is_associated(priv)) { | 248 | iwl_is_associated(priv)) { |
248 | if (rate == IWL_RATE_11M_INDEX) | 249 | if (rate == IWL_RATE_11M_INDEX) |
249 | next_rate = IWL_RATE_5M_INDEX; | 250 | next_rate = IWL_RATE_5M_INDEX; |
@@ -293,7 +294,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, | |||
293 | * iwl3945_rx_reply_tx - Handle Tx response | 294 | * iwl3945_rx_reply_tx - Handle Tx response |
294 | */ | 295 | */ |
295 | static void iwl3945_rx_reply_tx(struct iwl_priv *priv, | 296 | static void iwl3945_rx_reply_tx(struct iwl_priv *priv, |
296 | struct iwl_rx_mem_buffer *rxb) | 297 | struct iwl_rx_mem_buffer *rxb) |
297 | { | 298 | { |
298 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 299 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
299 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 300 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
@@ -351,18 +352,81 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, | |||
351 | * RX handler implementations | 352 | * RX handler implementations |
352 | * | 353 | * |
353 | *****************************************************************************/ | 354 | *****************************************************************************/ |
355 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
356 | /* | ||
357 | * based on the assumption of all statistics counter are in DWORD | ||
358 | * FIXME: This function is for debugging, do not deal with | ||
359 | * the case of counters roll-over. | ||
360 | */ | ||
361 | static void iwl3945_accumulative_statistics(struct iwl_priv *priv, | ||
362 | __le32 *stats) | ||
363 | { | ||
364 | int i; | ||
365 | __le32 *prev_stats; | ||
366 | u32 *accum_stats; | ||
367 | u32 *delta, *max_delta; | ||
368 | |||
369 | prev_stats = (__le32 *)&priv->_3945.statistics; | ||
370 | accum_stats = (u32 *)&priv->_3945.accum_statistics; | ||
371 | delta = (u32 *)&priv->_3945.delta_statistics; | ||
372 | max_delta = (u32 *)&priv->_3945.max_delta; | ||
373 | |||
374 | for (i = sizeof(__le32); i < sizeof(struct iwl3945_notif_statistics); | ||
375 | i += sizeof(__le32), stats++, prev_stats++, delta++, | ||
376 | max_delta++, accum_stats++) { | ||
377 | if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { | ||
378 | *delta = (le32_to_cpu(*stats) - | ||
379 | le32_to_cpu(*prev_stats)); | ||
380 | *accum_stats += *delta; | ||
381 | if (*delta > *max_delta) | ||
382 | *max_delta = *delta; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | /* reset accumulative statistics for "no-counter" type statistics */ | ||
387 | priv->_3945.accum_statistics.general.temperature = | ||
388 | priv->_3945.statistics.general.temperature; | ||
389 | priv->_3945.accum_statistics.general.ttl_timestamp = | ||
390 | priv->_3945.statistics.general.ttl_timestamp; | ||
391 | } | ||
392 | #endif | ||
354 | 393 | ||
355 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | 394 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, |
356 | struct iwl_rx_mem_buffer *rxb) | 395 | struct iwl_rx_mem_buffer *rxb) |
357 | { | 396 | { |
358 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 397 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
398 | |||
359 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", | 399 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", |
360 | (int)sizeof(struct iwl3945_notif_statistics), | 400 | (int)sizeof(struct iwl3945_notif_statistics), |
361 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | 401 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); |
402 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
403 | iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); | ||
404 | #endif | ||
362 | 405 | ||
363 | memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39)); | 406 | memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); |
364 | } | 407 | } |
365 | 408 | ||
409 | void iwl3945_reply_statistics(struct iwl_priv *priv, | ||
410 | struct iwl_rx_mem_buffer *rxb) | ||
411 | { | ||
412 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
413 | __le32 *flag = (__le32 *)&pkt->u.raw; | ||
414 | |||
415 | if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { | ||
416 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
417 | memset(&priv->_3945.accum_statistics, 0, | ||
418 | sizeof(struct iwl3945_notif_statistics)); | ||
419 | memset(&priv->_3945.delta_statistics, 0, | ||
420 | sizeof(struct iwl3945_notif_statistics)); | ||
421 | memset(&priv->_3945.max_delta, 0, | ||
422 | sizeof(struct iwl3945_notif_statistics)); | ||
423 | #endif | ||
424 | IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); | ||
425 | } | ||
426 | iwl3945_hw_rx_statistics(priv, rxb); | ||
427 | } | ||
428 | |||
429 | |||
366 | /****************************************************************************** | 430 | /****************************************************************************** |
367 | * | 431 | * |
368 | * Misc. internal state and helper functions | 432 | * Misc. internal state and helper functions |
@@ -487,7 +551,7 @@ static void _iwl3945_dbg_report_frame(struct iwl_priv *priv, | |||
487 | * but you can hack it to show more, if you'd like to. */ | 551 | * but you can hack it to show more, if you'd like to. */ |
488 | if (dataframe) | 552 | if (dataframe) |
489 | IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, " | 553 | IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, " |
490 | "len=%u, rssi=%d, chnl=%d, rate=%d, \n", | 554 | "len=%u, rssi=%d, chnl=%d, rate=%d,\n", |
491 | title, le16_to_cpu(fc), header->addr1[5], | 555 | title, le16_to_cpu(fc), header->addr1[5], |
492 | length, rssi, channel, rate); | 556 | length, rssi, channel, rate); |
493 | else { | 557 | else { |
@@ -549,7 +613,6 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
549 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 613 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
550 | u16 len = le16_to_cpu(rx_hdr->len); | 614 | u16 len = le16_to_cpu(rx_hdr->len); |
551 | struct sk_buff *skb; | 615 | struct sk_buff *skb; |
552 | int ret; | ||
553 | __le16 fc = hdr->frame_control; | 616 | __le16 fc = hdr->frame_control; |
554 | 617 | ||
555 | /* We received data from the HW, so stop the watchdog */ | 618 | /* We received data from the HW, so stop the watchdog */ |
@@ -566,9 +629,9 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
566 | return; | 629 | return; |
567 | } | 630 | } |
568 | 631 | ||
569 | skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC); | 632 | skb = dev_alloc_skb(128); |
570 | if (!skb) { | 633 | if (!skb) { |
571 | IWL_ERR(priv, "alloc_skb failed\n"); | 634 | IWL_ERR(priv, "dev_alloc_skb failed\n"); |
572 | return; | 635 | return; |
573 | } | 636 | } |
574 | 637 | ||
@@ -577,37 +640,13 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
577 | (struct ieee80211_hdr *)rxb_addr(rxb), | 640 | (struct ieee80211_hdr *)rxb_addr(rxb), |
578 | le32_to_cpu(rx_end->status), stats); | 641 | le32_to_cpu(rx_end->status), stats); |
579 | 642 | ||
580 | skb_reserve(skb, IWL_LINK_HDR_MAX); | ||
581 | skb_add_rx_frag(skb, 0, rxb->page, | 643 | skb_add_rx_frag(skb, 0, rxb->page, |
582 | (void *)rx_hdr->payload - (void *)pkt, len); | 644 | (void *)rx_hdr->payload - (void *)pkt, len); |
583 | 645 | ||
584 | /* mac80211 currently doesn't support paged SKB. Convert it to | ||
585 | * linear SKB for management frame and data frame requires | ||
586 | * software decryption or software defragementation. */ | ||
587 | if (ieee80211_is_mgmt(fc) || | ||
588 | ieee80211_has_protected(fc) || | ||
589 | ieee80211_has_morefrags(fc) || | ||
590 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) | ||
591 | ret = skb_linearize(skb); | ||
592 | else | ||
593 | ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ? | ||
594 | 0 : -ENOMEM; | ||
595 | |||
596 | if (ret) { | ||
597 | kfree_skb(skb); | ||
598 | goto out; | ||
599 | } | ||
600 | |||
601 | /* | ||
602 | * XXX: We cannot touch the page and its virtual memory (pkt) after | ||
603 | * here. It might have already been freed by the above skb change. | ||
604 | */ | ||
605 | |||
606 | iwl_update_stats(priv, false, fc, len); | 646 | iwl_update_stats(priv, false, fc, len); |
607 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 647 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
608 | 648 | ||
609 | ieee80211_rx(priv->hw, skb); | 649 | ieee80211_rx(priv->hw, skb); |
610 | out: | ||
611 | priv->alloc_rxb_page--; | 650 | priv->alloc_rxb_page--; |
612 | rxb->page = NULL; | 651 | rxb->page = NULL; |
613 | } | 652 | } |
@@ -623,9 +662,8 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
623 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); | 662 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); |
624 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 663 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
625 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 664 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
626 | int snr; | 665 | u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg); |
627 | u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg); | 666 | u16 rx_stats_noise_diff __maybe_unused = le16_to_cpu(rx_stats->noise_diff); |
628 | u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff); | ||
629 | u8 network_packet; | 667 | u8 network_packet; |
630 | 668 | ||
631 | rx_status.flag = 0; | 669 | rx_status.flag = 0; |
@@ -663,53 +701,29 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
663 | /* Convert 3945's rssi indicator to dBm */ | 701 | /* Convert 3945's rssi indicator to dBm */ |
664 | rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; | 702 | rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; |
665 | 703 | ||
666 | /* Set default noise value to -127 */ | 704 | IWL_DEBUG_STATS(priv, "Rssi %d sig_avg %d noise_diff %d\n", |
667 | if (priv->last_rx_noise == 0) | 705 | rx_status.signal, rx_stats_sig_avg, |
668 | priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | 706 | rx_stats_noise_diff); |
669 | |||
670 | /* 3945 provides noise info for OFDM frames only. | ||
671 | * sig_avg and noise_diff are measured by the 3945's digital signal | ||
672 | * processor (DSP), and indicate linear levels of signal level and | ||
673 | * distortion/noise within the packet preamble after | ||
674 | * automatic gain control (AGC). sig_avg should stay fairly | ||
675 | * constant if the radio's AGC is working well. | ||
676 | * Since these values are linear (not dB or dBm), linear | ||
677 | * signal-to-noise ratio (SNR) is (sig_avg / noise_diff). | ||
678 | * Convert linear SNR to dB SNR, then subtract that from rssi dBm | ||
679 | * to obtain noise level in dBm. | ||
680 | * Calculate rx_status.signal (quality indicator in %) based on SNR. */ | ||
681 | if (rx_stats_noise_diff) { | ||
682 | snr = rx_stats_sig_avg / rx_stats_noise_diff; | ||
683 | rx_status.noise = rx_status.signal - | ||
684 | iwl3945_calc_db_from_ratio(snr); | ||
685 | } else { | ||
686 | rx_status.noise = priv->last_rx_noise; | ||
687 | } | ||
688 | |||
689 | |||
690 | IWL_DEBUG_STATS(priv, "Rssi %d noise %d sig_avg %d noise_diff %d\n", | ||
691 | rx_status.signal, rx_status.noise, | ||
692 | rx_stats_sig_avg, rx_stats_noise_diff); | ||
693 | 707 | ||
694 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 708 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
695 | 709 | ||
696 | network_packet = iwl3945_is_network_packet(priv, header); | 710 | network_packet = iwl3945_is_network_packet(priv, header); |
697 | 711 | ||
698 | IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", | 712 | IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Rate:%u\n", |
699 | network_packet ? '*' : ' ', | 713 | network_packet ? '*' : ' ', |
700 | le16_to_cpu(rx_hdr->channel), | 714 | le16_to_cpu(rx_hdr->channel), |
701 | rx_status.signal, rx_status.signal, | 715 | rx_status.signal, rx_status.signal, |
702 | rx_status.noise, rx_status.rate_idx); | 716 | rx_status.rate_idx); |
703 | 717 | ||
704 | /* Set "1" to report good data frames in groups of 100 */ | 718 | /* Set "1" to report good data frames in groups of 100 */ |
705 | iwl3945_dbg_report_frame(priv, pkt, header, 1); | 719 | iwl3945_dbg_report_frame(priv, pkt, header, 1); |
706 | iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); | 720 | iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); |
707 | 721 | ||
708 | if (network_packet) { | 722 | if (network_packet) { |
709 | priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); | 723 | priv->_3945.last_beacon_time = |
710 | priv->last_tsf = le64_to_cpu(rx_end->timestamp); | 724 | le32_to_cpu(rx_end->beacon_timestamp); |
711 | priv->last_rx_rssi = rx_status.signal; | 725 | priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp); |
712 | priv->last_rx_noise = rx_status.noise; | 726 | priv->_3945.last_rx_rssi = rx_status.signal; |
713 | } | 727 | } |
714 | 728 | ||
715 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); | 729 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); |
@@ -957,7 +971,7 @@ static int iwl3945_tx_reset(struct iwl_priv *priv) | |||
957 | iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); | 971 | iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); |
958 | 972 | ||
959 | iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, | 973 | iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, |
960 | priv->shared_phys); | 974 | priv->_3945.shared_phys); |
961 | 975 | ||
962 | iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, | 976 | iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, |
963 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | | 977 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | |
@@ -1049,7 +1063,7 @@ static void iwl3945_nic_config(struct iwl_priv *priv) | |||
1049 | IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); | 1063 | IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); |
1050 | 1064 | ||
1051 | if (rev_id & PCI_CFG_REV_ID_BIT_RTP) | 1065 | if (rev_id & PCI_CFG_REV_ID_BIT_RTP) |
1052 | IWL_DEBUG_INFO(priv, "RTP type \n"); | 1066 | IWL_DEBUG_INFO(priv, "RTP type\n"); |
1053 | else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { | 1067 | else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { |
1054 | IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); | 1068 | IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); |
1055 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1069 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
@@ -1607,7 +1621,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv, | |||
1607 | int power; | 1621 | int power; |
1608 | 1622 | ||
1609 | /* Get this chnlgrp's rate-to-max/clip-powers table */ | 1623 | /* Get this chnlgrp's rate-to-max/clip-powers table */ |
1610 | clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; | 1624 | clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; |
1611 | 1625 | ||
1612 | /* Get this channel's rate-to-current-power settings table */ | 1626 | /* Get this channel's rate-to-current-power settings table */ |
1613 | power_info = ch_info->power_info; | 1627 | power_info = ch_info->power_info; |
@@ -1733,7 +1747,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv) | |||
1733 | } | 1747 | } |
1734 | 1748 | ||
1735 | /* Get this chnlgrp's rate-to-max/clip-powers table */ | 1749 | /* Get this chnlgrp's rate-to-max/clip-powers table */ |
1736 | clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; | 1750 | clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; |
1737 | 1751 | ||
1738 | /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ | 1752 | /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ |
1739 | for (scan_tbl_index = 0; | 1753 | for (scan_tbl_index = 0; |
@@ -1911,6 +1925,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) | |||
1911 | "configuration (%d).\n", rc); | 1925 | "configuration (%d).\n", rc); |
1912 | return rc; | 1926 | return rc; |
1913 | } | 1927 | } |
1928 | iwl_clear_ucode_stations(priv, false); | ||
1929 | iwl_restore_stations(priv); | ||
1914 | } | 1930 | } |
1915 | 1931 | ||
1916 | IWL_DEBUG_INFO(priv, "Sending RXON\n" | 1932 | IWL_DEBUG_INFO(priv, "Sending RXON\n" |
@@ -1941,7 +1957,10 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) | |||
1941 | 1957 | ||
1942 | memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); | 1958 | memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); |
1943 | 1959 | ||
1944 | iwl_clear_stations_table(priv); | 1960 | if (!new_assoc) { |
1961 | iwl_clear_ucode_stations(priv, false); | ||
1962 | iwl_restore_stations(priv); | ||
1963 | } | ||
1945 | 1964 | ||
1946 | /* If we issue a new RXON command which required a tune then we must | 1965 | /* If we issue a new RXON command which required a tune then we must |
1947 | * send a new TXPOWER command or we won't be able to Tx any frames */ | 1966 | * send a new TXPOWER command or we won't be able to Tx any frames */ |
@@ -1951,19 +1970,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) | |||
1951 | return rc; | 1970 | return rc; |
1952 | } | 1971 | } |
1953 | 1972 | ||
1954 | /* Add the broadcast address so we can send broadcast frames */ | ||
1955 | priv->cfg->ops->lib->add_bcast_station(priv); | ||
1956 | |||
1957 | /* If we have set the ASSOC_MSK and we are in BSS mode then | ||
1958 | * add the IWL_AP_ID to the station rate table */ | ||
1959 | if (iwl_is_associated(priv) && | ||
1960 | (priv->iw_mode == NL80211_IFTYPE_STATION)) | ||
1961 | if (iwl_add_station(priv, priv->active_rxon.bssid_addr, | ||
1962 | true, CMD_SYNC, NULL) == IWL_INVALID_STATION) { | ||
1963 | IWL_ERR(priv, "Error adding AP address for transmit\n"); | ||
1964 | return -EIO; | ||
1965 | } | ||
1966 | |||
1967 | /* Init the hardware's rate fallback order based on the band */ | 1973 | /* Init the hardware's rate fallback order based on the band */ |
1968 | rc = iwl3945_init_hw_rate_table(priv); | 1974 | rc = iwl3945_init_hw_rate_table(priv); |
1969 | if (rc) { | 1975 | if (rc) { |
@@ -1998,13 +2004,13 @@ void iwl3945_reg_txpower_periodic(struct iwl_priv *priv) | |||
1998 | 2004 | ||
1999 | reschedule: | 2005 | reschedule: |
2000 | queue_delayed_work(priv->workqueue, | 2006 | queue_delayed_work(priv->workqueue, |
2001 | &priv->thermal_periodic, REG_RECALIB_PERIOD * HZ); | 2007 | &priv->_3945.thermal_periodic, REG_RECALIB_PERIOD * HZ); |
2002 | } | 2008 | } |
2003 | 2009 | ||
2004 | static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) | 2010 | static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) |
2005 | { | 2011 | { |
2006 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 2012 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
2007 | thermal_periodic.work); | 2013 | _3945.thermal_periodic.work); |
2008 | 2014 | ||
2009 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2015 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2010 | return; | 2016 | return; |
@@ -2140,7 +2146,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) | |||
2140 | * power peaks, without too much distortion (clipping). | 2146 | * power peaks, without too much distortion (clipping). |
2141 | */ | 2147 | */ |
2142 | /* we'll fill in this array with h/w max power levels */ | 2148 | /* we'll fill in this array with h/w max power levels */ |
2143 | clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers; | 2149 | clip_pwrs = (s8 *) priv->_3945.clip_groups[i].clip_powers; |
2144 | 2150 | ||
2145 | /* divide factory saturation power by 2 to find -3dB level */ | 2151 | /* divide factory saturation power by 2 to find -3dB level */ |
2146 | satur_pwr = (s8) (group->saturation_power >> 1); | 2152 | satur_pwr = (s8) (group->saturation_power >> 1); |
@@ -2224,7 +2230,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) | |||
2224 | iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); | 2230 | iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); |
2225 | 2231 | ||
2226 | /* Get this chnlgrp's rate->max/clip-powers table */ | 2232 | /* Get this chnlgrp's rate->max/clip-powers table */ |
2227 | clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; | 2233 | clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; |
2228 | 2234 | ||
2229 | /* calculate power index *adjustment* value according to | 2235 | /* calculate power index *adjustment* value according to |
2230 | * diff between current temperature and factory temperature */ | 2236 | * diff between current temperature and factory temperature */ |
@@ -2332,7 +2338,7 @@ int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
2332 | { | 2338 | { |
2333 | int txq_id = txq->q.id; | 2339 | int txq_id = txq->q.id; |
2334 | 2340 | ||
2335 | struct iwl3945_shared *shared_data = priv->shared_virt; | 2341 | struct iwl3945_shared *shared_data = priv->_3945.shared_virt; |
2336 | 2342 | ||
2337 | shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); | 2343 | shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); |
2338 | 2344 | ||
@@ -2432,7 +2438,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv) | |||
2432 | /* If an OFDM rate is used, have it fall back to the | 2438 | /* If an OFDM rate is used, have it fall back to the |
2433 | * 1M CCK rates */ | 2439 | * 1M CCK rates */ |
2434 | 2440 | ||
2435 | if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && | 2441 | if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && |
2436 | iwl_is_associated(priv)) { | 2442 | iwl_is_associated(priv)) { |
2437 | 2443 | ||
2438 | index = IWL_FIRST_CCK_RATE; | 2444 | index = IWL_FIRST_CCK_RATE; |
@@ -2471,12 +2477,12 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) | |||
2471 | memset((void *)&priv->hw_params, 0, | 2477 | memset((void *)&priv->hw_params, 0, |
2472 | sizeof(struct iwl_hw_params)); | 2478 | sizeof(struct iwl_hw_params)); |
2473 | 2479 | ||
2474 | priv->shared_virt = dma_alloc_coherent(&priv->pci_dev->dev, | 2480 | priv->_3945.shared_virt = |
2475 | sizeof(struct iwl3945_shared), | 2481 | dma_alloc_coherent(&priv->pci_dev->dev, |
2476 | &priv->shared_phys, GFP_KERNEL); | 2482 | sizeof(struct iwl3945_shared), |
2477 | if (!priv->shared_virt) { | 2483 | &priv->_3945.shared_phys, GFP_KERNEL); |
2484 | if (!priv->_3945.shared_virt) { | ||
2478 | IWL_ERR(priv, "failed to allocate pci memory\n"); | 2485 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
2479 | mutex_unlock(&priv->mutex); | ||
2480 | return -ENOMEM; | 2486 | return -ENOMEM; |
2481 | } | 2487 | } |
2482 | 2488 | ||
@@ -2537,13 +2543,13 @@ void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv) | |||
2537 | 2543 | ||
2538 | void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) | 2544 | void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) |
2539 | { | 2545 | { |
2540 | INIT_DELAYED_WORK(&priv->thermal_periodic, | 2546 | INIT_DELAYED_WORK(&priv->_3945.thermal_periodic, |
2541 | iwl3945_bg_reg_txpower_periodic); | 2547 | iwl3945_bg_reg_txpower_periodic); |
2542 | } | 2548 | } |
2543 | 2549 | ||
2544 | void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) | 2550 | void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) |
2545 | { | 2551 | { |
2546 | cancel_delayed_work(&priv->thermal_periodic); | 2552 | cancel_delayed_work(&priv->_3945.thermal_periodic); |
2547 | } | 2553 | } |
2548 | 2554 | ||
2549 | /* check contents of special bootstrap uCode SRAM */ | 2555 | /* check contents of special bootstrap uCode SRAM */ |
@@ -2745,6 +2751,7 @@ IWL3945_UCODE_GET(boot_size); | |||
2745 | static struct iwl_hcmd_ops iwl3945_hcmd = { | 2751 | static struct iwl_hcmd_ops iwl3945_hcmd = { |
2746 | .rxon_assoc = iwl3945_send_rxon_assoc, | 2752 | .rxon_assoc = iwl3945_send_rxon_assoc, |
2747 | .commit_rxon = iwl3945_commit_rxon, | 2753 | .commit_rxon = iwl3945_commit_rxon, |
2754 | .send_bt_config = iwl_send_bt_config, | ||
2748 | }; | 2755 | }; |
2749 | 2756 | ||
2750 | static struct iwl_ucode_ops iwl3945_ucode = { | 2757 | static struct iwl_ucode_ops iwl3945_ucode = { |
@@ -2792,12 +2799,19 @@ static struct iwl_lib_ops iwl3945_lib = { | |||
2792 | .isr = iwl_isr_legacy, | 2799 | .isr = iwl_isr_legacy, |
2793 | .config_ap = iwl3945_config_ap, | 2800 | .config_ap = iwl3945_config_ap, |
2794 | .add_bcast_station = iwl3945_add_bcast_station, | 2801 | .add_bcast_station = iwl3945_add_bcast_station, |
2802 | |||
2803 | .debugfs_ops = { | ||
2804 | .rx_stats_read = iwl3945_ucode_rx_stats_read, | ||
2805 | .tx_stats_read = iwl3945_ucode_tx_stats_read, | ||
2806 | .general_stats_read = iwl3945_ucode_general_stats_read, | ||
2807 | }, | ||
2795 | }; | 2808 | }; |
2796 | 2809 | ||
2797 | static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { | 2810 | static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { |
2798 | .get_hcmd_size = iwl3945_get_hcmd_size, | 2811 | .get_hcmd_size = iwl3945_get_hcmd_size, |
2799 | .build_addsta_hcmd = iwl3945_build_addsta_hcmd, | 2812 | .build_addsta_hcmd = iwl3945_build_addsta_hcmd, |
2800 | .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, | 2813 | .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, |
2814 | .request_scan = iwl3945_request_scan, | ||
2801 | }; | 2815 | }; |
2802 | 2816 | ||
2803 | static const struct iwl_ops iwl3945_ops = { | 2817 | static const struct iwl_ops iwl3945_ops = { |
@@ -2827,6 +2841,8 @@ static struct iwl_cfg iwl3945_bg_cfg = { | |||
2827 | .led_compensation = 64, | 2841 | .led_compensation = 64, |
2828 | .broken_powersave = true, | 2842 | .broken_powersave = true, |
2829 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 2843 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
2844 | .monitor_recover_period = IWL_MONITORING_PERIOD, | ||
2845 | .max_event_log_size = 512, | ||
2830 | }; | 2846 | }; |
2831 | 2847 | ||
2832 | static struct iwl_cfg iwl3945_abg_cfg = { | 2848 | static struct iwl_cfg iwl3945_abg_cfg = { |
@@ -2845,6 +2861,8 @@ static struct iwl_cfg iwl3945_abg_cfg = { | |||
2845 | .led_compensation = 64, | 2861 | .led_compensation = 64, |
2846 | .broken_powersave = true, | 2862 | .broken_powersave = true, |
2847 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 2863 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
2864 | .monitor_recover_period = IWL_MONITORING_PERIOD, | ||
2865 | .max_event_log_size = 512, | ||
2848 | }; | 2866 | }; |
2849 | 2867 | ||
2850 | DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { | 2868 | DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { |