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 | ||
