Commit c5f97542 authored by Shahar S Matityahu's avatar Shahar S Matityahu Committed by Luca Coelho

iwlwifi: change monitor DMA to be coherent

Allow access to the memory by the host and the device simultaneously.
This will be needed in some future patches.
Signed-off-by: default avatarShahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 2859de76
...@@ -464,7 +464,7 @@ struct iwl_self_init_dram { ...@@ -464,7 +464,7 @@ struct iwl_self_init_dram {
* @mutex: to protect stop_device / start_fw / start_hw * @mutex: to protect stop_device / start_fw / start_hw
* @cmd_in_flight: true when we have a host command in flight * @cmd_in_flight: true when we have a host command in flight
* @fw_mon_phys: physical address of the buffer for the firmware monitor * @fw_mon_phys: physical address of the buffer for the firmware monitor
* @fw_mon_page: points to the first page of the buffer for the firmware monitor * @fw_mon_cpu_addr: address of the buffer for the firmware monitor
* @fw_mon_size: size of the buffer for the firmware monitor * @fw_mon_size: size of the buffer for the firmware monitor
* @msix_entries: array of MSI-X entries * @msix_entries: array of MSI-X entries
* @msix_enabled: true if managed to enable MSI-X * @msix_enabled: true if managed to enable MSI-X
...@@ -554,7 +554,7 @@ struct iwl_trans_pcie { ...@@ -554,7 +554,7 @@ struct iwl_trans_pcie {
bool ref_cmd_in_flight; bool ref_cmd_in_flight;
dma_addr_t fw_mon_phys; dma_addr_t fw_mon_phys;
struct page *fw_mon_page; void *fw_mon_cpu_addr;
u32 fw_mon_size; u32 fw_mon_size;
struct msix_entry msix_entries[IWL_MAX_RX_HW_QUEUES]; struct msix_entry msix_entries[IWL_MAX_RX_HW_QUEUES];
......
...@@ -187,14 +187,13 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans) ...@@ -187,14 +187,13 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
if (!trans_pcie->fw_mon_page) if (!trans_pcie->fw_mon_cpu_addr)
return; return;
dma_unmap_page(trans->dev, trans_pcie->fw_mon_phys, dma_free_coherent(trans->dev, trans_pcie->fw_mon_size,
trans_pcie->fw_mon_size, DMA_FROM_DEVICE); trans_pcie->fw_mon_cpu_addr,
__free_pages(trans_pcie->fw_mon_page, trans_pcie->fw_mon_phys);
get_order(trans_pcie->fw_mon_size)); trans_pcie->fw_mon_cpu_addr = NULL;
trans_pcie->fw_mon_page = NULL;
trans_pcie->fw_mon_phys = 0; trans_pcie->fw_mon_phys = 0;
trans_pcie->fw_mon_size = 0; trans_pcie->fw_mon_size = 0;
} }
...@@ -202,7 +201,7 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans) ...@@ -202,7 +201,7 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power) void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power)
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct page *page = NULL; void *cpu_addr = NULL;
dma_addr_t phys; dma_addr_t phys;
u32 size = 0; u32 size = 0;
u8 power; u8 power;
...@@ -219,38 +218,25 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power) ...@@ -219,38 +218,25 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power)
max_power)) max_power))
return; return;
if (trans_pcie->fw_mon_page) { if (trans_pcie->fw_mon_cpu_addr)
dma_sync_single_for_device(trans->dev, trans_pcie->fw_mon_phys,
trans_pcie->fw_mon_size,
DMA_FROM_DEVICE);
return; return;
}
phys = 0; phys = 0;
for (power = max_power; power >= 11; power--) { for (power = max_power; power >= 11; power--) {
int order;
size = BIT(power); size = BIT(power);
order = get_order(size); cpu_addr = dma_alloc_coherent(trans->dev, size, &phys,
page = alloc_pages(__GFP_COMP | __GFP_NOWARN | __GFP_ZERO, GFP_KERNEL | __GFP_NOWARN |
order); __GFP_ZERO | __GFP_COMP);
if (!page) if (!cpu_addr)
continue; continue;
phys = dma_map_page(trans->dev, page, 0, PAGE_SIZE << order,
DMA_FROM_DEVICE);
if (dma_mapping_error(trans->dev, phys)) {
__free_pages(page, order);
page = NULL;
continue;
}
IWL_INFO(trans, IWL_INFO(trans,
"Allocated 0x%08x bytes (order %d) for firmware monitor.\n", "Allocated 0x%08x bytes for firmware monitor.\n",
size, order); size);
break; break;
} }
if (WARN_ON_ONCE(!page)) if (WARN_ON_ONCE(!cpu_addr))
return; return;
if (power != max_power) if (power != max_power)
...@@ -259,7 +245,7 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power) ...@@ -259,7 +245,7 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power)
(unsigned long)BIT(power - 10), (unsigned long)BIT(power - 10),
(unsigned long)BIT(max_power - 10)); (unsigned long)BIT(max_power - 10));
trans_pcie->fw_mon_page = page; trans_pcie->fw_mon_cpu_addr = cpu_addr;
trans_pcie->fw_mon_phys = phys; trans_pcie->fw_mon_phys = phys;
trans_pcie->fw_mon_size = size; trans_pcie->fw_mon_size = size;
} }
...@@ -2863,7 +2849,7 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, ...@@ -2863,7 +2849,7 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
u32 len = 0; u32 len = 0;
if ((trans_pcie->fw_mon_page && if ((trans_pcie->fw_mon_cpu_addr &&
trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) || trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) ||
trans->dbg_dest_tlv) { trans->dbg_dest_tlv) {
struct iwl_fw_error_dump_fw_mon *fw_mon_data; struct iwl_fw_error_dump_fw_mon *fw_mon_data;
...@@ -2891,19 +2877,9 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, ...@@ -2891,19 +2877,9 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
cpu_to_le32(iwl_read_prph(trans, base)); cpu_to_le32(iwl_read_prph(trans, base));
len += sizeof(**data) + sizeof(*fw_mon_data); len += sizeof(**data) + sizeof(*fw_mon_data);
if (trans_pcie->fw_mon_page) { if (trans_pcie->fw_mon_cpu_addr) {
/*
* The firmware is now asserted, it won't write anything
* to the buffer. CPU can take ownership to fetch the
* data. The buffer will be handed back to the device
* before the firmware will be restarted.
*/
dma_sync_single_for_cpu(trans->dev,
trans_pcie->fw_mon_phys,
trans_pcie->fw_mon_size,
DMA_FROM_DEVICE);
memcpy(fw_mon_data->data, memcpy(fw_mon_data->data,
page_address(trans_pcie->fw_mon_page), trans_pcie->fw_mon_cpu_addr,
trans_pcie->fw_mon_size); trans_pcie->fw_mon_size);
monitor_len = trans_pcie->fw_mon_size; monitor_len = trans_pcie->fw_mon_size;
...@@ -2966,7 +2942,7 @@ static struct iwl_trans_dump_data ...@@ -2966,7 +2942,7 @@ static struct iwl_trans_dump_data
cmdq->n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE); cmdq->n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE);
/* FW monitor */ /* FW monitor */
if (trans_pcie->fw_mon_page) { if (trans_pcie->fw_mon_cpu_addr) {
len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) + len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
trans_pcie->fw_mon_size; trans_pcie->fw_mon_size;
monitor_len = trans_pcie->fw_mon_size; monitor_len = trans_pcie->fw_mon_size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment