diff options
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_cq.c')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cq.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index 4a8adcef2079..96f1a86bf049 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c | |||
@@ -128,12 +128,12 @@ struct mthca_err_cqe { | |||
128 | __be32 my_qpn; | 128 | __be32 my_qpn; |
129 | u32 reserved1[3]; | 129 | u32 reserved1[3]; |
130 | u8 syndrome; | 130 | u8 syndrome; |
131 | u8 reserved2; | 131 | u8 vendor_err; |
132 | __be16 db_cnt; | 132 | __be16 db_cnt; |
133 | u32 reserved3; | 133 | u32 reserved2; |
134 | __be32 wqe; | 134 | __be32 wqe; |
135 | u8 opcode; | 135 | u8 opcode; |
136 | u8 reserved4[2]; | 136 | u8 reserved3[2]; |
137 | u8 owner; | 137 | u8 owner; |
138 | }; | 138 | }; |
139 | 139 | ||
@@ -253,6 +253,15 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn, | |||
253 | wake_up(&cq->wait); | 253 | wake_up(&cq->wait); |
254 | } | 254 | } |
255 | 255 | ||
256 | static inline int is_recv_cqe(struct mthca_cqe *cqe) | ||
257 | { | ||
258 | if ((cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) == | ||
259 | MTHCA_ERROR_CQE_OPCODE_MASK) | ||
260 | return !(cqe->opcode & 0x01); | ||
261 | else | ||
262 | return !(cqe->is_send & 0x80); | ||
263 | } | ||
264 | |||
256 | void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, | 265 | void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, |
257 | struct mthca_srq *srq) | 266 | struct mthca_srq *srq) |
258 | { | 267 | { |
@@ -296,7 +305,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, | |||
296 | while ((int) --prod_index - (int) cq->cons_index >= 0) { | 305 | while ((int) --prod_index - (int) cq->cons_index >= 0) { |
297 | cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); | 306 | cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); |
298 | if (cqe->my_qpn == cpu_to_be32(qpn)) { | 307 | if (cqe->my_qpn == cpu_to_be32(qpn)) { |
299 | if (srq) | 308 | if (srq && is_recv_cqe(cqe)) |
300 | mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); | 309 | mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); |
301 | ++nfreed; | 310 | ++nfreed; |
302 | } else if (nfreed) | 311 | } else if (nfreed) |
@@ -333,8 +342,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, | |||
333 | } | 342 | } |
334 | 343 | ||
335 | /* | 344 | /* |
336 | * For completions in error, only work request ID, status (and | 345 | * For completions in error, only work request ID, status, vendor error |
337 | * freed resource count for RD) have to be set. | 346 | * (and freed resource count for RD) have to be set. |
338 | */ | 347 | */ |
339 | switch (cqe->syndrome) { | 348 | switch (cqe->syndrome) { |
340 | case SYNDROME_LOCAL_LENGTH_ERR: | 349 | case SYNDROME_LOCAL_LENGTH_ERR: |
@@ -396,6 +405,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, | |||
396 | break; | 405 | break; |
397 | } | 406 | } |
398 | 407 | ||
408 | entry->vendor_err = cqe->vendor_err; | ||
409 | |||
399 | /* | 410 | /* |
400 | * Mem-free HCAs always generate one CQE per WQE, even in the | 411 | * Mem-free HCAs always generate one CQE per WQE, even in the |
401 | * error case, so we don't have to check the doorbell count, etc. | 412 | * error case, so we don't have to check the doorbell count, etc. |