aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlegacy/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlegacy/common.c')
-rw-r--r--drivers/net/wireless/iwlegacy/common.c83
1 files changed, 69 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 02e8233ccf29..4f42174d9994 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -1078,29 +1078,82 @@ EXPORT_SYMBOL(il_get_channel_info);
1078 * Setting power level allows the card to go to sleep when not busy. 1078 * Setting power level allows the card to go to sleep when not busy.
1079 * 1079 *
1080 * We calculate a sleep command based on the required latency, which 1080 * We calculate a sleep command based on the required latency, which
1081 * we get from mac80211. In order to handle thermal throttling, we can 1081 * we get from mac80211.
1082 * also use pre-defined power levels.
1083 */ 1082 */
1084 1083
1085/* 1084#define SLP_VEC(X0, X1, X2, X3, X4) { \
1086 * This defines the old power levels. They are still used by default 1085 cpu_to_le32(X0), \
1087 * (level 1) and for thermal throttle (levels 3 through 5) 1086 cpu_to_le32(X1), \
1088 */ 1087 cpu_to_le32(X2), \
1089 1088 cpu_to_le32(X3), \
1090struct il_power_vec_entry { 1089 cpu_to_le32(X4) \
1091 struct il_powertable_cmd cmd; 1090}
1092 u8 no_dtim; /* number of skip dtim */
1093};
1094 1091
1095static void 1092static void
1096il_power_sleep_cam_cmd(struct il_priv *il, struct il_powertable_cmd *cmd) 1093il_build_powertable_cmd(struct il_priv *il, struct il_powertable_cmd *cmd)
1097{ 1094{
1095 const __le32 interval[3][IL_POWER_VEC_SIZE] = {
1096 SLP_VEC(2, 2, 4, 6, 0xFF),
1097 SLP_VEC(2, 4, 7, 10, 10),
1098 SLP_VEC(4, 7, 10, 10, 0xFF)
1099 };
1100 int i, dtim_period, no_dtim;
1101 u32 max_sleep;
1102 bool skip;
1103
1098 memset(cmd, 0, sizeof(*cmd)); 1104 memset(cmd, 0, sizeof(*cmd));
1099 1105
1100 if (il->power_data.pci_pm) 1106 if (il->power_data.pci_pm)
1101 cmd->flags |= IL_POWER_PCI_PM_MSK; 1107 cmd->flags |= IL_POWER_PCI_PM_MSK;
1102 1108
1103 D_POWER("Sleep command for CAM\n"); 1109 /* if no Power Save, we are done */
1110 if (il->power_data.ps_disabled)
1111 return;
1112
1113 cmd->flags = IL_POWER_DRIVER_ALLOW_SLEEP_MSK;
1114 cmd->keep_alive_seconds = 0;
1115 cmd->debug_flags = 0;
1116 cmd->rx_data_timeout = cpu_to_le32(25 * 1024);
1117 cmd->tx_data_timeout = cpu_to_le32(25 * 1024);
1118 cmd->keep_alive_beacons = 0;
1119
1120 dtim_period = il->vif ? il->vif->bss_conf.dtim_period : 0;
1121
1122 if (dtim_period <= 2) {
1123 memcpy(cmd->sleep_interval, interval[0], sizeof(interval[0]));
1124 no_dtim = 2;
1125 } else if (dtim_period <= 10) {
1126 memcpy(cmd->sleep_interval, interval[1], sizeof(interval[1]));
1127 no_dtim = 2;
1128 } else {
1129 memcpy(cmd->sleep_interval, interval[2], sizeof(interval[2]));
1130 no_dtim = 0;
1131 }
1132
1133 if (dtim_period == 0) {
1134 dtim_period = 1;
1135 skip = false;
1136 } else {
1137 skip = !!no_dtim;
1138 }
1139
1140 if (skip) {
1141 __le32 tmp = cmd->sleep_interval[IL_POWER_VEC_SIZE - 1];
1142
1143 max_sleep = le32_to_cpu(tmp);
1144 if (max_sleep == 0xFF)
1145 max_sleep = dtim_period * (skip + 1);
1146 else if (max_sleep > dtim_period)
1147 max_sleep = (max_sleep / dtim_period) * dtim_period;
1148 cmd->flags |= IL_POWER_SLEEP_OVER_DTIM_MSK;
1149 } else {
1150 max_sleep = dtim_period;
1151 cmd->flags &= ~IL_POWER_SLEEP_OVER_DTIM_MSK;
1152 }
1153
1154 for (i = 0; i < IL_POWER_VEC_SIZE; i++)
1155 if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
1156 cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
1104} 1157}
1105 1158
1106static int 1159static int
@@ -1173,7 +1226,8 @@ il_power_update_mode(struct il_priv *il, bool force)
1173{ 1226{
1174 struct il_powertable_cmd cmd; 1227 struct il_powertable_cmd cmd;
1175 1228
1176 il_power_sleep_cam_cmd(il, &cmd); 1229 il_build_powertable_cmd(il, &cmd);
1230
1177 return il_power_set_mode(il, &cmd, force); 1231 return il_power_set_mode(il, &cmd, force);
1178} 1232}
1179EXPORT_SYMBOL(il_power_update_mode); 1233EXPORT_SYMBOL(il_power_update_mode);
@@ -5081,6 +5135,7 @@ set_ch_out:
5081 } 5135 }
5082 5136
5083 if (changed & (IEEE80211_CONF_CHANGE_PS | IEEE80211_CONF_CHANGE_IDLE)) { 5137 if (changed & (IEEE80211_CONF_CHANGE_PS | IEEE80211_CONF_CHANGE_IDLE)) {
5138 il->power_data.ps_disabled = !(conf->flags & IEEE80211_CONF_PS);
5084 ret = il_power_update_mode(il, false); 5139 ret = il_power_update_mode(il, false);
5085 if (ret) 5140 if (ret)
5086 D_MAC80211("Error setting sleep level\n"); 5141 D_MAC80211("Error setting sleep level\n");