Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 242641
b: refs/heads/master
c: c1b43dc
h: refs/heads/master
i:
  242639: bb79789
v: v3
  • Loading branch information
Eli Cohen authored and David S. Miller committed Mar 23, 2011
1 parent 939d690 commit 33007f6
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1679200f91da6a054b06954c9bd3eeed29b6731f
refs/heads/master: c1b43dca137f2154845122417fba86d4bae67182
31 changes: 31 additions & 0 deletions trunk/drivers/net/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/io-mapping.h>

#include <linux/mlx4/device.h>
#include <linux/mlx4/doorbell.h>
Expand Down Expand Up @@ -721,8 +722,31 @@ static void mlx4_free_icms(struct mlx4_dev *dev)
mlx4_free_icm(dev, priv->fw.aux_icm, 0);
}

static int map_bf_area(struct mlx4_dev *dev)
{
struct mlx4_priv *priv = mlx4_priv(dev);
resource_size_t bf_start;
resource_size_t bf_len;
int err = 0;

bf_start = pci_resource_start(dev->pdev, 2) + (dev->caps.num_uars << PAGE_SHIFT);
bf_len = pci_resource_len(dev->pdev, 2) - (dev->caps.num_uars << PAGE_SHIFT);
priv->bf_mapping = io_mapping_create_wc(bf_start, bf_len);
if (!priv->bf_mapping)
err = -ENOMEM;

return err;
}

static void unmap_bf_area(struct mlx4_dev *dev)
{
if (mlx4_priv(dev)->bf_mapping)
io_mapping_free(mlx4_priv(dev)->bf_mapping);
}

static void mlx4_close_hca(struct mlx4_dev *dev)
{
unmap_bf_area(dev);
mlx4_CLOSE_HCA(dev, 0);
mlx4_free_icms(dev);
mlx4_UNMAP_FA(dev);
Expand Down Expand Up @@ -775,6 +799,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
goto err_stop_fw;
}

if (map_bf_area(dev))
mlx4_dbg(dev, "Failed to map blue flame area\n");

init_hca.log_uar_sz = ilog2(dev->caps.num_uars);

err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size);
Expand Down Expand Up @@ -805,6 +832,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
mlx4_free_icms(dev);

err_stop_fw:
unmap_bf_area(dev);
mlx4_UNMAP_FA(dev);
mlx4_free_icm(dev, priv->fw.fw_icm, 0);

Expand Down Expand Up @@ -1196,6 +1224,9 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)

pci_read_config_byte(pdev, PCI_REVISION_ID, &dev->rev_id);

INIT_LIST_HEAD(&priv->bf_list);
mutex_init(&priv->bf_mutex);

/*
* Now reset the HCA before we touch the PCI capabilities or
* attempt a firmware command, since a boot ROM may have left
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/mlx4/mlx4.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@ struct mlx4_priv {
struct mutex port_mutex;
struct mlx4_msix_ctl msix_ctl;
struct mlx4_steer *steer;
struct list_head bf_list;
struct mutex bf_mutex;
struct io_mapping *bf_mapping;
};

static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)
Expand Down
94 changes: 94 additions & 0 deletions trunk/drivers/net/mlx4/pd.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/

#include <linux/errno.h>
#include <linux/io-mapping.h>

#include <asm/page.h>

Expand Down Expand Up @@ -77,6 +78,7 @@ int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar)
return -ENOMEM;

uar->pfn = (pci_resource_start(dev->pdev, 2) >> PAGE_SHIFT) + uar->index;
uar->map = NULL;

return 0;
}
Expand All @@ -88,6 +90,98 @@ void mlx4_uar_free(struct mlx4_dev *dev, struct mlx4_uar *uar)
}
EXPORT_SYMBOL_GPL(mlx4_uar_free);

int mlx4_bf_alloc(struct mlx4_dev *dev, struct mlx4_bf *bf)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_uar *uar;
int err = 0;
int idx;

if (!priv->bf_mapping)
return -ENOMEM;

mutex_lock(&priv->bf_mutex);
if (!list_empty(&priv->bf_list))
uar = list_entry(priv->bf_list.next, struct mlx4_uar, bf_list);
else {
uar = kmalloc(sizeof *uar, GFP_KERNEL);
if (!uar) {
err = -ENOMEM;
goto out;
}
err = mlx4_uar_alloc(dev, uar);
if (err)
goto free_kmalloc;

uar->map = ioremap(uar->pfn << PAGE_SHIFT, PAGE_SIZE);
if (!uar->map) {
err = -ENOMEM;
goto free_uar;
}

uar->bf_map = io_mapping_map_wc(priv->bf_mapping, uar->index << PAGE_SHIFT);
if (!uar->bf_map) {
err = -ENOMEM;
goto unamp_uar;
}
uar->free_bf_bmap = 0;
list_add(&uar->bf_list, &priv->bf_list);
}

bf->uar = uar;
idx = ffz(uar->free_bf_bmap);
uar->free_bf_bmap |= 1 << idx;
bf->uar = uar;
bf->offset = 0;
bf->buf_size = dev->caps.bf_reg_size / 2;
bf->reg = uar->bf_map + idx * dev->caps.bf_reg_size;
if (uar->free_bf_bmap == (1 << dev->caps.bf_regs_per_page) - 1)
list_del_init(&uar->bf_list);

goto out;

unamp_uar:
bf->uar = NULL;
iounmap(uar->map);

free_uar:
mlx4_uar_free(dev, uar);

free_kmalloc:
kfree(uar);

out:
mutex_unlock(&priv->bf_mutex);
return err;
}
EXPORT_SYMBOL_GPL(mlx4_bf_alloc);

void mlx4_bf_free(struct mlx4_dev *dev, struct mlx4_bf *bf)
{
struct mlx4_priv *priv = mlx4_priv(dev);
int idx;

if (!bf->uar || !bf->uar->bf_map)
return;

mutex_lock(&priv->bf_mutex);
idx = (bf->reg - bf->uar->bf_map) / dev->caps.bf_reg_size;
bf->uar->free_bf_bmap &= ~(1 << idx);
if (!bf->uar->free_bf_bmap) {
if (!list_empty(&bf->uar->bf_list))
list_del(&bf->uar->bf_list);

io_mapping_unmap(bf->uar->bf_map);
iounmap(bf->uar->map);
mlx4_uar_free(dev, bf->uar);
kfree(bf->uar);
} else if (list_empty(&bf->uar->bf_list))
list_add(&bf->uar->bf_list, &priv->bf_list);

mutex_unlock(&priv->bf_mutex);
}
EXPORT_SYMBOL_GPL(mlx4_bf_free);

int mlx4_init_uar_table(struct mlx4_dev *dev)
{
if (dev->caps.num_uars <= 128) {
Expand Down
13 changes: 13 additions & 0 deletions trunk/include/linux/mlx4/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,17 @@ struct mlx4_fmr {
struct mlx4_uar {
unsigned long pfn;
int index;
struct list_head bf_list;
unsigned free_bf_bmap;
void __iomem *map;
void __iomem *bf_map;
};

struct mlx4_bf {
unsigned long offset;
int buf_size;
struct mlx4_uar *uar;
void __iomem *reg;
};

struct mlx4_cq {
Expand Down Expand Up @@ -478,6 +489,8 @@ void mlx4_pd_free(struct mlx4_dev *dev, u32 pdn);

int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar);
void mlx4_uar_free(struct mlx4_dev *dev, struct mlx4_uar *uar);
int mlx4_bf_alloc(struct mlx4_dev *dev, struct mlx4_bf *bf);
void mlx4_bf_free(struct mlx4_dev *dev, struct mlx4_bf *bf);

int mlx4_mtt_init(struct mlx4_dev *dev, int npages, int page_shift,
struct mlx4_mtt *mtt);
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/mlx4/qp.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ struct mlx4_wqe_data_seg {

enum {
MLX4_INLINE_ALIGN = 64,
MLX4_INLINE_SEG = 1 << 31,
};

struct mlx4_wqe_inline_seg {
Expand Down

0 comments on commit 33007f6

Please sign in to comment.