diff options
-rw-r--r-- | drivers/infiniband/hw/cxgb4/cq.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb4/t4.h | 28 |
2 files changed, 17 insertions, 12 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index 46ac00f728f3..2447f5295482 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c | |||
@@ -373,6 +373,7 @@ static void create_read_req_cqe(struct t4_wq *wq, struct t4_cqe *hw_cqe, | |||
373 | V_CQE_SWCQE(SW_CQE(hw_cqe)) | | 373 | V_CQE_SWCQE(SW_CQE(hw_cqe)) | |
374 | V_CQE_OPCODE(FW_RI_READ_REQ) | | 374 | V_CQE_OPCODE(FW_RI_READ_REQ) | |
375 | V_CQE_TYPE(1)); | 375 | V_CQE_TYPE(1)); |
376 | read_cqe->bits_type_ts = hw_cqe->bits_type_ts; | ||
376 | } | 377 | } |
377 | 378 | ||
378 | /* | 379 | /* |
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index d0e8af352408..712bc5620d3e 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h | |||
@@ -434,7 +434,7 @@ struct t4_cq { | |||
434 | struct c4iw_rdev *rdev; | 434 | struct c4iw_rdev *rdev; |
435 | u64 ugts; | 435 | u64 ugts; |
436 | size_t memsize; | 436 | size_t memsize; |
437 | u64 timestamp; | 437 | __be64 bits_type_ts; |
438 | u32 cqid; | 438 | u32 cqid; |
439 | u16 size; /* including status page */ | 439 | u16 size; /* including status page */ |
440 | u16 cidx; | 440 | u16 cidx; |
@@ -487,6 +487,7 @@ static inline void t4_swcq_consume(struct t4_cq *cq) | |||
487 | 487 | ||
488 | static inline void t4_hwcq_consume(struct t4_cq *cq) | 488 | static inline void t4_hwcq_consume(struct t4_cq *cq) |
489 | { | 489 | { |
490 | cq->bits_type_ts = cq->queue[cq->cidx].bits_type_ts; | ||
490 | cq->cidx_inc++; | 491 | cq->cidx_inc++; |
491 | if (++cq->cidx == cq->size) { | 492 | if (++cq->cidx == cq->size) { |
492 | cq->cidx = 0; | 493 | cq->cidx = 0; |
@@ -501,20 +502,23 @@ static inline int t4_valid_cqe(struct t4_cq *cq, struct t4_cqe *cqe) | |||
501 | 502 | ||
502 | static inline int t4_next_hw_cqe(struct t4_cq *cq, struct t4_cqe **cqe) | 503 | static inline int t4_next_hw_cqe(struct t4_cq *cq, struct t4_cqe **cqe) |
503 | { | 504 | { |
504 | int ret = 0; | 505 | int ret; |
505 | u64 bits_type_ts = be64_to_cpu(cq->queue[cq->cidx].bits_type_ts); | 506 | u16 prev_cidx; |
506 | 507 | ||
507 | if (G_CQE_GENBIT(bits_type_ts) == cq->gen) { | 508 | if (cq->cidx == 0) |
508 | *cqe = &cq->queue[cq->cidx]; | 509 | prev_cidx = cq->size - 1; |
509 | cq->timestamp = G_CQE_TS(bits_type_ts); | ||
510 | } else if (G_CQE_TS(bits_type_ts) > cq->timestamp) | ||
511 | ret = -EOVERFLOW; | ||
512 | else | 510 | else |
513 | ret = -ENODATA; | 511 | prev_cidx = cq->cidx - 1; |
514 | if (ret == -EOVERFLOW) { | 512 | |
515 | printk(KERN_ERR MOD "cq overflow cqid %u\n", cq->cqid); | 513 | if (cq->queue[prev_cidx].bits_type_ts != cq->bits_type_ts) { |
514 | ret = -EOVERFLOW; | ||
516 | cq->error = 1; | 515 | cq->error = 1; |
517 | } | 516 | printk(KERN_ERR MOD "cq overflow cqid %u\n", cq->cqid); |
517 | } else if (t4_valid_cqe(cq, &cq->queue[cq->cidx])) { | ||
518 | *cqe = &cq->queue[cq->cidx]; | ||
519 | ret = 0; | ||
520 | } else | ||
521 | ret = -ENODATA; | ||
518 | return ret; | 522 | return ret; |
519 | } | 523 | } |
520 | 524 | ||