aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c11
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.h1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/fw.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/lmac.h8
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c14
-rw-r--r--drivers/net/wireless/iwmc3200wifi/netdev.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c16
8 files changed, 55 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 23b52fa2605..aeea909992f 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -274,6 +274,17 @@ int iwm_send_calib_results(struct iwm_priv *iwm)
274 return ret; 274 return ret;
275} 275}
276 276
277int iwm_send_ct_kill_cfg(struct iwm_priv *iwm, u8 entry, u8 exit)
278{
279 struct iwm_ct_kill_cfg_cmd cmd;
280
281 cmd.entry_threshold = entry;
282 cmd.exit_threshold = exit;
283
284 return iwm_send_lmac_ptrough_cmd(iwm, REPLY_CT_KILL_CONFIG_CMD, &cmd,
285 sizeof(struct iwm_ct_kill_cfg_cmd), 0);
286}
287
277int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp) 288int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp)
278{ 289{
279 struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT; 290 struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
index 4e183be1f26..e486f8e8937 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.h
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -396,6 +396,7 @@ int iwm_send_init_calib_cfg(struct iwm_priv *iwm, u8 calib_requested);
396int iwm_send_periodic_calib_cfg(struct iwm_priv *iwm, u8 calib_requested); 396int iwm_send_periodic_calib_cfg(struct iwm_priv *iwm, u8 calib_requested);
397int iwm_send_calib_results(struct iwm_priv *iwm); 397int iwm_send_calib_results(struct iwm_priv *iwm);
398int iwm_store_rxiq_calib_result(struct iwm_priv *iwm); 398int iwm_store_rxiq_calib_result(struct iwm_priv *iwm);
399int iwm_send_ct_kill_cfg(struct iwm_priv *iwm, u8 entry, u8 exit);
399 400
400/* UMAC commands */ 401/* UMAC commands */
401int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size, 402int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
index 6b0bcad758c..f02d571b0a1 100644
--- a/drivers/net/wireless/iwmc3200wifi/fw.c
+++ b/drivers/net/wireless/iwmc3200wifi/fw.c
@@ -398,6 +398,8 @@ int iwm_load_fw(struct iwm_priv *iwm)
398 iwm_send_prio_table(iwm); 398 iwm_send_prio_table(iwm);
399 iwm_send_calib_results(iwm); 399 iwm_send_calib_results(iwm);
400 iwm_send_periodic_calib_cfg(iwm, periodic_calib_map); 400 iwm_send_periodic_calib_cfg(iwm, periodic_calib_map);
401 iwm_send_ct_kill_cfg(iwm, iwm->conf.ct_kill_entry,
402 iwm->conf.ct_kill_exit);
401 403
402 return 0; 404 return 0;
403 405
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 1b02a4e2a1a..fe0ab80994d 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -65,6 +65,8 @@ struct iwm_conf {
65 u32 sdio_ior_timeout; 65 u32 sdio_ior_timeout;
66 unsigned long calib_map; 66 unsigned long calib_map;
67 unsigned long expected_calib_map; 67 unsigned long expected_calib_map;
68 u8 ct_kill_entry;
69 u8 ct_kill_exit;
68 bool reset_on_fatal_err; 70 bool reset_on_fatal_err;
69 bool auto_connect; 71 bool auto_connect;
70 bool wimax_not_present; 72 bool wimax_not_present;
@@ -276,6 +278,7 @@ struct iwm_priv {
276 struct iw_statistics wstats; 278 struct iw_statistics wstats;
277 struct delayed_work stats_request; 279 struct delayed_work stats_request;
278 struct delayed_work disconnect; 280 struct delayed_work disconnect;
281 struct delayed_work ct_kill_delay;
279 282
280 struct iwm_debugfs dbg; 283 struct iwm_debugfs dbg;
281 284
diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h
index 6c1a14c4480..a3a79b5e289 100644
--- a/drivers/net/wireless/iwmc3200wifi/lmac.h
+++ b/drivers/net/wireless/iwmc3200wifi/lmac.h
@@ -187,6 +187,14 @@ struct iwm_coex_prio_table_cmd {
187 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \ 187 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \
188 COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK) 188 COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK)
189 189
190/* CT kill config command */
191struct iwm_ct_kill_cfg_cmd {
192 u32 exit_threshold;
193 u32 reserved;
194 u32 entry_threshold;
195} __attribute__ ((packed));
196
197
190/* LMAC OP CODES */ 198/* LMAC OP CODES */
191#define REPLY_PAD 0x0 199#define REPLY_PAD 0x0
192#define REPLY_ALIVE 0x1 200#define REPLY_ALIVE 0x1
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 170f3370649..3147fe7b513 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -63,6 +63,8 @@ static struct iwm_conf def_iwm_conf = {
63 BIT(PHY_CALIBRATE_TX_IQ_CMD) | 63 BIT(PHY_CALIBRATE_TX_IQ_CMD) |
64 BIT(PHY_CALIBRATE_RX_IQ_CMD) | 64 BIT(PHY_CALIBRATE_RX_IQ_CMD) |
65 BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD), 65 BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
66 .ct_kill_entry = 110,
67 .ct_kill_exit = 110,
66 .reset_on_fatal_err = 1, 68 .reset_on_fatal_err = 1,
67 .auto_connect = 1, 69 .auto_connect = 1,
68 .wimax_not_present = 0, 70 .wimax_not_present = 0,
@@ -133,6 +135,17 @@ static void iwm_disconnect_work(struct work_struct *work)
133 cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL); 135 cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
134} 136}
135 137
138static void iwm_ct_kill_work(struct work_struct *work)
139{
140 struct iwm_priv *iwm =
141 container_of(work, struct iwm_priv, ct_kill_delay.work);
142 struct wiphy *wiphy = iwm_to_wiphy(iwm);
143
144 IWM_INFO(iwm, "CT kill delay timeout\n");
145
146 wiphy_rfkill_set_hw_state(wiphy, false);
147}
148
136static int __iwm_up(struct iwm_priv *iwm); 149static int __iwm_up(struct iwm_priv *iwm);
137static int __iwm_down(struct iwm_priv *iwm); 150static int __iwm_down(struct iwm_priv *iwm);
138 151
@@ -225,6 +238,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
225 iwm->scan_id = 1; 238 iwm->scan_id = 1;
226 INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request); 239 INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
227 INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work); 240 INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
241 INIT_DELAYED_WORK(&iwm->ct_kill_delay, iwm_ct_kill_work);
228 INIT_WORK(&iwm->reset_worker, iwm_reset_worker); 242 INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
229 INIT_LIST_HEAD(&iwm->bss_list); 243 INIT_LIST_HEAD(&iwm->bss_list);
230 244
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c
index 35ec006c2d2..4f8dbdd7b91 100644
--- a/drivers/net/wireless/iwmc3200wifi/netdev.c
+++ b/drivers/net/wireless/iwmc3200wifi/netdev.c
@@ -152,6 +152,7 @@ void iwm_if_free(struct iwm_priv *iwm)
152 if (!iwm_to_ndev(iwm)) 152 if (!iwm_to_ndev(iwm))
153 return; 153 return;
154 154
155 cancel_delayed_work_sync(&iwm->ct_kill_delay);
155 free_netdev(iwm_to_ndev(iwm)); 156 free_netdev(iwm_to_ndev(iwm));
156 iwm_priv_deinit(iwm); 157 iwm_priv_deinit(iwm);
157 kfree(iwm->umac_profile); 158 kfree(iwm->umac_profile);
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 40dbcbc1659..14a2a0b3d61 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1078,6 +1078,7 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
1078 return 0; 1078 return 0;
1079} 1079}
1080 1080
1081#define CT_KILL_DELAY (30 * HZ)
1081static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf, 1082static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
1082 unsigned long buf_size, struct iwm_wifi_cmd *cmd) 1083 unsigned long buf_size, struct iwm_wifi_cmd *cmd)
1083{ 1084{
@@ -1090,7 +1091,20 @@ static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
1090 flags & IWM_CARD_STATE_HW_DISABLED ? "ON" : "OFF", 1091 flags & IWM_CARD_STATE_HW_DISABLED ? "ON" : "OFF",
1091 flags & IWM_CARD_STATE_CTKILL_DISABLED ? "ON" : "OFF"); 1092 flags & IWM_CARD_STATE_CTKILL_DISABLED ? "ON" : "OFF");
1092 1093
1093 wiphy_rfkill_set_hw_state(wiphy, flags & IWM_CARD_STATE_HW_DISABLED); 1094 if (flags & IWM_CARD_STATE_CTKILL_DISABLED) {
1095 /*
1096 * We got a CTKILL event: We bring the interface down in
1097 * oder to cool the device down, and try to bring it up
1098 * 30 seconds later. If it's still too hot, we'll go through
1099 * this code path again.
1100 */
1101 cancel_delayed_work_sync(&iwm->ct_kill_delay);
1102 schedule_delayed_work(&iwm->ct_kill_delay, CT_KILL_DELAY);
1103 }
1104
1105 wiphy_rfkill_set_hw_state(wiphy, flags &
1106 (IWM_CARD_STATE_HW_DISABLED |
1107 IWM_CARD_STATE_CTKILL_DISABLED));
1094 1108
1095 return 0; 1109 return 0;
1096} 1110}