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.c147
1 files changed, 101 insertions, 46 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 99b876a2feb9..068f7f8435c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -391,6 +391,67 @@ static void iwl3945_accumulative_statistics(struct iwl_priv *priv,
391} 391}
392#endif 392#endif
393 393
394/**
395 * iwl3945_good_plcp_health - checks for plcp error.
396 *
397 * When the plcp error is exceeding the thresholds, reset the radio
398 * to improve the throughput.
399 */
400static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
401 struct iwl_rx_packet *pkt)
402{
403 bool rc = true;
404 struct iwl3945_notif_statistics current_stat;
405 int combined_plcp_delta;
406 unsigned int plcp_msec;
407 unsigned long plcp_received_jiffies;
408
409 memcpy(&current_stat, pkt->u.raw, sizeof(struct
410 iwl3945_notif_statistics));
411 /*
412 * check for plcp_err and trigger radio reset if it exceeds
413 * the plcp error threshold plcp_delta.
414 */
415 plcp_received_jiffies = jiffies;
416 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
417 (long) priv->plcp_jiffies);
418 priv->plcp_jiffies = plcp_received_jiffies;
419 /*
420 * check to make sure plcp_msec is not 0 to prevent division
421 * by zero.
422 */
423 if (plcp_msec) {
424 combined_plcp_delta =
425 (le32_to_cpu(current_stat.rx.ofdm.plcp_err) -
426 le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err));
427
428 if ((combined_plcp_delta > 0) &&
429 ((combined_plcp_delta * 100) / plcp_msec) >
430 priv->cfg->plcp_delta_threshold) {
431 /*
432 * if plcp_err exceed the threshold, the following
433 * data is printed in csv format:
434 * Text: plcp_err exceeded %d,
435 * Received ofdm.plcp_err,
436 * Current ofdm.plcp_err,
437 * combined_plcp_delta,
438 * plcp_msec
439 */
440 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
441 "%u, %d, %u mSecs\n",
442 priv->cfg->plcp_delta_threshold,
443 le32_to_cpu(current_stat.rx.ofdm.plcp_err),
444 combined_plcp_delta, plcp_msec);
445 /*
446 * Reset the RF radio due to the high plcp
447 * error rate
448 */
449 rc = false;
450 }
451 }
452 return rc;
453}
454
394void iwl3945_hw_rx_statistics(struct iwl_priv *priv, 455void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
395 struct iwl_rx_mem_buffer *rxb) 456 struct iwl_rx_mem_buffer *rxb)
396{ 457{
@@ -402,6 +463,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
402#ifdef CONFIG_IWLWIFI_DEBUG 463#ifdef CONFIG_IWLWIFI_DEBUG
403 iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); 464 iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
404#endif 465#endif
466 iwl_recover_from_statistics(priv, pkt);
405 467
406 memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); 468 memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics));
407} 469}
@@ -885,7 +947,8 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
885 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); 947 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
886} 948}
887 949
888u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) 950static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
951 u16 tx_rate, u8 flags)
889{ 952{
890 unsigned long flags_spin; 953 unsigned long flags_spin;
891 struct iwl_station_entry *station; 954 struct iwl_station_entry *station;
@@ -1715,6 +1778,11 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
1715 int ref_temp; 1778 int ref_temp;
1716 int temperature = priv->temperature; 1779 int temperature = priv->temperature;
1717 1780
1781 if (priv->disable_tx_power_cal ||
1782 test_bit(STATUS_SCANNING, &priv->status)) {
1783 /* do not perform tx power calibration */
1784 return 0;
1785 }
1718 /* set up new Tx power info for each and every channel, 2.4 and 5.x */ 1786 /* set up new Tx power info for each and every channel, 2.4 and 5.x */
1719 for (i = 0; i < priv->channel_count; i++) { 1787 for (i = 0; i < priv->channel_count; i++) {
1720 ch_info = &priv->channel_info[i]; 1788 ch_info = &priv->channel_info[i];
@@ -1925,7 +1993,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1925 "configuration (%d).\n", rc); 1993 "configuration (%d).\n", rc);
1926 return rc; 1994 return rc;
1927 } 1995 }
1928 iwl_clear_ucode_stations(priv, false); 1996 iwl_clear_ucode_stations(priv);
1929 iwl_restore_stations(priv); 1997 iwl_restore_stations(priv);
1930 } 1998 }
1931 1999
@@ -1958,7 +2026,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1958 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); 2026 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
1959 2027
1960 if (!new_assoc) { 2028 if (!new_assoc) {
1961 iwl_clear_ucode_stations(priv, false); 2029 iwl_clear_ucode_stations(priv);
1962 iwl_restore_stations(priv); 2030 iwl_restore_stations(priv);
1963 } 2031 }
1964 2032
@@ -2391,6 +2459,30 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
2391 return (u16)sizeof(struct iwl3945_addsta_cmd); 2459 return (u16)sizeof(struct iwl3945_addsta_cmd);
2392} 2460}
2393 2461
2462static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
2463 struct ieee80211_vif *vif, bool add)
2464{
2465 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
2466 int ret;
2467
2468 if (add) {
2469 ret = iwl_add_bssid_station(priv, vif->bss_conf.bssid, false,
2470 &vif_priv->ibss_bssid_sta_id);
2471 if (ret)
2472 return ret;
2473
2474 iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id,
2475 (priv->band == IEEE80211_BAND_5GHZ) ?
2476 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
2477 CMD_ASYNC);
2478 iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id);
2479
2480 return 0;
2481 }
2482
2483 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
2484 vif->bss_conf.bssid);
2485}
2394 2486
2395/** 2487/**
2396 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table 2488 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
@@ -2720,51 +2812,12 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
2720 return 0; 2812 return 0;
2721} 2813}
2722 2814
2723#define IWL3945_UCODE_GET(item) \
2724static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode,\
2725 u32 api_ver) \
2726{ \
2727 return le32_to_cpu(ucode->u.v1.item); \
2728}
2729
2730static u32 iwl3945_ucode_get_header_size(u32 api_ver)
2731{
2732 return UCODE_HEADER_SIZE(1);
2733}
2734static u32 iwl3945_ucode_get_build(const struct iwl_ucode_header *ucode,
2735 u32 api_ver)
2736{
2737 return 0;
2738}
2739static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode,
2740 u32 api_ver)
2741{
2742 return (u8 *) ucode->u.v1.data;
2743}
2744
2745IWL3945_UCODE_GET(inst_size);
2746IWL3945_UCODE_GET(data_size);
2747IWL3945_UCODE_GET(init_size);
2748IWL3945_UCODE_GET(init_data_size);
2749IWL3945_UCODE_GET(boot_size);
2750
2751static struct iwl_hcmd_ops iwl3945_hcmd = { 2815static struct iwl_hcmd_ops iwl3945_hcmd = {
2752 .rxon_assoc = iwl3945_send_rxon_assoc, 2816 .rxon_assoc = iwl3945_send_rxon_assoc,
2753 .commit_rxon = iwl3945_commit_rxon, 2817 .commit_rxon = iwl3945_commit_rxon,
2754 .send_bt_config = iwl_send_bt_config, 2818 .send_bt_config = iwl_send_bt_config,
2755}; 2819};
2756 2820
2757static struct iwl_ucode_ops iwl3945_ucode = {
2758 .get_header_size = iwl3945_ucode_get_header_size,
2759 .get_build = iwl3945_ucode_get_build,
2760 .get_inst_size = iwl3945_ucode_get_inst_size,
2761 .get_data_size = iwl3945_ucode_get_data_size,
2762 .get_init_size = iwl3945_ucode_get_init_size,
2763 .get_init_data_size = iwl3945_ucode_get_init_data_size,
2764 .get_boot_size = iwl3945_ucode_get_boot_size,
2765 .get_data = iwl3945_ucode_get_data,
2766};
2767
2768static struct iwl_lib_ops iwl3945_lib = { 2821static struct iwl_lib_ops iwl3945_lib = {
2769 .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, 2822 .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
2770 .txq_free_tfd = iwl3945_hw_txq_free_tfd, 2823 .txq_free_tfd = iwl3945_hw_txq_free_tfd,
@@ -2798,7 +2851,8 @@ static struct iwl_lib_ops iwl3945_lib = {
2798 .post_associate = iwl3945_post_associate, 2851 .post_associate = iwl3945_post_associate,
2799 .isr = iwl_isr_legacy, 2852 .isr = iwl_isr_legacy,
2800 .config_ap = iwl3945_config_ap, 2853 .config_ap = iwl3945_config_ap,
2801 .add_bcast_station = iwl3945_add_bcast_station, 2854 .manage_ibss_station = iwl3945_manage_ibss_station,
2855 .check_plcp_health = iwl3945_good_plcp_health,
2802 2856
2803 .debugfs_ops = { 2857 .debugfs_ops = {
2804 .rx_stats_read = iwl3945_ucode_rx_stats_read, 2858 .rx_stats_read = iwl3945_ucode_rx_stats_read,
@@ -2815,7 +2869,6 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2815}; 2869};
2816 2870
2817static const struct iwl_ops iwl3945_ops = { 2871static const struct iwl_ops iwl3945_ops = {
2818 .ucode = &iwl3945_ucode,
2819 .lib = &iwl3945_lib, 2872 .lib = &iwl3945_lib,
2820 .hcmd = &iwl3945_hcmd, 2873 .hcmd = &iwl3945_hcmd,
2821 .utils = &iwl3945_hcmd_utils, 2874 .utils = &iwl3945_hcmd_utils,
@@ -2840,9 +2893,10 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2840 .ht_greenfield_support = false, 2893 .ht_greenfield_support = false,
2841 .led_compensation = 64, 2894 .led_compensation = 64,
2842 .broken_powersave = true, 2895 .broken_powersave = true,
2843 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2896 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
2844 .monitor_recover_period = IWL_MONITORING_PERIOD, 2897 .monitor_recover_period = IWL_MONITORING_PERIOD,
2845 .max_event_log_size = 512, 2898 .max_event_log_size = 512,
2899 .tx_power_by_driver = true,
2846}; 2900};
2847 2901
2848static struct iwl_cfg iwl3945_abg_cfg = { 2902static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2860,9 +2914,10 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2860 .ht_greenfield_support = false, 2914 .ht_greenfield_support = false,
2861 .led_compensation = 64, 2915 .led_compensation = 64,
2862 .broken_powersave = true, 2916 .broken_powersave = true,
2863 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2917 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
2864 .monitor_recover_period = IWL_MONITORING_PERIOD, 2918 .monitor_recover_period = IWL_MONITORING_PERIOD,
2865 .max_event_log_size = 512, 2919 .max_event_log_size = 512,
2920 .tx_power_by_driver = true,
2866}; 2921};
2867 2922
2868DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { 2923DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {