diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-20 18:39:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-20 18:39:24 -0400 |
commit | b3f4256fe0682143883ce6903e4646a03943f792 (patch) | |
tree | 3f090af16d721dd3d088a96a6defb0637ae74f76 | |
parent | 044f620ac65d0d90727cdbd0c058e4d150d62ddc (diff) | |
parent | e61ef2416b0b92828512b6cfcd0104a02b6431fe (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.c | 19 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 16 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mlx4_ib.h | 5 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 196 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/user.h | 9 | ||||
-rw-r--r-- | drivers/net/mlx4/fw.c | 110 | ||||
-rw-r--r-- | drivers/net/mlx4/fw.h | 10 | ||||
-rw-r--r-- | drivers/net/mlx4/main.c | 14 | ||||
-rw-r--r-- | include/linux/mlx4/cmd.h | 1 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 13 | ||||
-rw-r--r-- | include/linux/mlx4/qp.h | 4 |
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 { | |||
95 | struct mlx4_ib_wq { | 95 | struct 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 | */ | ||
117 | static 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 | |||
112 | static void mlx4_ib_qp_event(struct mlx4_qp *qp, enum mlx4_event type) | 126 | static 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, | |||
267 | static int set_user_sq_size(struct mlx4_ib_qp *qp, | 288 | static 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 | ||
586 | static void init_port(struct mlx4_ib_dev *dev, int port) | ||
587 | { | ||
588 | struct mlx4_init_port_param param; | ||
589 | int err; | ||
590 | |||
591 | memset(¶m, 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, ¶m, port); | ||
600 | if (err) | ||
601 | printk(KERN_WARNING "INIT_PORT failed, return code %d.\n", err); | ||
602 | } | ||
603 | |||
604 | static int to_mlx4_st(enum ib_qp_type type) | 608 | static 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 | ||
1121 | static int mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq) | 1169 | static 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 | ||
1138 | int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | 1186 | int 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 | ||
1381 | out: | 1441 | out: |
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 { | |||
87 | struct mlx4_ib_create_qp { | 87 | struct 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 | ||
40 | enum { | 40 | enum { |
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 | ||
44 | extern void __buggy_use_of_MLX4_GET(void); | 46 | 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 | 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 | ||
711 | int mlx4_INIT_PORT(struct mlx4_dev *dev, struct mlx4_init_port_param *param, int port) | 745 | int 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 = { | |||
88 | static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | 88 | static 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 | ||
42 | enum { | 42 | enum { |
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 | ||
46 | enum { | 47 | enum { |
@@ -131,10 +132,10 @@ enum { | |||
131 | struct mlx4_caps { | 132 | struct 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 | ||
180 | struct mlx4_buf_list { | 181 | struct mlx4_buf_list { |
@@ -322,7 +323,7 @@ int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, struct mlx4_mtt *mtt, | |||
322 | void mlx4_srq_free(struct mlx4_dev *dev, struct mlx4_srq *srq); | 323 | void mlx4_srq_free(struct mlx4_dev *dev, struct mlx4_srq *srq); |
323 | int mlx4_srq_arm(struct mlx4_dev *dev, struct mlx4_srq *srq, int limit_watermark); | 324 | int mlx4_srq_arm(struct mlx4_dev *dev, struct mlx4_srq *srq, int limit_watermark); |
324 | 325 | ||
325 | int mlx4_INIT_PORT(struct mlx4_dev *dev, struct mlx4_init_port_param *param, int port); | 326 | int mlx4_INIT_PORT(struct mlx4_dev *dev, int port); |
326 | int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); | 327 | int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); |
327 | 328 | ||
328 | int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); | 329 | int 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 | ||
272 | enum { | ||
273 | MLX4_INLINE_ALIGN = 64, | ||
274 | }; | ||
275 | |||
272 | struct mlx4_wqe_inline_seg { | 276 | struct mlx4_wqe_inline_seg { |
273 | __be32 byte_count; | 277 | __be32 byte_count; |
274 | }; | 278 | }; |