aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorCarl Huang <cjhuang@codeaurora.org>2018-10-11 03:55:26 -0400
committerKalle Valo <kvalo@codeaurora.org>2018-10-13 13:25:49 -0400
commit0738b4998c6d1caf9ca2447b946709a7278c70f1 (patch)
treeb997f74e72a793f724d10561d379262212d7593b /drivers/net/wireless
parent9de4162f099948ad85871b8b2ed61e84f139cb5a (diff)
ath10k: allocate small size dma memory in ath10k_pci_diag_write_mem
ath10k_pci_diag_write_mem may allocate big size of the dma memory based on the parameter nbytes. Take firmware diag download as example, the biggest size is about 500K. In some systems, the allocation is likely to fail because it can't acquire such a large contiguous dma memory. The fix is to allocate a small size dma memory. In the loop, driver copies the data to the allocated dma memory and writes to the destination until all the data is written. Tested with QCA6174 PCI with firmware-6.bin_WLAN.RM.4.4.1-00119-QCARMSWP-1, this also affects QCA9377 PCI. Signed-off-by: Carl Huang <cjhuang@codeaurora.org> Reviewed-by: Brian Norris <briannorris@chomium.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 873dbb65439f..01b4edb00e9e 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1071,10 +1071,9 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
1071 struct ath10k_ce *ce = ath10k_ce_priv(ar); 1071 struct ath10k_ce *ce = ath10k_ce_priv(ar);
1072 int ret = 0; 1072 int ret = 0;
1073 u32 *buf; 1073 u32 *buf;
1074 unsigned int completed_nbytes, orig_nbytes, remaining_bytes; 1074 unsigned int completed_nbytes, alloc_nbytes, remaining_bytes;
1075 struct ath10k_ce_pipe *ce_diag; 1075 struct ath10k_ce_pipe *ce_diag;
1076 void *data_buf = NULL; 1076 void *data_buf = NULL;
1077 u32 ce_data; /* Host buffer address in CE space */
1078 dma_addr_t ce_data_base = 0; 1077 dma_addr_t ce_data_base = 0;
1079 int i; 1078 int i;
1080 1079
@@ -1088,9 +1087,10 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
1088 * 1) 4-byte alignment 1087 * 1) 4-byte alignment
1089 * 2) Buffer in DMA-able space 1088 * 2) Buffer in DMA-able space
1090 */ 1089 */
1091 orig_nbytes = nbytes; 1090 alloc_nbytes = min_t(unsigned int, nbytes, DIAG_TRANSFER_LIMIT);
1091
1092 data_buf = (unsigned char *)dma_alloc_coherent(ar->dev, 1092 data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
1093 orig_nbytes, 1093 alloc_nbytes,
1094 &ce_data_base, 1094 &ce_data_base,
1095 GFP_ATOMIC); 1095 GFP_ATOMIC);
1096 if (!data_buf) { 1096 if (!data_buf) {
@@ -1098,9 +1098,6 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
1098 goto done; 1098 goto done;
1099 } 1099 }
1100 1100
1101 /* Copy caller's data to allocated DMA buf */
1102 memcpy(data_buf, data, orig_nbytes);
1103
1104 /* 1101 /*
1105 * The address supplied by the caller is in the 1102 * The address supplied by the caller is in the
1106 * Target CPU virtual address space. 1103 * Target CPU virtual address space.
@@ -1113,12 +1110,14 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
1113 */ 1110 */
1114 address = ath10k_pci_targ_cpu_to_ce_addr(ar, address); 1111 address = ath10k_pci_targ_cpu_to_ce_addr(ar, address);
1115 1112
1116 remaining_bytes = orig_nbytes; 1113 remaining_bytes = nbytes;
1117 ce_data = ce_data_base;
1118 while (remaining_bytes) { 1114 while (remaining_bytes) {
1119 /* FIXME: check cast */ 1115 /* FIXME: check cast */
1120 nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT); 1116 nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT);
1121 1117
1118 /* Copy caller's data to allocated DMA buf */
1119 memcpy(data_buf, data, nbytes);
1120
1122 /* Set up to receive directly into Target(!) address */ 1121 /* Set up to receive directly into Target(!) address */
1123 ret = ce_diag->ops->ce_rx_post_buf(ce_diag, &address, address); 1122 ret = ce_diag->ops->ce_rx_post_buf(ce_diag, &address, address);
1124 if (ret != 0) 1123 if (ret != 0)
@@ -1128,7 +1127,7 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
1128 * Request CE to send caller-supplied data that 1127 * Request CE to send caller-supplied data that
1129 * was copied to bounce buffer to Target(!) address. 1128 * was copied to bounce buffer to Target(!) address.
1130 */ 1129 */
1131 ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)ce_data, 1130 ret = ath10k_ce_send_nolock(ce_diag, NULL, ce_data_base,
1132 nbytes, 0, 0); 1131 nbytes, 0, 0);
1133 if (ret != 0) 1132 if (ret != 0)
1134 goto done; 1133 goto done;
@@ -1171,12 +1170,12 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
1171 1170
1172 remaining_bytes -= nbytes; 1171 remaining_bytes -= nbytes;
1173 address += nbytes; 1172 address += nbytes;
1174 ce_data += nbytes; 1173 data += nbytes;
1175 } 1174 }
1176 1175
1177done: 1176done:
1178 if (data_buf) { 1177 if (data_buf) {
1179 dma_free_coherent(ar->dev, orig_nbytes, data_buf, 1178 dma_free_coherent(ar->dev, alloc_nbytes, data_buf,
1180 ce_data_base); 1179 ce_data_base);
1181 } 1180 }
1182 1181