aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2014-11-06 03:34:49 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-11-11 10:15:08 -0500
commitea9af24d03a905143544ba383e23c731ba3bc5bd (patch)
treefb12642102582e4532346ff6d1abf22fe272a32c
parentfd1f75506d96481e61e86947a1aef85c130f714e (diff)
iwlwifi: mvm: handle unsolicited DTS_MEASUREMENT_NOTIFICATIONs
Currently, the firmware only sends temperature notificaitions inside RX statistics notifications, which are tied to beacon filtering. This is a problem because beacon filtering is not used with vifs that don't receive beacons (e.g. P2P GO and AP), so the driver doesn't receive temperature notifications in those cases. To solve that, the firmware will be changed so that it sends DTS_MEASUREMENT_NOTIFICATIONs, independently from the beacon filtering flows. To support that, the driver needs to also handle unsolicited DTS_MEASUREMENT_NOTIFICATIONs, that are not triggered by DTS_TRIGGER_CMD_FLAGS_TEMP requests. This change is backwards compatible and will simply not be used with firmware versions that do not send the notifications. Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c20
3 files changed, 25 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 9ac2d4c59bc6..7d2c5289464b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -1211,6 +1211,9 @@ bool iwl_mvm_is_idle(struct iwl_mvm *mvm);
1211/* Thermal management and CT-kill */ 1211/* Thermal management and CT-kill */
1212void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); 1212void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff);
1213void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp); 1213void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp);
1214int iwl_mvm_temp_notif(struct iwl_mvm *mvm,
1215 struct iwl_rx_cmd_buffer *rxb,
1216 struct iwl_device_cmd *cmd);
1214void iwl_mvm_tt_handler(struct iwl_mvm *mvm); 1217void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
1215void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff); 1218void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff);
1216void iwl_mvm_tt_exit(struct iwl_mvm *mvm); 1219void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index be3dd4f5c7e1..737aac32a73d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -254,6 +254,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
254 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false), 254 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
255 RX_HANDLER(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION, 255 RX_HANDLER(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION,
256 iwl_mvm_power_uapsd_misbehaving_ap_notif, false), 256 iwl_mvm_power_uapsd_misbehaving_ap_notif, false),
257 RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif, true),
258
257}; 259};
258#undef RX_HANDLER 260#undef RX_HANDLER
259#define CMD(x) [x] = #x 261#define CMD(x) [x] = #x
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index 35acf003cce8..2b1e61fac34a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -150,6 +150,26 @@ static bool iwl_mvm_temp_notif_wait(struct iwl_notif_wait_data *notif_wait,
150 return true; 150 return true;
151} 151}
152 152
153int iwl_mvm_temp_notif(struct iwl_mvm *mvm,
154 struct iwl_rx_cmd_buffer *rxb,
155 struct iwl_device_cmd *cmd)
156{
157 struct iwl_rx_packet *pkt = rxb_addr(rxb);
158 int temp;
159
160 /* the notification is handled synchronously in ctkill, so skip here */
161 if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
162 return 0;
163
164 temp = iwl_mvm_temp_notif_parse(mvm, pkt);
165 if (temp < 0)
166 return 0;
167
168 iwl_mvm_tt_temp_changed(mvm, temp);
169
170 return 0;
171}
172
153static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm) 173static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
154{ 174{
155 struct iwl_dts_measurement_cmd cmd = { 175 struct iwl_dts_measurement_cmd cmd = {