aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/mlx4/main.c31
-rw-r--r--drivers/net/mlx4/mlx4.h3
-rw-r--r--drivers/net/mlx4/pd.c94
-rw-r--r--include/linux/mlx4/device.h13
-rw-r--r--include/linux/mlx4/qp.h1
5 files changed, 142 insertions, 0 deletions
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index c8e276138f81..05c5671749aa 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -39,6 +39,7 @@
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/dma-mapping.h> 40#include <linux/dma-mapping.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/io-mapping.h>
42 43
43#include <linux/mlx4/device.h> 44#include <linux/mlx4/device.h>
44#include <linux/mlx4/doorbell.h> 45#include <linux/mlx4/doorbell.h>
@@ -721,8 +722,31 @@ static void mlx4_free_icms(struct mlx4_dev *dev)
721 mlx4_free_icm(dev, priv->fw.aux_icm, 0); 722 mlx4_free_icm(dev, priv->fw.aux_icm, 0);
722} 723}
723 724
725static int map_bf_area(struct mlx4_dev *dev)
726{
727 struct mlx4_priv *priv = mlx4_priv(dev);
728 resource_size_t bf_start;
729 resource_size_t bf_len;
730 int err = 0;
731
732 bf_start = pci_resource_start(dev->pdev, 2) + (dev->caps.num_uars << PAGE_SHIFT);
733 bf_len = pci_resource_len(dev->pdev, 2) - (dev->caps.num_uars << PAGE_SHIFT);
734 priv->bf_mapping = io_mapping_create_wc(bf_start, bf_len);
735 if (!priv->bf_mapping)
736 err = -ENOMEM;
737
738 return err;
739}
740
741static void unmap_bf_area(struct mlx4_dev *dev)
742{
743 if (mlx4_priv(dev)->bf_mapping)
744 io_mapping_free(mlx4_priv(dev)->bf_mapping);
745}
746
724static void mlx4_close_hca(struct mlx4_dev *dev) 747static void mlx4_close_hca(struct mlx4_dev *dev)
725{ 748{
749 unmap_bf_area(dev);
726 mlx4_CLOSE_HCA(dev, 0); 750 mlx4_CLOSE_HCA(dev, 0);
727 mlx4_free_icms(dev); 751 mlx4_free_icms(dev);
728 mlx4_UNMAP_FA(dev); 752 mlx4_UNMAP_FA(dev);
@@ -775,6 +799,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
775 goto err_stop_fw; 799 goto err_stop_fw;
776 } 800 }
777 801
802 if (map_bf_area(dev))
803 mlx4_dbg(dev, "Failed to map blue flame area\n");
804
778 init_hca.log_uar_sz = ilog2(dev->caps.num_uars); 805 init_hca.log_uar_sz = ilog2(dev->caps.num_uars);
779 806
780 err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size); 807 err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size);
@@ -805,6 +832,7 @@ err_free_icm:
805 mlx4_free_icms(dev); 832 mlx4_free_icms(dev);
806 833
807err_stop_fw: 834err_stop_fw:
835 unmap_bf_area(dev);
808 mlx4_UNMAP_FA(dev); 836 mlx4_UNMAP_FA(dev);
809 mlx4_free_icm(dev, priv->fw.fw_icm, 0); 837 mlx4_free_icm(dev, priv->fw.fw_icm, 0);
810 838
@@ -1196,6 +1224,9 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1196 1224
1197 pci_read_config_byte(pdev, PCI_REVISION_ID, &dev->rev_id); 1225 pci_read_config_byte(pdev, PCI_REVISION_ID, &dev->rev_id);
1198 1226
1227 INIT_LIST_HEAD(&priv->bf_list);
1228 mutex_init(&priv->bf_mutex);
1229
1199 /* 1230 /*
1200 * Now reset the HCA before we touch the PCI capabilities or 1231 * Now reset the HCA before we touch the PCI capabilities or
1201 * attempt a firmware command, since a boot ROM may have left 1232 * attempt a firmware command, since a boot ROM may have left
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index d8bb4418581b..bc9a21657a4f 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -353,6 +353,9 @@ struct mlx4_priv {
353 struct mutex port_mutex; 353 struct mutex port_mutex;
354 struct mlx4_msix_ctl msix_ctl; 354 struct mlx4_msix_ctl msix_ctl;
355 struct mlx4_steer *steer; 355 struct mlx4_steer *steer;
356 struct list_head bf_list;
357 struct mutex bf_mutex;
358 struct io_mapping *bf_mapping;
356}; 359};
357 360
358static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev) 361static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)
diff --git a/drivers/net/mlx4/pd.c b/drivers/net/mlx4/pd.c
index c4988d6bd5b2..5210a0f31413 100644
--- a/drivers/net/mlx4/pd.c
+++ b/drivers/net/mlx4/pd.c
@@ -32,6 +32,7 @@
32 */ 32 */
33 33
34#include <linux/errno.h> 34#include <linux/errno.h>
35#include <linux/io-mapping.h>
35 36
36#include <asm/page.h> 37#include <asm/page.h>
37 38
@@ -77,6 +78,7 @@ int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar)
77 return -ENOMEM; 78 return -ENOMEM;
78 79
79 uar->pfn = (pci_resource_start(dev->pdev, 2) >> PAGE_SHIFT) + uar->index; 80 uar->pfn = (pci_resource_start(dev->pdev, 2) >> PAGE_SHIFT) + uar->index;
81 uar->map = NULL;
80 82
81 return 0; 83 return 0;
82} 84}
@@ -88,6 +90,98 @@ void mlx4_uar_free(struct mlx4_dev *dev, struct mlx4_uar *uar)
88} 90}
89EXPORT_SYMBOL_GPL(mlx4_uar_free); 91EXPORT_SYMBOL_GPL(mlx4_uar_free);
90 92
93int mlx4_bf_alloc(struct mlx4_dev *dev, struct mlx4_bf *bf)
94{
95 struct mlx4_priv *priv = mlx4_priv(dev);
96 struct mlx4_uar *uar;
97 int err = 0;
98 int idx;
99
100 if (!priv->bf_mapping)
101 return -ENOMEM;
102
103 mutex_lock(&priv->bf_mutex);
104 if (!list_empty(&priv->bf_list))
105 uar = list_entry(priv->bf_list.next, struct mlx4_uar, bf_list);
106 else {
107 uar = kmalloc(sizeof *uar, GFP_KERNEL);
108 if (!uar) {
109 err = -ENOMEM;
110 goto out;
111 }
112 err = mlx4_uar_alloc(dev, uar);
113 if (err)
114 goto free_kmalloc;
115
116 uar->map = ioremap(uar->pfn << PAGE_SHIFT, PAGE_SIZE);
117 if (!uar->map) {
118 err = -ENOMEM;
119 goto free_uar;
120 }
121
122 uar->bf_map = io_mapping_map_wc(priv->bf_mapping, uar->index << PAGE_SHIFT);
123 if (!uar->bf_map) {
124 err = -ENOMEM;
125 goto unamp_uar;
126 }
127 uar->free_bf_bmap = 0;
128 list_add(&uar->bf_list, &priv->bf_list);
129 }
130
131 bf->uar = uar;
132 idx = ffz(uar->free_bf_bmap);
133 uar->free_bf_bmap |= 1 << idx;
134 bf->uar = uar;
135 bf->offset = 0;
136 bf->buf_size = dev->caps.bf_reg_size / 2;
137 bf->reg = uar->bf_map + idx * dev->caps.bf_reg_size;
138 if (uar->free_bf_bmap == (1 << dev->caps.bf_regs_per_page) - 1)
139 list_del_init(&uar->bf_list);
140
141 goto out;
142
143unamp_uar:
144 bf->uar = NULL;
145 iounmap(uar->map);
146
147free_uar:
148 mlx4_uar_free(dev, uar);
149
150free_kmalloc:
151 kfree(uar);
152
153out:
154 mutex_unlock(&priv->bf_mutex);
155 return err;
156}
157EXPORT_SYMBOL_GPL(mlx4_bf_alloc);
158
159void mlx4_bf_free(struct mlx4_dev *dev, struct mlx4_bf *bf)
160{
161 struct mlx4_priv *priv = mlx4_priv(dev);
162 int idx;
163
164 if (!bf->uar || !bf->uar->bf_map)
165 return;
166
167 mutex_lock(&priv->bf_mutex);
168 idx = (bf->reg - bf->uar->bf_map) / dev->caps.bf_reg_size;
169 bf->uar->free_bf_bmap &= ~(1 << idx);
170 if (!bf->uar->free_bf_bmap) {
171 if (!list_empty(&bf->uar->bf_list))
172 list_del(&bf->uar->bf_list);
173
174 io_mapping_unmap(bf->uar->bf_map);
175 iounmap(bf->uar->map);
176 mlx4_uar_free(dev, bf->uar);
177 kfree(bf->uar);
178 } else if (list_empty(&bf->uar->bf_list))
179 list_add(&bf->uar->bf_list, &priv->bf_list);
180
181 mutex_unlock(&priv->bf_mutex);
182}
183EXPORT_SYMBOL_GPL(mlx4_bf_free);
184
91int mlx4_init_uar_table(struct mlx4_dev *dev) 185int mlx4_init_uar_table(struct mlx4_dev *dev)
92{ 186{
93 if (dev->caps.num_uars <= 128) { 187 if (dev->caps.num_uars <= 128) {
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 56fa5e1cd6d4..8985768e2c0d 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -351,6 +351,17 @@ struct mlx4_fmr {
351struct mlx4_uar { 351struct mlx4_uar {
352 unsigned long pfn; 352 unsigned long pfn;
353 int index; 353 int index;
354 struct list_head bf_list;
355 unsigned free_bf_bmap;
356 void __iomem *map;
357 void __iomem *bf_map;
358};
359
360struct mlx4_bf {
361 unsigned long offset;
362 int buf_size;
363 struct mlx4_uar *uar;
364 void __iomem *reg;
354}; 365};
355 366
356struct mlx4_cq { 367struct mlx4_cq {
@@ -478,6 +489,8 @@ void mlx4_pd_free(struct mlx4_dev *dev, u32 pdn);
478 489
479int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar); 490int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar);
480void mlx4_uar_free(struct mlx4_dev *dev, struct mlx4_uar *uar); 491void mlx4_uar_free(struct mlx4_dev *dev, struct mlx4_uar *uar);
492int mlx4_bf_alloc(struct mlx4_dev *dev, struct mlx4_bf *bf);
493void mlx4_bf_free(struct mlx4_dev *dev, struct mlx4_bf *bf);
481 494
482int mlx4_mtt_init(struct mlx4_dev *dev, int npages, int page_shift, 495int mlx4_mtt_init(struct mlx4_dev *dev, int npages, int page_shift,
483 struct mlx4_mtt *mtt); 496 struct mlx4_mtt *mtt);
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index 0eeb2a1a867c..9e9eb21056ca 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -303,6 +303,7 @@ struct mlx4_wqe_data_seg {
303 303
304enum { 304enum {
305 MLX4_INLINE_ALIGN = 64, 305 MLX4_INLINE_ALIGN = 64,
306 MLX4_INLINE_SEG = 1 << 31,
306}; 307};
307 308
308struct mlx4_wqe_inline_seg { 309struct mlx4_wqe_inline_seg {