aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-20 18:39:24 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-20 18:39:24 -0400
commitb3f4256fe0682143883ce6903e4646a03943f792 (patch)
tree3f090af16d721dd3d088a96a6defb0637ae74f76
parent044f620ac65d0d90727cdbd0c058e4d150d62ddc (diff)
parente61ef2416b0b92828512b6cfcd0104a02b6431fe (diff)
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
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c19
-rw-r--r--drivers/infiniband/hw/mlx4/main.c16
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h5
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c196
-rw-r--r--drivers/infiniband/hw/mlx4/user.h9
-rw-r--r--drivers/net/mlx4/fw.c110
-rw-r--r--drivers/net/mlx4/fw.h10
-rw-r--r--drivers/net/mlx4/main.c14
-rw-r--r--include/linux/mlx4/cmd.h1
-rw-r--r--include/linux/mlx4/device.h13
-rw-r--r--include/linux/mlx4/qp.h4
11 files changed, 259 insertions, 138 deletions
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index b2a290c6703a..660b27aecae5 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -354,8 +354,8 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
354 if (is_send) { 354 if (is_send) {
355 wq = &(*cur_qp)->sq; 355 wq = &(*cur_qp)->sq;
356 wqe_ctr = be16_to_cpu(cqe->wqe_index); 356 wqe_ctr = be16_to_cpu(cqe->wqe_index);
357 wq->tail += wqe_ctr - (u16) wq->tail; 357 wq->tail += (u16) (wqe_ctr - (u16) wq->tail);
358 wc->wr_id = wq->wrid[wq->tail & (wq->max - 1)]; 358 wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
359 ++wq->tail; 359 ++wq->tail;
360 } else if ((*cur_qp)->ibqp.srq) { 360 } else if ((*cur_qp)->ibqp.srq) {
361 srq = to_msrq((*cur_qp)->ibqp.srq); 361 srq = to_msrq((*cur_qp)->ibqp.srq);
@@ -364,7 +364,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
364 mlx4_ib_free_srq_wqe(srq, wqe_ctr); 364 mlx4_ib_free_srq_wqe(srq, wqe_ctr);
365 } else { 365 } else {
366 wq = &(*cur_qp)->rq; 366 wq = &(*cur_qp)->rq;
367 wc->wr_id = wq->wrid[wq->tail & (wq->max - 1)]; 367 wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
368 ++wq->tail; 368 ++wq->tail;
369 } 369 }
370 370
@@ -478,7 +478,8 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq)
478{ 478{
479 u32 prod_index; 479 u32 prod_index;
480 int nfreed = 0; 480 int nfreed = 0;
481 struct mlx4_cqe *cqe; 481 struct mlx4_cqe *cqe, *dest;
482 u8 owner_bit;
482 483
483 /* 484 /*
484 * First we need to find the current producer index, so we 485 * 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 if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK)) 502 if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK))
502 mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index)); 503 mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index));
503 ++nfreed; 504 ++nfreed;
504 } else if (nfreed) 505 } else if (nfreed) {
505 memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe), 506 dest = get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe);
506 cqe, sizeof *cqe); 507 owner_bit = dest->owner_sr_opcode & MLX4_CQE_OWNER_MASK;
508 memcpy(dest, cqe, sizeof *cqe);
509 dest->owner_sr_opcode = owner_bit |
510 (dest->owner_sr_opcode & ~MLX4_CQE_OWNER_MASK);
511 }
507 } 512 }
508 513
509 if (nfreed) { 514 if (nfreed) {
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 402f3a20ec0a..1095c82b38c2 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -125,7 +125,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
125 props->local_ca_ack_delay = dev->dev->caps.local_ca_ack_delay; 125 props->local_ca_ack_delay = dev->dev->caps.local_ca_ack_delay;
126 props->atomic_cap = dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_ATOMIC ? 126 props->atomic_cap = dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_ATOMIC ?
127 IB_ATOMIC_HCA : IB_ATOMIC_NONE; 127 IB_ATOMIC_HCA : IB_ATOMIC_NONE;
128 props->max_pkeys = dev->dev->caps.pkey_table_len; 128 props->max_pkeys = dev->dev->caps.pkey_table_len[1];
129 props->max_mcast_grp = dev->dev->caps.num_mgms + dev->dev->caps.num_amgms; 129 props->max_mcast_grp = dev->dev->caps.num_mgms + dev->dev->caps.num_amgms;
130 props->max_mcast_qp_attach = dev->dev->caps.num_qp_per_mgm; 130 props->max_mcast_qp_attach = dev->dev->caps.num_qp_per_mgm;
131 props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * 131 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 props->state = out_mad->data[32] & 0xf; 168 props->state = out_mad->data[32] & 0xf;
169 props->phys_state = out_mad->data[33] >> 4; 169 props->phys_state = out_mad->data[33] >> 4;
170 props->port_cap_flags = be32_to_cpup((__be32 *) (out_mad->data + 20)); 170 props->port_cap_flags = be32_to_cpup((__be32 *) (out_mad->data + 20));
171 props->gid_tbl_len = to_mdev(ibdev)->dev->caps.gid_table_len; 171 props->gid_tbl_len = to_mdev(ibdev)->dev->caps.gid_table_len[port];
172 props->max_msg_sz = 0x80000000; 172 props->max_msg_sz = 0x80000000;
173 props->pkey_tbl_len = to_mdev(ibdev)->dev->caps.pkey_table_len; 173 props->pkey_tbl_len = to_mdev(ibdev)->dev->caps.pkey_table_len[port];
174 props->bad_pkey_cntr = be16_to_cpup((__be16 *) (out_mad->data + 46)); 174 props->bad_pkey_cntr = be16_to_cpup((__be16 *) (out_mad->data + 46));
175 props->qkey_viol_cntr = be16_to_cpup((__be16 *) (out_mad->data + 48)); 175 props->qkey_viol_cntr = be16_to_cpup((__be16 *) (out_mad->data + 48));
176 props->active_width = out_mad->data[31] & 0xf; 176 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 return PTR_ERR(mailbox); 280 return PTR_ERR(mailbox);
281 281
282 memset(mailbox->buf, 0, 256); 282 memset(mailbox->buf, 0, 256);
283 *(u8 *) mailbox->buf = !!reset_qkey_viols << 6; 283
284 ((__be32 *) mailbox->buf)[2] = cpu_to_be32(cap_mask); 284 if (dev->dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
285 *(u8 *) mailbox->buf = !!reset_qkey_viols << 6;
286 ((__be32 *) mailbox->buf)[2] = cpu_to_be32(cap_mask);
287 } else {
288 ((u8 *) mailbox->buf)[3] = !!reset_qkey_viols;
289 ((__be32 *) mailbox->buf)[1] = cpu_to_be32(cap_mask);
290 }
285 291
286 err = mlx4_cmd(dev->dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, 292 err = mlx4_cmd(dev->dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
287 MLX4_CMD_TIME_CLASS_B); 293 MLX4_CMD_TIME_CLASS_B);
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 93dac71f3230..24ccadd6e4f8 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -95,7 +95,8 @@ struct mlx4_ib_mr {
95struct mlx4_ib_wq { 95struct mlx4_ib_wq {
96 u64 *wrid; 96 u64 *wrid;
97 spinlock_t lock; 97 spinlock_t lock;
98 int max; 98 int wqe_cnt;
99 int max_post;
99 int max_gs; 100 int max_gs;
100 int offset; 101 int offset;
101 int wqe_shift; 102 int wqe_shift;
@@ -113,6 +114,7 @@ struct mlx4_ib_qp {
113 114
114 u32 doorbell_qpn; 115 u32 doorbell_qpn;
115 __be32 sq_signal_bits; 116 __be32 sq_signal_bits;
117 int sq_spare_wqes;
116 struct mlx4_ib_wq sq; 118 struct mlx4_ib_wq sq;
117 119
118 struct ib_umem *umem; 120 struct ib_umem *umem;
@@ -123,6 +125,7 @@ struct mlx4_ib_qp {
123 u8 alt_port; 125 u8 alt_port;
124 u8 atomic_rd_en; 126 u8 atomic_rd_en;
125 u8 resp_depth; 127 u8 resp_depth;
128 u8 sq_no_prefetch;
126 u8 state; 129 u8 state;
127}; 130};
128 131
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 5c6d05427a0f..28a08bdd1800 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -109,6 +109,20 @@ static void *get_send_wqe(struct mlx4_ib_qp *qp, int n)
109 return get_wqe(qp, qp->sq.offset + (n << qp->sq.wqe_shift)); 109 return get_wqe(qp, qp->sq.offset + (n << qp->sq.wqe_shift));
110} 110}
111 111
112/*
113 * Stamp a SQ WQE so that it is invalid if prefetched by marking the
114 * first four bytes of every 64 byte chunk with 0xffffffff, except for
115 * the very first chunk of the WQE.
116 */
117static void stamp_send_wqe(struct mlx4_ib_qp *qp, int n)
118{
119 u32 *wqe = get_send_wqe(qp, n);
120 int i;
121
122 for (i = 16; i < 1 << (qp->sq.wqe_shift - 2); i += 16)
123 wqe[i] = 0xffffffff;
124}
125
112static void mlx4_ib_qp_event(struct mlx4_qp *qp, enum mlx4_event type) 126static void mlx4_ib_qp_event(struct mlx4_qp *qp, enum mlx4_event type)
113{ 127{
114 struct ib_event event; 128 struct ib_event event;
@@ -178,6 +192,8 @@ static int send_wqe_overhead(enum ib_qp_type type)
178 case IB_QPT_GSI: 192 case IB_QPT_GSI:
179 return sizeof (struct mlx4_wqe_ctrl_seg) + 193 return sizeof (struct mlx4_wqe_ctrl_seg) +
180 ALIGN(MLX4_IB_UD_HEADER_SIZE + 194 ALIGN(MLX4_IB_UD_HEADER_SIZE +
195 DIV_ROUND_UP(MLX4_IB_UD_HEADER_SIZE,
196 MLX4_INLINE_ALIGN) *
181 sizeof (struct mlx4_wqe_inline_seg), 197 sizeof (struct mlx4_wqe_inline_seg),
182 sizeof (struct mlx4_wqe_data_seg)) + 198 sizeof (struct mlx4_wqe_data_seg)) +
183 ALIGN(4 + 199 ALIGN(4 +
@@ -201,18 +217,18 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
201 if (cap->max_recv_wr) 217 if (cap->max_recv_wr)
202 return -EINVAL; 218 return -EINVAL;
203 219
204 qp->rq.max = qp->rq.max_gs = 0; 220 qp->rq.wqe_cnt = qp->rq.max_gs = 0;
205 } else { 221 } else {
206 /* HW requires >= 1 RQ entry with >= 1 gather entry */ 222 /* HW requires >= 1 RQ entry with >= 1 gather entry */
207 if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge)) 223 if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge))
208 return -EINVAL; 224 return -EINVAL;
209 225
210 qp->rq.max = roundup_pow_of_two(max(1, cap->max_recv_wr)); 226 qp->rq.wqe_cnt = roundup_pow_of_two(max(1U, cap->max_recv_wr));
211 qp->rq.max_gs = roundup_pow_of_two(max(1, cap->max_recv_sge)); 227 qp->rq.max_gs = roundup_pow_of_two(max(1U, cap->max_recv_sge));
212 qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg)); 228 qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
213 } 229 }
214 230
215 cap->max_recv_wr = qp->rq.max; 231 cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt;
216 cap->max_recv_sge = qp->rq.max_gs; 232 cap->max_recv_sge = qp->rq.max_gs;
217 233
218 return 0; 234 return 0;
@@ -236,8 +252,6 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
236 cap->max_send_sge + 2 > dev->dev->caps.max_sq_sg) 252 cap->max_send_sge + 2 > dev->dev->caps.max_sq_sg)
237 return -EINVAL; 253 return -EINVAL;
238 254
239 qp->sq.max = cap->max_send_wr ? roundup_pow_of_two(cap->max_send_wr) : 1;
240
241 qp->sq.wqe_shift = ilog2(roundup_pow_of_two(max(cap->max_send_sge * 255 qp->sq.wqe_shift = ilog2(roundup_pow_of_two(max(cap->max_send_sge *
242 sizeof (struct mlx4_wqe_data_seg), 256 sizeof (struct mlx4_wqe_data_seg),
243 cap->max_inline_data + 257 cap->max_inline_data +
@@ -246,20 +260,27 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
246 qp->sq.max_gs = ((1 << qp->sq.wqe_shift) - send_wqe_overhead(type)) / 260 qp->sq.max_gs = ((1 << qp->sq.wqe_shift) - send_wqe_overhead(type)) /
247 sizeof (struct mlx4_wqe_data_seg); 261 sizeof (struct mlx4_wqe_data_seg);
248 262
249 qp->buf_size = (qp->rq.max << qp->rq.wqe_shift) + 263 /*
250 (qp->sq.max << qp->sq.wqe_shift); 264 * We need to leave 2 KB + 1 WQE of headroom in the SQ to
265 * allow HW to prefetch.
266 */
267 qp->sq_spare_wqes = (2048 >> qp->sq.wqe_shift) + 1;
268 qp->sq.wqe_cnt = roundup_pow_of_two(cap->max_send_wr + qp->sq_spare_wqes);
269
270 qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
271 (qp->sq.wqe_cnt << qp->sq.wqe_shift);
251 if (qp->rq.wqe_shift > qp->sq.wqe_shift) { 272 if (qp->rq.wqe_shift > qp->sq.wqe_shift) {
252 qp->rq.offset = 0; 273 qp->rq.offset = 0;
253 qp->sq.offset = qp->rq.max << qp->rq.wqe_shift; 274 qp->sq.offset = qp->rq.wqe_cnt << qp->rq.wqe_shift;
254 } else { 275 } else {
255 qp->rq.offset = qp->sq.max << qp->sq.wqe_shift; 276 qp->rq.offset = qp->sq.wqe_cnt << qp->sq.wqe_shift;
256 qp->sq.offset = 0; 277 qp->sq.offset = 0;
257 } 278 }
258 279
259 cap->max_send_wr = qp->sq.max; 280 cap->max_send_wr = qp->sq.max_post = qp->sq.wqe_cnt - qp->sq_spare_wqes;
260 cap->max_send_sge = qp->sq.max_gs; 281 cap->max_send_sge = qp->sq.max_gs;
261 cap->max_inline_data = (1 << qp->sq.wqe_shift) - send_wqe_overhead(type) - 282 /* We don't support inline sends for kernel QPs (yet) */
262 sizeof (struct mlx4_wqe_inline_seg); 283 cap->max_inline_data = 0;
263 284
264 return 0; 285 return 0;
265} 286}
@@ -267,11 +288,11 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
267static int set_user_sq_size(struct mlx4_ib_qp *qp, 288static int set_user_sq_size(struct mlx4_ib_qp *qp,
268 struct mlx4_ib_create_qp *ucmd) 289 struct mlx4_ib_create_qp *ucmd)
269{ 290{
270 qp->sq.max = 1 << ucmd->log_sq_bb_count; 291 qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count;
271 qp->sq.wqe_shift = ucmd->log_sq_stride; 292 qp->sq.wqe_shift = ucmd->log_sq_stride;
272 293
273 qp->buf_size = (qp->rq.max << qp->rq.wqe_shift) + 294 qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
274 (qp->sq.max << qp->sq.wqe_shift); 295 (qp->sq.wqe_cnt << qp->sq.wqe_shift);
275 296
276 return 0; 297 return 0;
277} 298}
@@ -307,6 +328,8 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
307 goto err; 328 goto err;
308 } 329 }
309 330
331 qp->sq_no_prefetch = ucmd.sq_no_prefetch;
332
310 err = set_user_sq_size(qp, &ucmd); 333 err = set_user_sq_size(qp, &ucmd);
311 if (err) 334 if (err)
312 goto err; 335 goto err;
@@ -334,6 +357,8 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
334 goto err_mtt; 357 goto err_mtt;
335 } 358 }
336 } else { 359 } else {
360 qp->sq_no_prefetch = 0;
361
337 err = set_kernel_sq_size(dev, &init_attr->cap, init_attr->qp_type, qp); 362 err = set_kernel_sq_size(dev, &init_attr->cap, init_attr->qp_type, qp);
338 if (err) 363 if (err)
339 goto err; 364 goto err;
@@ -360,16 +385,13 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
360 if (err) 385 if (err)
361 goto err_mtt; 386 goto err_mtt;
362 387
363 qp->sq.wrid = kmalloc(qp->sq.max * sizeof (u64), GFP_KERNEL); 388 qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof (u64), GFP_KERNEL);
364 qp->rq.wrid = kmalloc(qp->rq.max * sizeof (u64), GFP_KERNEL); 389 qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof (u64), GFP_KERNEL);
365 390
366 if (!qp->sq.wrid || !qp->rq.wrid) { 391 if (!qp->sq.wrid || !qp->rq.wrid) {
367 err = -ENOMEM; 392 err = -ENOMEM;
368 goto err_wrid; 393 goto err_wrid;
369 } 394 }
370
371 /* We don't support inline sends for kernel QPs (yet) */
372 init_attr->cap.max_inline_data = 0;
373 } 395 }
374 396
375 err = mlx4_qp_alloc(dev->dev, sqpn, &qp->mqp); 397 err = mlx4_qp_alloc(dev->dev, sqpn, &qp->mqp);
@@ -583,24 +605,6 @@ int mlx4_ib_destroy_qp(struct ib_qp *qp)
583 return 0; 605 return 0;
584} 606}
585 607
586static void init_port(struct mlx4_ib_dev *dev, int port)
587{
588 struct mlx4_init_port_param param;
589 int err;
590
591 memset(&param, 0, sizeof param);
592
593 param.port_width_cap = dev->dev->caps.port_width_cap;
594 param.vl_cap = dev->dev->caps.vl_cap;
595 param.mtu = ib_mtu_enum_to_int(dev->dev->caps.mtu_cap);
596 param.max_gid = dev->dev->caps.gid_table_len;
597 param.max_pkey = dev->dev->caps.pkey_table_len;
598
599 err = mlx4_INIT_PORT(dev->dev, &param, port);
600 if (err)
601 printk(KERN_WARNING "INIT_PORT failed, return code %d.\n", err);
602}
603
604static int to_mlx4_st(enum ib_qp_type type) 608static int to_mlx4_st(enum ib_qp_type type)
605{ 609{
606 switch (type) { 610 switch (type) {
@@ -674,9 +678,9 @@ static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
674 path->counter_index = 0xff; 678 path->counter_index = 0xff;
675 679
676 if (ah->ah_flags & IB_AH_GRH) { 680 if (ah->ah_flags & IB_AH_GRH) {
677 if (ah->grh.sgid_index >= dev->dev->caps.gid_table_len) { 681 if (ah->grh.sgid_index >= dev->dev->caps.gid_table_len[port]) {
678 printk(KERN_ERR "sgid_index (%u) too large. max is %d\n", 682 printk(KERN_ERR "sgid_index (%u) too large. max is %d\n",
679 ah->grh.sgid_index, dev->dev->caps.gid_table_len - 1); 683 ah->grh.sgid_index, dev->dev->caps.gid_table_len[port] - 1);
680 return -1; 684 return -1;
681 } 685 }
682 686
@@ -743,14 +747,17 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
743 context->mtu_msgmax = (attr->path_mtu << 5) | 31; 747 context->mtu_msgmax = (attr->path_mtu << 5) | 31;
744 } 748 }
745 749
746 if (qp->rq.max) 750 if (qp->rq.wqe_cnt)
747 context->rq_size_stride = ilog2(qp->rq.max) << 3; 751 context->rq_size_stride = ilog2(qp->rq.wqe_cnt) << 3;
748 context->rq_size_stride |= qp->rq.wqe_shift - 4; 752 context->rq_size_stride |= qp->rq.wqe_shift - 4;
749 753
750 if (qp->sq.max) 754 if (qp->sq.wqe_cnt)
751 context->sq_size_stride = ilog2(qp->sq.max) << 3; 755 context->sq_size_stride = ilog2(qp->sq.wqe_cnt) << 3;
752 context->sq_size_stride |= qp->sq.wqe_shift - 4; 756 context->sq_size_stride |= qp->sq.wqe_shift - 4;
753 757
758 if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
759 context->sq_size_stride |= !!qp->sq_no_prefetch << 7;
760
754 if (qp->ibqp.uobject) 761 if (qp->ibqp.uobject)
755 context->usr_page = cpu_to_be32(to_mucontext(ibqp->uobject->context)->uar.index); 762 context->usr_page = cpu_to_be32(to_mucontext(ibqp->uobject->context)->uar.index);
756 else 763 else
@@ -789,13 +796,14 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
789 } 796 }
790 797
791 if (attr_mask & IB_QP_ALT_PATH) { 798 if (attr_mask & IB_QP_ALT_PATH) {
792 if (attr->alt_pkey_index >= dev->dev->caps.pkey_table_len)
793 return -EINVAL;
794
795 if (attr->alt_port_num == 0 || 799 if (attr->alt_port_num == 0 ||
796 attr->alt_port_num > dev->dev->caps.num_ports) 800 attr->alt_port_num > dev->dev->caps.num_ports)
797 return -EINVAL; 801 return -EINVAL;
798 802
803 if (attr->alt_pkey_index >=
804 dev->dev->caps.pkey_table_len[attr->alt_port_num])
805 return -EINVAL;
806
799 if (mlx4_set_path(dev, &attr->alt_ah_attr, &context->alt_path, 807 if (mlx4_set_path(dev, &attr->alt_ah_attr, &context->alt_path,
800 attr->alt_port_num)) 808 attr->alt_port_num))
801 return -EINVAL; 809 return -EINVAL;
@@ -884,16 +892,19 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
884 892
885 /* 893 /*
886 * Before passing a kernel QP to the HW, make sure that the 894 * Before passing a kernel QP to the HW, make sure that the
887 * ownership bits of the send queue are set so that the 895 * ownership bits of the send queue are set and the SQ
888 * hardware doesn't start processing stale work requests. 896 * headroom is stamped so that the hardware doesn't start
897 * processing stale work requests.
889 */ 898 */
890 if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) { 899 if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
891 struct mlx4_wqe_ctrl_seg *ctrl; 900 struct mlx4_wqe_ctrl_seg *ctrl;
892 int i; 901 int i;
893 902
894 for (i = 0; i < qp->sq.max; ++i) { 903 for (i = 0; i < qp->sq.wqe_cnt; ++i) {
895 ctrl = get_send_wqe(qp, i); 904 ctrl = get_send_wqe(qp, i);
896 ctrl->owner_opcode = cpu_to_be32(1 << 31); 905 ctrl->owner_opcode = cpu_to_be32(1 << 31);
906
907 stamp_send_wqe(qp, i);
897 } 908 }
898 } 909 }
899 910
@@ -923,7 +934,9 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
923 */ 934 */
924 if (is_qp0(dev, qp)) { 935 if (is_qp0(dev, qp)) {
925 if (cur_state != IB_QPS_RTR && new_state == IB_QPS_RTR) 936 if (cur_state != IB_QPS_RTR && new_state == IB_QPS_RTR)
926 init_port(dev, qp->port); 937 if (mlx4_INIT_PORT(dev->dev, qp->port))
938 printk(KERN_WARNING "INIT_PORT failed for port %d\n",
939 qp->port);
927 940
928 if (cur_state != IB_QPS_RESET && cur_state != IB_QPS_ERR && 941 if (cur_state != IB_QPS_RESET && cur_state != IB_QPS_ERR &&
929 (new_state == IB_QPS_RESET || new_state == IB_QPS_ERR)) 942 (new_state == IB_QPS_RESET || new_state == IB_QPS_ERR))
@@ -986,16 +999,17 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
986 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) 999 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask))
987 goto out; 1000 goto out;
988 1001
989 if ((attr_mask & IB_QP_PKEY_INDEX) &&
990 attr->pkey_index >= dev->dev->caps.pkey_table_len) {
991 goto out;
992 }
993
994 if ((attr_mask & IB_QP_PORT) && 1002 if ((attr_mask & IB_QP_PORT) &&
995 (attr->port_num == 0 || attr->port_num > dev->dev->caps.num_ports)) { 1003 (attr->port_num == 0 || attr->port_num > dev->dev->caps.num_ports)) {
996 goto out; 1004 goto out;
997 } 1005 }
998 1006
1007 if (attr_mask & IB_QP_PKEY_INDEX) {
1008 int p = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
1009 if (attr->pkey_index >= dev->dev->caps.pkey_table_len[p])
1010 goto out;
1011 }
1012
999 if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && 1013 if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
1000 attr->max_rd_atomic > dev->dev->caps.max_qp_init_rdma) { 1014 attr->max_rd_atomic > dev->dev->caps.max_qp_init_rdma) {
1001 goto out; 1015 goto out;
@@ -1037,6 +1051,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
1037 u16 pkey; 1051 u16 pkey;
1038 int send_size; 1052 int send_size;
1039 int header_size; 1053 int header_size;
1054 int spc;
1040 int i; 1055 int i;
1041 1056
1042 send_size = 0; 1057 send_size = 0;
@@ -1112,10 +1127,43 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
1112 printk("\n"); 1127 printk("\n");
1113 } 1128 }
1114 1129
1115 inl->byte_count = cpu_to_be32(1 << 31 | header_size); 1130 /*
1116 memcpy(inl + 1, sqp->header_buf, header_size); 1131 * Inline data segments may not cross a 64 byte boundary. If
1132 * our UD header is bigger than the space available up to the
1133 * next 64 byte boundary in the WQE, use two inline data
1134 * segments to hold the UD header.
1135 */
1136 spc = MLX4_INLINE_ALIGN -
1137 ((unsigned long) (inl + 1) & (MLX4_INLINE_ALIGN - 1));
1138 if (header_size <= spc) {
1139 inl->byte_count = cpu_to_be32(1 << 31 | header_size);
1140 memcpy(inl + 1, sqp->header_buf, header_size);
1141 i = 1;
1142 } else {
1143 inl->byte_count = cpu_to_be32(1 << 31 | spc);
1144 memcpy(inl + 1, sqp->header_buf, spc);
1117 1145
1118 return ALIGN(sizeof (struct mlx4_wqe_inline_seg) + header_size, 16); 1146 inl = (void *) (inl + 1) + spc;
1147 memcpy(inl + 1, sqp->header_buf + spc, header_size - spc);
1148 /*
1149 * Need a barrier here to make sure all the data is
1150 * visible before the byte_count field is set.
1151 * Otherwise the HCA prefetcher could grab the 64-byte
1152 * chunk with this inline segment and get a valid (!=
1153 * 0xffffffff) byte count but stale data, and end up
1154 * generating a packet with bad headers.
1155 *
1156 * The first inline segment's byte_count field doesn't
1157 * need a barrier, because it comes after a
1158 * control/MLX segment and therefore is at an offset
1159 * of 16 mod 64.
1160 */
1161 wmb();
1162 inl->byte_count = cpu_to_be32(1 << 31 | (header_size - spc));
1163 i = 2;
1164 }
1165
1166 return ALIGN(i * sizeof (struct mlx4_wqe_inline_seg) + header_size, 16);
1119} 1167}
1120 1168
1121static int mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq) 1169static int mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq)
@@ -1124,7 +1172,7 @@ static int mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq
1124 struct mlx4_ib_cq *cq; 1172 struct mlx4_ib_cq *cq;
1125 1173
1126 cur = wq->head - wq->tail; 1174 cur = wq->head - wq->tail;
1127 if (likely(cur + nreq < wq->max)) 1175 if (likely(cur + nreq < wq->max_post))
1128 return 0; 1176 return 0;
1129 1177
1130 cq = to_mcq(ib_cq); 1178 cq = to_mcq(ib_cq);
@@ -1132,7 +1180,7 @@ static int mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq
1132 cur = wq->head - wq->tail; 1180 cur = wq->head - wq->tail;
1133 spin_unlock(&cq->lock); 1181 spin_unlock(&cq->lock);
1134 1182
1135 return cur + nreq >= wq->max; 1183 return cur + nreq >= wq->max_post;
1136} 1184}
1137 1185
1138int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, 1186int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
@@ -1165,8 +1213,8 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1165 goto out; 1213 goto out;
1166 } 1214 }
1167 1215
1168 ctrl = wqe = get_send_wqe(qp, ind & (qp->sq.max - 1)); 1216 ctrl = wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1));
1169 qp->sq.wrid[ind & (qp->sq.max - 1)] = wr->wr_id; 1217 qp->sq.wrid[ind & (qp->sq.wqe_cnt - 1)] = wr->wr_id;
1170 1218
1171 ctrl->srcrb_flags = 1219 ctrl->srcrb_flags =
1172 (wr->send_flags & IB_SEND_SIGNALED ? 1220 (wr->send_flags & IB_SEND_SIGNALED ?
@@ -1301,7 +1349,16 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1301 } 1349 }
1302 1350
1303 ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] | 1351 ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] |
1304 (ind & qp->sq.max ? cpu_to_be32(1 << 31) : 0); 1352 (ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0);
1353
1354 /*
1355 * We can improve latency by not stamping the last
1356 * send queue WQE until after ringing the doorbell, so
1357 * only stamp here if there are still more WQEs to post.
1358 */
1359 if (wr->next)
1360 stamp_send_wqe(qp, (ind + qp->sq_spare_wqes) &
1361 (qp->sq.wqe_cnt - 1));
1305 1362
1306 ++ind; 1363 ++ind;
1307 } 1364 }
@@ -1324,6 +1381,9 @@ out:
1324 * and reach the HCA out of order. 1381 * and reach the HCA out of order.
1325 */ 1382 */
1326 mmiowb(); 1383 mmiowb();
1384
1385 stamp_send_wqe(qp, (ind + qp->sq_spare_wqes - 1) &
1386 (qp->sq.wqe_cnt - 1));
1327 } 1387 }
1328 1388
1329 spin_unlock_irqrestore(&qp->rq.lock, flags); 1389 spin_unlock_irqrestore(&qp->rq.lock, flags);
@@ -1344,7 +1404,7 @@ int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1344 1404
1345 spin_lock_irqsave(&qp->rq.lock, flags); 1405 spin_lock_irqsave(&qp->rq.lock, flags);
1346 1406
1347 ind = qp->rq.head & (qp->rq.max - 1); 1407 ind = qp->rq.head & (qp->rq.wqe_cnt - 1);
1348 1408
1349 for (nreq = 0; wr; ++nreq, wr = wr->next) { 1409 for (nreq = 0; wr; ++nreq, wr = wr->next) {
1350 if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.send_cq)) { 1410 if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.send_cq)) {
@@ -1375,7 +1435,7 @@ int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1375 1435
1376 qp->rq.wrid[ind] = wr->wr_id; 1436 qp->rq.wrid[ind] = wr->wr_id;
1377 1437
1378 ind = (ind + 1) & (qp->rq.max - 1); 1438 ind = (ind + 1) & (qp->rq.wqe_cnt - 1);
1379 } 1439 }
1380 1440
1381out: 1441out:
diff --git a/drivers/infiniband/hw/mlx4/user.h b/drivers/infiniband/hw/mlx4/user.h
index 88c72d56368b..e2d11be4525c 100644
--- a/drivers/infiniband/hw/mlx4/user.h
+++ b/drivers/infiniband/hw/mlx4/user.h
@@ -39,7 +39,7 @@
39 * Increment this value if any changes that break userspace ABI 39 * Increment this value if any changes that break userspace ABI
40 * compatibility are made. 40 * compatibility are made.
41 */ 41 */
42#define MLX4_IB_UVERBS_ABI_VERSION 2 42#define MLX4_IB_UVERBS_ABI_VERSION 3
43 43
44/* 44/*
45 * Make sure that all structs defined in this file remain laid out so 45 * Make sure that all structs defined in this file remain laid out so
@@ -87,9 +87,10 @@ struct mlx4_ib_create_srq_resp {
87struct mlx4_ib_create_qp { 87struct mlx4_ib_create_qp {
88 __u64 buf_addr; 88 __u64 buf_addr;
89 __u64 db_addr; 89 __u64 db_addr;
90 __u8 log_sq_bb_count; 90 __u8 log_sq_bb_count;
91 __u8 log_sq_stride; 91 __u8 log_sq_stride;
92 __u8 reserved[6]; 92 __u8 sq_no_prefetch;
93 __u8 reserved[5];
93}; 94};
94 95
95#endif /* MLX4_IB_USER_H */ 96#endif /* MLX4_IB_USER_H */
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index e7ca118c8dfd..d2b065351e45 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -38,7 +38,9 @@
38#include "icm.h" 38#include "icm.h"
39 39
40enum { 40enum {
41 MLX4_COMMAND_INTERFACE_REV = 1 41 MLX4_COMMAND_INTERFACE_MIN_REV = 2,
42 MLX4_COMMAND_INTERFACE_MAX_REV = 3,
43 MLX4_COMMAND_INTERFACE_NEW_PORT_CMDS = 3,
42}; 44};
43 45
44extern void __buggy_use_of_MLX4_GET(void); 46extern 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 u16 size; 109 u16 size;
108 u16 stat_rate; 110 u16 stat_rate;
109 int err; 111 int err;
112 int i;
110 113
111#define QUERY_DEV_CAP_OUT_SIZE 0x100 114#define QUERY_DEV_CAP_OUT_SIZE 0x100
112#define QUERY_DEV_CAP_MAX_SRQ_SZ_OFFSET 0x10 115#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 179
177 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, 180 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP,
178 MLX4_CMD_TIME_CLASS_A); 181 MLX4_CMD_TIME_CLASS_A);
179
180 if (err) 182 if (err)
181 goto out; 183 goto out;
182 184
@@ -216,18 +218,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
216 dev_cap->max_rdma_global = 1 << (field & 0x3f); 218 dev_cap->max_rdma_global = 1 << (field & 0x3f);
217 MLX4_GET(field, outbox, QUERY_DEV_CAP_ACK_DELAY_OFFSET); 219 MLX4_GET(field, outbox, QUERY_DEV_CAP_ACK_DELAY_OFFSET);
218 dev_cap->local_ca_ack_delay = field & 0x1f; 220 dev_cap->local_ca_ack_delay = field & 0x1f;
219 MLX4_GET(field, outbox, QUERY_DEV_CAP_MTU_WIDTH_OFFSET);
220 dev_cap->max_mtu = field >> 4;
221 dev_cap->max_port_width = field & 0xf;
222 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET); 221 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET);
223 dev_cap->max_vl = field >> 4;
224 dev_cap->num_ports = field & 0xf; 222 dev_cap->num_ports = field & 0xf;
225 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_GID_OFFSET);
226 dev_cap->max_gids = 1 << (field & 0xf);
227 MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); 223 MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET);
228 dev_cap->stat_rate_support = stat_rate; 224 dev_cap->stat_rate_support = stat_rate;
229 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PKEY_OFFSET);
230 dev_cap->max_pkeys = 1 << (field & 0xf);
231 MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); 225 MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
232 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET); 226 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET);
233 dev_cap->reserved_uars = field >> 4; 227 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 MLX4_GET(dev_cap->max_icm_sz, outbox, 298 MLX4_GET(dev_cap->max_icm_sz, outbox,
305 QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET); 299 QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET);
306 300
301 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
302 for (i = 1; i <= dev_cap->num_ports; ++i) {
303 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET);
304 dev_cap->max_vl[i] = field >> 4;
305 MLX4_GET(field, outbox, QUERY_DEV_CAP_MTU_WIDTH_OFFSET);
306 dev_cap->max_mtu[i] = field >> 4;
307 dev_cap->max_port_width[i] = field & 0xf;
308 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_GID_OFFSET);
309 dev_cap->max_gids[i] = 1 << (field & 0xf);
310 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PKEY_OFFSET);
311 dev_cap->max_pkeys[i] = 1 << (field & 0xf);
312 }
313 } else {
314#define QUERY_PORT_MTU_OFFSET 0x01
315#define QUERY_PORT_WIDTH_OFFSET 0x06
316#define QUERY_PORT_MAX_GID_PKEY_OFFSET 0x07
317#define QUERY_PORT_MAX_VL_OFFSET 0x0b
318
319 for (i = 1; i <= dev_cap->num_ports; ++i) {
320 err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT,
321 MLX4_CMD_TIME_CLASS_B);
322 if (err)
323 goto out;
324
325 MLX4_GET(field, outbox, QUERY_PORT_MTU_OFFSET);
326 dev_cap->max_mtu[i] = field & 0xf;
327 MLX4_GET(field, outbox, QUERY_PORT_WIDTH_OFFSET);
328 dev_cap->max_port_width[i] = field & 0xf;
329 MLX4_GET(field, outbox, QUERY_PORT_MAX_GID_PKEY_OFFSET);
330 dev_cap->max_gids[i] = 1 << (field >> 4);
331 dev_cap->max_pkeys[i] = 1 << (field & 0xf);
332 MLX4_GET(field, outbox, QUERY_PORT_MAX_VL_OFFSET);
333 dev_cap->max_vl[i] = field & 0xf;
334 }
335 }
336
307 if (dev_cap->bmme_flags & 1) 337 if (dev_cap->bmme_flags & 1)
308 mlx4_dbg(dev, "Base MM extensions: yes " 338 mlx4_dbg(dev, "Base MM extensions: yes "
309 "(flags %d, rsvd L_Key %08x)\n", 339 "(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 mlx4_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", 368 mlx4_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n",
339 dev_cap->max_cq_sz, dev_cap->max_qp_sz, dev_cap->max_srq_sz); 369 dev_cap->max_cq_sz, dev_cap->max_qp_sz, dev_cap->max_srq_sz);
340 mlx4_dbg(dev, "Local CA ACK delay: %d, max MTU: %d, port width cap: %d\n", 370 mlx4_dbg(dev, "Local CA ACK delay: %d, max MTU: %d, port width cap: %d\n",
341 dev_cap->local_ca_ack_delay, 128 << dev_cap->max_mtu, 371 dev_cap->local_ca_ack_delay, 128 << dev_cap->max_mtu[1],
342 dev_cap->max_port_width); 372 dev_cap->max_port_width[1]);
343 mlx4_dbg(dev, "Max SQ desc size: %d, max SQ S/G: %d\n", 373 mlx4_dbg(dev, "Max SQ desc size: %d, max SQ S/G: %d\n",
344 dev_cap->max_sq_desc_sz, dev_cap->max_sq_sg); 374 dev_cap->max_sq_desc_sz, dev_cap->max_sq_sg);
345 mlx4_dbg(dev, "Max RQ desc size: %d, max RQ S/G: %d\n", 375 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 ((fw_ver & 0x0000ffffull) << 16); 521 ((fw_ver & 0x0000ffffull) << 16);
492 522
493 MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET); 523 MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET);
494 if (cmd_if_rev != MLX4_COMMAND_INTERFACE_REV) { 524 if (cmd_if_rev < MLX4_COMMAND_INTERFACE_MIN_REV ||
525 cmd_if_rev > MLX4_COMMAND_INTERFACE_MAX_REV) {
495 mlx4_err(dev, "Installed FW has unsupported " 526 mlx4_err(dev, "Installed FW has unsupported "
496 "command interface revision %d.\n", 527 "command interface revision %d.\n",
497 cmd_if_rev); 528 cmd_if_rev);
@@ -499,12 +530,15 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
499 (int) (dev->caps.fw_ver >> 32), 530 (int) (dev->caps.fw_ver >> 32),
500 (int) (dev->caps.fw_ver >> 16) & 0xffff, 531 (int) (dev->caps.fw_ver >> 16) & 0xffff,
501 (int) dev->caps.fw_ver & 0xffff); 532 (int) dev->caps.fw_ver & 0xffff);
502 mlx4_err(dev, "This driver version supports only revision %d.\n", 533 mlx4_err(dev, "This driver version supports only revisions %d to %d.\n",
503 MLX4_COMMAND_INTERFACE_REV); 534 MLX4_COMMAND_INTERFACE_MIN_REV, MLX4_COMMAND_INTERFACE_MAX_REV);
504 err = -ENODEV; 535 err = -ENODEV;
505 goto out; 536 goto out;
506 } 537 }
507 538
539 if (cmd_if_rev < MLX4_COMMAND_INTERFACE_NEW_PORT_CMDS)
540 dev->flags |= MLX4_FLAG_OLD_PORT_CMDS;
541
508 MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); 542 MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
509 cmd->max_cmds = 1 << lg; 543 cmd->max_cmds = 1 << lg;
510 544
@@ -708,13 +742,15 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
708 return err; 742 return err;
709} 743}
710 744
711int mlx4_INIT_PORT(struct mlx4_dev *dev, struct mlx4_init_port_param *param, int port) 745int mlx4_INIT_PORT(struct mlx4_dev *dev, int port)
712{ 746{
713 struct mlx4_cmd_mailbox *mailbox; 747 struct mlx4_cmd_mailbox *mailbox;
714 u32 *inbox; 748 u32 *inbox;
715 int err; 749 int err;
716 u32 flags; 750 u32 flags;
751 u16 field;
717 752
753 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
718#define INIT_PORT_IN_SIZE 256 754#define INIT_PORT_IN_SIZE 256
719#define INIT_PORT_FLAGS_OFFSET 0x00 755#define INIT_PORT_FLAGS_OFFSET 0x00
720#define INIT_PORT_FLAG_SIG (1 << 18) 756#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#define INIT_PORT_NODE_GUID_OFFSET 0x18 765#define INIT_PORT_NODE_GUID_OFFSET 0x18
730#define INIT_PORT_SI_GUID_OFFSET 0x20 766#define INIT_PORT_SI_GUID_OFFSET 0x20
731 767
732 mailbox = mlx4_alloc_cmd_mailbox(dev); 768 mailbox = mlx4_alloc_cmd_mailbox(dev);
733 if (IS_ERR(mailbox)) 769 if (IS_ERR(mailbox))
734 return PTR_ERR(mailbox); 770 return PTR_ERR(mailbox);
735 inbox = mailbox->buf; 771 inbox = mailbox->buf;
736 772
737 memset(inbox, 0, INIT_PORT_IN_SIZE); 773 memset(inbox, 0, INIT_PORT_IN_SIZE);
738 774
739 flags = 0; 775 flags = 0;
740 flags |= param->set_guid0 ? INIT_PORT_FLAG_G0 : 0; 776 flags |= (dev->caps.vl_cap[port] & 0xf) << INIT_PORT_VL_SHIFT;
741 flags |= param->set_node_guid ? INIT_PORT_FLAG_NG : 0; 777 flags |= (dev->caps.port_width_cap[port] & 0xf) << INIT_PORT_PORT_WIDTH_SHIFT;
742 flags |= param->set_si_guid ? INIT_PORT_FLAG_SIG : 0; 778 MLX4_PUT(inbox, flags, INIT_PORT_FLAGS_OFFSET);
743 flags |= (param->vl_cap & 0xf) << INIT_PORT_VL_SHIFT;
744 flags |= (param->port_width_cap & 0xf) << INIT_PORT_PORT_WIDTH_SHIFT;
745 MLX4_PUT(inbox, flags, INIT_PORT_FLAGS_OFFSET);
746 779
747 MLX4_PUT(inbox, param->mtu, INIT_PORT_MTU_OFFSET); 780 field = 128 << dev->caps.mtu_cap[port];
748 MLX4_PUT(inbox, param->max_gid, INIT_PORT_MAX_GID_OFFSET); 781 MLX4_PUT(inbox, field, INIT_PORT_MTU_OFFSET);
749 MLX4_PUT(inbox, param->max_pkey, INIT_PORT_MAX_PKEY_OFFSET); 782 field = dev->caps.gid_table_len[port];
750 MLX4_PUT(inbox, param->guid0, INIT_PORT_GUID0_OFFSET); 783 MLX4_PUT(inbox, field, INIT_PORT_MAX_GID_OFFSET);
751 MLX4_PUT(inbox, param->node_guid, INIT_PORT_NODE_GUID_OFFSET); 784 field = dev->caps.pkey_table_len[port];
752 MLX4_PUT(inbox, param->si_guid, INIT_PORT_SI_GUID_OFFSET); 785 MLX4_PUT(inbox, field, INIT_PORT_MAX_PKEY_OFFSET);
753 786
754 err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_INIT_PORT, 787 err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_INIT_PORT,
755 MLX4_CMD_TIME_CLASS_A); 788 MLX4_CMD_TIME_CLASS_A);
756 789
757 mlx4_free_cmd_mailbox(dev, mailbox); 790 mlx4_free_cmd_mailbox(dev, mailbox);
791 } else
792 err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_INIT_PORT,
793 MLX4_CMD_TIME_CLASS_A);
758 794
759 return err; 795 return err;
760} 796}
diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h
index 2616fa53d4d0..296254ac27c1 100644
--- a/drivers/net/mlx4/fw.h
+++ b/drivers/net/mlx4/fw.h
@@ -59,13 +59,13 @@ struct mlx4_dev_cap {
59 int max_responder_per_qp; 59 int max_responder_per_qp;
60 int max_rdma_global; 60 int max_rdma_global;
61 int local_ca_ack_delay; 61 int local_ca_ack_delay;
62 int max_mtu;
63 int max_port_width;
64 int max_vl;
65 int num_ports; 62 int num_ports;
66 int max_gids; 63 int max_mtu[MLX4_MAX_PORTS + 1];
64 int max_port_width[MLX4_MAX_PORTS + 1];
65 int max_vl[MLX4_MAX_PORTS + 1];
66 int max_gids[MLX4_MAX_PORTS + 1];
67 int max_pkeys[MLX4_MAX_PORTS + 1];
67 u16 stat_rate_support; 68 u16 stat_rate_support;
68 int max_pkeys;
69 u32 flags; 69 u32 flags;
70 int reserved_uars; 70 int reserved_uars;
71 int uar_size; 71 int uar_size;
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index d4172937025b..41eafebf5823 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -88,6 +88,7 @@ static struct mlx4_profile default_profile = {
88static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) 88static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
89{ 89{
90 int err; 90 int err;
91 int i;
91 92
92 err = mlx4_QUERY_DEV_CAP(dev, dev_cap); 93 err = mlx4_QUERY_DEV_CAP(dev, dev_cap);
93 if (err) { 94 if (err) {
@@ -117,11 +118,15 @@ static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev
117 } 118 }
118 119
119 dev->caps.num_ports = dev_cap->num_ports; 120 dev->caps.num_ports = dev_cap->num_ports;
121 for (i = 1; i <= dev->caps.num_ports; ++i) {
122 dev->caps.vl_cap[i] = dev_cap->max_vl[i];
123 dev->caps.mtu_cap[i] = dev_cap->max_mtu[i];
124 dev->caps.gid_table_len[i] = dev_cap->max_gids[i];
125 dev->caps.pkey_table_len[i] = dev_cap->max_pkeys[i];
126 dev->caps.port_width_cap[i] = dev_cap->max_port_width[i];
127 }
128
120 dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; 129 dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE;
121 dev->caps.vl_cap = dev_cap->max_vl;
122 dev->caps.mtu_cap = dev_cap->max_mtu;
123 dev->caps.gid_table_len = dev_cap->max_gids;
124 dev->caps.pkey_table_len = dev_cap->max_pkeys;
125 dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay; 130 dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay;
126 dev->caps.bf_reg_size = dev_cap->bf_reg_size; 131 dev->caps.bf_reg_size = dev_cap->bf_reg_size;
127 dev->caps.bf_regs_per_page = dev_cap->bf_regs_per_page; 132 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 dev->caps.reserved_mrws = dev_cap->reserved_mrws; 153 dev->caps.reserved_mrws = dev_cap->reserved_mrws;
149 dev->caps.reserved_uars = dev_cap->reserved_uars; 154 dev->caps.reserved_uars = dev_cap->reserved_uars;
150 dev->caps.reserved_pds = dev_cap->reserved_pds; 155 dev->caps.reserved_pds = dev_cap->reserved_pds;
151 dev->caps.port_width_cap = dev_cap->max_port_width;
152 dev->caps.mtt_entry_sz = MLX4_MTT_ENTRY_PER_SEG * dev_cap->mtt_entry_sz; 156 dev->caps.mtt_entry_sz = MLX4_MTT_ENTRY_PER_SEG * dev_cap->mtt_entry_sz;
153 dev->caps.page_size_cap = ~(u32) (dev_cap->min_page_sz - 1); 157 dev->caps.page_size_cap = ~(u32) (dev_cap->min_page_sz - 1);
154 dev->caps.flags = dev_cap->flags; 158 dev->caps.flags = dev_cap->flags;
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 4fb552d12f7a..7d1eaa97de13 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -54,6 +54,7 @@ enum {
54 MLX4_CMD_INIT_PORT = 0x9, 54 MLX4_CMD_INIT_PORT = 0x9,
55 MLX4_CMD_CLOSE_PORT = 0xa, 55 MLX4_CMD_CLOSE_PORT = 0xa,
56 MLX4_CMD_QUERY_HCA = 0xb, 56 MLX4_CMD_QUERY_HCA = 0xb,
57 MLX4_CMD_QUERY_PORT = 0x43,
57 MLX4_CMD_SET_PORT = 0xc, 58 MLX4_CMD_SET_PORT = 0xc,
58 MLX4_CMD_ACCESS_DDR = 0x2e, 59 MLX4_CMD_ACCESS_DDR = 0x2e,
59 MLX4_CMD_MAP_ICM = 0xffa, 60 MLX4_CMD_MAP_ICM = 0xffa,
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 8c5f8fd86841..b372f5910fc1 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -41,6 +41,7 @@
41 41
42enum { 42enum {
43 MLX4_FLAG_MSI_X = 1 << 0, 43 MLX4_FLAG_MSI_X = 1 << 0,
44 MLX4_FLAG_OLD_PORT_CMDS = 1 << 1,
44}; 45};
45 46
46enum { 47enum {
@@ -131,10 +132,10 @@ enum {
131struct mlx4_caps { 132struct mlx4_caps {
132 u64 fw_ver; 133 u64 fw_ver;
133 int num_ports; 134 int num_ports;
134 int vl_cap; 135 int vl_cap[MLX4_MAX_PORTS + 1];
135 int mtu_cap; 136 int mtu_cap[MLX4_MAX_PORTS + 1];
136 int gid_table_len; 137 int gid_table_len[MLX4_MAX_PORTS + 1];
137 int pkey_table_len; 138 int pkey_table_len[MLX4_MAX_PORTS + 1];
138 int local_ca_ack_delay; 139 int local_ca_ack_delay;
139 int num_uars; 140 int num_uars;
140 int bf_reg_size; 141 int bf_reg_size;
@@ -174,7 +175,7 @@ struct mlx4_caps {
174 u32 page_size_cap; 175 u32 page_size_cap;
175 u32 flags; 176 u32 flags;
176 u16 stat_rate_support; 177 u16 stat_rate_support;
177 u8 port_width_cap; 178 u8 port_width_cap[MLX4_MAX_PORTS + 1];
178}; 179};
179 180
180struct mlx4_buf_list { 181struct mlx4_buf_list {
@@ -322,7 +323,7 @@ int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, struct mlx4_mtt *mtt,
322void mlx4_srq_free(struct mlx4_dev *dev, struct mlx4_srq *srq); 323void mlx4_srq_free(struct mlx4_dev *dev, struct mlx4_srq *srq);
323int mlx4_srq_arm(struct mlx4_dev *dev, struct mlx4_srq *srq, int limit_watermark); 324int mlx4_srq_arm(struct mlx4_dev *dev, struct mlx4_srq *srq, int limit_watermark);
324 325
325int mlx4_INIT_PORT(struct mlx4_dev *dev, struct mlx4_init_port_param *param, int port); 326int mlx4_INIT_PORT(struct mlx4_dev *dev, int port);
326int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); 327int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port);
327 328
328int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); 329int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]);
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index 9eeb61adf6a3..10c57d279144 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -269,6 +269,10 @@ struct mlx4_wqe_data_seg {
269 __be64 addr; 269 __be64 addr;
270}; 270};
271 271
272enum {
273 MLX4_INLINE_ALIGN = 64,
274};
275
272struct mlx4_wqe_inline_seg { 276struct mlx4_wqe_inline_seg {
273 __be32 byte_count; 277 __be32 byte_count;
274}; 278};