aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c261
5 files changed, 60 insertions, 242 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8ff5798ad641..cb6db4525dc3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1063,7 +1063,7 @@ static int iwl3945_apm_init(struct iwl_priv *priv)
1063{ 1063{
1064 int ret = 0; 1064 int ret = 0;
1065 1065
1066 iwl3945_power_init_handle(priv); 1066 iwl_power_initialize(priv);
1067 1067
1068 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, 1068 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
1069 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); 1069 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
@@ -2372,7 +2372,9 @@ static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
2372{ 2372{
2373 switch (cmd_id) { 2373 switch (cmd_id) {
2374 case REPLY_RXON: 2374 case REPLY_RXON:
2375 return (u16) sizeof(struct iwl3945_rxon_cmd); 2375 return sizeof(struct iwl3945_rxon_cmd);
2376 case POWER_TABLE_CMD:
2377 return sizeof(struct iwl3945_powertable_cmd);
2376 default: 2378 default:
2377 return len; 2379 return len;
2378 } 2380 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5f92cfbe9267..e18c3f326f71 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1355,8 +1355,8 @@ int iwl_init_drv(struct iwl_priv *priv)
1355 priv->qos_data.qos_cap.val = 0; 1355 priv->qos_data.qos_cap.val = 0;
1356 1356
1357 priv->rates_mask = IWL_RATES_MASK; 1357 priv->rates_mask = IWL_RATES_MASK;
1358 /* If power management is turned on, default to AC mode */ 1358 /* If power management is turned on, default to CAM mode */
1359 priv->power_mode = IWL_POWER_AC; 1359 priv->power_mode = IWL_POWER_MODE_CAM;
1360 priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX; 1360 priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;
1361 1361
1362 ret = iwl_init_channel_map(priv); 1362 ret = iwl_init_channel_map(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index abe0d2966a56..4c5a775f48b7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -102,6 +102,7 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
102 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} 102 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
103}; 103};
104 104
105
105/* set card power command */ 106/* set card power command */
106static int iwl_set_power(struct iwl_priv *priv, void *cmd) 107static int iwl_set_power(struct iwl_priv *priv, void *cmd)
107{ 108{
@@ -126,13 +127,6 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
126 else 127 else
127 mode = IWL_POWER_ON_AC_DISASSOC; 128 mode = IWL_POWER_ON_AC_DISASSOC;
128 break; 129 break;
129 /* FIXME: remove battery and ac from here */
130 case IWL_POWER_BATTERY:
131 mode = IWL_POWER_INDEX_3;
132 break;
133 case IWL_POWER_AC:
134 mode = IWL_POWER_MODE_CAM;
135 break;
136 default: 130 default:
137 mode = priv->power_data.user_power_setting; 131 mode = priv->power_data.user_power_setting;
138 break; 132 break;
@@ -357,7 +351,7 @@ EXPORT_SYMBOL(iwl_power_enable_management);
357/* set user_power_setting */ 351/* set user_power_setting */
358int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode) 352int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
359{ 353{
360 if (mode > IWL_POWER_LIMIT) 354 if (mode > IWL_POWER_MAX)
361 return -EINVAL; 355 return -EINVAL;
362 356
363 priv->power_data.user_power_setting = mode; 357 priv->power_data.user_power_setting = mode;
@@ -371,11 +365,10 @@ EXPORT_SYMBOL(iwl_power_set_user_mode);
371 */ 365 */
372int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode) 366int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
373{ 367{
374 if (mode > IWL_POWER_LIMIT) 368 if (mode < IWL_POWER_SYS_MAX)
369 priv->power_data.system_power_setting = mode;
370 else
375 return -EINVAL; 371 return -EINVAL;
376
377 priv->power_data.system_power_setting = mode;
378
379 return iwl_power_update_mode(priv, 0); 372 return iwl_power_update_mode(priv, 0);
380} 373}
381EXPORT_SYMBOL(iwl_power_set_system_mode); 374EXPORT_SYMBOL(iwl_power_set_system_mode);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 859b60b5335c..879eafdd7369 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -42,27 +42,15 @@ enum {
42 IWL_POWER_INDEX_5, 42 IWL_POWER_INDEX_5,
43 IWL_POWER_AUTO, 43 IWL_POWER_AUTO,
44 IWL_POWER_MAX = IWL_POWER_AUTO, 44 IWL_POWER_MAX = IWL_POWER_AUTO,
45 IWL39_POWER_AC = IWL_POWER_AUTO, /* 0x06 */
46 IWL_POWER_AC,
47 IWL39_POWER_BATTERY = IWL_POWER_AC, /* 0x07 */
48 IWL39_POWER_LIMIT = IWL_POWER_AC,
49 IWL_POWER_BATTERY,
50}; 45};
51 46
52enum { 47enum {
53 IWL_POWER_SYS_AUTO, 48 IWL_POWER_SYS_AUTO,
54 IWL_POWER_SYS_AC, 49 IWL_POWER_SYS_AC,
55 IWL_POWER_SYS_BATTERY, 50 IWL_POWER_SYS_BATTERY,
51 IWL_POWER_SYS_MAX,
56}; 52};
57 53
58#define IWL_POWER_LIMIT 0x08
59#define IWL_POWER_MASK 0x0F
60#define IWL_POWER_ENABLED 0x10
61
62#define IWL_POWER_RANGE_0 (0)
63#define IWL_POWER_RANGE_1 (1)
64
65#define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK)
66 54
67/* Power management (not Tx power) structures */ 55/* Power management (not Tx power) structures */
68 56
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ac337177fdb3..800e46c9a68b 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -656,162 +656,6 @@ static void iwl3945_activate_qos(struct iwl_priv *priv, u8 force)
656 } 656 }
657} 657}
658 658
659/*
660 * Power management (not Tx power!) functions
661 */
662#define MSEC_TO_USEC 1024
663
664
665/* default power management (not Tx power) table values */
666/* for TIM 0-10 */
667static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
668 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
669 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
670 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
671 {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0},
672 {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1},
673 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
674};
675
676/* for TIM > 10 */
677static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
678 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
679 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
680 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
681 {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 6, 9, 9, 0xFF)}, 0},
682 {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
683 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
684};
685
686int iwl3945_power_init_handle(struct iwl_priv *priv)
687{
688 int rc = 0, i;
689 struct iwl_power_mgr *pow_data;
690 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
691 u16 pci_pm;
692
693 IWL_DEBUG_POWER(priv, "Initialize power \n");
694
695 pow_data = &priv->power_data;
696
697 memset(pow_data, 0, sizeof(*pow_data));
698
699 pow_data->dtim_period = 1;
700
701 memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
702 memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
703
704 rc = pci_read_config_word(priv->pci_dev, PCI_LINK_CTRL, &pci_pm);
705 if (rc != 0)
706 return 0;
707 else {
708 struct iwl_powertable_cmd *cmd;
709
710 IWL_DEBUG_POWER(priv, "adjust power command flags\n");
711
712 for (i = 0; i < IWL_POWER_MAX; i++) {
713 cmd = &pow_data->pwr_range_0[i].cmd;
714
715 if (pci_pm & 0x1)
716 cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
717 else
718 cmd->flags |= IWL_POWER_PCI_PM_MSK;
719 }
720 }
721 return rc;
722}
723
724static int iwl3945_update_power_cmd(struct iwl_priv *priv,
725 struct iwl_powertable_cmd *cmd, u32 mode)
726{
727 struct iwl_power_mgr *pow_data;
728 struct iwl_power_vec_entry *range;
729 u32 max_sleep = 0;
730 int i;
731 u8 period = 0;
732 bool skip;
733
734 if (mode > IWL_POWER_INDEX_5) {
735 IWL_DEBUG_POWER(priv, "Error invalid power mode \n");
736 return -EINVAL;
737 }
738 pow_data = &priv->power_data;
739
740 if (pow_data->dtim_period < 10)
741 range = &pow_data->pwr_range_0[0];
742 else
743 range = &pow_data->pwr_range_1[1];
744
745 memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd));
746
747
748 if (period == 0) {
749 period = 1;
750 skip = false;
751 } else {
752 skip = !!range[mode].no_dtim;
753 }
754
755 if (skip) {
756 __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
757 max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
758 cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
759 } else {
760 max_sleep = period;
761 cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
762 }
763
764 for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
765 if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
766 cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
767
768 IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags);
769 IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
770 IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
771 IWL_DEBUG_POWER(priv, "Sleep interval vector = { %d , %d , %d , %d , %d }\n",
772 le32_to_cpu(cmd->sleep_interval[0]),
773 le32_to_cpu(cmd->sleep_interval[1]),
774 le32_to_cpu(cmd->sleep_interval[2]),
775 le32_to_cpu(cmd->sleep_interval[3]),
776 le32_to_cpu(cmd->sleep_interval[4]));
777
778 return 0;
779}
780
781static int iwl3945_send_power_mode(struct iwl_priv *priv, u32 mode)
782{
783 u32 uninitialized_var(final_mode);
784 int rc;
785 struct iwl_powertable_cmd cmd;
786
787 /* If on battery, set to 3,
788 * if plugged into AC power, set to CAM ("continuously aware mode"),
789 * else user level */
790 switch (mode) {
791 case IWL39_POWER_BATTERY:
792 final_mode = IWL_POWER_INDEX_3;
793 break;
794 case IWL39_POWER_AC:
795 final_mode = IWL_POWER_MODE_CAM;
796 break;
797 default:
798 final_mode = mode;
799 break;
800 }
801
802 iwl3945_update_power_cmd(priv, &cmd, final_mode);
803
804 /* FIXME use get_hcmd_size 3945 command is 4 bytes shorter */
805 rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
806 sizeof(struct iwl3945_powertable_cmd), &cmd);
807
808 if (final_mode == IWL_POWER_MODE_CAM)
809 clear_bit(STATUS_POWER_PMI, &priv->status);
810 else
811 set_bit(STATUS_POWER_PMI, &priv->status);
812
813 return rc;
814}
815 659
816#define MAX_UCODE_BEACON_INTERVAL 1024 660#define MAX_UCODE_BEACON_INTERVAL 1024
817#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) 661#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
@@ -3467,7 +3311,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
3467 priv->active_rate = priv->rates_mask; 3311 priv->active_rate = priv->rates_mask;
3468 priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; 3312 priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
3469 3313
3470 iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode)); 3314 iwl_power_update_mode(priv, false);
3471 3315
3472 if (iwl_is_associated(priv)) { 3316 if (iwl_is_associated(priv)) {
3473 struct iwl3945_rxon_cmd *active_rxon = 3317 struct iwl3945_rxon_cmd *active_rxon =
@@ -5136,44 +4980,70 @@ static ssize_t show_retry_rate(struct device *d,
5136static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate, 4980static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
5137 store_retry_rate); 4981 store_retry_rate);
5138 4982
4983
5139static ssize_t store_power_level(struct device *d, 4984static ssize_t store_power_level(struct device *d,
5140 struct device_attribute *attr, 4985 struct device_attribute *attr,
5141 const char *buf, size_t count) 4986 const char *buf, size_t count)
5142{ 4987{
5143 struct iwl_priv *priv = dev_get_drvdata(d); 4988 struct iwl_priv *priv = dev_get_drvdata(d);
5144 int rc; 4989 int ret;
5145 int mode; 4990 unsigned long mode;
4991
5146 4992
5147 mode = simple_strtoul(buf, NULL, 0);
5148 mutex_lock(&priv->mutex); 4993 mutex_lock(&priv->mutex);
5149 4994
5150 if (!iwl_is_ready(priv)) { 4995 if (!iwl_is_ready(priv)) {
5151 rc = -EAGAIN; 4996 ret = -EAGAIN;
5152 goto out; 4997 goto out;
5153 } 4998 }
5154 4999
5155 if ((mode < 1) || (mode > IWL39_POWER_LIMIT) || 5000 ret = strict_strtoul(buf, 10, &mode);
5156 (mode == IWL39_POWER_AC)) 5001 if (ret)
5157 mode = IWL39_POWER_AC; 5002 goto out;
5158 else
5159 mode |= IWL_POWER_ENABLED;
5160 5003
5161 if (mode != priv->power_mode) { 5004 ret = iwl_power_set_user_mode(priv, mode);
5162 rc = iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(mode)); 5005 if (ret) {
5163 if (rc) { 5006 IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
5164 IWL_DEBUG_MAC80211(priv, "failed setting power mode\n"); 5007 goto out;
5165 goto out;
5166 }
5167 priv->power_mode = mode;
5168 } 5008 }
5169 5009 ret = count;
5170 rc = count;
5171 5010
5172 out: 5011 out:
5173 mutex_unlock(&priv->mutex); 5012 mutex_unlock(&priv->mutex);
5174 return rc; 5013 return ret;
5175} 5014}
5176 5015
5016static ssize_t show_power_level(struct device *d,
5017 struct device_attribute *attr, char *buf)
5018{
5019 struct iwl_priv *priv = dev_get_drvdata(d);
5020 int mode = priv->power_data.user_power_setting;
5021 int system = priv->power_data.system_power_setting;
5022 int level = priv->power_data.power_mode;
5023 char *p = buf;
5024
5025 switch (system) {
5026 case IWL_POWER_SYS_AUTO:
5027 p += sprintf(p, "SYSTEM:auto");
5028 break;
5029 case IWL_POWER_SYS_AC:
5030 p += sprintf(p, "SYSTEM:ac");
5031 break;
5032 case IWL_POWER_SYS_BATTERY:
5033 p += sprintf(p, "SYSTEM:battery");
5034 break;
5035 }
5036
5037 p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
5038 "fixed" : "auto");
5039 p += sprintf(p, "\tINDEX:%d", level);
5040 p += sprintf(p, "\n");
5041 return p - buf + 1;
5042}
5043
5044static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR,
5045 show_power_level, store_power_level);
5046
5177#define MAX_WX_STRING 80 5047#define MAX_WX_STRING 80
5178 5048
5179/* Values are in microsecond */ 5049/* Values are in microsecond */
@@ -5192,41 +5062,6 @@ static const s32 period_duration[] = {
5192 1000000 5062 1000000
5193}; 5063};
5194 5064
5195static ssize_t show_power_level(struct device *d,
5196 struct device_attribute *attr, char *buf)
5197{
5198 struct iwl_priv *priv = dev_get_drvdata(d);
5199 int level = IWL_POWER_LEVEL(priv->power_mode);
5200 char *p = buf;
5201
5202 p += sprintf(p, "%d ", level);
5203 switch (level) {
5204 case IWL_POWER_MODE_CAM:
5205 case IWL39_POWER_AC:
5206 p += sprintf(p, "(AC)");
5207 break;
5208 case IWL39_POWER_BATTERY:
5209 p += sprintf(p, "(BATTERY)");
5210 break;
5211 default:
5212 p += sprintf(p,
5213 "(Timeout %dms, Period %dms)",
5214 timeout_duration[level - 1] / 1000,
5215 period_duration[level - 1] / 1000);
5216 }
5217
5218 if (!(priv->power_mode & IWL_POWER_ENABLED))
5219 p += sprintf(p, " OFF\n");
5220 else
5221 p += sprintf(p, " \n");
5222
5223 return p - buf + 1;
5224
5225}
5226
5227static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
5228 store_power_level);
5229
5230static ssize_t show_channels(struct device *d, 5065static ssize_t show_channels(struct device *d,
5231 struct device_attribute *attr, char *buf) 5066 struct device_attribute *attr, char *buf)
5232{ 5067{
@@ -5469,8 +5304,8 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
5469 priv->qos_data.qos_cap.val = 0; 5304 priv->qos_data.qos_cap.val = 0;
5470 5305
5471 priv->rates_mask = IWL_RATES_MASK; 5306 priv->rates_mask = IWL_RATES_MASK;
5472 /* If power management is turned on, default to AC mode */ 5307 /* If power management is turned on, default to CAM mode */
5473 priv->power_mode = IWL39_POWER_AC; 5308 priv->power_mode = IWL_POWER_MODE_CAM;
5474 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; 5309 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
5475 5310
5476 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { 5311 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {