aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoa Osherovich <noaos@mellanox.com>2016-10-25 11:36:35 -0400
committerDavid S. Miller <davem@davemloft.net>2016-10-29 12:00:39 -0400
commit6b276190c50a12511d889d9079ffb901ff94a822 (patch)
tree2fbd8a81031683406fa5fbd8a50f310aea4be4fc
parent04c0c1ab38e95105d950db5b84e727637e149ce7 (diff)
net/mlx5: Avoid passing dma address 0 to firmware
Currently the firmware can't work with a page with dma address 0. Passing such an address to the firmware will cause the give_pages command to fail. To avoid this, in case we get a 0 dma address of a page from the dma engine, we avoid passing it to FW by remapping to get an address other than 0. Fixes: bf0bf77f6519 ('mlx5: Support communicating arbitrary host...') Signed-off-by: Noa Osherovich <noaos@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
index cc4fd61914d3..a57d5a81eb05 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -209,6 +209,7 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr)
209static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id) 209static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id)
210{ 210{
211 struct page *page; 211 struct page *page;
212 u64 zero_addr = 1;
212 u64 addr; 213 u64 addr;
213 int err; 214 int err;
214 int nid = dev_to_node(&dev->pdev->dev); 215 int nid = dev_to_node(&dev->pdev->dev);
@@ -218,26 +219,35 @@ static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id)
218 mlx5_core_warn(dev, "failed to allocate page\n"); 219 mlx5_core_warn(dev, "failed to allocate page\n");
219 return -ENOMEM; 220 return -ENOMEM;
220 } 221 }
222map:
221 addr = dma_map_page(&dev->pdev->dev, page, 0, 223 addr = dma_map_page(&dev->pdev->dev, page, 0,
222 PAGE_SIZE, DMA_BIDIRECTIONAL); 224 PAGE_SIZE, DMA_BIDIRECTIONAL);
223 if (dma_mapping_error(&dev->pdev->dev, addr)) { 225 if (dma_mapping_error(&dev->pdev->dev, addr)) {
224 mlx5_core_warn(dev, "failed dma mapping page\n"); 226 mlx5_core_warn(dev, "failed dma mapping page\n");
225 err = -ENOMEM; 227 err = -ENOMEM;
226 goto out_alloc; 228 goto err_mapping;
227 } 229 }
230
231 /* Firmware doesn't support page with physical address 0 */
232 if (addr == 0) {
233 zero_addr = addr;
234 goto map;
235 }
236
228 err = insert_page(dev, addr, page, func_id); 237 err = insert_page(dev, addr, page, func_id);
229 if (err) { 238 if (err) {
230 mlx5_core_err(dev, "failed to track allocated page\n"); 239 mlx5_core_err(dev, "failed to track allocated page\n");
231 goto out_mapping; 240 dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE,
241 DMA_BIDIRECTIONAL);
232 } 242 }
233 243
234 return 0; 244err_mapping:
235 245 if (err)
236out_mapping: 246 __free_page(page);
237 dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
238 247
239out_alloc: 248 if (zero_addr == 0)
240 __free_page(page); 249 dma_unmap_page(&dev->pdev->dev, zero_addr, PAGE_SIZE,
250 DMA_BIDIRECTIONAL);
241 251
242 return err; 252 return err;
243} 253}