aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/pcie
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h7
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c125
2 files changed, 128 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 6c22b23a2845..78f72c34438a 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -260,6 +260,9 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
260 * @wd_timeout: queue watchdog timeout (jiffies) 260 * @wd_timeout: queue watchdog timeout (jiffies)
261 * @reg_lock: protect hw register access 261 * @reg_lock: protect hw register access
262 * @cmd_in_flight: true when we have a host command in flight 262 * @cmd_in_flight: true when we have a host command in flight
263 * @fw_mon_phys: physical address of the buffer for the firmware monitor
264 * @fw_mon_page: points to the first page of the buffer for the firmware monitor
265 * @fw_mon_size: size of the buffer for the firmware monitor
263 */ 266 */
264struct iwl_trans_pcie { 267struct iwl_trans_pcie {
265 struct iwl_rxq rxq; 268 struct iwl_rxq rxq;
@@ -312,6 +315,10 @@ struct iwl_trans_pcie {
312 /*protect hw register */ 315 /*protect hw register */
313 spinlock_t reg_lock; 316 spinlock_t reg_lock;
314 bool cmd_in_flight; 317 bool cmd_in_flight;
318
319 dma_addr_t fw_mon_phys;
320 struct page *fw_mon_page;
321 u32 fw_mon_size;
315}; 322};
316 323
317#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ 324#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 788085bc65d7..3ffac4888c12 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -76,6 +76,68 @@
76#include "iwl-fw-error-dump.h" 76#include "iwl-fw-error-dump.h"
77#include "internal.h" 77#include "internal.h"
78 78
79static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
80{
81 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
82
83 if (!trans_pcie->fw_mon_page)
84 return;
85
86 dma_unmap_page(trans->dev, trans_pcie->fw_mon_phys,
87 trans_pcie->fw_mon_size, DMA_FROM_DEVICE);
88 __free_pages(trans_pcie->fw_mon_page,
89 get_order(trans_pcie->fw_mon_size));
90 trans_pcie->fw_mon_page = NULL;
91 trans_pcie->fw_mon_phys = 0;
92 trans_pcie->fw_mon_size = 0;
93}
94
95static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans)
96{
97 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
98 struct page *page;
99 dma_addr_t phys;
100 u32 size;
101 u8 power;
102
103 if (trans_pcie->fw_mon_page) {
104 dma_sync_single_for_device(trans->dev, trans_pcie->fw_mon_phys,
105 trans_pcie->fw_mon_size,
106 DMA_FROM_DEVICE);
107 return;
108 }
109
110 phys = 0;
111 for (power = 26; power >= 11; power--) {
112 int order;
113
114 size = BIT(power);
115 order = get_order(size);
116 page = alloc_pages(__GFP_COMP | __GFP_NOWARN | __GFP_ZERO,
117 order);
118 if (!page)
119 continue;
120
121 phys = dma_map_page(trans->dev, page, 0, PAGE_SIZE << order,
122 DMA_FROM_DEVICE);
123 if (dma_mapping_error(trans->dev, phys)) {
124 __free_pages(page, order);
125 continue;
126 }
127 IWL_INFO(trans,
128 "Allocated 0x%08x bytes (order %d) for firmware monitor.\n",
129 size, order);
130 break;
131 }
132
133 if (!page)
134 return;
135
136 trans_pcie->fw_mon_page = page;
137 trans_pcie->fw_mon_phys = phys;
138 trans_pcie->fw_mon_size = size;
139}
140
79static u32 iwl_trans_pcie_read_shr(struct iwl_trans *trans, u32 reg) 141static u32 iwl_trans_pcie_read_shr(struct iwl_trans *trans, u32 reg)
80{ 142{
81 iwl_write32(trans, HEEP_CTRL_WRD_PCIEX_CTRL_REG, 143 iwl_write32(trans, HEEP_CTRL_WRD_PCIEX_CTRL_REG,
@@ -675,6 +737,7 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
675static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, 737static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
676 const struct fw_img *image) 738 const struct fw_img *image)
677{ 739{
740 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
678 int ret = 0; 741 int ret = 0;
679 int first_ucode_section; 742 int first_ucode_section;
680 743
@@ -733,6 +796,20 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
733 return ret; 796 return ret;
734 } 797 }
735 798
799 /* supported for 7000 only for the moment */
800 if (iwlwifi_mod_params.fw_monitor &&
801 trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
802 iwl_pcie_alloc_fw_monitor(trans);
803
804 if (trans_pcie->fw_mon_size) {
805 iwl_write_prph(trans, MON_BUFF_BASE_ADDR,
806 trans_pcie->fw_mon_phys >> 4);
807 iwl_write_prph(trans, MON_BUFF_END_ADDR,
808 (trans_pcie->fw_mon_phys +
809 trans_pcie->fw_mon_size) >> 4);
810 }
811 }
812
736 /* release CPU reset */ 813 /* release CPU reset */
737 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) 814 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
738 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); 815 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
@@ -1126,6 +1203,8 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
1126 if (trans_pcie->napi.poll) 1203 if (trans_pcie->napi.poll)
1127 netif_napi_del(&trans_pcie->napi); 1204 netif_napi_del(&trans_pcie->napi);
1128 1205
1206 iwl_pcie_free_fw_monitor(trans);
1207
1129 kfree(trans); 1208 kfree(trans);
1130} 1209}
1131 1210
@@ -1698,10 +1777,15 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
1698 u32 len; 1777 u32 len;
1699 int i, ptr; 1778 int i, ptr;
1700 1779
1780 len = sizeof(*data) +
1781 cmdq->q.n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE);
1782
1783 if (trans_pcie->fw_mon_page)
1784 len += sizeof(*data) + sizeof(struct iwl_fw_error_fw_mon) +
1785 trans_pcie->fw_mon_size;
1786
1701 if (!buf) 1787 if (!buf)
1702 return sizeof(*data) + 1788 return len;
1703 cmdq->q.n_window * (sizeof(*txcmd) +
1704 TFD_MAX_PAYLOAD_SIZE);
1705 1789
1706 len = 0; 1790 len = 0;
1707 data = buf; 1791 data = buf;
@@ -1729,7 +1813,40 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
1729 spin_unlock_bh(&cmdq->lock); 1813 spin_unlock_bh(&cmdq->lock);
1730 1814
1731 data->len = cpu_to_le32(len); 1815 data->len = cpu_to_le32(len);
1732 return sizeof(*data) + len; 1816 len += sizeof(*data);
1817
1818 if (trans_pcie->fw_mon_page) {
1819 struct iwl_fw_error_fw_mon *fw_mon_data;
1820
1821 data = iwl_fw_error_next_data(data);
1822 data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
1823 data->len = cpu_to_le32(trans_pcie->fw_mon_size +
1824 sizeof(*fw_mon_data));
1825 fw_mon_data = (void *)data->data;
1826 fw_mon_data->fw_mon_wr_ptr =
1827 cpu_to_le32(iwl_read_prph(trans, MON_BUFF_WRPTR));
1828 fw_mon_data->fw_mon_cycle_cnt =
1829 cpu_to_le32(iwl_read_prph(trans, MON_BUFF_CYCLE_CNT));
1830 fw_mon_data->fw_mon_base_ptr =
1831 cpu_to_le32(iwl_read_prph(trans, MON_BUFF_BASE_ADDR));
1832
1833 /*
1834 * The firmware is now asserted, it won't write anything to
1835 * the buffer. CPU can take ownership to fetch the data.
1836 * The buffer will be handed back to the device before the
1837 * firmware will be restarted.
1838 */
1839 dma_sync_single_for_cpu(trans->dev, trans_pcie->fw_mon_phys,
1840 trans_pcie->fw_mon_size,
1841 DMA_FROM_DEVICE);
1842 memcpy(fw_mon_data->data, page_address(trans_pcie->fw_mon_page),
1843 trans_pcie->fw_mon_size);
1844
1845 len += sizeof(*data) + sizeof(*fw_mon_data) +
1846 trans_pcie->fw_mon_size;
1847 }
1848
1849 return len;
1733} 1850}
1734#else 1851#else
1735static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, 1852static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,