1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2009-2013 Chelsio, Inc. All rights reserved. 5 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * OpenIB.org BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 */ 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include "opt_inet.h" 38 39 #ifdef TCP_OFFLOAD 40 #include <linux/slab.h> 41 42 #include "iw_cxgbe.h" 43 44 static void print_tpte(struct adapter *sc, const u32 stag, 45 const struct fw_ri_tpte *tpte) 46 { 47 const __be64 *p = (const void *)tpte; 48 49 CH_ERR(sc, "stag idx 0x%x valid %d key 0x%x state %d pdid %d " 50 "perm 0x%x ps %d len 0x%016llx va 0x%016llx\n", 51 stag & 0xffffff00, 52 G_FW_RI_TPTE_VALID(ntohl(tpte->valid_to_pdid)), 53 G_FW_RI_TPTE_STAGKEY(ntohl(tpte->valid_to_pdid)), 54 G_FW_RI_TPTE_STAGSTATE(ntohl(tpte->valid_to_pdid)), 55 G_FW_RI_TPTE_PDID(ntohl(tpte->valid_to_pdid)), 56 G_FW_RI_TPTE_PERM(ntohl(tpte->locread_to_qpid)), 57 G_FW_RI_TPTE_PS(ntohl(tpte->locread_to_qpid)), 58 (long long)(((u64)ntohl(tpte->len_hi) << 32) | ntohl(tpte->len_lo)), 59 (long long)(((u64)ntohl(tpte->va_hi) << 32) | ntohl(tpte->va_lo_fbo))); 60 CH_ERR(sc, "stag idx 0x%x: %016llx %016llx %016llx %016llx\n", 61 stag & 0xffffff00, 62 (long long)be64_to_cpu(p[0]), (long long)be64_to_cpu(p[1]), 63 (long long)be64_to_cpu(p[2]), (long long)be64_to_cpu(p[3])); 64 } 65 66 void t4_dump_stag(struct adapter *sc, const u32 stag) 67 { 68 struct fw_ri_tpte tpte __aligned(sizeof(__be64)) = {0}; 69 const u32 offset = sc->vres.stag.start + ((stag >> 8) * 32); 70 71 if (offset > sc->vres.stag.start + sc->vres.stag.size - 32) { 72 CH_ERR(sc, "stag 0x%x is invalid for current configuration.\n", 73 stag); 74 return; 75 } 76 read_via_memwin(sc, 0, offset, (u32 *)&tpte, 32); 77 print_tpte(sc, stag, &tpte); 78 } 79 80 void t4_dump_all_stag(struct adapter *sc) 81 { 82 struct fw_ri_tpte tpte __aligned(sizeof(__be64)) = {0}; 83 const u32 first = sc->vres.stag.start; 84 const u32 last = first + sc->vres.stag.size - 32; 85 u32 offset, i; 86 87 for (i = 0, offset = first; offset <= last; i++, offset += 32) { 88 tpte.valid_to_pdid = 0; 89 read_via_memwin(sc, 0, offset, (u32 *)&tpte, 4); 90 if (tpte.valid_to_pdid != 0) { 91 read_via_memwin(sc, 0, offset, (u32 *)&tpte, 32); 92 print_tpte(sc, i << 8, &tpte); 93 } 94 } 95 } 96 97 static void dump_err_cqe(struct c4iw_dev *dev, struct t4_cqe *err_cqe) 98 { 99 struct adapter *sc = dev->rdev.adap; 100 __be64 *p = (void *)err_cqe; 101 102 CH_ERR(sc, "AE qpid 0x%x opcode %d status 0x%x " 103 "type %d wrid.hi 0x%x wrid.lo 0x%x\n", 104 CQE_QPID(err_cqe), CQE_OPCODE(err_cqe), 105 CQE_STATUS(err_cqe), CQE_TYPE(err_cqe), 106 CQE_WRID_HI(err_cqe), CQE_WRID_LOW(err_cqe)); 107 CH_ERR(sc, "%016llx %016llx %016llx %016llx\n", 108 (long long)be64_to_cpu(p[0]), (long long)be64_to_cpu(p[1]), 109 (long long)be64_to_cpu(p[2]), (long long)be64_to_cpu(p[3])); 110 111 /* 112 * Ingress WRITE and READ_RESP errors provide 113 * the offending stag, so parse and log it. 114 */ 115 if (RQ_TYPE(err_cqe) && (CQE_OPCODE(err_cqe) == FW_RI_RDMA_WRITE || 116 CQE_OPCODE(err_cqe) == FW_RI_READ_RESP)) 117 t4_dump_stag(sc, CQE_WRID_STAG(err_cqe)); 118 } 119 120 static void post_qp_event(struct c4iw_dev *dev, struct c4iw_cq *chp, 121 struct c4iw_qp *qhp, 122 struct t4_cqe *err_cqe, 123 enum ib_event_type ib_event) 124 { 125 struct ib_event event; 126 struct c4iw_qp_attributes attrs; 127 unsigned long flag; 128 129 if ((qhp->attr.state == C4IW_QP_STATE_ERROR) || 130 (qhp->attr.state == C4IW_QP_STATE_TERMINATE)) { 131 CTR4(KTR_IW_CXGBE, "%s AE received after RTS - " 132 "qp state %d qpid 0x%x status 0x%x", __func__, 133 qhp->attr.state, qhp->wq.sq.qid, CQE_STATUS(err_cqe)); 134 return; 135 } 136 137 dump_err_cqe(dev, err_cqe); 138 139 if (qhp->attr.state == C4IW_QP_STATE_RTS) { 140 attrs.next_state = C4IW_QP_STATE_TERMINATE; 141 c4iw_modify_qp(qhp->rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, 142 &attrs, 0); 143 } 144 145 event.event = ib_event; 146 event.device = chp->ibcq.device; 147 if (ib_event == IB_EVENT_CQ_ERR) 148 event.element.cq = &chp->ibcq; 149 else 150 event.element.qp = &qhp->ibqp; 151 if (qhp->ibqp.event_handler) 152 (*qhp->ibqp.event_handler)(&event, qhp->ibqp.qp_context); 153 154 spin_lock_irqsave(&chp->comp_handler_lock, flag); 155 (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context); 156 spin_unlock_irqrestore(&chp->comp_handler_lock, flag); 157 } 158 159 void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe) 160 { 161 struct c4iw_cq *chp; 162 struct c4iw_qp *qhp; 163 u32 cqid; 164 165 spin_lock_irq(&dev->lock); 166 qhp = get_qhp(dev, CQE_QPID(err_cqe)); 167 if (!qhp) { 168 printf("BAD AE qpid 0x%x opcode %d " 169 "status 0x%x type %d wrid.hi 0x%x wrid.lo 0x%x\n", 170 CQE_QPID(err_cqe), 171 CQE_OPCODE(err_cqe), CQE_STATUS(err_cqe), 172 CQE_TYPE(err_cqe), CQE_WRID_HI(err_cqe), 173 CQE_WRID_LOW(err_cqe)); 174 spin_unlock_irq(&dev->lock); 175 goto out; 176 } 177 178 if (SQ_TYPE(err_cqe)) 179 cqid = qhp->attr.scq; 180 else 181 cqid = qhp->attr.rcq; 182 chp = get_chp(dev, cqid); 183 if (!chp) { 184 printf("BAD AE cqid 0x%x qpid 0x%x opcode %d " 185 "status 0x%x type %d wrid.hi 0x%x wrid.lo 0x%x\n", 186 cqid, CQE_QPID(err_cqe), 187 CQE_OPCODE(err_cqe), CQE_STATUS(err_cqe), 188 CQE_TYPE(err_cqe), CQE_WRID_HI(err_cqe), 189 CQE_WRID_LOW(err_cqe)); 190 spin_unlock_irq(&dev->lock); 191 goto out; 192 } 193 194 c4iw_qp_add_ref(&qhp->ibqp); 195 atomic_inc(&chp->refcnt); 196 spin_unlock_irq(&dev->lock); 197 198 /* Bad incoming write */ 199 if (RQ_TYPE(err_cqe) && 200 (CQE_OPCODE(err_cqe) == FW_RI_RDMA_WRITE)) { 201 post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_QP_REQ_ERR); 202 goto done; 203 } 204 205 switch (CQE_STATUS(err_cqe)) { 206 207 /* Completion Events */ 208 case T4_ERR_SUCCESS: 209 printf(KERN_ERR MOD "AE with status 0!\n"); 210 break; 211 212 case T4_ERR_STAG: 213 case T4_ERR_PDID: 214 case T4_ERR_QPID: 215 case T4_ERR_ACCESS: 216 case T4_ERR_WRAP: 217 case T4_ERR_BOUND: 218 case T4_ERR_INVALIDATE_SHARED_MR: 219 case T4_ERR_INVALIDATE_MR_WITH_MW_BOUND: 220 post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_QP_ACCESS_ERR); 221 break; 222 223 /* Device Fatal Errors */ 224 case T4_ERR_ECC: 225 case T4_ERR_ECC_PSTAG: 226 case T4_ERR_INTERNAL_ERR: 227 post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_DEVICE_FATAL); 228 break; 229 230 /* QP Fatal Errors */ 231 case T4_ERR_OUT_OF_RQE: 232 case T4_ERR_PBL_ADDR_BOUND: 233 case T4_ERR_CRC: 234 case T4_ERR_MARKER: 235 case T4_ERR_PDU_LEN_ERR: 236 case T4_ERR_DDP_VERSION: 237 case T4_ERR_RDMA_VERSION: 238 case T4_ERR_OPCODE: 239 case T4_ERR_DDP_QUEUE_NUM: 240 case T4_ERR_MSN: 241 case T4_ERR_TBIT: 242 case T4_ERR_MO: 243 case T4_ERR_MSN_GAP: 244 case T4_ERR_MSN_RANGE: 245 case T4_ERR_RQE_ADDR_BOUND: 246 case T4_ERR_IRD_OVERFLOW: 247 post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_QP_FATAL); 248 break; 249 250 default: 251 printf("Unknown T4 status 0x%x QPID 0x%x\n", 252 CQE_STATUS(err_cqe), qhp->wq.sq.qid); 253 post_qp_event(dev, chp, qhp, err_cqe, IB_EVENT_QP_FATAL); 254 break; 255 } 256 done: 257 if (atomic_dec_and_test(&chp->refcnt)) 258 wake_up(&chp->wait); 259 c4iw_qp_rem_ref(&qhp->ibqp); 260 out: 261 return; 262 } 263 264 int c4iw_ev_handler(struct sge_iq *iq, const struct rsp_ctrl *rc) 265 { 266 struct c4iw_dev *dev = iq->adapter->iwarp_softc; 267 u32 qid = be32_to_cpu(rc->pldbuflen_qid); 268 struct c4iw_cq *chp; 269 unsigned long flag; 270 271 spin_lock_irqsave(&dev->lock, flag); 272 chp = get_chp(dev, qid); 273 if (chp) { 274 atomic_inc(&chp->refcnt); 275 spin_unlock_irqrestore(&dev->lock, flag); 276 277 spin_lock_irqsave(&chp->comp_handler_lock, flag); 278 (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context); 279 spin_unlock_irqrestore(&chp->comp_handler_lock, flag); 280 if (atomic_dec_and_test(&chp->refcnt)) 281 wake_up(&chp->wait); 282 } else { 283 CTR2(KTR_IW_CXGBE, "%s unknown cqid 0x%x", __func__, qid); 284 spin_unlock_irqrestore(&dev->lock, flag); 285 } 286 287 return 0; 288 } 289 #endif 290