diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/commands.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/debugfs.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/led.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/mac80211.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/main.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tt.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tx.c | 51 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/ucode.c | 96 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-csr.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fh.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-io.c | 168 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-io.h | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-test.c | 53 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.h | 99 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/internal.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/rx.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/trans.c | 309 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c | 79 |
18 files changed, 519 insertions, 446 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 71ab76b2b39d..0ca99c13f7f2 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h | |||
@@ -3695,7 +3695,7 @@ struct iwl_bt_uart_msg { | |||
3695 | u8 frame5; | 3695 | u8 frame5; |
3696 | u8 frame6; | 3696 | u8 frame6; |
3697 | u8 frame7; | 3697 | u8 frame7; |
3698 | } __attribute__((packed)); | 3698 | } __packed; |
3699 | 3699 | ||
3700 | struct iwl_bt_coex_profile_notif { | 3700 | struct iwl_bt_coex_profile_notif { |
3701 | struct iwl_bt_uart_msg last_bt_uart_msg; | 3701 | struct iwl_bt_uart_msg last_bt_uart_msg; |
@@ -3703,7 +3703,7 @@ struct iwl_bt_coex_profile_notif { | |||
3703 | u8 bt_traffic_load; /* 0 .. 3? */ | 3703 | u8 bt_traffic_load; /* 0 .. 3? */ |
3704 | u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ | 3704 | u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ |
3705 | u8 reserved; | 3705 | u8 reserved; |
3706 | } __attribute__((packed)); | 3706 | } __packed; |
3707 | 3707 | ||
3708 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0 | 3708 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0 |
3709 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1 | 3709 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1 |
@@ -3752,7 +3752,7 @@ enum bt_coex_prio_table_priorities { | |||
3752 | 3752 | ||
3753 | struct iwl_bt_coex_prio_table_cmd { | 3753 | struct iwl_bt_coex_prio_table_cmd { |
3754 | u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; | 3754 | u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; |
3755 | } __attribute__((packed)); | 3755 | } __packed; |
3756 | 3756 | ||
3757 | #define IWL_BT_COEX_ENV_CLOSE 0 | 3757 | #define IWL_BT_COEX_ENV_CLOSE 0 |
3758 | #define IWL_BT_COEX_ENV_OPEN 1 | 3758 | #define IWL_BT_COEX_ENV_OPEN 1 |
@@ -3764,7 +3764,7 @@ struct iwl_bt_coex_prot_env_cmd { | |||
3764 | u8 action; /* 0 = closed, 1 = open */ | 3764 | u8 action; /* 0 = closed, 1 = open */ |
3765 | u8 type; /* 0 .. 15 */ | 3765 | u8 type; /* 0 .. 15 */ |
3766 | u8 reserved[2]; | 3766 | u8 reserved[2]; |
3767 | } __attribute__((packed)); | 3767 | } __packed; |
3768 | 3768 | ||
3769 | /* | 3769 | /* |
3770 | * REPLY_D3_CONFIG | 3770 | * REPLY_D3_CONFIG |
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 5b9533eef54d..72c74af38138 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
@@ -157,7 +157,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
157 | sram = priv->dbgfs_sram_offset & ~0x3; | 157 | sram = priv->dbgfs_sram_offset & ~0x3; |
158 | 158 | ||
159 | /* read the first u32 from sram */ | 159 | /* read the first u32 from sram */ |
160 | val = iwl_read_targ_mem(priv->trans, sram); | 160 | val = iwl_trans_read_mem32(priv->trans, sram); |
161 | 161 | ||
162 | for (; len; len--) { | 162 | for (; len; len--) { |
163 | /* put the address at the start of every line */ | 163 | /* put the address at the start of every line */ |
@@ -176,7 +176,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
176 | if (++offset == 4) { | 176 | if (++offset == 4) { |
177 | sram += 4; | 177 | sram += 4; |
178 | offset = 0; | 178 | offset = 0; |
179 | val = iwl_read_targ_mem(priv->trans, sram); | 179 | val = iwl_trans_read_mem32(priv->trans, sram); |
180 | } | 180 | } |
181 | 181 | ||
182 | /* put in extra spaces and split lines for human readability */ | 182 | /* put in extra spaces and split lines for human readability */ |
diff --git a/drivers/net/wireless/iwlwifi/dvm/led.c b/drivers/net/wireless/iwlwifi/dvm/led.c index bf479f709091..844a17f99a18 100644 --- a/drivers/net/wireless/iwlwifi/dvm/led.c +++ b/drivers/net/wireless/iwlwifi/dvm/led.c | |||
@@ -69,7 +69,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { | |||
69 | /* Set led register off */ | 69 | /* Set led register off */ |
70 | void iwlagn_led_enable(struct iwl_priv *priv) | 70 | void iwlagn_led_enable(struct iwl_priv *priv) |
71 | { | 71 | { |
72 | iwl_write32(priv->trans, CSR_LED_REG, CSR_LED_REG_TRUN_ON); | 72 | iwl_write32(priv->trans, CSR_LED_REG, CSR_LED_REG_TURN_ON); |
73 | } | 73 | } |
74 | 74 | ||
75 | /* | 75 | /* |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 3163e0f38c25..0353e1c0670d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -206,7 +206,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
206 | 206 | ||
207 | #ifdef CONFIG_PM_SLEEP | 207 | #ifdef CONFIG_PM_SLEEP |
208 | if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && | 208 | if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && |
209 | priv->trans->ops->wowlan_suspend && | 209 | priv->trans->ops->d3_suspend && |
210 | priv->trans->ops->d3_resume && | ||
210 | device_can_wakeup(priv->trans->dev)) { | 211 | device_can_wakeup(priv->trans->dev)) { |
211 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | 212 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | |
212 | WIPHY_WOWLAN_DISCONNECT | | 213 | WIPHY_WOWLAN_DISCONNECT | |
@@ -426,7 +427,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | |||
426 | if (ret) | 427 | if (ret) |
427 | goto error; | 428 | goto error; |
428 | 429 | ||
429 | iwl_trans_wowlan_suspend(priv->trans); | 430 | iwl_trans_d3_suspend(priv->trans); |
430 | 431 | ||
431 | goto out; | 432 | goto out; |
432 | 433 | ||
@@ -459,11 +460,11 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
459 | base = priv->device_pointers.error_event_table; | 460 | base = priv->device_pointers.error_event_table; |
460 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 461 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
461 | spin_lock_irqsave(&priv->trans->reg_lock, flags); | 462 | spin_lock_irqsave(&priv->trans->reg_lock, flags); |
462 | ret = iwl_grab_nic_access_silent(priv->trans); | 463 | if (iwl_trans_grab_nic_access(priv->trans, true)) { |
463 | if (likely(ret == 0)) { | ||
464 | iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base); | 464 | iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base); |
465 | status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); | 465 | status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); |
466 | iwl_release_nic_access(priv->trans); | 466 | iwl_trans_release_nic_access(priv->trans); |
467 | ret = 0; | ||
467 | } | 468 | } |
468 | spin_unlock_irqrestore(&priv->trans->reg_lock, flags); | 469 | spin_unlock_irqrestore(&priv->trans->reg_lock, flags); |
469 | 470 | ||
@@ -479,7 +480,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
479 | } | 480 | } |
480 | 481 | ||
481 | if (priv->wowlan_sram) | 482 | if (priv->wowlan_sram) |
482 | _iwl_read_targ_mem_dwords( | 483 | iwl_trans_read_mem( |
483 | priv->trans, 0x800000, | 484 | priv->trans, 0x800000, |
484 | priv->wowlan_sram, | 485 | priv->wowlan_sram, |
485 | img->sec[IWL_UCODE_SECTION_DATA].len / 4); | 486 | img->sec[IWL_UCODE_SECTION_DATA].len / 4); |
@@ -520,9 +521,6 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, | |||
520 | { | 521 | { |
521 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 522 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
522 | 523 | ||
523 | IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | ||
524 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | ||
525 | |||
526 | if (iwlagn_tx_skb(priv, control->sta, skb)) | 524 | if (iwlagn_tx_skb(priv, control->sta, skb)) |
527 | ieee80211_free_txskb(hw, skb); | 525 | ieee80211_free_txskb(hw, skb); |
528 | } | 526 | } |
@@ -679,7 +677,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
679 | IWL_DEBUG_HT(priv, "start Tx\n"); | 677 | IWL_DEBUG_HT(priv, "start Tx\n"); |
680 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | 678 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); |
681 | break; | 679 | break; |
682 | case IEEE80211_AMPDU_TX_STOP: | 680 | case IEEE80211_AMPDU_TX_STOP_CONT: |
681 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
682 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
683 | IWL_DEBUG_HT(priv, "stop Tx\n"); | 683 | IWL_DEBUG_HT(priv, "stop Tx\n"); |
684 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); | 684 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); |
685 | if ((ret == 0) && (priv->agg_tids_count > 0)) { | 685 | if ((ret == 0) && (priv->agg_tids_count > 0)) { |
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index faa05932efae..a64f361e341c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -354,7 +354,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
354 | 354 | ||
355 | /* Make sure device is powered up for SRAM reads */ | 355 | /* Make sure device is powered up for SRAM reads */ |
356 | spin_lock_irqsave(&priv->trans->reg_lock, reg_flags); | 356 | spin_lock_irqsave(&priv->trans->reg_lock, reg_flags); |
357 | if (unlikely(!iwl_grab_nic_access(priv->trans))) { | 357 | if (!iwl_trans_grab_nic_access(priv->trans, false)) { |
358 | spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); | 358 | spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); |
359 | return; | 359 | return; |
360 | } | 360 | } |
@@ -388,7 +388,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
388 | } | 388 | } |
389 | } | 389 | } |
390 | /* Allow device to power down */ | 390 | /* Allow device to power down */ |
391 | iwl_release_nic_access(priv->trans); | 391 | iwl_trans_release_nic_access(priv->trans); |
392 | spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); | 392 | spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); |
393 | } | 393 | } |
394 | 394 | ||
@@ -408,7 +408,8 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) | |||
408 | 408 | ||
409 | base = priv->device_pointers.log_event_table; | 409 | base = priv->device_pointers.log_event_table; |
410 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 410 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
411 | iwl_read_targ_mem_bytes(priv->trans, base, &read, sizeof(read)); | 411 | iwl_trans_read_mem_bytes(priv->trans, base, |
412 | &read, sizeof(read)); | ||
412 | capacity = read.capacity; | 413 | capacity = read.capacity; |
413 | mode = read.mode; | 414 | mode = read.mode; |
414 | num_wraps = read.wrap_counter; | 415 | num_wraps = read.wrap_counter; |
@@ -1627,7 +1628,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1627 | } | 1628 | } |
1628 | 1629 | ||
1629 | /*TODO: Update dbgfs with ISR error stats obtained below */ | 1630 | /*TODO: Update dbgfs with ISR error stats obtained below */ |
1630 | iwl_read_targ_mem_bytes(trans, base, &table, sizeof(table)); | 1631 | iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); |
1631 | 1632 | ||
1632 | if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { | 1633 | if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { |
1633 | IWL_ERR(trans, "Start IWL Error Log Dump:\n"); | 1634 | IWL_ERR(trans, "Start IWL Error Log Dump:\n"); |
@@ -1717,7 +1718,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1717 | 1718 | ||
1718 | /* Make sure device is powered up for SRAM reads */ | 1719 | /* Make sure device is powered up for SRAM reads */ |
1719 | spin_lock_irqsave(&trans->reg_lock, reg_flags); | 1720 | spin_lock_irqsave(&trans->reg_lock, reg_flags); |
1720 | if (unlikely(!iwl_grab_nic_access(trans))) | 1721 | if (!iwl_trans_grab_nic_access(trans, false)) |
1721 | goto out_unlock; | 1722 | goto out_unlock; |
1722 | 1723 | ||
1723 | /* Set starting address; reads will auto-increment */ | 1724 | /* Set starting address; reads will auto-increment */ |
@@ -1756,7 +1757,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1756 | } | 1757 | } |
1757 | 1758 | ||
1758 | /* Allow device to power down */ | 1759 | /* Allow device to power down */ |
1759 | iwl_release_nic_access(trans); | 1760 | iwl_trans_release_nic_access(trans); |
1760 | out_unlock: | 1761 | out_unlock: |
1761 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); | 1762 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); |
1762 | return pos; | 1763 | return pos; |
@@ -1835,10 +1836,10 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
1835 | } | 1836 | } |
1836 | 1837 | ||
1837 | /* event log header */ | 1838 | /* event log header */ |
1838 | capacity = iwl_read_targ_mem(trans, base); | 1839 | capacity = iwl_trans_read_mem32(trans, base); |
1839 | mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32))); | 1840 | mode = iwl_trans_read_mem32(trans, base + (1 * sizeof(u32))); |
1840 | num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32))); | 1841 | num_wraps = iwl_trans_read_mem32(trans, base + (2 * sizeof(u32))); |
1841 | next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32))); | 1842 | next_entry = iwl_trans_read_mem32(trans, base + (3 * sizeof(u32))); |
1842 | 1843 | ||
1843 | if (capacity > logsize) { | 1844 | if (capacity > logsize) { |
1844 | IWL_ERR(priv, "Log capacity %d is bogus, limit to %d " | 1845 | IWL_ERR(priv, "Log capacity %d is bogus, limit to %d " |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c index eb864433e59d..b28cfc8553d7 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tt.c +++ b/drivers/net/wireless/iwlwifi/dvm/tt.c | |||
@@ -186,8 +186,8 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) | |||
186 | } | 186 | } |
187 | iwl_read32(priv->trans, CSR_UCODE_DRV_GP1); | 187 | iwl_read32(priv->trans, CSR_UCODE_DRV_GP1); |
188 | spin_lock_irqsave(&priv->trans->reg_lock, flags); | 188 | spin_lock_irqsave(&priv->trans->reg_lock, flags); |
189 | if (likely(iwl_grab_nic_access(priv->trans))) | 189 | if (iwl_trans_grab_nic_access(priv->trans, false)) |
190 | iwl_release_nic_access(priv->trans); | 190 | iwl_trans_release_nic_access(priv->trans); |
191 | spin_unlock_irqrestore(&priv->trans->reg_lock, flags); | 191 | spin_unlock_irqrestore(&priv->trans->reg_lock, flags); |
192 | 192 | ||
193 | /* Reschedule the ct_kill timer to occur in | 193 | /* Reschedule the ct_kill timer to occur in |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index a790599fe2c2..6b01fc195940 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -231,13 +231,11 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | |||
231 | memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); | 231 | memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); |
232 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 232 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
233 | tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; | 233 | tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; |
234 | IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); | ||
235 | break; | 234 | break; |
236 | 235 | ||
237 | case WLAN_CIPHER_SUITE_TKIP: | 236 | case WLAN_CIPHER_SUITE_TKIP: |
238 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; | 237 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; |
239 | ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); | 238 | ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); |
240 | IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); | ||
241 | break; | 239 | break; |
242 | 240 | ||
243 | case WLAN_CIPHER_SUITE_WEP104: | 241 | case WLAN_CIPHER_SUITE_WEP104: |
@@ -355,8 +353,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, | |||
355 | } | 353 | } |
356 | } | 354 | } |
357 | 355 | ||
358 | IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); | ||
359 | |||
360 | if (sta) | 356 | if (sta) |
361 | sta_priv = (void *)sta->drv_priv; | 357 | sta_priv = (void *)sta->drv_priv; |
362 | 358 | ||
@@ -472,6 +468,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, | |||
472 | WARN_ON_ONCE(is_agg && | 468 | WARN_ON_ONCE(is_agg && |
473 | priv->queue_to_mac80211[txq_id] != info->hw_queue); | 469 | priv->queue_to_mac80211[txq_id] != info->hw_queue); |
474 | 470 | ||
471 | IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d - seq: 0x%x\n", sta_id, tid, | ||
472 | txq_id, seq_number); | ||
473 | |||
475 | if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id)) | 474 | if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id)) |
476 | goto drop_unlock_sta; | 475 | goto drop_unlock_sta; |
477 | 476 | ||
@@ -541,9 +540,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
541 | spin_lock_bh(&priv->sta_lock); | 540 | spin_lock_bh(&priv->sta_lock); |
542 | 541 | ||
543 | tid_data = &priv->tid_data[sta_id][tid]; | 542 | tid_data = &priv->tid_data[sta_id][tid]; |
544 | txq_id = priv->tid_data[sta_id][tid].agg.txq_id; | 543 | txq_id = tid_data->agg.txq_id; |
545 | 544 | ||
546 | switch (priv->tid_data[sta_id][tid].agg.state) { | 545 | switch (tid_data->agg.state) { |
547 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | 546 | case IWL_EMPTYING_HW_QUEUE_ADDBA: |
548 | /* | 547 | /* |
549 | * This can happen if the peer stops aggregation | 548 | * This can happen if the peer stops aggregation |
@@ -563,9 +562,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
563 | case IWL_AGG_ON: | 562 | case IWL_AGG_ON: |
564 | break; | 563 | break; |
565 | default: | 564 | default: |
566 | IWL_WARN(priv, "Stopping AGG while state not ON " | 565 | IWL_WARN(priv, |
567 | "or starting for %d on %d (%d)\n", sta_id, tid, | 566 | "Stopping AGG while state not ON or starting for %d on %d (%d)\n", |
568 | priv->tid_data[sta_id][tid].agg.state); | 567 | sta_id, tid, tid_data->agg.state); |
569 | spin_unlock_bh(&priv->sta_lock); | 568 | spin_unlock_bh(&priv->sta_lock); |
570 | return 0; | 569 | return 0; |
571 | } | 570 | } |
@@ -578,12 +577,11 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
578 | "stopping AGG on STA/TID %d/%d but hwq %d not used\n", | 577 | "stopping AGG on STA/TID %d/%d but hwq %d not used\n", |
579 | sta_id, tid, txq_id); | 578 | sta_id, tid, txq_id); |
580 | } else if (tid_data->agg.ssn != tid_data->next_reclaimed) { | 579 | } else if (tid_data->agg.ssn != tid_data->next_reclaimed) { |
581 | IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, " | 580 | IWL_DEBUG_TX_QUEUES(priv, |
582 | "next_recl = %d\n", | 581 | "Can't proceed: ssn %d, next_recl = %d\n", |
583 | tid_data->agg.ssn, | 582 | tid_data->agg.ssn, |
584 | tid_data->next_reclaimed); | 583 | tid_data->next_reclaimed); |
585 | priv->tid_data[sta_id][tid].agg.state = | 584 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_DELBA; |
586 | IWL_EMPTYING_HW_QUEUE_DELBA; | ||
587 | spin_unlock_bh(&priv->sta_lock); | 585 | spin_unlock_bh(&priv->sta_lock); |
588 | return 0; | 586 | return 0; |
589 | } | 587 | } |
@@ -591,8 +589,8 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
591 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", | 589 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", |
592 | tid_data->agg.ssn); | 590 | tid_data->agg.ssn); |
593 | turn_off: | 591 | turn_off: |
594 | agg_state = priv->tid_data[sta_id][tid].agg.state; | 592 | agg_state = tid_data->agg.state; |
595 | priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; | 593 | tid_data->agg.state = IWL_AGG_OFF; |
596 | 594 | ||
597 | spin_unlock_bh(&priv->sta_lock); | 595 | spin_unlock_bh(&priv->sta_lock); |
598 | 596 | ||
@@ -954,12 +952,6 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, | |||
954 | if (status & (AGG_TX_STATE_FEW_BYTES_MSK | | 952 | if (status & (AGG_TX_STATE_FEW_BYTES_MSK | |
955 | AGG_TX_STATE_ABORT_MSK)) | 953 | AGG_TX_STATE_ABORT_MSK)) |
956 | continue; | 954 | continue; |
957 | |||
958 | IWL_DEBUG_TX_REPLY(priv, "status %s (0x%08x), " | ||
959 | "try-count (0x%08x)\n", | ||
960 | iwl_get_agg_tx_fail_reason(fstatus), | ||
961 | fstatus & AGG_TX_STATUS_MSK, | ||
962 | fstatus & AGG_TX_TRY_MSK); | ||
963 | } | 955 | } |
964 | } | 956 | } |
965 | 957 | ||
@@ -1079,6 +1071,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, | |||
1079 | { | 1071 | { |
1080 | u16 status = le16_to_cpu(tx_resp->status.status); | 1072 | u16 status = le16_to_cpu(tx_resp->status.status); |
1081 | 1073 | ||
1074 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
1075 | |||
1082 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 1076 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1083 | info->flags |= iwl_tx_status_to_mac80211(status); | 1077 | info->flags |= iwl_tx_status_to_mac80211(status); |
1084 | iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), | 1078 | iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), |
@@ -1223,16 +1217,27 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1223 | next_reclaimed); | 1217 | next_reclaimed); |
1224 | } | 1218 | } |
1225 | 1219 | ||
1226 | WARN_ON(!is_agg && freed != 1); | 1220 | if (!is_agg && freed != 1) |
1221 | IWL_ERR(priv, "Q: %d, freed %d\n", txq_id, freed); | ||
1227 | 1222 | ||
1228 | /* | 1223 | /* |
1229 | * An offchannel frame can be send only on the AUX queue, where | 1224 | * An offchannel frame can be send only on the AUX queue, where |
1230 | * there is no aggregation (and reordering) so it only is single | 1225 | * there is no aggregation (and reordering) so it only is single |
1231 | * skb is expected to be processed. | 1226 | * skb is expected to be processed. |
1232 | */ | 1227 | */ |
1233 | WARN_ON(is_offchannel_skb && freed != 1); | 1228 | if (is_offchannel_skb && freed != 1) |
1229 | IWL_ERR(priv, "OFFCHANNEL SKB freed %d\n", freed); | ||
1234 | } | 1230 | } |
1235 | 1231 | ||
1232 | IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id, | ||
1233 | iwl_get_tx_fail_reason(status), status); | ||
1234 | |||
1235 | IWL_DEBUG_TX_REPLY(priv, | ||
1236 | "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x\n", | ||
1237 | le32_to_cpu(tx_resp->rate_n_flags), | ||
1238 | tx_resp->failure_frame, SEQ_TO_INDEX(sequence), ssn, | ||
1239 | le16_to_cpu(tx_resp->seq_ctl)); | ||
1240 | |||
1236 | iwl_check_abort_status(priv, tx_resp->frame_count, status); | 1241 | iwl_check_abort_status(priv, tx_resp->frame_count, status); |
1237 | spin_unlock(&priv->sta_lock); | 1242 | spin_unlock(&priv->sta_lock); |
1238 | 1243 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index c6467e5554f5..ebec13a3329f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c | |||
@@ -286,89 +286,6 @@ static int iwl_alive_notify(struct iwl_priv *priv) | |||
286 | return iwl_send_calib_results(priv); | 286 | return iwl_send_calib_results(priv); |
287 | } | 287 | } |
288 | 288 | ||
289 | |||
290 | /** | ||
291 | * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host, | ||
292 | * using sample data 100 bytes apart. If these sample points are good, | ||
293 | * it's a pretty good bet that everything between them is good, too. | ||
294 | */ | ||
295 | static int iwl_verify_sec_sparse(struct iwl_priv *priv, | ||
296 | const struct fw_desc *fw_desc) | ||
297 | { | ||
298 | __le32 *image = (__le32 *)fw_desc->data; | ||
299 | u32 len = fw_desc->len; | ||
300 | u32 val; | ||
301 | u32 i; | ||
302 | |||
303 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); | ||
304 | |||
305 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | ||
306 | /* read data comes through single port, auto-incr addr */ | ||
307 | /* NOTE: Use the debugless read so we don't flood kernel log | ||
308 | * if IWL_DL_IO is set */ | ||
309 | iwl_write_direct32(priv->trans, HBUS_TARG_MEM_RADDR, | ||
310 | i + fw_desc->offset); | ||
311 | val = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); | ||
312 | if (val != le32_to_cpu(*image)) | ||
313 | return -EIO; | ||
314 | } | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static void iwl_print_mismatch_sec(struct iwl_priv *priv, | ||
320 | const struct fw_desc *fw_desc) | ||
321 | { | ||
322 | __le32 *image = (__le32 *)fw_desc->data; | ||
323 | u32 len = fw_desc->len; | ||
324 | u32 val; | ||
325 | u32 offs; | ||
326 | int errors = 0; | ||
327 | |||
328 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); | ||
329 | |||
330 | iwl_write_direct32(priv->trans, HBUS_TARG_MEM_RADDR, | ||
331 | fw_desc->offset); | ||
332 | |||
333 | for (offs = 0; | ||
334 | offs < len && errors < 20; | ||
335 | offs += sizeof(u32), image++) { | ||
336 | /* read data comes through single port, auto-incr addr */ | ||
337 | val = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); | ||
338 | if (val != le32_to_cpu(*image)) { | ||
339 | IWL_ERR(priv, "uCode INST section at " | ||
340 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | ||
341 | offs, val, le32_to_cpu(*image)); | ||
342 | errors++; | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | |||
347 | /** | ||
348 | * iwl_verify_ucode - determine which instruction image is in SRAM, | ||
349 | * and verify its contents | ||
350 | */ | ||
351 | static int iwl_verify_ucode(struct iwl_priv *priv, | ||
352 | enum iwl_ucode_type ucode_type) | ||
353 | { | ||
354 | const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); | ||
355 | |||
356 | if (!img) { | ||
357 | IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type); | ||
358 | return -EINVAL; | ||
359 | } | ||
360 | |||
361 | if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) { | ||
362 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | ||
367 | |||
368 | iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]); | ||
369 | return -EIO; | ||
370 | } | ||
371 | |||
372 | struct iwl_alive_data { | 289 | struct iwl_alive_data { |
373 | bool valid; | 290 | bool valid; |
374 | u8 subtype; | 291 | u8 subtype; |
@@ -426,7 +343,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, | |||
426 | alive_cmd, ARRAY_SIZE(alive_cmd), | 343 | alive_cmd, ARRAY_SIZE(alive_cmd), |
427 | iwl_alive_fn, &alive_data); | 344 | iwl_alive_fn, &alive_data); |
428 | 345 | ||
429 | ret = iwl_trans_start_fw(priv->trans, fw); | 346 | ret = iwl_trans_start_fw(priv->trans, fw, false); |
430 | if (ret) { | 347 | if (ret) { |
431 | priv->cur_ucode = old_type; | 348 | priv->cur_ucode = old_type; |
432 | iwl_remove_notification(&priv->notif_wait, &alive_wait); | 349 | iwl_remove_notification(&priv->notif_wait, &alive_wait); |
@@ -450,18 +367,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, | |||
450 | return -EIO; | 367 | return -EIO; |
451 | } | 368 | } |
452 | 369 | ||
453 | /* | ||
454 | * This step takes a long time (60-80ms!!) and | ||
455 | * WoWLAN image should be loaded quickly, so | ||
456 | * skip it for WoWLAN. | ||
457 | */ | ||
458 | if (ucode_type != IWL_UCODE_WOWLAN) { | 370 | if (ucode_type != IWL_UCODE_WOWLAN) { |
459 | ret = iwl_verify_ucode(priv, ucode_type); | ||
460 | if (ret) { | ||
461 | priv->cur_ucode = old_type; | ||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | /* delay a bit to give rfkill time to run */ | 371 | /* delay a bit to give rfkill time to run */ |
466 | msleep(5); | 372 | msleep(5); |
467 | } | 373 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 34a5287dfc2f..b419a1efac0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -381,8 +381,8 @@ | |||
381 | 381 | ||
382 | /* LED */ | 382 | /* LED */ |
383 | #define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF) | 383 | #define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF) |
384 | #define CSR_LED_REG_TRUN_ON (0x78) | 384 | #define CSR_LED_REG_TURN_ON (0x60) |
385 | #define CSR_LED_REG_TRUN_OFF (0x38) | 385 | #define CSR_LED_REG_TURN_OFF (0x20) |
386 | 386 | ||
387 | /* ANA_PLL */ | 387 | /* ANA_PLL */ |
388 | #define CSR50_ANA_PLL_CFG_VAL (0x00880300) | 388 | #define CSR50_ANA_PLL_CFG_VAL (0x00880300) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index ec48563d3c6a..c646a90b725e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
@@ -225,6 +225,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) | |||
225 | #define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008) | 225 | #define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008) |
226 | #define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG) | 226 | #define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG) |
227 | 227 | ||
228 | #define FW_RSCSR_CHNL0_RXDCB_RDPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x00c) | ||
229 | #define FH_RSCSR_CHNL0_RDPTR FW_RSCSR_CHNL0_RXDCB_RDPTR_REG | ||
228 | 230 | ||
229 | /** | 231 | /** |
230 | * Rx Config/Status Registers (RCSR) | 232 | * Rx Config/Status Registers (RCSR) |
@@ -257,6 +259,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) | |||
257 | #define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND) | 259 | #define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND) |
258 | 260 | ||
259 | #define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0) | 261 | #define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0) |
262 | #define FH_MEM_RCSR_CHNL0_RBDCB_WPTR (FH_MEM_RCSR_CHNL0 + 0x8) | ||
263 | #define FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ (FH_MEM_RCSR_CHNL0 + 0x10) | ||
260 | 264 | ||
261 | #define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MSK (0x00000FF0) /* bits 4-11 */ | 265 | #define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MSK (0x00000FF0) /* bits 4-11 */ |
262 | #define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MSK (0x00001000) /* bits 12 */ | 266 | #define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MSK (0x00001000) /* bits 12 */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index cdaff9572059..bff3ac96c00b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -35,12 +35,12 @@ | |||
35 | 35 | ||
36 | #define IWL_POLL_INTERVAL 10 /* microseconds */ | 36 | #define IWL_POLL_INTERVAL 10 /* microseconds */ |
37 | 37 | ||
38 | static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) | 38 | void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) |
39 | { | 39 | { |
40 | iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); | 40 | iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); |
41 | } | 41 | } |
42 | 42 | ||
43 | static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) | 43 | void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) |
44 | { | 44 | { |
45 | iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); | 45 | iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); |
46 | } | 46 | } |
@@ -99,86 +99,16 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | |||
99 | } | 99 | } |
100 | EXPORT_SYMBOL_GPL(iwl_poll_bit); | 100 | EXPORT_SYMBOL_GPL(iwl_poll_bit); |
101 | 101 | ||
102 | int iwl_grab_nic_access_silent(struct iwl_trans *trans) | ||
103 | { | ||
104 | int ret; | ||
105 | |||
106 | lockdep_assert_held(&trans->reg_lock); | ||
107 | |||
108 | /* this bit wakes up the NIC */ | ||
109 | __iwl_set_bit(trans, CSR_GP_CNTRL, | ||
110 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
111 | |||
112 | /* | ||
113 | * These bits say the device is running, and should keep running for | ||
114 | * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), | ||
115 | * but they do not indicate that embedded SRAM is restored yet; | ||
116 | * 3945 and 4965 have volatile SRAM, and must save/restore contents | ||
117 | * to/from host DRAM when sleeping/waking for power-saving. | ||
118 | * Each direction takes approximately 1/4 millisecond; with this | ||
119 | * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a | ||
120 | * series of register accesses are expected (e.g. reading Event Log), | ||
121 | * to keep device from sleeping. | ||
122 | * | ||
123 | * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that | ||
124 | * SRAM is okay/restored. We don't check that here because this call | ||
125 | * is just for hardware register access; but GP1 MAC_SLEEP check is a | ||
126 | * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). | ||
127 | * | ||
128 | * 5000 series and later (including 1000 series) have non-volatile SRAM, | ||
129 | * and do not save/restore SRAM when power cycling. | ||
130 | */ | ||
131 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
132 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, | ||
133 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | ||
134 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); | ||
135 | if (ret < 0) { | ||
136 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); | ||
137 | return -EIO; | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | EXPORT_SYMBOL_GPL(iwl_grab_nic_access_silent); | ||
143 | |||
144 | bool iwl_grab_nic_access(struct iwl_trans *trans) | ||
145 | { | ||
146 | int ret = iwl_grab_nic_access_silent(trans); | ||
147 | if (unlikely(ret)) { | ||
148 | u32 val = iwl_read32(trans, CSR_GP_CNTRL); | ||
149 | WARN_ONCE(1, "Timeout waiting for hardware access " | ||
150 | "(CSR_GP_CNTRL 0x%08x)\n", val); | ||
151 | return false; | ||
152 | } | ||
153 | |||
154 | return true; | ||
155 | } | ||
156 | EXPORT_SYMBOL_GPL(iwl_grab_nic_access); | ||
157 | |||
158 | void iwl_release_nic_access(struct iwl_trans *trans) | ||
159 | { | ||
160 | lockdep_assert_held(&trans->reg_lock); | ||
161 | __iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
162 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
163 | /* | ||
164 | * Above we read the CSR_GP_CNTRL register, which will flush | ||
165 | * any previous writes, but we need the write that clears the | ||
166 | * MAC_ACCESS_REQ bit to be performed before any other writes | ||
167 | * scheduled on different CPUs (after we drop reg_lock). | ||
168 | */ | ||
169 | mmiowb(); | ||
170 | } | ||
171 | EXPORT_SYMBOL_GPL(iwl_release_nic_access); | ||
172 | |||
173 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) | 102 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) |
174 | { | 103 | { |
175 | u32 value; | 104 | u32 value = 0x5a5a5a5a; |
176 | unsigned long flags; | 105 | unsigned long flags; |
177 | 106 | ||
178 | spin_lock_irqsave(&trans->reg_lock, flags); | 107 | spin_lock_irqsave(&trans->reg_lock, flags); |
179 | iwl_grab_nic_access(trans); | 108 | if (iwl_trans_grab_nic_access(trans, false)) { |
180 | value = iwl_read32(trans, reg); | 109 | value = iwl_read32(trans, reg); |
181 | iwl_release_nic_access(trans); | 110 | iwl_trans_release_nic_access(trans); |
111 | } | ||
182 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 112 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
183 | 113 | ||
184 | return value; | 114 | return value; |
@@ -190,9 +120,9 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) | |||
190 | unsigned long flags; | 120 | unsigned long flags; |
191 | 121 | ||
192 | spin_lock_irqsave(&trans->reg_lock, flags); | 122 | spin_lock_irqsave(&trans->reg_lock, flags); |
193 | if (likely(iwl_grab_nic_access(trans))) { | 123 | if (iwl_trans_grab_nic_access(trans, false)) { |
194 | iwl_write32(trans, reg, value); | 124 | iwl_write32(trans, reg, value); |
195 | iwl_release_nic_access(trans); | 125 | iwl_trans_release_nic_access(trans); |
196 | } | 126 | } |
197 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 127 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
198 | } | 128 | } |
@@ -230,12 +160,13 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) | |||
230 | u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) | 160 | u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) |
231 | { | 161 | { |
232 | unsigned long flags; | 162 | unsigned long flags; |
233 | u32 val; | 163 | u32 val = 0x5a5a5a5a; |
234 | 164 | ||
235 | spin_lock_irqsave(&trans->reg_lock, flags); | 165 | spin_lock_irqsave(&trans->reg_lock, flags); |
236 | iwl_grab_nic_access(trans); | 166 | if (iwl_trans_grab_nic_access(trans, false)) { |
237 | val = __iwl_read_prph(trans, ofs); | 167 | val = __iwl_read_prph(trans, ofs); |
238 | iwl_release_nic_access(trans); | 168 | iwl_trans_release_nic_access(trans); |
169 | } | ||
239 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 170 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
240 | return val; | 171 | return val; |
241 | } | 172 | } |
@@ -246,9 +177,9 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) | |||
246 | unsigned long flags; | 177 | unsigned long flags; |
247 | 178 | ||
248 | spin_lock_irqsave(&trans->reg_lock, flags); | 179 | spin_lock_irqsave(&trans->reg_lock, flags); |
249 | if (likely(iwl_grab_nic_access(trans))) { | 180 | if (iwl_trans_grab_nic_access(trans, false)) { |
250 | __iwl_write_prph(trans, ofs, val); | 181 | __iwl_write_prph(trans, ofs, val); |
251 | iwl_release_nic_access(trans); | 182 | iwl_trans_release_nic_access(trans); |
252 | } | 183 | } |
253 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 184 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
254 | } | 185 | } |
@@ -259,10 +190,10 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | |||
259 | unsigned long flags; | 190 | unsigned long flags; |
260 | 191 | ||
261 | spin_lock_irqsave(&trans->reg_lock, flags); | 192 | spin_lock_irqsave(&trans->reg_lock, flags); |
262 | if (likely(iwl_grab_nic_access(trans))) { | 193 | if (iwl_trans_grab_nic_access(trans, false)) { |
263 | __iwl_write_prph(trans, ofs, | 194 | __iwl_write_prph(trans, ofs, |
264 | __iwl_read_prph(trans, ofs) | mask); | 195 | __iwl_read_prph(trans, ofs) | mask); |
265 | iwl_release_nic_access(trans); | 196 | iwl_trans_release_nic_access(trans); |
266 | } | 197 | } |
267 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 198 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
268 | } | 199 | } |
@@ -274,10 +205,10 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, | |||
274 | unsigned long flags; | 205 | unsigned long flags; |
275 | 206 | ||
276 | spin_lock_irqsave(&trans->reg_lock, flags); | 207 | spin_lock_irqsave(&trans->reg_lock, flags); |
277 | if (likely(iwl_grab_nic_access(trans))) { | 208 | if (iwl_trans_grab_nic_access(trans, false)) { |
278 | __iwl_write_prph(trans, ofs, | 209 | __iwl_write_prph(trans, ofs, |
279 | (__iwl_read_prph(trans, ofs) & mask) | bits); | 210 | (__iwl_read_prph(trans, ofs) & mask) | bits); |
280 | iwl_release_nic_access(trans); | 211 | iwl_trans_release_nic_access(trans); |
281 | } | 212 | } |
282 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 213 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
283 | } | 214 | } |
@@ -289,66 +220,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | |||
289 | u32 val; | 220 | u32 val; |
290 | 221 | ||
291 | spin_lock_irqsave(&trans->reg_lock, flags); | 222 | spin_lock_irqsave(&trans->reg_lock, flags); |
292 | if (likely(iwl_grab_nic_access(trans))) { | 223 | if (iwl_trans_grab_nic_access(trans, false)) { |
293 | val = __iwl_read_prph(trans, ofs); | 224 | val = __iwl_read_prph(trans, ofs); |
294 | __iwl_write_prph(trans, ofs, (val & ~mask)); | 225 | __iwl_write_prph(trans, ofs, (val & ~mask)); |
295 | iwl_release_nic_access(trans); | 226 | iwl_trans_release_nic_access(trans); |
296 | } | 227 | } |
297 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 228 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
298 | } | 229 | } |
299 | EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); | 230 | EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); |
300 | |||
301 | void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | ||
302 | void *buf, int dwords) | ||
303 | { | ||
304 | unsigned long flags; | ||
305 | int offs; | ||
306 | u32 *vals = buf; | ||
307 | |||
308 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
309 | if (likely(iwl_grab_nic_access(trans))) { | ||
310 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | ||
311 | for (offs = 0; offs < dwords; offs++) | ||
312 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | ||
313 | iwl_release_nic_access(trans); | ||
314 | } | ||
315 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
316 | } | ||
317 | EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_dwords); | ||
318 | |||
319 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) | ||
320 | { | ||
321 | u32 value; | ||
322 | |||
323 | _iwl_read_targ_mem_dwords(trans, addr, &value, 1); | ||
324 | |||
325 | return value; | ||
326 | } | ||
327 | EXPORT_SYMBOL_GPL(iwl_read_targ_mem); | ||
328 | |||
329 | int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | ||
330 | const void *buf, int dwords) | ||
331 | { | ||
332 | unsigned long flags; | ||
333 | int offs, result = 0; | ||
334 | const u32 *vals = buf; | ||
335 | |||
336 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
337 | if (likely(iwl_grab_nic_access(trans))) { | ||
338 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); | ||
339 | for (offs = 0; offs < dwords; offs++) | ||
340 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); | ||
341 | iwl_release_nic_access(trans); | ||
342 | } else | ||
343 | result = -EBUSY; | ||
344 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
345 | |||
346 | return result; | ||
347 | } | ||
348 | EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_dwords); | ||
349 | |||
350 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) | ||
351 | { | ||
352 | return _iwl_write_targ_mem_dwords(trans, addr, &val, 1); | ||
353 | } | ||
354 | EXPORT_SYMBOL_GPL(iwl_write_targ_mem); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 48dc753e3742..dc478068596b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -53,6 +53,8 @@ static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) | |||
53 | 53 | ||
54 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); | 54 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
55 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); | 55 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
56 | void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); | ||
57 | void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); | ||
56 | 58 | ||
57 | void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); | 59 | void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); |
58 | 60 | ||
@@ -61,10 +63,6 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | |||
61 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | 63 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, |
62 | int timeout); | 64 | int timeout); |
63 | 65 | ||
64 | int iwl_grab_nic_access_silent(struct iwl_trans *trans); | ||
65 | bool iwl_grab_nic_access(struct iwl_trans *trans); | ||
66 | void iwl_release_nic_access(struct iwl_trans *trans); | ||
67 | |||
68 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); | 66 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); |
69 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value); | 67 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value); |
70 | 68 | ||
@@ -76,19 +74,4 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, | |||
76 | u32 bits, u32 mask); | 74 | u32 bits, u32 mask); |
77 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); | 75 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); |
78 | 76 | ||
79 | void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | ||
80 | void *buf, int dwords); | ||
81 | |||
82 | #define iwl_read_targ_mem_bytes(trans, addr, buf, bufsize) \ | ||
83 | do { \ | ||
84 | BUILD_BUG_ON((bufsize) % sizeof(u32)); \ | ||
85 | _iwl_read_targ_mem_dwords(trans, addr, buf, \ | ||
86 | (bufsize) / sizeof(u32));\ | ||
87 | } while (0) | ||
88 | |||
89 | int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | ||
90 | const void *buf, int dwords); | ||
91 | |||
92 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); | ||
93 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); | ||
94 | #endif | 77 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index 81e8c7126d72..1a226114fe73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c | |||
@@ -467,18 +467,20 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size) | |||
467 | if (IWL_ABS_PRPH_START <= addr && | 467 | if (IWL_ABS_PRPH_START <= addr && |
468 | addr < IWL_ABS_PRPH_START + PRPH_END) { | 468 | addr < IWL_ABS_PRPH_START + PRPH_END) { |
469 | spin_lock_irqsave(&trans->reg_lock, flags); | 469 | spin_lock_irqsave(&trans->reg_lock, flags); |
470 | iwl_grab_nic_access(trans); | 470 | if (!iwl_trans_grab_nic_access(trans, false)) { |
471 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
472 | return -EIO; | ||
473 | } | ||
471 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, | 474 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, |
472 | addr | (3 << 24)); | 475 | addr | (3 << 24)); |
473 | for (i = 0; i < size; i += 4) | 476 | for (i = 0; i < size; i += 4) |
474 | *(u32 *)(tst->mem.addr + i) = | 477 | *(u32 *)(tst->mem.addr + i) = |
475 | iwl_read32(trans, HBUS_TARG_PRPH_RDAT); | 478 | iwl_read32(trans, HBUS_TARG_PRPH_RDAT); |
476 | iwl_release_nic_access(trans); | 479 | iwl_trans_release_nic_access(trans); |
477 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 480 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
478 | } else { /* target memory (SRAM) */ | 481 | } else { /* target memory (SRAM) */ |
479 | _iwl_read_targ_mem_dwords(trans, addr, | 482 | iwl_trans_read_mem(trans, addr, tst->mem.addr, |
480 | tst->mem.addr, | 483 | tst->mem.size / 4); |
481 | tst->mem.size / 4); | ||
482 | } | 484 | } |
483 | 485 | ||
484 | tst->mem.nchunks = | 486 | tst->mem.nchunks = |
@@ -501,28 +503,31 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr, | |||
501 | 503 | ||
502 | if (IWL_ABS_PRPH_START <= addr && | 504 | if (IWL_ABS_PRPH_START <= addr && |
503 | addr < IWL_ABS_PRPH_START + PRPH_END) { | 505 | addr < IWL_ABS_PRPH_START + PRPH_END) { |
504 | /* Periphery writes can be 1-3 bytes long, or DWORDs */ | 506 | /* Periphery writes can be 1-3 bytes long, or DWORDs */ |
505 | if (size < 4) { | 507 | if (size < 4) { |
506 | memcpy(&val, buf, size); | 508 | memcpy(&val, buf, size); |
507 | spin_lock_irqsave(&trans->reg_lock, flags); | 509 | spin_lock_irqsave(&trans->reg_lock, flags); |
508 | iwl_grab_nic_access(trans); | 510 | if (!iwl_trans_grab_nic_access(trans, false)) { |
509 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, | ||
510 | (addr & 0x0000FFFF) | | ||
511 | ((size - 1) << 24)); | ||
512 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); | ||
513 | iwl_release_nic_access(trans); | ||
514 | /* needed after consecutive writes w/o read */ | ||
515 | mmiowb(); | ||
516 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 511 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
517 | } else { | 512 | return -EIO; |
518 | if (size % 4) | ||
519 | return -EINVAL; | ||
520 | for (i = 0; i < size; i += 4) | ||
521 | iwl_write_prph(trans, addr+i, | ||
522 | *(u32 *)(buf+i)); | ||
523 | } | 513 | } |
514 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, | ||
515 | (addr & 0x0000FFFF) | | ||
516 | ((size - 1) << 24)); | ||
517 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); | ||
518 | iwl_trans_release_nic_access(trans); | ||
519 | /* needed after consecutive writes w/o read */ | ||
520 | mmiowb(); | ||
521 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
522 | } else { | ||
523 | if (size % 4) | ||
524 | return -EINVAL; | ||
525 | for (i = 0; i < size; i += 4) | ||
526 | iwl_write_prph(trans, addr+i, | ||
527 | *(u32 *)(buf+i)); | ||
528 | } | ||
524 | } else if (iwl_test_valid_hw_addr(tst, addr)) { | 529 | } else if (iwl_test_valid_hw_addr(tst, addr)) { |
525 | _iwl_write_targ_mem_dwords(trans, addr, buf, size / 4); | 530 | iwl_trans_write_mem(trans, addr, buf, size / 4); |
526 | } else { | 531 | } else { |
527 | return -EINVAL; | 532 | return -EINVAL; |
528 | } | 533 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index b76532e238c1..0f85eb305878 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -308,6 +308,16 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
308 | #define IWL_FRAME_LIMIT 64 | 308 | #define IWL_FRAME_LIMIT 64 |
309 | 309 | ||
310 | /** | 310 | /** |
311 | * enum iwl_wowlan_status - WoWLAN image/device status | ||
312 | * @IWL_D3_STATUS_ALIVE: firmware is still running after resume | ||
313 | * @IWL_D3_STATUS_RESET: device was reset while suspended | ||
314 | */ | ||
315 | enum iwl_d3_status { | ||
316 | IWL_D3_STATUS_ALIVE, | ||
317 | IWL_D3_STATUS_RESET, | ||
318 | }; | ||
319 | |||
320 | /** | ||
311 | * struct iwl_trans_config - transport configuration | 321 | * struct iwl_trans_config - transport configuration |
312 | * | 322 | * |
313 | * @op_mode: pointer to the upper layer. | 323 | * @op_mode: pointer to the upper layer. |
@@ -321,6 +331,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
321 | * @n_no_reclaim_cmds: # of commands in list | 331 | * @n_no_reclaim_cmds: # of commands in list |
322 | * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs, | 332 | * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs, |
323 | * if unset 4k will be the RX buffer size | 333 | * if unset 4k will be the RX buffer size |
334 | * @bc_table_dword: set to true if the BC table expects the byte count to be | ||
335 | * in DWORD (as opposed to bytes) | ||
324 | * @queue_watchdog_timeout: time (in ms) after which queues | 336 | * @queue_watchdog_timeout: time (in ms) after which queues |
325 | * are considered stuck and will trigger device restart | 337 | * are considered stuck and will trigger device restart |
326 | * @command_names: array of command names, must be 256 entries | 338 | * @command_names: array of command names, must be 256 entries |
@@ -335,6 +347,7 @@ struct iwl_trans_config { | |||
335 | int n_no_reclaim_cmds; | 347 | int n_no_reclaim_cmds; |
336 | 348 | ||
337 | bool rx_buf_size_8k; | 349 | bool rx_buf_size_8k; |
350 | bool bc_table_dword; | ||
338 | unsigned int queue_watchdog_timeout; | 351 | unsigned int queue_watchdog_timeout; |
339 | const char **command_names; | 352 | const char **command_names; |
340 | }; | 353 | }; |
@@ -360,9 +373,12 @@ struct iwl_trans; | |||
360 | * May sleep | 373 | * May sleep |
361 | * @stop_device:stops the whole device (embedded CPU put to reset) | 374 | * @stop_device:stops the whole device (embedded CPU put to reset) |
362 | * May sleep | 375 | * May sleep |
363 | * @wowlan_suspend: put the device into the correct mode for WoWLAN during | 376 | * @d3_suspend: put the device into the correct mode for WoWLAN during |
364 | * suspend. This is optional, if not implemented WoWLAN will not be | 377 | * suspend. This is optional, if not implemented WoWLAN will not be |
365 | * supported. This callback may sleep. | 378 | * supported. This callback may sleep. |
379 | * @d3_resume: resume the device after WoWLAN, enabling the opmode to | ||
380 | * talk to the WoWLAN image to get its status. This is optional, if not | ||
381 | * implemented WoWLAN will not be supported. This callback may sleep. | ||
366 | * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted. | 382 | * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted. |
367 | * If RFkill is asserted in the middle of a SYNC host command, it must | 383 | * If RFkill is asserted in the middle of a SYNC host command, it must |
368 | * return -ERFKILL straight away. | 384 | * return -ERFKILL straight away. |
@@ -387,20 +403,27 @@ struct iwl_trans; | |||
387 | * @read32: read a u32 register at offset ofs from the BAR | 403 | * @read32: read a u32 register at offset ofs from the BAR |
388 | * @read_prph: read a DWORD from a periphery register | 404 | * @read_prph: read a DWORD from a periphery register |
389 | * @write_prph: write a DWORD to a periphery register | 405 | * @write_prph: write a DWORD to a periphery register |
406 | * @read_mem: read device's SRAM in DWORD | ||
407 | * @write_mem: write device's SRAM in DWORD. If %buf is %NULL, then the memory | ||
408 | * will be zeroed. | ||
390 | * @configure: configure parameters required by the transport layer from | 409 | * @configure: configure parameters required by the transport layer from |
391 | * the op_mode. May be called several times before start_fw, can't be | 410 | * the op_mode. May be called several times before start_fw, can't be |
392 | * called after that. | 411 | * called after that. |
393 | * @set_pmi: set the power pmi state | 412 | * @set_pmi: set the power pmi state |
413 | * @grab_nic_access: wake the NIC to be able to access non-HBUS regs | ||
414 | * @release_nic_access: let the NIC go to sleep | ||
394 | */ | 415 | */ |
395 | struct iwl_trans_ops { | 416 | struct iwl_trans_ops { |
396 | 417 | ||
397 | int (*start_hw)(struct iwl_trans *iwl_trans); | 418 | int (*start_hw)(struct iwl_trans *iwl_trans); |
398 | void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); | 419 | void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); |
399 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); | 420 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, |
421 | bool run_in_rfkill); | ||
400 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); | 422 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); |
401 | void (*stop_device)(struct iwl_trans *trans); | 423 | void (*stop_device)(struct iwl_trans *trans); |
402 | 424 | ||
403 | void (*wowlan_suspend)(struct iwl_trans *trans); | 425 | void (*d3_suspend)(struct iwl_trans *trans); |
426 | int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status); | ||
404 | 427 | ||
405 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 428 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
406 | 429 | ||
@@ -424,9 +447,15 @@ struct iwl_trans_ops { | |||
424 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); | 447 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); |
425 | u32 (*read_prph)(struct iwl_trans *trans, u32 ofs); | 448 | u32 (*read_prph)(struct iwl_trans *trans, u32 ofs); |
426 | void (*write_prph)(struct iwl_trans *trans, u32 ofs, u32 val); | 449 | void (*write_prph)(struct iwl_trans *trans, u32 ofs, u32 val); |
450 | int (*read_mem)(struct iwl_trans *trans, u32 addr, | ||
451 | void *buf, int dwords); | ||
452 | int (*write_mem)(struct iwl_trans *trans, u32 addr, | ||
453 | void *buf, int dwords); | ||
427 | void (*configure)(struct iwl_trans *trans, | 454 | void (*configure)(struct iwl_trans *trans, |
428 | const struct iwl_trans_config *trans_cfg); | 455 | const struct iwl_trans_config *trans_cfg); |
429 | void (*set_pmi)(struct iwl_trans *trans, bool state); | 456 | void (*set_pmi)(struct iwl_trans *trans, bool state); |
457 | bool (*grab_nic_access)(struct iwl_trans *trans, bool silent); | ||
458 | void (*release_nic_access)(struct iwl_trans *trans); | ||
430 | }; | 459 | }; |
431 | 460 | ||
432 | /** | 461 | /** |
@@ -528,13 +557,14 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr) | |||
528 | } | 557 | } |
529 | 558 | ||
530 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, | 559 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, |
531 | const struct fw_img *fw) | 560 | const struct fw_img *fw, |
561 | bool run_in_rfkill) | ||
532 | { | 562 | { |
533 | might_sleep(); | 563 | might_sleep(); |
534 | 564 | ||
535 | WARN_ON_ONCE(!trans->rx_mpdu_cmd); | 565 | WARN_ON_ONCE(!trans->rx_mpdu_cmd); |
536 | 566 | ||
537 | return trans->ops->start_fw(trans, fw); | 567 | return trans->ops->start_fw(trans, fw, run_in_rfkill); |
538 | } | 568 | } |
539 | 569 | ||
540 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) | 570 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) |
@@ -546,10 +576,17 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) | |||
546 | trans->state = IWL_TRANS_NO_FW; | 576 | trans->state = IWL_TRANS_NO_FW; |
547 | } | 577 | } |
548 | 578 | ||
549 | static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) | 579 | static inline void iwl_trans_d3_suspend(struct iwl_trans *trans) |
580 | { | ||
581 | might_sleep(); | ||
582 | trans->ops->d3_suspend(trans); | ||
583 | } | ||
584 | |||
585 | static inline int iwl_trans_d3_resume(struct iwl_trans *trans, | ||
586 | enum iwl_d3_status *status) | ||
550 | { | 587 | { |
551 | might_sleep(); | 588 | might_sleep(); |
552 | trans->ops->wowlan_suspend(trans); | 589 | return trans->ops->d3_resume(trans, status); |
553 | } | 590 | } |
554 | 591 | ||
555 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | 592 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, |
@@ -636,7 +673,7 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | |||
636 | } | 673 | } |
637 | 674 | ||
638 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, | 675 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, |
639 | struct dentry *dir) | 676 | struct dentry *dir) |
640 | { | 677 | { |
641 | return trans->ops->dbgfs_register(trans, dir); | 678 | return trans->ops->dbgfs_register(trans, dir); |
642 | } | 679 | } |
@@ -679,11 +716,57 @@ static inline void iwl_trans_write_prph(struct iwl_trans *trans, u32 ofs, | |||
679 | return trans->ops->write_prph(trans, ofs, val); | 716 | return trans->ops->write_prph(trans, ofs, val); |
680 | } | 717 | } |
681 | 718 | ||
719 | static inline int iwl_trans_read_mem(struct iwl_trans *trans, u32 addr, | ||
720 | void *buf, int dwords) | ||
721 | { | ||
722 | return trans->ops->read_mem(trans, addr, buf, dwords); | ||
723 | } | ||
724 | |||
725 | #define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize) \ | ||
726 | do { \ | ||
727 | if (__builtin_constant_p(bufsize)) \ | ||
728 | BUILD_BUG_ON((bufsize) % sizeof(u32)); \ | ||
729 | iwl_trans_read_mem(trans, addr, buf, (bufsize) / sizeof(u32));\ | ||
730 | } while (0) | ||
731 | |||
732 | static inline u32 iwl_trans_read_mem32(struct iwl_trans *trans, u32 addr) | ||
733 | { | ||
734 | u32 value; | ||
735 | |||
736 | if (WARN_ON(iwl_trans_read_mem(trans, addr, &value, 1))) | ||
737 | return 0xa5a5a5a5; | ||
738 | |||
739 | return value; | ||
740 | } | ||
741 | |||
742 | static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr, | ||
743 | void *buf, int dwords) | ||
744 | { | ||
745 | return trans->ops->write_mem(trans, addr, buf, dwords); | ||
746 | } | ||
747 | |||
748 | static inline u32 iwl_trans_write_mem32(struct iwl_trans *trans, u32 addr, | ||
749 | u32 val) | ||
750 | { | ||
751 | return iwl_trans_write_mem(trans, addr, &val, 1); | ||
752 | } | ||
753 | |||
682 | static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state) | 754 | static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state) |
683 | { | 755 | { |
684 | trans->ops->set_pmi(trans, state); | 756 | trans->ops->set_pmi(trans, state); |
685 | } | 757 | } |
686 | 758 | ||
759 | #define iwl_trans_grab_nic_access(trans, silent) \ | ||
760 | __cond_lock(nic_access, \ | ||
761 | likely((trans)->ops->grab_nic_access(trans, silent))) | ||
762 | |||
763 | static inline void __releases(nic_access) | ||
764 | iwl_trans_release_nic_access(struct iwl_trans *trans) | ||
765 | { | ||
766 | trans->ops->release_nic_access(trans); | ||
767 | __release(nic_access); | ||
768 | } | ||
769 | |||
687 | /***************************************************** | 770 | /***************************************************** |
688 | * driver (transport) register/unregister functions | 771 | * driver (transport) register/unregister functions |
689 | ******************************************************/ | 772 | ******************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index d91d2e8c62f5..20735a008cab 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -222,8 +222,6 @@ struct iwl_txq { | |||
222 | * @rx_replenish: work that will be called when buffers need to be allocated | 222 | * @rx_replenish: work that will be called when buffers need to be allocated |
223 | * @drv - pointer to iwl_drv | 223 | * @drv - pointer to iwl_drv |
224 | * @trans: pointer to the generic transport area | 224 | * @trans: pointer to the generic transport area |
225 | * @irq - the irq number for the device | ||
226 | * @irq_requested: true when the irq has been requested | ||
227 | * @scd_base_addr: scheduler sram base address in SRAM | 225 | * @scd_base_addr: scheduler sram base address in SRAM |
228 | * @scd_bc_tbls: pointer to the byte count table of the scheduler | 226 | * @scd_bc_tbls: pointer to the byte count table of the scheduler |
229 | * @kw: keep warm address | 227 | * @kw: keep warm address |
@@ -234,6 +232,7 @@ struct iwl_txq { | |||
234 | * @status - transport specific status flags | 232 | * @status - transport specific status flags |
235 | * @cmd_queue - command queue number | 233 | * @cmd_queue - command queue number |
236 | * @rx_buf_size_8k: 8 kB RX buffer size | 234 | * @rx_buf_size_8k: 8 kB RX buffer size |
235 | * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) | ||
237 | * @rx_page_order: page order for receive buffer size | 236 | * @rx_page_order: page order for receive buffer size |
238 | * @wd_timeout: queue watchdog timeout (jiffies) | 237 | * @wd_timeout: queue watchdog timeout (jiffies) |
239 | */ | 238 | */ |
@@ -249,11 +248,9 @@ struct iwl_trans_pcie { | |||
249 | int ict_index; | 248 | int ict_index; |
250 | u32 inta; | 249 | u32 inta; |
251 | bool use_ict; | 250 | bool use_ict; |
252 | bool irq_requested; | ||
253 | struct tasklet_struct irq_tasklet; | 251 | struct tasklet_struct irq_tasklet; |
254 | struct isr_statistics isr_stats; | 252 | struct isr_statistics isr_stats; |
255 | 253 | ||
256 | unsigned int irq; | ||
257 | spinlock_t irq_lock; | 254 | spinlock_t irq_lock; |
258 | u32 inta_mask; | 255 | u32 inta_mask; |
259 | u32 scd_base_addr; | 256 | u32 scd_base_addr; |
@@ -279,6 +276,7 @@ struct iwl_trans_pcie { | |||
279 | u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; | 276 | u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; |
280 | 277 | ||
281 | bool rx_buf_size_8k; | 278 | bool rx_buf_size_8k; |
279 | bool bc_table_dword; | ||
282 | u32 rx_page_order; | 280 | u32 rx_page_order; |
283 | 281 | ||
284 | const char **command_names; | 282 | const char **command_names; |
@@ -359,6 +357,8 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, | |||
359 | struct iwl_rx_cmd_buffer *rxb, int handler_status); | 357 | struct iwl_rx_cmd_buffer *rxb, int handler_status); |
360 | void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, | 358 | void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, |
361 | struct sk_buff_head *skbs); | 359 | struct sk_buff_head *skbs); |
360 | void iwl_trans_pcie_tx_reset(struct iwl_trans *trans); | ||
361 | |||
362 | /***************************************************** | 362 | /***************************************************** |
363 | * Error handling | 363 | * Error handling |
364 | ******************************************************/ | 364 | ******************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 8389cd38338b..4e6591d24e61 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -436,7 +436,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) | |||
436 | err_rb_stts: | 436 | err_rb_stts: |
437 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | 437 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, |
438 | rxq->bd, rxq->bd_dma); | 438 | rxq->bd, rxq->bd_dma); |
439 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | 439 | rxq->bd_dma = 0; |
440 | rxq->bd = NULL; | 440 | rxq->bd = NULL; |
441 | err_bd: | 441 | err_bd: |
442 | return -ENOMEM; | 442 | return -ENOMEM; |
@@ -455,6 +455,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) | |||
455 | 455 | ||
456 | /* Stop Rx DMA */ | 456 | /* Stop Rx DMA */ |
457 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | 457 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); |
458 | /* reset and flush pointers */ | ||
459 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0); | ||
460 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0); | ||
461 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RDPTR, 0); | ||
458 | 462 | ||
459 | /* Reset driver's Rx queue write index */ | 463 | /* Reset driver's Rx queue write index */ |
460 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | 464 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); |
@@ -491,7 +495,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
491 | { | 495 | { |
492 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 496 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
493 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 497 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
494 | |||
495 | int i, err; | 498 | int i, err; |
496 | unsigned long flags; | 499 | unsigned long flags; |
497 | 500 | ||
@@ -518,6 +521,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
518 | rxq->read = rxq->write = 0; | 521 | rxq->read = rxq->write = 0; |
519 | rxq->write_actual = 0; | 522 | rxq->write_actual = 0; |
520 | rxq->free_count = 0; | 523 | rxq->free_count = 0; |
524 | memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); | ||
521 | spin_unlock_irqrestore(&rxq->lock, flags); | 525 | spin_unlock_irqrestore(&rxq->lock, flags); |
522 | 526 | ||
523 | iwl_pcie_rx_replenish(trans); | 527 | iwl_pcie_rx_replenish(trans); |
@@ -545,13 +549,15 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) | |||
545 | return; | 549 | return; |
546 | } | 550 | } |
547 | 551 | ||
552 | cancel_work_sync(&trans_pcie->rx_replenish); | ||
553 | |||
548 | spin_lock_irqsave(&rxq->lock, flags); | 554 | spin_lock_irqsave(&rxq->lock, flags); |
549 | iwl_pcie_rxq_free_rbs(trans); | 555 | iwl_pcie_rxq_free_rbs(trans); |
550 | spin_unlock_irqrestore(&rxq->lock, flags); | 556 | spin_unlock_irqrestore(&rxq->lock, flags); |
551 | 557 | ||
552 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, | 558 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, |
553 | rxq->bd, rxq->bd_dma); | 559 | rxq->bd, rxq->bd_dma); |
554 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | 560 | rxq->bd_dma = 0; |
555 | rxq->bd = NULL; | 561 | rxq->bd = NULL; |
556 | 562 | ||
557 | if (rxq->rb_stts) | 563 | if (rxq->rb_stts) |
@@ -560,7 +566,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) | |||
560 | rxq->rb_stts, rxq->rb_stts_dma); | 566 | rxq->rb_stts, rxq->rb_stts_dma); |
561 | else | 567 | else |
562 | IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); | 568 | IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); |
563 | memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma)); | 569 | rxq->rb_stts_dma = 0; |
564 | rxq->rb_stts = NULL; | 570 | rxq->rb_stts = NULL; |
565 | } | 571 | } |
566 | 572 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 35708b959ad6..c57641eb83d5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -75,21 +75,16 @@ | |||
75 | #include "iwl-agn-hw.h" | 75 | #include "iwl-agn-hw.h" |
76 | #include "internal.h" | 76 | #include "internal.h" |
77 | 77 | ||
78 | static void iwl_pcie_set_pwr_vmain(struct iwl_trans *trans) | 78 | static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux) |
79 | { | 79 | { |
80 | /* | 80 | if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold)) |
81 | * (for documentation purposes) | 81 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, |
82 | * to set power to V_AUX, do: | 82 | APMG_PS_CTRL_VAL_PWR_SRC_VAUX, |
83 | 83 | ~APMG_PS_CTRL_MSK_PWR_SRC); | |
84 | if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) | 84 | else |
85 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, | 85 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, |
86 | APMG_PS_CTRL_VAL_PWR_SRC_VAUX, | 86 | APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, |
87 | ~APMG_PS_CTRL_MSK_PWR_SRC); | 87 | ~APMG_PS_CTRL_MSK_PWR_SRC); |
88 | */ | ||
89 | |||
90 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, | ||
91 | APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, | ||
92 | ~APMG_PS_CTRL_MSK_PWR_SRC); | ||
93 | } | 88 | } |
94 | 89 | ||
95 | /* PCI registers */ | 90 | /* PCI registers */ |
@@ -259,7 +254,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans) | |||
259 | 254 | ||
260 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 255 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
261 | 256 | ||
262 | iwl_pcie_set_pwr_vmain(trans); | 257 | iwl_pcie_set_pwr(trans, false); |
263 | 258 | ||
264 | iwl_op_mode_nic_config(trans->op_mode); | 259 | iwl_op_mode_nic_config(trans->op_mode); |
265 | 260 | ||
@@ -435,7 +430,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, | |||
435 | } | 430 | } |
436 | 431 | ||
437 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | 432 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, |
438 | const struct fw_img *fw) | 433 | const struct fw_img *fw, bool run_in_rfkill) |
439 | { | 434 | { |
440 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 435 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
441 | int ret; | 436 | int ret; |
@@ -454,7 +449,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | |||
454 | /* If platform's RF_KILL switch is NOT set to KILL */ | 449 | /* If platform's RF_KILL switch is NOT set to KILL */ |
455 | hw_rfkill = iwl_is_rfkill_set(trans); | 450 | hw_rfkill = iwl_is_rfkill_set(trans); |
456 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 451 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
457 | if (hw_rfkill) | 452 | if (hw_rfkill && !run_in_rfkill) |
458 | return -ERFKILL; | 453 | return -ERFKILL; |
459 | 454 | ||
460 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | 455 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); |
@@ -534,12 +529,6 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
534 | 529 | ||
535 | iwl_enable_rfkill_int(trans); | 530 | iwl_enable_rfkill_int(trans); |
536 | 531 | ||
537 | /* wait to make sure we flush pending tasklet*/ | ||
538 | synchronize_irq(trans_pcie->irq); | ||
539 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
540 | |||
541 | cancel_work_sync(&trans_pcie->rx_replenish); | ||
542 | |||
543 | /* stop and reset the on-board processor */ | 532 | /* stop and reset the on-board processor */ |
544 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 533 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
545 | 534 | ||
@@ -551,46 +540,87 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
551 | clear_bit(STATUS_RFKILL, &trans_pcie->status); | 540 | clear_bit(STATUS_RFKILL, &trans_pcie->status); |
552 | } | 541 | } |
553 | 542 | ||
554 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) | 543 | static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans) |
555 | { | 544 | { |
556 | /* let the ucode operate on its own */ | 545 | /* let the ucode operate on its own */ |
557 | iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, | 546 | iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, |
558 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | 547 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); |
559 | 548 | ||
560 | iwl_disable_interrupts(trans); | 549 | iwl_disable_interrupts(trans); |
550 | iwl_pcie_disable_ict(trans); | ||
551 | |||
561 | iwl_clear_bit(trans, CSR_GP_CNTRL, | 552 | iwl_clear_bit(trans, CSR_GP_CNTRL, |
562 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 553 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
554 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
555 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
556 | |||
557 | /* | ||
558 | * reset TX queues -- some of their registers reset during S3 | ||
559 | * so if we don't reset everything here the D3 image would try | ||
560 | * to execute some invalid memory upon resume | ||
561 | */ | ||
562 | iwl_trans_pcie_tx_reset(trans); | ||
563 | |||
564 | iwl_pcie_set_pwr(trans, true); | ||
563 | } | 565 | } |
564 | 566 | ||
565 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | 567 | static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, |
568 | enum iwl_d3_status *status) | ||
566 | { | 569 | { |
567 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 570 | u32 val; |
568 | int err; | 571 | int ret; |
569 | bool hw_rfkill; | ||
570 | 572 | ||
571 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | 573 | iwl_pcie_set_pwr(trans, false); |
572 | 574 | ||
573 | if (!trans_pcie->irq_requested) { | 575 | val = iwl_read32(trans, CSR_RESET); |
574 | tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) | 576 | if (val & CSR_RESET_REG_FLAG_NEVO_RESET) { |
575 | iwl_pcie_tasklet, (unsigned long)trans); | 577 | *status = IWL_D3_STATUS_RESET; |
578 | return 0; | ||
579 | } | ||
576 | 580 | ||
577 | iwl_pcie_alloc_ict(trans); | 581 | /* |
582 | * Also enables interrupts - none will happen as the device doesn't | ||
583 | * know we're waking it up, only when the opmode actually tells it | ||
584 | * after this call. | ||
585 | */ | ||
586 | iwl_pcie_reset_ict(trans); | ||
578 | 587 | ||
579 | err = request_irq(trans_pcie->irq, iwl_pcie_isr_ict, | 588 | iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
580 | IRQF_SHARED, DRV_NAME, trans); | 589 | iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
581 | if (err) { | ||
582 | IWL_ERR(trans, "Error allocating IRQ %d\n", | ||
583 | trans_pcie->irq); | ||
584 | goto error; | ||
585 | } | ||
586 | 590 | ||
587 | trans_pcie->irq_requested = true; | 591 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, |
592 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
593 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
594 | 25000); | ||
595 | if (ret) { | ||
596 | IWL_ERR(trans, "Failed to resume the device (mac ready)\n"); | ||
597 | return ret; | ||
588 | } | 598 | } |
589 | 599 | ||
600 | iwl_trans_pcie_tx_reset(trans); | ||
601 | |||
602 | ret = iwl_pcie_rx_init(trans); | ||
603 | if (ret) { | ||
604 | IWL_ERR(trans, "Failed to resume the device (RX reset)\n"); | ||
605 | return ret; | ||
606 | } | ||
607 | |||
608 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, | ||
609 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
610 | |||
611 | *status = IWL_D3_STATUS_ALIVE; | ||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | ||
616 | { | ||
617 | bool hw_rfkill; | ||
618 | int err; | ||
619 | |||
590 | err = iwl_pcie_prepare_card_hw(trans); | 620 | err = iwl_pcie_prepare_card_hw(trans); |
591 | if (err) { | 621 | if (err) { |
592 | IWL_ERR(trans, "Error while preparing HW: %d\n", err); | 622 | IWL_ERR(trans, "Error while preparing HW: %d\n", err); |
593 | goto err_free_irq; | 623 | return err; |
594 | } | 624 | } |
595 | 625 | ||
596 | iwl_pcie_apm_init(trans); | 626 | iwl_pcie_apm_init(trans); |
@@ -601,15 +631,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
601 | hw_rfkill = iwl_is_rfkill_set(trans); | 631 | hw_rfkill = iwl_is_rfkill_set(trans); |
602 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 632 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
603 | 633 | ||
604 | return err; | 634 | return 0; |
605 | |||
606 | err_free_irq: | ||
607 | trans_pcie->irq_requested = false; | ||
608 | free_irq(trans_pcie->irq, trans); | ||
609 | error: | ||
610 | iwl_pcie_free_ict(trans); | ||
611 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
612 | return err; | ||
613 | } | 635 | } |
614 | 636 | ||
615 | static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, | 637 | static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, |
@@ -703,19 +725,21 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, | |||
703 | msecs_to_jiffies(trans_cfg->queue_watchdog_timeout); | 725 | msecs_to_jiffies(trans_cfg->queue_watchdog_timeout); |
704 | 726 | ||
705 | trans_pcie->command_names = trans_cfg->command_names; | 727 | trans_pcie->command_names = trans_cfg->command_names; |
728 | trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; | ||
706 | } | 729 | } |
707 | 730 | ||
708 | void iwl_trans_pcie_free(struct iwl_trans *trans) | 731 | void iwl_trans_pcie_free(struct iwl_trans *trans) |
709 | { | 732 | { |
710 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 733 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
711 | 734 | ||
735 | synchronize_irq(trans_pcie->pci_dev->irq); | ||
736 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
737 | |||
712 | iwl_pcie_tx_free(trans); | 738 | iwl_pcie_tx_free(trans); |
713 | iwl_pcie_rx_free(trans); | 739 | iwl_pcie_rx_free(trans); |
714 | 740 | ||
715 | if (trans_pcie->irq_requested == true) { | 741 | free_irq(trans_pcie->pci_dev->irq, trans); |
716 | free_irq(trans_pcie->irq, trans); | 742 | iwl_pcie_free_ict(trans); |
717 | iwl_pcie_free_ict(trans); | ||
718 | } | ||
719 | 743 | ||
720 | pci_disable_msi(trans_pcie->pci_dev); | 744 | pci_disable_msi(trans_pcie->pci_dev); |
721 | iounmap(trans_pcie->hw_base); | 745 | iounmap(trans_pcie->hw_base); |
@@ -751,13 +775,112 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) | |||
751 | hw_rfkill = iwl_is_rfkill_set(trans); | 775 | hw_rfkill = iwl_is_rfkill_set(trans); |
752 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 776 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
753 | 777 | ||
754 | if (!hw_rfkill) | ||
755 | iwl_enable_interrupts(trans); | ||
756 | |||
757 | return 0; | 778 | return 0; |
758 | } | 779 | } |
759 | #endif /* CONFIG_PM_SLEEP */ | 780 | #endif /* CONFIG_PM_SLEEP */ |
760 | 781 | ||
782 | static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) | ||
783 | { | ||
784 | int ret; | ||
785 | |||
786 | lockdep_assert_held(&trans->reg_lock); | ||
787 | |||
788 | /* this bit wakes up the NIC */ | ||
789 | __iwl_set_bit(trans, CSR_GP_CNTRL, | ||
790 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
791 | |||
792 | /* | ||
793 | * These bits say the device is running, and should keep running for | ||
794 | * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), | ||
795 | * but they do not indicate that embedded SRAM is restored yet; | ||
796 | * 3945 and 4965 have volatile SRAM, and must save/restore contents | ||
797 | * to/from host DRAM when sleeping/waking for power-saving. | ||
798 | * Each direction takes approximately 1/4 millisecond; with this | ||
799 | * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a | ||
800 | * series of register accesses are expected (e.g. reading Event Log), | ||
801 | * to keep device from sleeping. | ||
802 | * | ||
803 | * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that | ||
804 | * SRAM is okay/restored. We don't check that here because this call | ||
805 | * is just for hardware register access; but GP1 MAC_SLEEP check is a | ||
806 | * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). | ||
807 | * | ||
808 | * 5000 series and later (including 1000 series) have non-volatile SRAM, | ||
809 | * and do not save/restore SRAM when power cycling. | ||
810 | */ | ||
811 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
812 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, | ||
813 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | ||
814 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); | ||
815 | if (unlikely(ret < 0)) { | ||
816 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); | ||
817 | if (!silent) { | ||
818 | u32 val = iwl_read32(trans, CSR_GP_CNTRL); | ||
819 | WARN_ONCE(1, | ||
820 | "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", | ||
821 | val); | ||
822 | return false; | ||
823 | } | ||
824 | } | ||
825 | |||
826 | return true; | ||
827 | } | ||
828 | |||
829 | static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) | ||
830 | { | ||
831 | lockdep_assert_held(&trans->reg_lock); | ||
832 | __iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
833 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
834 | /* | ||
835 | * Above we read the CSR_GP_CNTRL register, which will flush | ||
836 | * any previous writes, but we need the write that clears the | ||
837 | * MAC_ACCESS_REQ bit to be performed before any other writes | ||
838 | * scheduled on different CPUs (after we drop reg_lock). | ||
839 | */ | ||
840 | mmiowb(); | ||
841 | } | ||
842 | |||
843 | static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, | ||
844 | void *buf, int dwords) | ||
845 | { | ||
846 | unsigned long flags; | ||
847 | int offs, ret = 0; | ||
848 | u32 *vals = buf; | ||
849 | |||
850 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
851 | if (iwl_trans_grab_nic_access(trans, false)) { | ||
852 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | ||
853 | for (offs = 0; offs < dwords; offs++) | ||
854 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | ||
855 | iwl_trans_release_nic_access(trans); | ||
856 | } else { | ||
857 | ret = -EBUSY; | ||
858 | } | ||
859 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
860 | return ret; | ||
861 | } | ||
862 | |||
863 | static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, | ||
864 | void *buf, int dwords) | ||
865 | { | ||
866 | unsigned long flags; | ||
867 | int offs, ret = 0; | ||
868 | u32 *vals = buf; | ||
869 | |||
870 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
871 | if (iwl_trans_grab_nic_access(trans, false)) { | ||
872 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); | ||
873 | for (offs = 0; offs < dwords; offs++) | ||
874 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, | ||
875 | vals ? vals[offs] : 0); | ||
876 | iwl_trans_release_nic_access(trans); | ||
877 | } else { | ||
878 | ret = -EBUSY; | ||
879 | } | ||
880 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
881 | return ret; | ||
882 | } | ||
883 | |||
761 | #define IWL_FLUSH_WAIT_MS 2000 | 884 | #define IWL_FLUSH_WAIT_MS 2000 |
762 | 885 | ||
763 | static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) | 886 | static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) |
@@ -767,6 +890,8 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) | |||
767 | struct iwl_queue *q; | 890 | struct iwl_queue *q; |
768 | int cnt; | 891 | int cnt; |
769 | unsigned long now = jiffies; | 892 | unsigned long now = jiffies; |
893 | u32 scd_sram_addr; | ||
894 | u8 buf[16]; | ||
770 | int ret = 0; | 895 | int ret = 0; |
771 | 896 | ||
772 | /* waiting for all the tx frames complete might take a while */ | 897 | /* waiting for all the tx frames complete might take a while */ |
@@ -780,11 +905,50 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) | |||
780 | msleep(1); | 905 | msleep(1); |
781 | 906 | ||
782 | if (q->read_ptr != q->write_ptr) { | 907 | if (q->read_ptr != q->write_ptr) { |
783 | IWL_ERR(trans, "fail to flush all tx fifo queues\n"); | 908 | IWL_ERR(trans, |
909 | "fail to flush all tx fifo queues Q %d\n", cnt); | ||
784 | ret = -ETIMEDOUT; | 910 | ret = -ETIMEDOUT; |
785 | break; | 911 | break; |
786 | } | 912 | } |
787 | } | 913 | } |
914 | |||
915 | if (!ret) | ||
916 | return 0; | ||
917 | |||
918 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | ||
919 | txq->q.read_ptr, txq->q.write_ptr); | ||
920 | |||
921 | scd_sram_addr = trans_pcie->scd_base_addr + | ||
922 | SCD_TX_STTS_QUEUE_OFFSET(txq->q.id); | ||
923 | iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); | ||
924 | |||
925 | iwl_print_hex_error(trans, buf, sizeof(buf)); | ||
926 | |||
927 | for (cnt = 0; cnt < FH_TCSR_CHNL_NUM; cnt++) | ||
928 | IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", cnt, | ||
929 | iwl_read_direct32(trans, FH_TX_TRB_REG(cnt))); | ||
930 | |||
931 | for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) { | ||
932 | u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(cnt)); | ||
933 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; | ||
934 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); | ||
935 | u32 tbl_dw = | ||
936 | iwl_trans_read_mem32(trans, trans_pcie->scd_base_addr + | ||
937 | SCD_TRANS_TBL_OFFSET_QUEUE(cnt)); | ||
938 | |||
939 | if (cnt & 0x1) | ||
940 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; | ||
941 | else | ||
942 | tbl_dw = tbl_dw & 0x0000FFFF; | ||
943 | |||
944 | IWL_ERR(trans, | ||
945 | "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", | ||
946 | cnt, active ? "" : "in", fifo, tbl_dw, | ||
947 | iwl_read_prph(trans, | ||
948 | SCD_QUEUE_RDPTR(cnt)) & (txq->q.n_bd - 1), | ||
949 | iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt))); | ||
950 | } | ||
951 | |||
788 | return ret; | 952 | return ret; |
789 | } | 953 | } |
790 | 954 | ||
@@ -1212,7 +1376,8 @@ static const struct iwl_trans_ops trans_ops_pcie = { | |||
1212 | .start_fw = iwl_trans_pcie_start_fw, | 1376 | .start_fw = iwl_trans_pcie_start_fw, |
1213 | .stop_device = iwl_trans_pcie_stop_device, | 1377 | .stop_device = iwl_trans_pcie_stop_device, |
1214 | 1378 | ||
1215 | .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, | 1379 | .d3_suspend = iwl_trans_pcie_d3_suspend, |
1380 | .d3_resume = iwl_trans_pcie_d3_resume, | ||
1216 | 1381 | ||
1217 | .send_cmd = iwl_trans_pcie_send_hcmd, | 1382 | .send_cmd = iwl_trans_pcie_send_hcmd, |
1218 | 1383 | ||
@@ -1235,8 +1400,12 @@ static const struct iwl_trans_ops trans_ops_pcie = { | |||
1235 | .read32 = iwl_trans_pcie_read32, | 1400 | .read32 = iwl_trans_pcie_read32, |
1236 | .read_prph = iwl_trans_pcie_read_prph, | 1401 | .read_prph = iwl_trans_pcie_read_prph, |
1237 | .write_prph = iwl_trans_pcie_write_prph, | 1402 | .write_prph = iwl_trans_pcie_write_prph, |
1403 | .read_mem = iwl_trans_pcie_read_mem, | ||
1404 | .write_mem = iwl_trans_pcie_write_mem, | ||
1238 | .configure = iwl_trans_pcie_configure, | 1405 | .configure = iwl_trans_pcie_configure, |
1239 | .set_pmi = iwl_trans_pcie_set_pmi, | 1406 | .set_pmi = iwl_trans_pcie_set_pmi, |
1407 | .grab_nic_access = iwl_trans_pcie_grab_nic_access, | ||
1408 | .release_nic_access = iwl_trans_pcie_release_nic_access | ||
1240 | }; | 1409 | }; |
1241 | 1410 | ||
1242 | struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | 1411 | struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, |
@@ -1318,7 +1487,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1318 | } | 1487 | } |
1319 | 1488 | ||
1320 | trans->dev = &pdev->dev; | 1489 | trans->dev = &pdev->dev; |
1321 | trans_pcie->irq = pdev->irq; | ||
1322 | trans_pcie->pci_dev = pdev; | 1490 | trans_pcie->pci_dev = pdev; |
1323 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); | 1491 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); |
1324 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; | 1492 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; |
@@ -1344,8 +1512,27 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1344 | if (!trans->dev_cmd_pool) | 1512 | if (!trans->dev_cmd_pool) |
1345 | goto out_pci_disable_msi; | 1513 | goto out_pci_disable_msi; |
1346 | 1514 | ||
1515 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | ||
1516 | |||
1517 | tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) | ||
1518 | iwl_pcie_tasklet, (unsigned long)trans); | ||
1519 | |||
1520 | if (iwl_pcie_alloc_ict(trans)) | ||
1521 | goto out_free_cmd_pool; | ||
1522 | |||
1523 | err = request_irq(pdev->irq, iwl_pcie_isr_ict, | ||
1524 | IRQF_SHARED, DRV_NAME, trans); | ||
1525 | if (err) { | ||
1526 | IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq); | ||
1527 | goto out_free_ict; | ||
1528 | } | ||
1529 | |||
1347 | return trans; | 1530 | return trans; |
1348 | 1531 | ||
1532 | out_free_ict: | ||
1533 | iwl_pcie_free_ict(trans); | ||
1534 | out_free_cmd_pool: | ||
1535 | kmem_cache_destroy(trans->dev_cmd_pool); | ||
1349 | out_pci_disable_msi: | 1536 | out_pci_disable_msi: |
1350 | pci_disable_msi(pdev); | 1537 | pci_disable_msi(pdev); |
1351 | out_pci_release_regions: | 1538 | out_pci_release_regions: |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 6c5b867c353a..a93f06762b96 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -160,7 +160,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) | |||
160 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | 160 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", |
161 | txq->q.read_ptr, txq->q.write_ptr); | 161 | txq->q.read_ptr, txq->q.write_ptr); |
162 | 162 | ||
163 | iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); | 163 | iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); |
164 | 164 | ||
165 | iwl_print_hex_error(trans, buf, sizeof(buf)); | 165 | iwl_print_hex_error(trans, buf, sizeof(buf)); |
166 | 166 | ||
@@ -173,9 +173,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) | |||
173 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; | 173 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; |
174 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); | 174 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); |
175 | u32 tbl_dw = | 175 | u32 tbl_dw = |
176 | iwl_read_targ_mem(trans, | 176 | iwl_trans_read_mem32(trans, |
177 | trans_pcie->scd_base_addr + | 177 | trans_pcie->scd_base_addr + |
178 | SCD_TRANS_TBL_OFFSET_QUEUE(i)); | 178 | SCD_TRANS_TBL_OFFSET_QUEUE(i)); |
179 | 179 | ||
180 | if (i & 0x1) | 180 | if (i & 0x1) |
181 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; | 181 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; |
@@ -237,7 +237,10 @@ static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | |||
237 | break; | 237 | break; |
238 | } | 238 | } |
239 | 239 | ||
240 | bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12)); | 240 | if (trans_pcie->bc_table_dword) |
241 | len = DIV_ROUND_UP(len, 4); | ||
242 | |||
243 | bc_ent = cpu_to_le16(len | (sta_id << 12)); | ||
241 | 244 | ||
242 | scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; | 245 | scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; |
243 | 246 | ||
@@ -306,6 +309,9 @@ void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) | |||
306 | return; | 309 | return; |
307 | } | 310 | } |
308 | 311 | ||
312 | IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, | ||
313 | txq->q.write_ptr); | ||
314 | |||
309 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | 315 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, |
310 | txq->q.write_ptr | (txq_id << 8)); | 316 | txq->q.write_ptr | (txq_id << 8)); |
311 | 317 | ||
@@ -612,7 +618,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) | |||
612 | if (txq->q.n_bd) { | 618 | if (txq->q.n_bd) { |
613 | dma_free_coherent(dev, sizeof(struct iwl_tfd) * | 619 | dma_free_coherent(dev, sizeof(struct iwl_tfd) * |
614 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); | 620 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); |
615 | memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr)); | 621 | txq->q.dma_addr = 0; |
616 | } | 622 | } |
617 | 623 | ||
618 | kfree(txq->entries); | 624 | kfree(txq->entries); |
@@ -638,9 +644,11 @@ static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask) | |||
638 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | 644 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) |
639 | { | 645 | { |
640 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 646 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
641 | u32 a; | 647 | int nq = trans->cfg->base_params->num_of_queues; |
642 | int chan; | 648 | int chan; |
643 | u32 reg_val; | 649 | u32 reg_val; |
650 | int clear_dwords = (SCD_TRANS_TBL_OFFSET_QUEUE(nq) - | ||
651 | SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(u32); | ||
644 | 652 | ||
645 | /* make sure all queue are not stopped/used */ | 653 | /* make sure all queue are not stopped/used */ |
646 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); | 654 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); |
@@ -652,20 +660,10 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | |||
652 | WARN_ON(scd_base_addr != 0 && | 660 | WARN_ON(scd_base_addr != 0 && |
653 | scd_base_addr != trans_pcie->scd_base_addr); | 661 | scd_base_addr != trans_pcie->scd_base_addr); |
654 | 662 | ||
655 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; | 663 | /* reset context data, TX status and translation data */ |
656 | /* reset conext data memory */ | 664 | iwl_trans_write_mem(trans, trans_pcie->scd_base_addr + |
657 | for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; | 665 | SCD_CONTEXT_MEM_LOWER_BOUND, |
658 | a += 4) | 666 | NULL, clear_dwords); |
659 | iwl_write_targ_mem(trans, a, 0); | ||
660 | /* reset tx status memory */ | ||
661 | for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; | ||
662 | a += 4) | ||
663 | iwl_write_targ_mem(trans, a, 0); | ||
664 | for (; a < trans_pcie->scd_base_addr + | ||
665 | SCD_TRANS_TBL_OFFSET_QUEUE( | ||
666 | trans->cfg->base_params->num_of_queues); | ||
667 | a += 4) | ||
668 | iwl_write_targ_mem(trans, a, 0); | ||
669 | 667 | ||
670 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, | 668 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, |
671 | trans_pcie->scd_bc_tbls.dma >> 10); | 669 | trans_pcie->scd_bc_tbls.dma >> 10); |
@@ -697,6 +695,29 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | |||
697 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | 695 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
698 | } | 696 | } |
699 | 697 | ||
698 | void iwl_trans_pcie_tx_reset(struct iwl_trans *trans) | ||
699 | { | ||
700 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
701 | int txq_id; | ||
702 | |||
703 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | ||
704 | txq_id++) { | ||
705 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; | ||
706 | |||
707 | iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), | ||
708 | txq->q.dma_addr >> 8); | ||
709 | iwl_pcie_txq_unmap(trans, txq_id); | ||
710 | txq->q.read_ptr = 0; | ||
711 | txq->q.write_ptr = 0; | ||
712 | } | ||
713 | |||
714 | /* Tell NIC where to find the "keep warm" buffer */ | ||
715 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, | ||
716 | trans_pcie->kw.dma >> 4); | ||
717 | |||
718 | iwl_pcie_tx_start(trans, trans_pcie->scd_base_addr); | ||
719 | } | ||
720 | |||
700 | /* | 721 | /* |
701 | * iwl_pcie_tx_stop - Stop all Tx DMA channels | 722 | * iwl_pcie_tx_stop - Stop all Tx DMA channels |
702 | */ | 723 | */ |
@@ -1002,14 +1023,14 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, | |||
1002 | tbl_dw_addr = trans_pcie->scd_base_addr + | 1023 | tbl_dw_addr = trans_pcie->scd_base_addr + |
1003 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); | 1024 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); |
1004 | 1025 | ||
1005 | tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); | 1026 | tbl_dw = iwl_trans_read_mem32(trans, tbl_dw_addr); |
1006 | 1027 | ||
1007 | if (txq_id & 0x1) | 1028 | if (txq_id & 0x1) |
1008 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); | 1029 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); |
1009 | else | 1030 | else |
1010 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); | 1031 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); |
1011 | 1032 | ||
1012 | iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); | 1033 | iwl_trans_write_mem32(trans, tbl_dw_addr, tbl_dw); |
1013 | 1034 | ||
1014 | return 0; | 1035 | return 0; |
1015 | } | 1036 | } |
@@ -1068,9 +1089,9 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
1068 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | 1089 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); |
1069 | 1090 | ||
1070 | /* Set up Tx window size and frame limit for this queue */ | 1091 | /* Set up Tx window size and frame limit for this queue */ |
1071 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 1092 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + |
1072 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); | 1093 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); |
1073 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 1094 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + |
1074 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), | 1095 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), |
1075 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 1096 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
1076 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 1097 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
@@ -1101,8 +1122,8 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | |||
1101 | 1122 | ||
1102 | iwl_pcie_txq_set_inactive(trans, txq_id); | 1123 | iwl_pcie_txq_set_inactive(trans, txq_id); |
1103 | 1124 | ||
1104 | _iwl_write_targ_mem_dwords(trans, stts_addr, | 1125 | iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, |
1105 | zero_val, ARRAY_SIZE(zero_val)); | 1126 | ARRAY_SIZE(zero_val)); |
1106 | 1127 | ||
1107 | iwl_pcie_txq_unmap(trans, txq_id); | 1128 | iwl_pcie_txq_unmap(trans, txq_id); |
1108 | 1129 | ||
@@ -1642,10 +1663,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1642 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | 1663 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); |
1643 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | 1664 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); |
1644 | 1665 | ||
1645 | IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", | ||
1646 | le16_to_cpu(dev_cmd->hdr.sequence)); | ||
1647 | IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); | ||
1648 | |||
1649 | /* Set up entry for this TFD in Tx byte-count array */ | 1666 | /* Set up entry for this TFD in Tx byte-count array */ |
1650 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); | 1667 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); |
1651 | 1668 | ||