Commit a2e4df35 authored by Roland Dreier's avatar Roland Dreier Committed by Linus Torvalds

[PATCH] InfiniBand/mthca: implement modifying port attributes

Implement the port_modify() device method for mthca using the SET_IB firmware
command.  In particular this allows changing the port capability mask.
Signed-off-by: default avatarRoland Dreier <roland@topspin.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent af87a943
...@@ -1238,6 +1238,41 @@ int mthca_CLOSE_HCA(struct mthca_dev *dev, int panic, u8 *status) ...@@ -1238,6 +1238,41 @@ int mthca_CLOSE_HCA(struct mthca_dev *dev, int panic, u8 *status)
return mthca_cmd(dev, 0, 0, panic, CMD_CLOSE_HCA, HZ, status); return mthca_cmd(dev, 0, 0, panic, CMD_CLOSE_HCA, HZ, status);
} }
int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param,
int port, u8 *status)
{
u32 *inbox;
dma_addr_t indma;
int err;
u32 flags = 0;
#define SET_IB_IN_SIZE 0x40
#define SET_IB_FLAGS_OFFSET 0x00
#define SET_IB_FLAG_SIG (1 << 18)
#define SET_IB_FLAG_RQK (1 << 0)
#define SET_IB_CAP_MASK_OFFSET 0x04
#define SET_IB_SI_GUID_OFFSET 0x08
inbox = pci_alloc_consistent(dev->pdev, SET_IB_IN_SIZE, &indma);
if (!inbox)
return -ENOMEM;
memset(inbox, 0, SET_IB_IN_SIZE);
flags |= param->set_si_guid ? SET_IB_FLAG_SIG : 0;
flags |= param->reset_qkey_viol ? SET_IB_FLAG_RQK : 0;
MTHCA_PUT(inbox, flags, SET_IB_FLAGS_OFFSET);
MTHCA_PUT(inbox, param->cap_mask, SET_IB_CAP_MASK_OFFSET);
MTHCA_PUT(inbox, param->si_guid, SET_IB_SI_GUID_OFFSET);
err = mthca_cmd(dev, indma, port, 0, CMD_SET_IB,
CMD_TIME_CLASS_B, status);
pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma);
return err;
}
int mthca_MAP_ICM(struct mthca_dev *dev, struct mthca_icm *icm, u64 virt, u8 *status) int mthca_MAP_ICM(struct mthca_dev *dev, struct mthca_icm *icm, u64 virt, u8 *status)
{ {
return mthca_map_cmd(dev, CMD_MAP_ICM, icm, virt, status); return mthca_map_cmd(dev, CMD_MAP_ICM, icm, virt, status);
......
...@@ -215,6 +215,13 @@ struct mthca_init_ib_param { ...@@ -215,6 +215,13 @@ struct mthca_init_ib_param {
u64 si_guid; u64 si_guid;
}; };
struct mthca_set_ib_param {
int set_si_guid;
int reset_qkey_viol;
u64 si_guid;
u32 cap_mask;
};
int mthca_cmd_use_events(struct mthca_dev *dev); int mthca_cmd_use_events(struct mthca_dev *dev);
void mthca_cmd_use_polling(struct mthca_dev *dev); void mthca_cmd_use_polling(struct mthca_dev *dev);
void mthca_cmd_event(struct mthca_dev *dev, u16 token, void mthca_cmd_event(struct mthca_dev *dev, u16 token,
...@@ -241,6 +248,8 @@ int mthca_INIT_IB(struct mthca_dev *dev, ...@@ -241,6 +248,8 @@ int mthca_INIT_IB(struct mthca_dev *dev,
int port, u8 *status); int port, u8 *status);
int mthca_CLOSE_IB(struct mthca_dev *dev, int port, u8 *status); int mthca_CLOSE_IB(struct mthca_dev *dev, int port, u8 *status);
int mthca_CLOSE_HCA(struct mthca_dev *dev, int panic, u8 *status); int mthca_CLOSE_HCA(struct mthca_dev *dev, int panic, u8 *status);
int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param,
int port, u8 *status);
int mthca_MAP_ICM(struct mthca_dev *dev, struct mthca_icm *icm, u64 virt, u8 *status); int mthca_MAP_ICM(struct mthca_dev *dev, struct mthca_icm *icm, u64 virt, u8 *status);
int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status); int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status);
int mthca_UNMAP_ICM(struct mthca_dev *dev, u64 virt, u32 page_count, u8 *status); int mthca_UNMAP_ICM(struct mthca_dev *dev, u64 virt, u32 page_count, u8 *status);
......
...@@ -234,6 +234,7 @@ struct mthca_dev { ...@@ -234,6 +234,7 @@ struct mthca_dev {
u64 ddr_end; u64 ddr_end;
MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock) MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock)
struct semaphore cap_mask_mutex;
void __iomem *hcr; void __iomem *hcr;
void __iomem *clr_base; void __iomem *clr_base;
......
...@@ -137,7 +137,35 @@ static int mthca_modify_port(struct ib_device *ibdev, ...@@ -137,7 +137,35 @@ static int mthca_modify_port(struct ib_device *ibdev,
u8 port, int port_modify_mask, u8 port, int port_modify_mask,
struct ib_port_modify *props) struct ib_port_modify *props)
{ {
return 0; struct mthca_set_ib_param set_ib;
struct ib_port_attr attr;
int err;
u8 status;
if (down_interruptible(&to_mdev(ibdev)->cap_mask_mutex))
return -ERESTARTSYS;
err = mthca_query_port(ibdev, port, &attr);
if (err)
goto out;
set_ib.set_si_guid = 0;
set_ib.reset_qkey_viol = !!(port_modify_mask & IB_PORT_RESET_QKEY_CNTR);
set_ib.cap_mask = (attr.port_cap_flags | props->set_port_cap_mask) &
~props->clr_port_cap_mask;
err = mthca_SET_IB(to_mdev(ibdev), &set_ib, port, &status);
if (err)
goto out;
if (status) {
err = -EINVAL;
goto out;
}
out:
up(&to_mdev(ibdev)->cap_mask_mutex);
return err;
} }
static int mthca_query_pkey(struct ib_device *ibdev, static int mthca_query_pkey(struct ib_device *ibdev,
...@@ -619,6 +647,8 @@ int mthca_register_device(struct mthca_dev *dev) ...@@ -619,6 +647,8 @@ int mthca_register_device(struct mthca_dev *dev)
} }
} }
init_MUTEX(&dev->cap_mask_mutex);
return 0; return 0;
} }
......
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