Commit b3f4256f authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
  IB/mlx4: Make sure inline data segments don't cross a 64 byte boundary
  IB/mlx4: Handle FW command interface rev 3
  IB/mlx4: Handle buffer wraparound in __mlx4_ib_cq_clean()
  IB/mlx4: Get rid of max_inline_data calculation
  IB/mlx4: Handle new FW requirement for send request prefetching
  IB/mlx4: Fix warning in rounding up queue sizes
  IB/mlx4: Fix handling of wq->tail for send completions
parents 044f620a e61ef241
...@@ -354,8 +354,8 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, ...@@ -354,8 +354,8 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
if (is_send) { if (is_send) {
wq = &(*cur_qp)->sq; wq = &(*cur_qp)->sq;
wqe_ctr = be16_to_cpu(cqe->wqe_index); wqe_ctr = be16_to_cpu(cqe->wqe_index);
wq->tail += wqe_ctr - (u16) wq->tail; wq->tail += (u16) (wqe_ctr - (u16) wq->tail);
wc->wr_id = wq->wrid[wq->tail & (wq->max - 1)]; wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
++wq->tail; ++wq->tail;
} else if ((*cur_qp)->ibqp.srq) { } else if ((*cur_qp)->ibqp.srq) {
srq = to_msrq((*cur_qp)->ibqp.srq); srq = to_msrq((*cur_qp)->ibqp.srq);
...@@ -364,7 +364,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, ...@@ -364,7 +364,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
mlx4_ib_free_srq_wqe(srq, wqe_ctr); mlx4_ib_free_srq_wqe(srq, wqe_ctr);
} else { } else {
wq = &(*cur_qp)->rq; wq = &(*cur_qp)->rq;
wc->wr_id = wq->wrid[wq->tail & (wq->max - 1)]; wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
++wq->tail; ++wq->tail;
} }
...@@ -478,7 +478,8 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq) ...@@ -478,7 +478,8 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq)
{ {
u32 prod_index; u32 prod_index;
int nfreed = 0; int nfreed = 0;
struct mlx4_cqe *cqe; struct mlx4_cqe *cqe, *dest;
u8 owner_bit;
/* /*
* First we need to find the current producer index, so we * First we need to find the current producer index, so we
...@@ -501,9 +502,13 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq) ...@@ -501,9 +502,13 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq)
if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK)) if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK))
mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index)); mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index));
++nfreed; ++nfreed;
} else if (nfreed) } else if (nfreed) {
memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe), dest = get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe);
cqe, sizeof *cqe); owner_bit = dest->owner_sr_opcode & MLX4_CQE_OWNER_MASK;
memcpy(dest, cqe, sizeof *cqe);
dest->owner_sr_opcode = owner_bit |
(dest->owner_sr_opcode & ~MLX4_CQE_OWNER_MASK);
}
} }
if (nfreed) { if (nfreed) {
......
...@@ -125,7 +125,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, ...@@ -125,7 +125,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
props->local_ca_ack_delay = dev->dev->caps.local_ca_ack_delay; props->local_ca_ack_delay = dev->dev->caps.local_ca_ack_delay;
props->atomic_cap = dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_ATOMIC ? props->atomic_cap = dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_ATOMIC ?
IB_ATOMIC_HCA : IB_ATOMIC_NONE; IB_ATOMIC_HCA : IB_ATOMIC_NONE;
props->max_pkeys = dev->dev->caps.pkey_table_len; props->max_pkeys = dev->dev->caps.pkey_table_len[1];
props->max_mcast_grp = dev->dev->caps.num_mgms + dev->dev->caps.num_amgms; props->max_mcast_grp = dev->dev->caps.num_mgms + dev->dev->caps.num_amgms;
props->max_mcast_qp_attach = dev->dev->caps.num_qp_per_mgm; props->max_mcast_qp_attach = dev->dev->caps.num_qp_per_mgm;
props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
...@@ -168,9 +168,9 @@ static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port, ...@@ -168,9 +168,9 @@ static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
props->state = out_mad->data[32] & 0xf; props->state = out_mad->data[32] & 0xf;
props->phys_state = out_mad->data[33] >> 4; props->phys_state = out_mad->data[33] >> 4;
props->port_cap_flags = be32_to_cpup((__be32 *) (out_mad->data + 20)); props->port_cap_flags = be32_to_cpup((__be32 *) (out_mad->data + 20));
props->gid_tbl_len = to_mdev(ibdev)->dev->caps.gid_table_len; props->gid_tbl_len = to_mdev(ibdev)->dev->caps.gid_table_len[port];
props->max_msg_sz = 0x80000000; props->max_msg_sz = 0x80000000;
props->pkey_tbl_len = to_mdev(ibdev)->dev->caps.pkey_table_len; props->pkey_tbl_len = to_mdev(ibdev)->dev->caps.pkey_table_len[port];
props->bad_pkey_cntr = be16_to_cpup((__be16 *) (out_mad->data + 46)); props->bad_pkey_cntr = be16_to_cpup((__be16 *) (out_mad->data + 46));
props->qkey_viol_cntr = be16_to_cpup((__be16 *) (out_mad->data + 48)); props->qkey_viol_cntr = be16_to_cpup((__be16 *) (out_mad->data + 48));
props->active_width = out_mad->data[31] & 0xf; props->active_width = out_mad->data[31] & 0xf;
...@@ -280,8 +280,14 @@ static int mlx4_SET_PORT(struct mlx4_ib_dev *dev, u8 port, int reset_qkey_viols, ...@@ -280,8 +280,14 @@ static int mlx4_SET_PORT(struct mlx4_ib_dev *dev, u8 port, int reset_qkey_viols,
return PTR_ERR(mailbox); return PTR_ERR(mailbox);
memset(mailbox->buf, 0, 256); memset(mailbox->buf, 0, 256);
*(u8 *) mailbox->buf = !!reset_qkey_viols << 6;
((__be32 *) mailbox->buf)[2] = cpu_to_be32(cap_mask); if (dev->dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
*(u8 *) mailbox->buf = !!reset_qkey_viols << 6;
((__be32 *) mailbox->buf)[2] = cpu_to_be32(cap_mask);
} else {
((u8 *) mailbox->buf)[3] = !!reset_qkey_viols;
((__be32 *) mailbox->buf)[1] = cpu_to_be32(cap_mask);
}
err = mlx4_cmd(dev->dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, err = mlx4_cmd(dev->dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
MLX4_CMD_TIME_CLASS_B); MLX4_CMD_TIME_CLASS_B);
......
...@@ -95,7 +95,8 @@ struct mlx4_ib_mr { ...@@ -95,7 +95,8 @@ struct mlx4_ib_mr {
struct mlx4_ib_wq { struct mlx4_ib_wq {
u64 *wrid; u64 *wrid;
spinlock_t lock; spinlock_t lock;
int max; int wqe_cnt;
int max_post;
int max_gs; int max_gs;
int offset; int offset;
int wqe_shift; int wqe_shift;
...@@ -113,6 +114,7 @@ struct mlx4_ib_qp { ...@@ -113,6 +114,7 @@ struct mlx4_ib_qp {
u32 doorbell_qpn; u32 doorbell_qpn;
__be32 sq_signal_bits; __be32 sq_signal_bits;
int sq_spare_wqes;
struct mlx4_ib_wq sq; struct mlx4_ib_wq sq;
struct ib_umem *umem; struct ib_umem *umem;
...@@ -123,6 +125,7 @@ struct mlx4_ib_qp { ...@@ -123,6 +125,7 @@ struct mlx4_ib_qp {
u8 alt_port; u8 alt_port;
u8 atomic_rd_en; u8 atomic_rd_en;
u8 resp_depth; u8 resp_depth;
u8 sq_no_prefetch;
u8 state; u8 state;
}; };
......
This diff is collapsed.
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* Increment this value if any changes that break userspace ABI * Increment this value if any changes that break userspace ABI
* compatibility are made. * compatibility are made.
*/ */
#define MLX4_IB_UVERBS_ABI_VERSION 2 #define MLX4_IB_UVERBS_ABI_VERSION 3
/* /*
* Make sure that all structs defined in this file remain laid out so * Make sure that all structs defined in this file remain laid out so
...@@ -87,9 +87,10 @@ struct mlx4_ib_create_srq_resp { ...@@ -87,9 +87,10 @@ struct mlx4_ib_create_srq_resp {
struct mlx4_ib_create_qp { struct mlx4_ib_create_qp {
__u64 buf_addr; __u64 buf_addr;
__u64 db_addr; __u64 db_addr;
__u8 log_sq_bb_count; __u8 log_sq_bb_count;
__u8 log_sq_stride; __u8 log_sq_stride;
__u8 reserved[6]; __u8 sq_no_prefetch;
__u8 reserved[5];
}; };
#endif /* MLX4_IB_USER_H */ #endif /* MLX4_IB_USER_H */
...@@ -38,7 +38,9 @@ ...@@ -38,7 +38,9 @@
#include "icm.h" #include "icm.h"
enum { enum {
MLX4_COMMAND_INTERFACE_REV = 1 MLX4_COMMAND_INTERFACE_MIN_REV = 2,
MLX4_COMMAND_INTERFACE_MAX_REV = 3,
MLX4_COMMAND_INTERFACE_NEW_PORT_CMDS = 3,
}; };
extern void __buggy_use_of_MLX4_GET(void); extern void __buggy_use_of_MLX4_GET(void);
...@@ -107,6 +109,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -107,6 +109,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
u16 size; u16 size;
u16 stat_rate; u16 stat_rate;
int err; int err;
int i;
#define QUERY_DEV_CAP_OUT_SIZE 0x100 #define QUERY_DEV_CAP_OUT_SIZE 0x100
#define QUERY_DEV_CAP_MAX_SRQ_SZ_OFFSET 0x10 #define QUERY_DEV_CAP_MAX_SRQ_SZ_OFFSET 0x10
...@@ -176,7 +179,6 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -176,7 +179,6 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP,
MLX4_CMD_TIME_CLASS_A); MLX4_CMD_TIME_CLASS_A);
if (err) if (err)
goto out; goto out;
...@@ -216,18 +218,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -216,18 +218,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev_cap->max_rdma_global = 1 << (field & 0x3f); dev_cap->max_rdma_global = 1 << (field & 0x3f);
MLX4_GET(field, outbox, QUERY_DEV_CAP_ACK_DELAY_OFFSET); MLX4_GET(field, outbox, QUERY_DEV_CAP_ACK_DELAY_OFFSET);
dev_cap->local_ca_ack_delay = field & 0x1f; dev_cap->local_ca_ack_delay = field & 0x1f;
MLX4_GET(field, outbox, QUERY_DEV_CAP_MTU_WIDTH_OFFSET);
dev_cap->max_mtu = field >> 4;
dev_cap->max_port_width = field & 0xf;
MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET); MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET);
dev_cap->max_vl = field >> 4;
dev_cap->num_ports = field & 0xf; dev_cap->num_ports = field & 0xf;
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_GID_OFFSET);
dev_cap->max_gids = 1 << (field & 0xf);
MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET);
dev_cap->stat_rate_support = stat_rate; dev_cap->stat_rate_support = stat_rate;
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PKEY_OFFSET);
dev_cap->max_pkeys = 1 << (field & 0xf);
MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET); MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET);
dev_cap->reserved_uars = field >> 4; dev_cap->reserved_uars = field >> 4;
...@@ -304,6 +298,42 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -304,6 +298,42 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
MLX4_GET(dev_cap->max_icm_sz, outbox, MLX4_GET(dev_cap->max_icm_sz, outbox,
QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET); QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET);
if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
for (i = 1; i <= dev_cap->num_ports; ++i) {
MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET);
dev_cap->max_vl[i] = field >> 4;
MLX4_GET(field, outbox, QUERY_DEV_CAP_MTU_WIDTH_OFFSET);
dev_cap->max_mtu[i] = field >> 4;
dev_cap->max_port_width[i] = field & 0xf;
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_GID_OFFSET);
dev_cap->max_gids[i] = 1 << (field & 0xf);
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PKEY_OFFSET);
dev_cap->max_pkeys[i] = 1 << (field & 0xf);
}
} else {
#define QUERY_PORT_MTU_OFFSET 0x01
#define QUERY_PORT_WIDTH_OFFSET 0x06
#define QUERY_PORT_MAX_GID_PKEY_OFFSET 0x07
#define QUERY_PORT_MAX_VL_OFFSET 0x0b
for (i = 1; i <= dev_cap->num_ports; ++i) {
err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT,
MLX4_CMD_TIME_CLASS_B);
if (err)
goto out;
MLX4_GET(field, outbox, QUERY_PORT_MTU_OFFSET);
dev_cap->max_mtu[i] = field & 0xf;
MLX4_GET(field, outbox, QUERY_PORT_WIDTH_OFFSET);
dev_cap->max_port_width[i] = field & 0xf;
MLX4_GET(field, outbox, QUERY_PORT_MAX_GID_PKEY_OFFSET);
dev_cap->max_gids[i] = 1 << (field >> 4);
dev_cap->max_pkeys[i] = 1 << (field & 0xf);
MLX4_GET(field, outbox, QUERY_PORT_MAX_VL_OFFSET);
dev_cap->max_vl[i] = field & 0xf;
}
}
if (dev_cap->bmme_flags & 1) if (dev_cap->bmme_flags & 1)
mlx4_dbg(dev, "Base MM extensions: yes " mlx4_dbg(dev, "Base MM extensions: yes "
"(flags %d, rsvd L_Key %08x)\n", "(flags %d, rsvd L_Key %08x)\n",
...@@ -338,8 +368,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) ...@@ -338,8 +368,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
mlx4_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", mlx4_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n",
dev_cap->max_cq_sz, dev_cap->max_qp_sz, dev_cap->max_srq_sz); dev_cap->max_cq_sz, dev_cap->max_qp_sz, dev_cap->max_srq_sz);
mlx4_dbg(dev, "Local CA ACK delay: %d, max MTU: %d, port width cap: %d\n", mlx4_dbg(dev, "Local CA ACK delay: %d, max MTU: %d, port width cap: %d\n",
dev_cap->local_ca_ack_delay, 128 << dev_cap->max_mtu, dev_cap->local_ca_ack_delay, 128 << dev_cap->max_mtu[1],
dev_cap->max_port_width); dev_cap->max_port_width[1]);
mlx4_dbg(dev, "Max SQ desc size: %d, max SQ S/G: %d\n", mlx4_dbg(dev, "Max SQ desc size: %d, max SQ S/G: %d\n",
dev_cap->max_sq_desc_sz, dev_cap->max_sq_sg); dev_cap->max_sq_desc_sz, dev_cap->max_sq_sg);
mlx4_dbg(dev, "Max RQ desc size: %d, max RQ S/G: %d\n", mlx4_dbg(dev, "Max RQ desc size: %d, max RQ S/G: %d\n",
...@@ -491,7 +521,8 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev) ...@@ -491,7 +521,8 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
((fw_ver & 0x0000ffffull) << 16); ((fw_ver & 0x0000ffffull) << 16);
MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET); MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET);
if (cmd_if_rev != MLX4_COMMAND_INTERFACE_REV) { if (cmd_if_rev < MLX4_COMMAND_INTERFACE_MIN_REV ||
cmd_if_rev > MLX4_COMMAND_INTERFACE_MAX_REV) {
mlx4_err(dev, "Installed FW has unsupported " mlx4_err(dev, "Installed FW has unsupported "
"command interface revision %d.\n", "command interface revision %d.\n",
cmd_if_rev); cmd_if_rev);
...@@ -499,12 +530,15 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev) ...@@ -499,12 +530,15 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
(int) (dev->caps.fw_ver >> 32), (int) (dev->caps.fw_ver >> 32),
(int) (dev->caps.fw_ver >> 16) & 0xffff, (int) (dev->caps.fw_ver >> 16) & 0xffff,
(int) dev->caps.fw_ver & 0xffff); (int) dev->caps.fw_ver & 0xffff);
mlx4_err(dev, "This driver version supports only revision %d.\n", mlx4_err(dev, "This driver version supports only revisions %d to %d.\n",
MLX4_COMMAND_INTERFACE_REV); MLX4_COMMAND_INTERFACE_MIN_REV, MLX4_COMMAND_INTERFACE_MAX_REV);
err = -ENODEV; err = -ENODEV;
goto out; goto out;
} }
if (cmd_if_rev < MLX4_COMMAND_INTERFACE_NEW_PORT_CMDS)
dev->flags |= MLX4_FLAG_OLD_PORT_CMDS;
MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
cmd->max_cmds = 1 << lg; cmd->max_cmds = 1 << lg;
...@@ -708,13 +742,15 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) ...@@ -708,13 +742,15 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
return err; return err;
} }
int mlx4_INIT_PORT(struct mlx4_dev *dev, struct mlx4_init_port_param *param, int port) int mlx4_INIT_PORT(struct mlx4_dev *dev, int port)
{ {
struct mlx4_cmd_mailbox *mailbox; struct mlx4_cmd_mailbox *mailbox;
u32 *inbox; u32 *inbox;
int err; int err;
u32 flags; u32 flags;
u16 field;
if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
#define INIT_PORT_IN_SIZE 256 #define INIT_PORT_IN_SIZE 256
#define INIT_PORT_FLAGS_OFFSET 0x00 #define INIT_PORT_FLAGS_OFFSET 0x00
#define INIT_PORT_FLAG_SIG (1 << 18) #define INIT_PORT_FLAG_SIG (1 << 18)
...@@ -729,32 +765,32 @@ int mlx4_INIT_PORT(struct mlx4_dev *dev, struct mlx4_init_port_param *param, int ...@@ -729,32 +765,32 @@ int mlx4_INIT_PORT(struct mlx4_dev *dev, struct mlx4_init_port_param *param, int
#define INIT_PORT_NODE_GUID_OFFSET 0x18 #define INIT_PORT_NODE_GUID_OFFSET 0x18
#define INIT_PORT_SI_GUID_OFFSET 0x20 #define INIT_PORT_SI_GUID_OFFSET 0x20
mailbox = mlx4_alloc_cmd_mailbox(dev); mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox)) if (IS_ERR(mailbox))
return PTR_ERR(mailbox); return PTR_ERR(mailbox);
inbox = mailbox->buf; inbox = mailbox->buf;
memset(inbox, 0, INIT_PORT_IN_SIZE); memset(inbox, 0, INIT_PORT_IN_SIZE);
flags = 0; flags = 0;
flags |= param->set_guid0 ? INIT_PORT_FLAG_G0 : 0; flags |= (dev->caps.vl_cap[port] & 0xf) << INIT_PORT_VL_SHIFT;
flags |= param->set_node_guid ? INIT_PORT_FLAG_NG : 0; flags |= (dev->caps.port_width_cap[port] & 0xf) << INIT_PORT_PORT_WIDTH_SHIFT;
flags |= param->set_si_guid ? INIT_PORT_FLAG_SIG : 0; MLX4_PUT(inbox, flags, INIT_PORT_FLAGS_OFFSET);
flags |= (param->vl_cap & 0xf) << INIT_PORT_VL_SHIFT;
flags |= (param->port_width_cap & 0xf) << INIT_PORT_PORT_WIDTH_SHIFT;
MLX4_PUT(inbox, flags, INIT_PORT_FLAGS_OFFSET);
MLX4_PUT(inbox, param->mtu, INIT_PORT_MTU_OFFSET); field = 128 << dev->caps.mtu_cap[port];
MLX4_PUT(inbox, param->max_gid, INIT_PORT_MAX_GID_OFFSET); MLX4_PUT(inbox, field, INIT_PORT_MTU_OFFSET);
MLX4_PUT(inbox, param->max_pkey, INIT_PORT_MAX_PKEY_OFFSET); field = dev->caps.gid_table_len[port];
MLX4_PUT(inbox, param->guid0, INIT_PORT_GUID0_OFFSET); MLX4_PUT(inbox, field, INIT_PORT_MAX_GID_OFFSET);
MLX4_PUT(inbox, param->node_guid, INIT_PORT_NODE_GUID_OFFSET); field = dev->caps.pkey_table_len[port];
MLX4_PUT(inbox, param->si_guid, INIT_PORT_SI_GUID_OFFSET); MLX4_PUT(inbox, field, INIT_PORT_MAX_PKEY_OFFSET);
err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_INIT_PORT, err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_INIT_PORT,
MLX4_CMD_TIME_CLASS_A); MLX4_CMD_TIME_CLASS_A);
mlx4_free_cmd_mailbox(dev, mailbox); mlx4_free_cmd_mailbox(dev, mailbox);
} else
err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_INIT_PORT,
MLX4_CMD_TIME_CLASS_A);
return err; return err;
} }
......
...@@ -59,13 +59,13 @@ struct mlx4_dev_cap { ...@@ -59,13 +59,13 @@ struct mlx4_dev_cap {
int max_responder_per_qp; int max_responder_per_qp;
int max_rdma_global; int max_rdma_global;
int local_ca_ack_delay; int local_ca_ack_delay;
int max_mtu;
int max_port_width;
int max_vl;
int num_ports; int num_ports;
int max_gids; int max_mtu[MLX4_MAX_PORTS + 1];
int max_port_width[MLX4_MAX_PORTS + 1];
int max_vl[MLX4_MAX_PORTS + 1];
int max_gids[MLX4_MAX_PORTS + 1];
int max_pkeys[MLX4_MAX_PORTS + 1];
u16 stat_rate_support; u16 stat_rate_support;
int max_pkeys;
u32 flags; u32 flags;
int reserved_uars; int reserved_uars;
int uar_size; int uar_size;
......
...@@ -88,6 +88,7 @@ static struct mlx4_profile default_profile = { ...@@ -88,6 +88,7 @@ static struct mlx4_profile default_profile = {
static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
{ {
int err; int err;
int i;
err = mlx4_QUERY_DEV_CAP(dev, dev_cap); err = mlx4_QUERY_DEV_CAP(dev, dev_cap);
if (err) { if (err) {
...@@ -117,11 +118,15 @@ static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev ...@@ -117,11 +118,15 @@ static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev
} }
dev->caps.num_ports = dev_cap->num_ports; dev->caps.num_ports = dev_cap->num_ports;
for (i = 1; i <= dev->caps.num_ports; ++i) {
dev->caps.vl_cap[i] = dev_cap->max_vl[i];
dev->caps.mtu_cap[i] = dev_cap->max_mtu[i];
dev->caps.gid_table_len[i] = dev_cap->max_gids[i];
dev->caps.pkey_table_len[i] = dev_cap->max_pkeys[i];
dev->caps.port_width_cap[i] = dev_cap->max_port_width[i];
}
dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE;
dev->caps.vl_cap = dev_cap->max_vl;
dev->caps.mtu_cap = dev_cap->max_mtu;
dev->caps.gid_table_len = dev_cap->max_gids;
dev->caps.pkey_table_len = dev_cap->max_pkeys;
dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay; dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay;
dev->caps.bf_reg_size = dev_cap->bf_reg_size; dev->caps.bf_reg_size = dev_cap->bf_reg_size;
dev->caps.bf_regs_per_page = dev_cap->bf_regs_per_page; dev->caps.bf_regs_per_page = dev_cap->bf_regs_per_page;
...@@ -148,7 +153,6 @@ static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev ...@@ -148,7 +153,6 @@ static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev
dev->caps.reserved_mrws = dev_cap->reserved_mrws; dev->caps.reserved_mrws = dev_cap->reserved_mrws;
dev->caps.reserved_uars = dev_cap->reserved_uars; dev->caps.reserved_uars = dev_cap->reserved_uars;
dev->caps.reserved_pds = dev_cap->reserved_pds; dev->caps.reserved_pds = dev_cap->reserved_pds;
dev->caps.port_width_cap = dev_cap->max_port_width;
dev->caps.mtt_entry_sz = MLX4_MTT_ENTRY_PER_SEG * dev_cap->mtt_entry_sz; dev->caps.mtt_entry_sz = MLX4_MTT_ENTRY_PER_SEG * dev_cap->mtt_entry_sz;
dev->caps.page_size_cap = ~(u32) (dev_cap->min_page_sz - 1); dev->caps.page_size_cap = ~(u32) (dev_cap->min_page_sz - 1);
dev->caps.flags = dev_cap->flags; dev->caps.flags = dev_cap->flags;
......
...@@ -54,6 +54,7 @@ enum { ...@@ -54,6 +54,7 @@ enum {
MLX4_CMD_INIT_PORT = 0x9, MLX4_CMD_INIT_PORT = 0x9,
MLX4_CMD_CLOSE_PORT = 0xa, MLX4_CMD_CLOSE_PORT = 0xa,
MLX4_CMD_QUERY_HCA = 0xb, MLX4_CMD_QUERY_HCA = 0xb,
MLX4_CMD_QUERY_PORT = 0x43,
MLX4_CMD_SET_PORT = 0xc, MLX4_CMD_SET_PORT = 0xc,
MLX4_CMD_ACCESS_DDR = 0x2e, MLX4_CMD_ACCESS_DDR = 0x2e,
MLX4_CMD_MAP_ICM = 0xffa, MLX4_CMD_MAP_ICM = 0xffa,
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
enum { enum {
MLX4_FLAG_MSI_X = 1 << 0, MLX4_FLAG_MSI_X = 1 << 0,
MLX4_FLAG_OLD_PORT_CMDS = 1 << 1,
}; };
enum { enum {
...@@ -131,10 +132,10 @@ enum { ...@@ -131,10 +132,10 @@ enum {
struct mlx4_caps { struct mlx4_caps {
u64 fw_ver; u64 fw_ver;
int num_ports; int num_ports;
int vl_cap; int vl_cap[MLX4_MAX_PORTS + 1];
int mtu_cap; int mtu_cap[MLX4_MAX_PORTS + 1];
int gid_table_len; int gid_table_len[MLX4_MAX_PORTS + 1];
int pkey_table_len; int pkey_table_len[MLX4_MAX_PORTS + 1];
int local_ca_ack_delay; int local_ca_ack_delay;
int num_uars; int num_uars;
int bf_reg_size; int bf_reg_size;
...@@ -174,7 +175,7 @@ struct mlx4_caps { ...@@ -174,7 +175,7 @@ struct mlx4_caps {
u32 page_size_cap; u32 page_size_cap;
u32 flags; u32 flags;
u16 stat_rate_support; u16 stat_rate_support;
u8 port_width_cap; u8 port_width_cap[MLX4_MAX_PORTS + 1];
}; };
struct mlx4_buf_list { struct mlx4_buf_list {
...@@ -322,7 +323,7 @@ int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, struct mlx4_mtt *mtt, ...@@ -322,7 +323,7 @@ int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, struct mlx4_mtt *mtt,
void mlx4_srq_free(struct mlx4_dev *dev, struct mlx4_srq *srq); void mlx4_srq_free(struct mlx4_dev *dev, struct mlx4_srq *srq);
int mlx4_srq_arm(struct mlx4_dev *dev, struct mlx4_srq *srq, int limit_watermark); int mlx4_srq_arm(struct mlx4_dev *dev, struct mlx4_srq *srq, int limit_watermark);
int mlx4_INIT_PORT(struct mlx4_dev *dev, struct mlx4_init_port_param *param, int port); int mlx4_INIT_PORT(struct mlx4_dev *dev, int port);
int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port);
int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]);
......
...@@ -269,6 +269,10 @@ struct mlx4_wqe_data_seg { ...@@ -269,6 +269,10 @@ struct mlx4_wqe_data_seg {
__be64 addr; __be64 addr;
}; };
enum {
MLX4_INLINE_ALIGN = 64,
};
struct mlx4_wqe_inline_seg { struct mlx4_wqe_inline_seg {
__be32 byte_count; __be32 byte_count;
}; };
......
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