aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c517
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h128
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c6
11 files changed, 705 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index e77f91380a4a..3bee0f119bcd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -400,6 +400,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
400 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 400 struct iwl_tx_queue *txq = &priv->txq[txq_id];
401 struct ieee80211_tx_info *info; 401 struct ieee80211_tx_info *info;
402 struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 402 struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
403 struct ieee80211_hdr *hdr;
403 struct iwl_tx_info *txb; 404 struct iwl_tx_info *txb;
404 u32 status = le16_to_cpu(tx_resp->status.status); 405 u32 status = le16_to_cpu(tx_resp->status.status);
405 int tid; 406 int tid;
@@ -426,6 +427,11 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
426 IWLAGN_TX_RES_RA_POS; 427 IWLAGN_TX_RES_RA_POS;
427 428
428 spin_lock_irqsave(&priv->sta_lock, flags); 429 spin_lock_irqsave(&priv->sta_lock, flags);
430
431 hdr = (void *)txb->skb->data;
432 if (!ieee80211_is_data_qos(hdr->frame_control))
433 priv->last_seq_ctl = tx_resp->seq_ctl;
434
429 if (txq->sched_retry) { 435 if (txq->sched_retry) {
430 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp); 436 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp);
431 struct iwl_ht_agg *agg; 437 struct iwl_ht_agg *agg;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 71487487d603..d78a4659dbff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -855,6 +855,9 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
855 iwl_wake_any_queue(priv, ctx); 855 iwl_wake_any_queue(priv, ctx);
856 } 856 }
857 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 857 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
858
859 if (ctx->ctxid == IWL_RXON_CTX_BSS)
860 priv->have_rekey_data = false;
858 } 861 }
859 862
860 iwlagn_bt_coex_rssi_monitor(priv); 863 iwlagn_bt_coex_rssi_monitor(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 946d3a16e494..a895a099d086 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -513,14 +513,21 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
513 return -EIO; 513 return -EIO;
514 } 514 }
515 515
516 ret = iwl_verify_ucode(priv, image); 516 /*
517 if (ret) { 517 * This step takes a long time (60-80ms!!) and
518 priv->ucode_type = old_type; 518 * WoWLAN image should be loaded quickly, so
519 return ret; 519 * skip it for WoWLAN.
520 } 520 */
521 if (ucode_type != IWL_UCODE_WOWLAN) {
522 ret = iwl_verify_ucode(priv, image);
523 if (ret) {
524 priv->ucode_type = old_type;
525 return ret;
526 }
521 527
522 /* delay a bit to give rfkill time to run */ 528 /* delay a bit to give rfkill time to run */
523 msleep(5); 529 msleep(5);
530 }
524 531
525 ret = iwlagn_alive_notify(priv); 532 ret = iwlagn_alive_notify(priv);
526 if (ret) { 533 if (ret) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 0bab19563394..299acb491f0d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -593,6 +593,7 @@ static void iwl_dealloc_ucode(struct iwl_priv *priv)
593{ 593{
594 iwl_free_fw_img(priv, &priv->ucode_rt); 594 iwl_free_fw_img(priv, &priv->ucode_rt);
595 iwl_free_fw_img(priv, &priv->ucode_init); 595 iwl_free_fw_img(priv, &priv->ucode_init);
596 iwl_free_fw_img(priv, &priv->ucode_wowlan);
596} 597}
597 598
598static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc, 599static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
@@ -662,8 +663,9 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
662} 663}
663 664
664struct iwlagn_firmware_pieces { 665struct iwlagn_firmware_pieces {
665 const void *inst, *data, *init, *init_data; 666 const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data;
666 size_t inst_size, data_size, init_size, init_data_size; 667 size_t inst_size, data_size, init_size, init_data_size,
668 wowlan_inst_size, wowlan_data_size;
667 669
668 u32 build; 670 u32 build;
669 671
@@ -902,6 +904,14 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
902 goto invalid_tlv_len; 904 goto invalid_tlv_len;
903 priv->enhance_sensitivity_table = true; 905 priv->enhance_sensitivity_table = true;
904 break; 906 break;
907 case IWL_UCODE_TLV_WOWLAN_INST:
908 pieces->wowlan_inst = tlv_data;
909 pieces->wowlan_inst_size = tlv_len;
910 break;
911 case IWL_UCODE_TLV_WOWLAN_DATA:
912 pieces->wowlan_data = tlv_data;
913 pieces->wowlan_data_size = tlv_len;
914 break;
905 case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: 915 case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
906 if (tlv_len != sizeof(u32)) 916 if (tlv_len != sizeof(u32))
907 goto invalid_tlv_len; 917 goto invalid_tlv_len;
@@ -1096,6 +1106,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1096 goto err_pci_alloc; 1106 goto err_pci_alloc;
1097 } 1107 }
1098 1108
1109 /* WoWLAN instructions and data */
1110 if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
1111 if (iwl_alloc_fw_desc(priv, &priv->ucode_wowlan.code,
1112 pieces.wowlan_inst,
1113 pieces.wowlan_inst_size))
1114 goto err_pci_alloc;
1115 if (iwl_alloc_fw_desc(priv, &priv->ucode_wowlan.data,
1116 pieces.wowlan_data,
1117 pieces.wowlan_data_size))
1118 goto err_pci_alloc;
1119 }
1120
1099 /* Now that we can no longer fail, copy information */ 1121 /* Now that we can no longer fail, copy information */
1100 1122
1101 /* 1123 /*
@@ -1698,7 +1720,7 @@ int iwl_alive_start(struct iwl_priv *priv)
1698 /* Configure Tx antenna selection based on H/W config */ 1720 /* Configure Tx antenna selection based on H/W config */
1699 iwlagn_send_tx_ant_config(priv, priv->cfg->valid_tx_ant); 1721 iwlagn_send_tx_ant_config(priv, priv->cfg->valid_tx_ant);
1700 1722
1701 if (iwl_is_associated_ctx(ctx)) { 1723 if (iwl_is_associated_ctx(ctx) && !priv->wowlan) {
1702 struct iwl_rxon_cmd *active_rxon = 1724 struct iwl_rxon_cmd *active_rxon =
1703 (struct iwl_rxon_cmd *)&ctx->active; 1725 (struct iwl_rxon_cmd *)&ctx->active;
1704 /* apply any changes in staging */ 1726 /* apply any changes in staging */
@@ -1713,7 +1735,10 @@ int iwl_alive_start(struct iwl_priv *priv)
1713 iwlagn_set_rxon_chain(priv, ctx); 1735 iwlagn_set_rxon_chain(priv, ctx);
1714 } 1736 }
1715 1737
1716 iwl_reset_run_time_calib(priv); 1738 if (!priv->wowlan) {
1739 /* WoWLAN ucode will not reply in the same way, skip it */
1740 iwl_reset_run_time_calib(priv);
1741 }
1717 1742
1718 set_bit(STATUS_READY, &priv->status); 1743 set_bit(STATUS_READY, &priv->status);
1719 1744
@@ -2153,6 +2178,23 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
2153 WIPHY_FLAG_DISABLE_BEACON_HINTS | 2178 WIPHY_FLAG_DISABLE_BEACON_HINTS |
2154 WIPHY_FLAG_IBSS_RSN; 2179 WIPHY_FLAG_IBSS_RSN;
2155 2180
2181 if (priv->ucode_wowlan.code.len && device_can_wakeup(priv->bus->dev)) {
2182 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
2183 WIPHY_WOWLAN_DISCONNECT |
2184 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
2185 WIPHY_WOWLAN_RFKILL_RELEASE;
2186 if (!iwlagn_mod_params.sw_crypto)
2187 hw->wiphy->wowlan.flags |=
2188 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
2189 WIPHY_WOWLAN_GTK_REKEY_FAILURE;
2190
2191 hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS;
2192 hw->wiphy->wowlan.pattern_min_len =
2193 IWLAGN_WOWLAN_MIN_PATTERN_LEN;
2194 hw->wiphy->wowlan.pattern_max_len =
2195 IWLAGN_WOWLAN_MAX_PATTERN_LEN;
2196 }
2197
2156 if (iwlagn_mod_params.power_save) 2198 if (iwlagn_mod_params.power_save)
2157 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; 2199 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
2158 else 2200 else
@@ -2237,6 +2279,467 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
2237 IWL_DEBUG_MAC80211(priv, "leave\n"); 2279 IWL_DEBUG_MAC80211(priv, "leave\n");
2238} 2280}
2239 2281
2282static int iwlagn_send_patterns(struct iwl_priv *priv,
2283 struct cfg80211_wowlan *wowlan)
2284{
2285 struct iwlagn_wowlan_patterns_cmd *pattern_cmd;
2286 struct iwl_host_cmd cmd = {
2287 .id = REPLY_WOWLAN_PATTERNS,
2288 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
2289 .flags = CMD_SYNC,
2290 };
2291 int i, err;
2292
2293 if (!wowlan->n_patterns)
2294 return 0;
2295
2296 cmd.len[0] = sizeof(*pattern_cmd) +
2297 wowlan->n_patterns * sizeof(struct iwlagn_wowlan_pattern);
2298
2299 pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
2300 if (!pattern_cmd)
2301 return -ENOMEM;
2302
2303 pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);
2304
2305 for (i = 0; i < wowlan->n_patterns; i++) {
2306 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
2307
2308 memcpy(&pattern_cmd->patterns[i].mask,
2309 wowlan->patterns[i].mask, mask_len);
2310 memcpy(&pattern_cmd->patterns[i].pattern,
2311 wowlan->patterns[i].pattern,
2312 wowlan->patterns[i].pattern_len);
2313 pattern_cmd->patterns[i].mask_size = mask_len;
2314 pattern_cmd->patterns[i].pattern_size =
2315 wowlan->patterns[i].pattern_len;
2316 }
2317
2318 cmd.data[0] = pattern_cmd;
2319 err = trans_send_cmd(&priv->trans, &cmd);
2320 kfree(pattern_cmd);
2321 return err;
2322}
2323
2324static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
2325 struct ieee80211_vif *vif,
2326 struct cfg80211_gtk_rekey_data *data)
2327{
2328 struct iwl_priv *priv = hw->priv;
2329
2330 if (iwlagn_mod_params.sw_crypto)
2331 return;
2332
2333 mutex_lock(&priv->mutex);
2334
2335 if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif)
2336 goto out;
2337
2338 memcpy(priv->kek, data->kek, NL80211_KEK_LEN);
2339 memcpy(priv->kck, data->kck, NL80211_KCK_LEN);
2340 priv->replay_ctr = cpu_to_le64(be64_to_cpup((__be64 *)&data->replay_ctr));
2341 priv->have_rekey_data = true;
2342
2343 out:
2344 mutex_unlock(&priv->mutex);
2345}
2346
2347struct wowlan_key_data {
2348 struct iwl_rxon_context *ctx;
2349 struct iwlagn_wowlan_rsc_tsc_params_cmd *rsc_tsc;
2350 struct iwlagn_wowlan_tkip_params_cmd *tkip;
2351 const u8 *bssid;
2352 bool error, use_rsc_tsc, use_tkip;
2353};
2354
2355static void iwlagn_convert_p1k(u16 *p1k, __le16 *out)
2356{
2357 int i;
2358
2359 for (i = 0; i < IWLAGN_P1K_SIZE; i++)
2360 out[i] = cpu_to_le16(p1k[i]);
2361}
2362
2363static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
2364 struct ieee80211_vif *vif,
2365 struct ieee80211_sta *sta,
2366 struct ieee80211_key_conf *key,
2367 void *_data)
2368{
2369 struct iwl_priv *priv = hw->priv;
2370 struct wowlan_key_data *data = _data;
2371 struct iwl_rxon_context *ctx = data->ctx;
2372 struct aes_sc *aes_sc, *aes_tx_sc = NULL;
2373 struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
2374 struct iwlagn_p1k_cache *rx_p1ks;
2375 u8 *rx_mic_key;
2376 struct ieee80211_key_seq seq;
2377 u32 cur_rx_iv32 = 0;
2378 u16 p1k[IWLAGN_P1K_SIZE];
2379 int ret, i;
2380
2381 mutex_lock(&priv->mutex);
2382
2383 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
2384 key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
2385 !sta && !ctx->key_mapping_keys)
2386 ret = iwl_set_default_wep_key(priv, ctx, key);
2387 else
2388 ret = iwl_set_dynamic_key(priv, ctx, key, sta);
2389
2390 if (ret) {
2391 IWL_ERR(priv, "Error setting key during suspend!\n");
2392 data->error = true;
2393 }
2394
2395 switch (key->cipher) {
2396 case WLAN_CIPHER_SUITE_TKIP:
2397 if (sta) {
2398 tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;
2399 tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc;
2400
2401 rx_p1ks = data->tkip->rx_uni;
2402
2403 ieee80211_get_key_tx_seq(key, &seq);
2404 tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16);
2405 tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32);
2406
2407 ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k);
2408 iwlagn_convert_p1k(p1k, data->tkip->tx.p1k);
2409
2410 memcpy(data->tkip->mic_keys.tx,
2411 &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
2412 IWLAGN_MIC_KEY_SIZE);
2413
2414 rx_mic_key = data->tkip->mic_keys.rx_unicast;
2415 } else {
2416 tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc;
2417 rx_p1ks = data->tkip->rx_multi;
2418 rx_mic_key = data->tkip->mic_keys.rx_mcast;
2419 }
2420
2421 /*
2422 * For non-QoS this relies on the fact that both the uCode and
2423 * mac80211 use TID 0 (as they need to to avoid replay attacks)
2424 * for checking the IV in the frames.
2425 */
2426 for (i = 0; i < IWLAGN_NUM_RSC; i++) {
2427 ieee80211_get_key_rx_seq(key, i, &seq);
2428 tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);
2429 tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
2430 /* wrapping isn't allowed, AP must rekey */
2431 if (seq.tkip.iv32 > cur_rx_iv32)
2432 cur_rx_iv32 = seq.tkip.iv32;
2433 }
2434
2435 ieee80211_get_tkip_rx_p1k(key, data->bssid, cur_rx_iv32, p1k);
2436 iwlagn_convert_p1k(p1k, rx_p1ks[0].p1k);
2437 ieee80211_get_tkip_rx_p1k(key, data->bssid,
2438 cur_rx_iv32 + 1, p1k);
2439 iwlagn_convert_p1k(p1k, rx_p1ks[1].p1k);
2440
2441 memcpy(rx_mic_key,
2442 &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
2443 IWLAGN_MIC_KEY_SIZE);
2444
2445 data->use_tkip = true;
2446 data->use_rsc_tsc = true;
2447 break;
2448 case WLAN_CIPHER_SUITE_CCMP:
2449 if (sta) {
2450 u8 *pn = seq.ccmp.pn;
2451
2452 aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
2453 aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc;
2454
2455 ieee80211_get_key_tx_seq(key, &seq);
2456 aes_tx_sc->pn = cpu_to_le64(
2457 (u64)pn[5] |
2458 ((u64)pn[4] << 8) |
2459 ((u64)pn[3] << 16) |
2460 ((u64)pn[2] << 24) |
2461 ((u64)pn[1] << 32) |
2462 ((u64)pn[0] << 40));
2463 } else
2464 aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
2465
2466 /*
2467 * For non-QoS this relies on the fact that both the uCode and
2468 * mac80211 use TID 0 for checking the IV in the frames.
2469 */
2470 for (i = 0; i < IWLAGN_NUM_RSC; i++) {
2471 u8 *pn = seq.ccmp.pn;
2472
2473 ieee80211_get_key_rx_seq(key, i, &seq);
2474 aes_sc->pn = cpu_to_le64(
2475 (u64)pn[5] |
2476 ((u64)pn[4] << 8) |
2477 ((u64)pn[3] << 16) |
2478 ((u64)pn[2] << 24) |
2479 ((u64)pn[1] << 32) |
2480 ((u64)pn[0] << 40));
2481 }
2482 data->use_rsc_tsc = true;
2483 break;
2484 }
2485
2486 mutex_unlock(&priv->mutex);
2487}
2488
2489static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
2490 struct cfg80211_wowlan *wowlan)
2491{
2492 struct iwl_priv *priv = hw->priv;
2493 struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd;
2494 struct iwl_rxon_cmd rxon;
2495 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2496 struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd;
2497 struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {};
2498 struct wowlan_key_data key_data = {
2499 .ctx = ctx,
2500 .bssid = ctx->active.bssid_addr,
2501 .use_rsc_tsc = false,
2502 .tkip = &tkip_cmd,
2503 .use_tkip = false,
2504 };
2505 int ret, i;
2506 u16 seq;
2507
2508 if (WARN_ON(!wowlan))
2509 return -EINVAL;
2510
2511 mutex_lock(&priv->mutex);
2512
2513 /* Don't attempt WoWLAN when not associated, tear down instead. */
2514 if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION ||
2515 !iwl_is_associated_ctx(ctx)) {
2516 ret = 1;
2517 goto out;
2518 }
2519
2520 key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL);
2521 if (!key_data.rsc_tsc) {
2522 ret = -ENOMEM;
2523 goto out;
2524 }
2525
2526 memset(&wakeup_filter_cmd, 0, sizeof(wakeup_filter_cmd));
2527
2528 /*
2529 * We know the last used seqno, and the uCode expects to know that
2530 * one, it will increment before TX.
2531 */
2532 seq = le16_to_cpu(priv->last_seq_ctl) & IEEE80211_SCTL_SEQ;
2533 wakeup_filter_cmd.non_qos_seq = cpu_to_le16(seq);
2534
2535 /*
2536 * For QoS counters, we store the one to use next, so subtract 0x10
2537 * since the uCode will add 0x10 before using the value.
2538 */
2539 for (i = 0; i < 8; i++) {
2540 seq = priv->stations[IWL_AP_ID].tid[i].seq_number;
2541 seq -= 0x10;
2542 wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq);
2543 }
2544
2545 if (wowlan->disconnect)
2546 wakeup_filter_cmd.enabled |=
2547 cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_BEACON_MISS |
2548 IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE);
2549 if (wowlan->magic_pkt)
2550 wakeup_filter_cmd.enabled |=
2551 cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET);
2552 if (wowlan->gtk_rekey_failure)
2553 wakeup_filter_cmd.enabled |=
2554 cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
2555 if (wowlan->eap_identity_req)
2556 wakeup_filter_cmd.enabled |=
2557 cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ);
2558 if (wowlan->four_way_handshake)
2559 wakeup_filter_cmd.enabled |=
2560 cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
2561 if (wowlan->rfkill_release)
2562 wakeup_filter_cmd.enabled |=
2563 cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_RFKILL);
2564 if (wowlan->n_patterns)
2565 wakeup_filter_cmd.enabled |=
2566 cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH);
2567
2568 iwl_scan_cancel_timeout(priv, 200);
2569
2570 memcpy(&rxon, &ctx->active, sizeof(rxon));
2571
2572 trans_stop_device(&priv->trans);
2573
2574 priv->wowlan = true;
2575
2576 ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_wowlan,
2577 IWL_UCODE_WOWLAN);
2578 if (ret)
2579 goto error;
2580
2581 /* now configure WoWLAN ucode */
2582 ret = iwl_alive_start(priv);
2583 if (ret)
2584 goto error;
2585
2586 memcpy(&ctx->staging, &rxon, sizeof(rxon));
2587 ret = iwlagn_commit_rxon(priv, ctx);
2588 if (ret)
2589 goto error;
2590
2591 ret = iwl_power_update_mode(priv, true);
2592 if (ret)
2593 goto error;
2594
2595 if (!iwlagn_mod_params.sw_crypto) {
2596 /* mark all keys clear */
2597 priv->ucode_key_table = 0;
2598 ctx->key_mapping_keys = 0;
2599
2600 /*
2601 * This needs to be unlocked due to lock ordering
2602 * constraints. Since we're in the suspend path
2603 * that isn't really a problem though.
2604 */
2605 mutex_unlock(&priv->mutex);
2606 ieee80211_iter_keys(priv->hw, ctx->vif,
2607 iwlagn_wowlan_program_keys,
2608 &key_data);
2609 mutex_lock(&priv->mutex);
2610 if (key_data.error) {
2611 ret = -EIO;
2612 goto error;
2613 }
2614
2615 if (key_data.use_rsc_tsc) {
2616 struct iwl_host_cmd rsc_tsc_cmd = {
2617 .id = REPLY_WOWLAN_TSC_RSC_PARAMS,
2618 .flags = CMD_SYNC,
2619 .data[0] = key_data.rsc_tsc,
2620 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
2621 .len[0] = sizeof(*key_data.rsc_tsc),
2622 };
2623
2624 ret = trans_send_cmd(&priv->trans, &rsc_tsc_cmd);
2625 if (ret)
2626 goto error;
2627 }
2628
2629 if (key_data.use_tkip) {
2630 ret = trans_send_cmd_pdu(&priv->trans,
2631 REPLY_WOWLAN_TKIP_PARAMS,
2632 CMD_SYNC, sizeof(tkip_cmd),
2633 &tkip_cmd);
2634 if (ret)
2635 goto error;
2636 }
2637
2638 if (priv->have_rekey_data) {
2639 memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));
2640 memcpy(kek_kck_cmd.kck, priv->kck, NL80211_KCK_LEN);
2641 kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN);
2642 memcpy(kek_kck_cmd.kek, priv->kek, NL80211_KEK_LEN);
2643 kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN);
2644 kek_kck_cmd.replay_ctr = priv->replay_ctr;
2645
2646 ret = trans_send_cmd_pdu(&priv->trans,
2647 REPLY_WOWLAN_KEK_KCK_MATERIAL,
2648 CMD_SYNC, sizeof(kek_kck_cmd),
2649 &kek_kck_cmd);
2650 if (ret)
2651 goto error;
2652 }
2653 }
2654
2655 ret = trans_send_cmd_pdu(&priv->trans, REPLY_WOWLAN_WAKEUP_FILTER,
2656 CMD_SYNC, sizeof(wakeup_filter_cmd),
2657 &wakeup_filter_cmd);
2658 if (ret)
2659 goto error;
2660
2661 ret = iwlagn_send_patterns(priv, wowlan);
2662 if (ret)
2663 goto error;
2664
2665 device_set_wakeup_enable(priv->bus->dev, true);
2666
2667 /* Now let the ucode operate on its own */
2668 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
2669 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
2670
2671 goto out;
2672
2673 error:
2674 priv->wowlan = false;
2675 iwlagn_prepare_restart(priv);
2676 ieee80211_restart_hw(priv->hw);
2677 out:
2678 mutex_unlock(&priv->mutex);
2679 kfree(key_data.rsc_tsc);
2680 return ret;
2681}
2682
2683static int iwlagn_mac_resume(struct ieee80211_hw *hw)
2684{
2685 struct iwl_priv *priv = hw->priv;
2686 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2687 struct ieee80211_vif *vif;
2688 unsigned long flags;
2689 u32 base, status = 0xffffffff;
2690 int ret = -EIO;
2691
2692 mutex_lock(&priv->mutex);
2693
2694 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
2695 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
2696
2697 base = priv->device_pointers.error_event_table;
2698 if (iwlagn_hw_valid_rtc_data_addr(base)) {
2699 spin_lock_irqsave(&priv->reg_lock, flags);
2700 ret = iwl_grab_nic_access_silent(priv);
2701 if (ret == 0) {
2702 iwl_write32(priv, HBUS_TARG_MEM_RADDR, base);
2703 status = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
2704 iwl_release_nic_access(priv);
2705 }
2706 spin_unlock_irqrestore(&priv->reg_lock, flags);
2707
2708#ifdef CONFIG_IWLWIFI_DEBUGFS
2709 if (ret == 0) {
2710 if (!priv->wowlan_sram)
2711 priv->wowlan_sram =
2712 kzalloc(priv->ucode_wowlan.data.len,
2713 GFP_KERNEL);
2714
2715 if (priv->wowlan_sram)
2716 _iwl_read_targ_mem_words(
2717 priv, 0x800000, priv->wowlan_sram,
2718 priv->ucode_wowlan.data.len / 4);
2719 }
2720#endif
2721 }
2722
2723 /* we'll clear ctx->vif during iwlagn_prepare_restart() */
2724 vif = ctx->vif;
2725
2726 priv->wowlan = false;
2727
2728 device_set_wakeup_enable(priv->bus->dev, false);
2729
2730 iwlagn_prepare_restart(priv);
2731
2732 memset((void *)&ctx->active, 0, sizeof(ctx->active));
2733 iwl_connection_init_rx_config(priv, ctx);
2734 iwlagn_set_rxon_chain(priv, ctx);
2735
2736 mutex_unlock(&priv->mutex);
2737
2738 ieee80211_resume_disconnect(vif);
2739
2740 return 1;
2741}
2742
2240static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 2743static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2241{ 2744{
2242 struct iwl_priv *priv = hw->priv; 2745 struct iwl_priv *priv = hw->priv;
@@ -2926,6 +3429,9 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
2926 iwl_free_channel_map(priv); 3429 iwl_free_channel_map(priv);
2927 kfree(priv->scan_cmd); 3430 kfree(priv->scan_cmd);
2928 kfree(priv->beacon_cmd); 3431 kfree(priv->beacon_cmd);
3432#ifdef CONFIG_IWLWIFI_DEBUGFS
3433 kfree(priv->wowlan_sram);
3434#endif
2929} 3435}
2930 3436
2931static void iwl_mac_rssi_callback(struct ieee80211_hw *hw, 3437static void iwl_mac_rssi_callback(struct ieee80211_hw *hw,
@@ -2955,6 +3461,8 @@ struct ieee80211_ops iwlagn_hw_ops = {
2955 .tx = iwlagn_mac_tx, 3461 .tx = iwlagn_mac_tx,
2956 .start = iwlagn_mac_start, 3462 .start = iwlagn_mac_start,
2957 .stop = iwlagn_mac_stop, 3463 .stop = iwlagn_mac_stop,
3464 .suspend = iwlagn_mac_suspend,
3465 .resume = iwlagn_mac_resume,
2958 .add_interface = iwl_mac_add_interface, 3466 .add_interface = iwl_mac_add_interface,
2959 .remove_interface = iwl_mac_remove_interface, 3467 .remove_interface = iwl_mac_remove_interface,
2960 .change_interface = iwl_mac_change_interface, 3468 .change_interface = iwl_mac_change_interface,
@@ -2962,6 +3470,7 @@ struct ieee80211_ops iwlagn_hw_ops = {
2962 .configure_filter = iwlagn_configure_filter, 3470 .configure_filter = iwlagn_configure_filter,
2963 .set_key = iwlagn_mac_set_key, 3471 .set_key = iwlagn_mac_set_key,
2964 .update_tkip_key = iwlagn_mac_update_tkip_key, 3472 .update_tkip_key = iwlagn_mac_update_tkip_key,
3473 .set_rekey_data = iwlagn_mac_set_rekey_data,
2965 .conf_tx = iwl_mac_conf_tx, 3474 .conf_tx = iwl_mac_conf_tx,
2966 .bss_info_changed = iwlagn_bss_info_changed, 3475 .bss_info_changed = iwlagn_bss_info_changed,
2967 .ampdu_action = iwlagn_mac_ampdu_action, 3476 .ampdu_action = iwlagn_mac_ampdu_action,
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index b58985373a71..5769ca5cebca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -188,6 +188,13 @@ enum {
188 REPLY_WIPAN_NOA_NOTIFICATION = 0xbc, 188 REPLY_WIPAN_NOA_NOTIFICATION = 0xbc,
189 REPLY_WIPAN_DEACTIVATION_COMPLETE = 0xbd, 189 REPLY_WIPAN_DEACTIVATION_COMPLETE = 0xbd,
190 190
191 REPLY_WOWLAN_PATTERNS = 0xe0,
192 REPLY_WOWLAN_WAKEUP_FILTER = 0xe1,
193 REPLY_WOWLAN_TSC_RSC_PARAMS = 0xe2,
194 REPLY_WOWLAN_TKIP_PARAMS = 0xe3,
195 REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4,
196 REPLY_WOWLAN_GET_STATUS = 0xe5,
197
191 REPLY_MAX = 0xff 198 REPLY_MAX = 0xff
192}; 199};
193 200
@@ -3764,6 +3771,127 @@ struct iwl_bt_coex_prot_env_cmd {
3764 u8 reserved[2]; 3771 u8 reserved[2];
3765} __attribute__((packed)); 3772} __attribute__((packed));
3766 3773
3774/*
3775 * REPLY_WOWLAN_PATTERNS
3776 */
3777#define IWLAGN_WOWLAN_MIN_PATTERN_LEN 16
3778#define IWLAGN_WOWLAN_MAX_PATTERN_LEN 128
3779
3780struct iwlagn_wowlan_pattern {
3781 u8 mask[IWLAGN_WOWLAN_MAX_PATTERN_LEN / 8];
3782 u8 pattern[IWLAGN_WOWLAN_MAX_PATTERN_LEN];
3783 u8 mask_size;
3784 u8 pattern_size;
3785 __le16 reserved;
3786} __packed;
3787
3788#define IWLAGN_WOWLAN_MAX_PATTERNS 20
3789
3790struct iwlagn_wowlan_patterns_cmd {
3791 __le32 n_patterns;
3792 struct iwlagn_wowlan_pattern patterns[];
3793} __packed;
3794
3795/*
3796 * REPLY_WOWLAN_WAKEUP_FILTER
3797 */
3798enum iwlagn_wowlan_wakeup_filters {
3799 IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET = BIT(0),
3800 IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH = BIT(1),
3801 IWLAGN_WOWLAN_WAKEUP_BEACON_MISS = BIT(2),
3802 IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3),
3803 IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4),
3804 IWLAGN_WOWLAN_WAKEUP_RFKILL = BIT(5),
3805 IWLAGN_WOWLAN_WAKEUP_UCODE_ERROR = BIT(6),
3806 IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(7),
3807 IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(8),
3808 IWLAGN_WOWLAN_WAKEUP_ALWAYS = BIT(9),
3809 IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(10),
3810};
3811
3812struct iwlagn_wowlan_wakeup_filter_cmd {
3813 __le32 enabled;
3814 __le16 non_qos_seq;
3815 u8 min_sleep_seconds;
3816 u8 reserved;
3817 __le16 qos_seq[8];
3818};
3819
3820/*
3821 * REPLY_WOWLAN_TSC_RSC_PARAMS
3822 */
3823#define IWLAGN_NUM_RSC 16
3824
3825struct tkip_sc {
3826 __le16 iv16;
3827 __le16 pad;
3828 __le32 iv32;
3829} __packed;
3830
3831struct iwlagn_tkip_rsc_tsc {
3832 struct tkip_sc unicast_rsc[IWLAGN_NUM_RSC];
3833 struct tkip_sc multicast_rsc[IWLAGN_NUM_RSC];
3834 struct tkip_sc tsc;
3835} __packed;
3836
3837struct aes_sc {
3838 __le64 pn;
3839} __packed;
3840
3841struct iwlagn_aes_rsc_tsc {
3842 struct aes_sc unicast_rsc[IWLAGN_NUM_RSC];
3843 struct aes_sc multicast_rsc[IWLAGN_NUM_RSC];
3844 struct aes_sc tsc;
3845} __packed;
3846
3847union iwlagn_all_tsc_rsc {
3848 struct iwlagn_tkip_rsc_tsc tkip;
3849 struct iwlagn_aes_rsc_tsc aes;
3850};
3851
3852struct iwlagn_wowlan_rsc_tsc_params_cmd {
3853 union iwlagn_all_tsc_rsc all_tsc_rsc;
3854} __packed;
3855
3856/*
3857 * REPLY_WOWLAN_TKIP_PARAMS
3858 */
3859#define IWLAGN_MIC_KEY_SIZE 8
3860#define IWLAGN_P1K_SIZE 5
3861struct iwlagn_mic_keys {
3862 u8 tx[IWLAGN_MIC_KEY_SIZE];
3863 u8 rx_unicast[IWLAGN_MIC_KEY_SIZE];
3864 u8 rx_mcast[IWLAGN_MIC_KEY_SIZE];
3865} __packed;
3866
3867struct iwlagn_p1k_cache {
3868 __le16 p1k[IWLAGN_P1K_SIZE];
3869} __packed;
3870
3871#define IWLAGN_NUM_RX_P1K_CACHE 2
3872
3873struct iwlagn_wowlan_tkip_params_cmd {
3874 struct iwlagn_mic_keys mic_keys;
3875 struct iwlagn_p1k_cache tx;
3876 struct iwlagn_p1k_cache rx_uni[IWLAGN_NUM_RX_P1K_CACHE];
3877 struct iwlagn_p1k_cache rx_multi[IWLAGN_NUM_RX_P1K_CACHE];
3878} __packed;
3879
3880/*
3881 * REPLY_WOWLAN_KEK_KCK_MATERIAL
3882 */
3883
3884#define IWLAGN_KCK_MAX_SIZE 32
3885#define IWLAGN_KEK_MAX_SIZE 32
3886
3887struct iwlagn_wowlan_kek_kck_material_cmd {
3888 u8 kck[IWLAGN_KCK_MAX_SIZE];
3889 u8 kek[IWLAGN_KEK_MAX_SIZE];
3890 __le16 kck_len;
3891 __le16 kek_len;
3892 __le64 replay_ctr;
3893} __packed;
3894
3767/****************************************************************************** 3895/******************************************************************************
3768 * (13) 3896 * (13)
3769 * Union of all expected notifications/responses: 3897 * Union of all expected notifications/responses:
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 9b9f462ea0ff..2f42547622d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1903,8 +1903,12 @@ int iwl_suspend(struct iwl_priv *priv)
1903 * first but since iwl_mac_stop() has no knowledge of who the caller is, 1903 * first but since iwl_mac_stop() has no knowledge of who the caller is,
1904 * it will not call apm_ops.stop() to stop the DMA operation. 1904 * it will not call apm_ops.stop() to stop the DMA operation.
1905 * Calling apm_ops.stop here to make sure we stop the DMA. 1905 * Calling apm_ops.stop here to make sure we stop the DMA.
1906 *
1907 * But of course ... if we have configured WoWLAN then we did other
1908 * things already :-)
1906 */ 1909 */
1907 iwl_apm_stop(priv); 1910 if (!priv->wowlan)
1911 iwl_apm_stop(priv);
1908 1912
1909 return 0; 1913 return 0;
1910} 1914}
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 5ab90ba7a024..d6dbb0423045 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -351,6 +351,7 @@
351#define CSR_UCODE_SW_BIT_RFKILL (0x00000002) 351#define CSR_UCODE_SW_BIT_RFKILL (0x00000002)
352#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004) 352#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004)
353#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008) 353#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008)
354#define CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE (0x00000020)
354 355
355/* GP Driver */ 356/* GP Driver */
356#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_MSK (0x00000003) 357#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_MSK (0x00000003)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 17aebf08dff8..ec1485b2d3fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -322,6 +322,19 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
322 return count; 322 return count;
323} 323}
324 324
325static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
326 char __user *user_buf,
327 size_t count, loff_t *ppos)
328{
329 struct iwl_priv *priv = file->private_data;
330
331 if (!priv->wowlan_sram)
332 return -ENODATA;
333
334 return simple_read_from_buffer(user_buf, count, ppos,
335 priv->wowlan_sram,
336 priv->ucode_wowlan.data.len);
337}
325static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 338static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
326 size_t count, loff_t *ppos) 339 size_t count, loff_t *ppos)
327{ 340{
@@ -856,6 +869,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
856} 869}
857 870
858DEBUGFS_READ_WRITE_FILE_OPS(sram); 871DEBUGFS_READ_WRITE_FILE_OPS(sram);
872DEBUGFS_READ_FILE_OPS(wowlan_sram);
859DEBUGFS_READ_WRITE_FILE_OPS(log_event); 873DEBUGFS_READ_WRITE_FILE_OPS(log_event);
860DEBUGFS_READ_FILE_OPS(nvm); 874DEBUGFS_READ_FILE_OPS(nvm);
861DEBUGFS_READ_FILE_OPS(stations); 875DEBUGFS_READ_FILE_OPS(stations);
@@ -2667,6 +2681,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2667 2681
2668 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); 2682 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
2669 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); 2683 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
2684 DEBUGFS_ADD_FILE(wowlan_sram, dir_data, S_IRUSR);
2670 DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR); 2685 DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
2671 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); 2686 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
2672 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); 2687 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index c27380440b66..fc2387342456 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -551,7 +551,8 @@ enum iwl_ucode_tlv_type {
551 IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, 551 IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
552 IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, 552 IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14,
553 IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, 553 IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
554 /* 16 and 17 reserved for future use */ 554 IWL_UCODE_TLV_WOWLAN_INST = 16,
555 IWL_UCODE_TLV_WOWLAN_DATA = 17,
555 IWL_UCODE_TLV_FLAGS = 18, 556 IWL_UCODE_TLV_FLAGS = 18,
556}; 557};
557 558
@@ -1284,6 +1285,7 @@ struct iwl_priv {
1284 1285
1285 struct fw_img ucode_rt; 1286 struct fw_img ucode_rt;
1286 struct fw_img ucode_init; 1287 struct fw_img ucode_init;
1288 struct fw_img ucode_wowlan;
1287 1289
1288 enum iwlagn_ucode_type ucode_type; 1290 enum iwlagn_ucode_type ucode_type;
1289 u8 ucode_write_complete; /* the image write is complete */ 1291 u8 ucode_write_complete; /* the image write is complete */
@@ -1356,6 +1358,8 @@ struct iwl_priv {
1356 1358
1357 u8 mac80211_registered; 1359 u8 mac80211_registered;
1358 1360
1361 bool wowlan;
1362
1359 /* eeprom -- this is in the card's little endian byte order */ 1363 /* eeprom -- this is in the card's little endian byte order */
1360 u8 *eeprom; 1364 u8 *eeprom;
1361 int nvm_device_type; 1365 int nvm_device_type;
@@ -1508,6 +1512,7 @@ struct iwl_priv {
1508 struct dentry *debugfs_dir; 1512 struct dentry *debugfs_dir;
1509 u32 dbgfs_sram_offset, dbgfs_sram_len; 1513 u32 dbgfs_sram_offset, dbgfs_sram_len;
1510 bool disable_ht40; 1514 bool disable_ht40;
1515 void *wowlan_sram;
1511#endif /* CONFIG_IWLWIFI_DEBUGFS */ 1516#endif /* CONFIG_IWLWIFI_DEBUGFS */
1512 1517
1513 struct work_struct txpower_work; 1518 struct work_struct txpower_work;
@@ -1528,6 +1533,11 @@ struct iwl_priv {
1528 u32 tm_fixed_rate; 1533 u32 tm_fixed_rate;
1529#endif 1534#endif
1530 1535
1536 /* WoWLAN GTK rekey data */
1537 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
1538 __le64 replay_ctr;
1539 __le16 last_seq_ctl;
1540 bool have_rekey_data;
1531}; /*iwl_priv */ 1541}; /*iwl_priv */
1532 1542
1533static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) 1543static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index de4f33304edb..3ec619c6881c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -347,7 +347,9 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
347 347
348 dtimper = priv->hw->conf.ps_dtim_period ?: 1; 348 dtimper = priv->hw->conf.ps_dtim_period ?: 1;
349 349
350 if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) 350 if (priv->wowlan)
351 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper);
352 else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE)
351 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); 353 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
352 else if (iwl_tt_is_low_power_state(priv)) { 354 else if (iwl_tt_is_low_power_state(priv)) {
353 /* in thermal throttling low power state */ 355 /* in thermal throttling low power state */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
index 27f78fed2ec2..a6b2b1db0b1d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
@@ -866,6 +866,12 @@ const char *get_cmd_string(u8 cmd)
866 IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); 866 IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH);
867 IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); 867 IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION);
868 IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE); 868 IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE);
869 IWL_CMD(REPLY_WOWLAN_PATTERNS);
870 IWL_CMD(REPLY_WOWLAN_WAKEUP_FILTER);
871 IWL_CMD(REPLY_WOWLAN_TSC_RSC_PARAMS);
872 IWL_CMD(REPLY_WOWLAN_TKIP_PARAMS);
873 IWL_CMD(REPLY_WOWLAN_KEK_KCK_MATERIAL);
874 IWL_CMD(REPLY_WOWLAN_GET_STATUS);
869 default: 875 default:
870 return "UNKNOWN"; 876 return "UNKNOWN";
871 877