1 /* 2 * Broadcom NetXtreme-E RoCE driver. 3 * 4 * Copyright (c) 2016 - 2017, Broadcom. All rights reserved. The term 5 * Broadcom refers to Broadcom Limited and/or its subsidiaries. 6 * 7 * This software is available to you under a choice of one of two 8 * licenses. You may choose to be licensed under the terms of the GNU 9 * General Public License (GPL) Version 2, available from the file 10 * COPYING in the main directory of this source tree, or the 11 * BSD license below: 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in 21 * the documentation and/or other materials provided with the 22 * distribution. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 26 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 31 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 33 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 34 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 * 36 * Description: RDMA Controller HW interface 37 */ 38 #include <linux/interrupt.h> 39 #include <linux/spinlock.h> 40 #include <linux/pci.h> 41 #include <linux/prefetch.h> 42 #include <linux/delay.h> 43 44 #include "roce_hsi.h" 45 #include "qplib_res.h" 46 #include "qplib_rcfw.h" 47 #include "qplib_sp.h" 48 #include "qplib_fp.h" 49 50 static void bnxt_qplib_service_creq(unsigned long data); 51 52 /* Hardware communication channel */ 53 static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie) 54 { 55 u16 cbit; 56 int rc; 57 58 cbit = cookie % RCFW_MAX_OUTSTANDING_CMD; 59 rc = wait_event_timeout(rcfw->waitq, 60 !test_bit(cbit, rcfw->cmdq_bitmap), 61 msecs_to_jiffies(RCFW_CMD_WAIT_TIME_MS)); 62 return rc ? 0 : -ETIMEDOUT; 63 }; 64 65 static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie) 66 { 67 u32 count = RCFW_BLOCKED_CMD_WAIT_COUNT; 68 u16 cbit; 69 70 cbit = cookie % RCFW_MAX_OUTSTANDING_CMD; 71 if (!test_bit(cbit, rcfw->cmdq_bitmap)) 72 goto done; 73 do { 74 mdelay(1); /* 1m sec */ 75 bnxt_qplib_service_creq((unsigned long)rcfw); 76 } while (test_bit(cbit, rcfw->cmdq_bitmap) && --count); 77 done: 78 return count ? 0 : -ETIMEDOUT; 79 }; 80 81 static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req, 82 struct creq_base *resp, void *sb, u8 is_block) 83 { 84 struct bnxt_qplib_cmdqe *cmdqe, **cmdq_ptr; 85 struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq; 86 struct bnxt_qplib_crsq *crsqe; 87 u32 sw_prod, cmdq_prod; 88 unsigned long flags; 89 u32 size, opcode; 90 u16 cookie, cbit; 91 int pg, idx; 92 u8 *preq; 93 94 opcode = req->opcode; 95 if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags) && 96 (opcode != CMDQ_BASE_OPCODE_QUERY_FUNC && 97 opcode != CMDQ_BASE_OPCODE_INITIALIZE_FW)) { 98 dev_err(&rcfw->pdev->dev, 99 "QPLIB: RCFW not initialized, reject opcode 0x%x", 100 opcode); 101 return -EINVAL; 102 } 103 104 if (test_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags) && 105 opcode == CMDQ_BASE_OPCODE_INITIALIZE_FW) { 106 dev_err(&rcfw->pdev->dev, "QPLIB: RCFW already initialized!"); 107 return -EINVAL; 108 } 109 110 if (test_bit(FIRMWARE_TIMED_OUT, &rcfw->flags)) 111 return -ETIMEDOUT; 112 113 /* Cmdq are in 16-byte units, each request can consume 1 or more 114 * cmdqe 115 */ 116 spin_lock_irqsave(&cmdq->lock, flags); 117 if (req->cmd_size >= HWQ_FREE_SLOTS(cmdq)) { 118 dev_err(&rcfw->pdev->dev, "QPLIB: RCFW: CMDQ is full!"); 119 spin_unlock_irqrestore(&cmdq->lock, flags); 120 return -EAGAIN; 121 } 122 123 124 cookie = rcfw->seq_num & RCFW_MAX_COOKIE_VALUE; 125 cbit = cookie % RCFW_MAX_OUTSTANDING_CMD; 126 if (is_block) 127 cookie |= RCFW_CMD_IS_BLOCKING; 128 129 set_bit(cbit, rcfw->cmdq_bitmap); 130 req->cookie = cpu_to_le16(cookie); 131 crsqe = &rcfw->crsqe_tbl[cbit]; 132 if (crsqe->resp) { 133 spin_unlock_irqrestore(&cmdq->lock, flags); 134 return -EBUSY; 135 } 136 memset(resp, 0, sizeof(*resp)); 137 crsqe->resp = (struct creq_qp_event *)resp; 138 crsqe->resp->cookie = req->cookie; 139 crsqe->req_size = req->cmd_size; 140 if (req->resp_size && sb) { 141 struct bnxt_qplib_rcfw_sbuf *sbuf = sb; 142 143 req->resp_addr = cpu_to_le64(sbuf->dma_addr); 144 req->resp_size = (sbuf->size + BNXT_QPLIB_CMDQE_UNITS - 1) / 145 BNXT_QPLIB_CMDQE_UNITS; 146 } 147 148 cmdq_ptr = (struct bnxt_qplib_cmdqe **)cmdq->pbl_ptr; 149 preq = (u8 *)req; 150 size = req->cmd_size * BNXT_QPLIB_CMDQE_UNITS; 151 do { 152 pg = 0; 153 idx = 0; 154 155 /* Locate the next cmdq slot */ 156 sw_prod = HWQ_CMP(cmdq->prod, cmdq); 157 cmdqe = &cmdq_ptr[get_cmdq_pg(sw_prod)][get_cmdq_idx(sw_prod)]; 158 if (!cmdqe) { 159 dev_err(&rcfw->pdev->dev, 160 "QPLIB: RCFW request failed with no cmdqe!"); 161 goto done; 162 } 163 /* Copy a segment of the req cmd to the cmdq */ 164 memset(cmdqe, 0, sizeof(*cmdqe)); 165 memcpy(cmdqe, preq, min_t(u32, size, sizeof(*cmdqe))); 166 preq += min_t(u32, size, sizeof(*cmdqe)); 167 size -= min_t(u32, size, sizeof(*cmdqe)); 168 cmdq->prod++; 169 rcfw->seq_num++; 170 } while (size > 0); 171 172 rcfw->seq_num++; 173 174 cmdq_prod = cmdq->prod; 175 if (rcfw->flags & FIRMWARE_FIRST_FLAG) { 176 /* The very first doorbell write 177 * is required to set this flag 178 * which prompts the FW to reset 179 * its internal pointers 180 */ 181 cmdq_prod |= FIRMWARE_FIRST_FLAG; 182 rcfw->flags &= ~FIRMWARE_FIRST_FLAG; 183 } 184 185 /* ring CMDQ DB */ 186 wmb(); 187 writel(cmdq_prod, rcfw->cmdq_bar_reg_iomem + 188 rcfw->cmdq_bar_reg_prod_off); 189 writel(RCFW_CMDQ_TRIG_VAL, rcfw->cmdq_bar_reg_iomem + 190 rcfw->cmdq_bar_reg_trig_off); 191 done: 192 spin_unlock_irqrestore(&cmdq->lock, flags); 193 /* Return the CREQ response pointer */ 194 return 0; 195 } 196 197 int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, 198 struct cmdq_base *req, 199 struct creq_base *resp, 200 void *sb, u8 is_block) 201 { 202 struct creq_qp_event *evnt = (struct creq_qp_event *)resp; 203 u16 cookie; 204 u8 opcode, retry_cnt = 0xFF; 205 int rc = 0; 206 207 do { 208 opcode = req->opcode; 209 rc = __send_message(rcfw, req, resp, sb, is_block); 210 cookie = le16_to_cpu(req->cookie) & RCFW_MAX_COOKIE_VALUE; 211 if (!rc) 212 break; 213 214 if (!retry_cnt || (rc != -EAGAIN && rc != -EBUSY)) { 215 /* send failed */ 216 dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x send failed", 217 cookie, opcode); 218 return rc; 219 } 220 is_block ? mdelay(1) : usleep_range(500, 1000); 221 222 } while (retry_cnt--); 223 224 if (is_block) 225 rc = __block_for_resp(rcfw, cookie); 226 else 227 rc = __wait_for_resp(rcfw, cookie); 228 if (rc) { 229 /* timed out */ 230 dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x timedout (%d)msec", 231 cookie, opcode, RCFW_CMD_WAIT_TIME_MS); 232 set_bit(FIRMWARE_TIMED_OUT, &rcfw->flags); 233 return rc; 234 } 235 236 if (evnt->status) { 237 /* failed with status */ 238 dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x status %#x", 239 cookie, opcode, evnt->status); 240 rc = -EFAULT; 241 } 242 243 return rc; 244 } 245 /* Completions */ 246 static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw, 247 struct creq_func_event *func_event) 248 { 249 switch (func_event->event) { 250 case CREQ_FUNC_EVENT_EVENT_TX_WQE_ERROR: 251 break; 252 case CREQ_FUNC_EVENT_EVENT_TX_DATA_ERROR: 253 break; 254 case CREQ_FUNC_EVENT_EVENT_RX_WQE_ERROR: 255 break; 256 case CREQ_FUNC_EVENT_EVENT_RX_DATA_ERROR: 257 break; 258 case CREQ_FUNC_EVENT_EVENT_CQ_ERROR: 259 break; 260 case CREQ_FUNC_EVENT_EVENT_TQM_ERROR: 261 break; 262 case CREQ_FUNC_EVENT_EVENT_CFCQ_ERROR: 263 break; 264 case CREQ_FUNC_EVENT_EVENT_CFCS_ERROR: 265 /* SRQ ctx error, call srq_handler?? 266 * But there's no SRQ handle! 267 */ 268 break; 269 case CREQ_FUNC_EVENT_EVENT_CFCC_ERROR: 270 break; 271 case CREQ_FUNC_EVENT_EVENT_CFCM_ERROR: 272 break; 273 case CREQ_FUNC_EVENT_EVENT_TIM_ERROR: 274 break; 275 case CREQ_FUNC_EVENT_EVENT_VF_COMM_REQUEST: 276 break; 277 case CREQ_FUNC_EVENT_EVENT_RESOURCE_EXHAUSTED: 278 break; 279 default: 280 return -EINVAL; 281 } 282 return 0; 283 } 284 285 static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, 286 struct creq_qp_event *qp_event) 287 { 288 struct bnxt_qplib_hwq *cmdq = &rcfw->cmdq; 289 struct creq_qp_error_notification *err_event; 290 struct bnxt_qplib_crsq *crsqe; 291 unsigned long flags; 292 struct bnxt_qplib_qp *qp; 293 u16 cbit, blocked = 0; 294 u16 cookie; 295 __le16 mcookie; 296 u32 qp_id; 297 298 switch (qp_event->event) { 299 case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION: 300 err_event = (struct creq_qp_error_notification *)qp_event; 301 qp_id = le32_to_cpu(err_event->xid); 302 qp = rcfw->qp_tbl[qp_id].qp_handle; 303 dev_dbg(&rcfw->pdev->dev, 304 "QPLIB: Received QP error notification"); 305 dev_dbg(&rcfw->pdev->dev, 306 "QPLIB: qpid 0x%x, req_err=0x%x, resp_err=0x%x\n", 307 qp_id, err_event->req_err_state_reason, 308 err_event->res_err_state_reason); 309 bnxt_qplib_acquire_cq_locks(qp, &flags); 310 bnxt_qplib_mark_qp_error(qp); 311 bnxt_qplib_release_cq_locks(qp, &flags); 312 break; 313 default: 314 /* Command Response */ 315 spin_lock_irqsave(&cmdq->lock, flags); 316 cookie = le16_to_cpu(qp_event->cookie); 317 mcookie = qp_event->cookie; 318 blocked = cookie & RCFW_CMD_IS_BLOCKING; 319 cookie &= RCFW_MAX_COOKIE_VALUE; 320 cbit = cookie % RCFW_MAX_OUTSTANDING_CMD; 321 crsqe = &rcfw->crsqe_tbl[cbit]; 322 if (crsqe->resp && 323 crsqe->resp->cookie == mcookie) { 324 memcpy(crsqe->resp, qp_event, sizeof(*qp_event)); 325 crsqe->resp = NULL; 326 } else { 327 dev_err(&rcfw->pdev->dev, 328 "QPLIB: CMD %s resp->cookie = %#x, evnt->cookie = %#x", 329 crsqe->resp ? "mismatch" : "collision", 330 crsqe->resp ? crsqe->resp->cookie : 0, mcookie); 331 } 332 if (!test_and_clear_bit(cbit, rcfw->cmdq_bitmap)) 333 dev_warn(&rcfw->pdev->dev, 334 "QPLIB: CMD bit %d was not requested", cbit); 335 cmdq->cons += crsqe->req_size; 336 crsqe->req_size = 0; 337 338 if (!blocked) 339 wake_up(&rcfw->waitq); 340 spin_unlock_irqrestore(&cmdq->lock, flags); 341 } 342 return 0; 343 } 344 345 /* SP - CREQ Completion handlers */ 346 static void bnxt_qplib_service_creq(unsigned long data) 347 { 348 struct bnxt_qplib_rcfw *rcfw = (struct bnxt_qplib_rcfw *)data; 349 struct bnxt_qplib_hwq *creq = &rcfw->creq; 350 struct creq_base *creqe, **creq_ptr; 351 u32 sw_cons, raw_cons; 352 unsigned long flags; 353 u32 type, budget = CREQ_ENTRY_POLL_BUDGET; 354 355 /* Service the CREQ until budget is over */ 356 spin_lock_irqsave(&creq->lock, flags); 357 raw_cons = creq->cons; 358 while (budget > 0) { 359 sw_cons = HWQ_CMP(raw_cons, creq); 360 creq_ptr = (struct creq_base **)creq->pbl_ptr; 361 creqe = &creq_ptr[get_creq_pg(sw_cons)][get_creq_idx(sw_cons)]; 362 if (!CREQ_CMP_VALID(creqe, raw_cons, creq->max_elements)) 363 break; 364 365 type = creqe->type & CREQ_BASE_TYPE_MASK; 366 switch (type) { 367 case CREQ_BASE_TYPE_QP_EVENT: 368 bnxt_qplib_process_qp_event 369 (rcfw, (struct creq_qp_event *)creqe); 370 rcfw->creq_qp_event_processed++; 371 break; 372 case CREQ_BASE_TYPE_FUNC_EVENT: 373 if (!bnxt_qplib_process_func_event 374 (rcfw, (struct creq_func_event *)creqe)) 375 rcfw->creq_func_event_processed++; 376 else 377 dev_warn 378 (&rcfw->pdev->dev, "QPLIB:aeqe:%#x Not handled", 379 type); 380 break; 381 default: 382 dev_warn(&rcfw->pdev->dev, "QPLIB: creqe with "); 383 dev_warn(&rcfw->pdev->dev, 384 "QPLIB: op_event = 0x%x not handled", type); 385 break; 386 } 387 raw_cons++; 388 budget--; 389 } 390 391 if (creq->cons != raw_cons) { 392 creq->cons = raw_cons; 393 CREQ_DB_REARM(rcfw->creq_bar_reg_iomem, raw_cons, 394 creq->max_elements); 395 } 396 spin_unlock_irqrestore(&creq->lock, flags); 397 } 398 399 static irqreturn_t bnxt_qplib_creq_irq(int irq, void *dev_instance) 400 { 401 struct bnxt_qplib_rcfw *rcfw = dev_instance; 402 struct bnxt_qplib_hwq *creq = &rcfw->creq; 403 struct creq_base **creq_ptr; 404 u32 sw_cons; 405 406 /* Prefetch the CREQ element */ 407 sw_cons = HWQ_CMP(creq->cons, creq); 408 creq_ptr = (struct creq_base **)rcfw->creq.pbl_ptr; 409 prefetch(&creq_ptr[get_creq_pg(sw_cons)][get_creq_idx(sw_cons)]); 410 411 tasklet_schedule(&rcfw->worker); 412 413 return IRQ_HANDLED; 414 } 415 416 /* RCFW */ 417 int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw) 418 { 419 struct cmdq_deinitialize_fw req; 420 struct creq_deinitialize_fw_resp resp; 421 u16 cmd_flags = 0; 422 int rc; 423 424 RCFW_CMD_PREP(req, DEINITIALIZE_FW, cmd_flags); 425 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp, 426 NULL, 0); 427 if (rc) 428 return rc; 429 430 clear_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags); 431 return 0; 432 } 433 434 static int __get_pbl_pg_idx(struct bnxt_qplib_pbl *pbl) 435 { 436 return (pbl->pg_size == ROCE_PG_SIZE_4K ? 437 CMDQ_INITIALIZE_FW_QPC_PG_SIZE_PG_4K : 438 pbl->pg_size == ROCE_PG_SIZE_8K ? 439 CMDQ_INITIALIZE_FW_QPC_PG_SIZE_PG_8K : 440 pbl->pg_size == ROCE_PG_SIZE_64K ? 441 CMDQ_INITIALIZE_FW_QPC_PG_SIZE_PG_64K : 442 pbl->pg_size == ROCE_PG_SIZE_2M ? 443 CMDQ_INITIALIZE_FW_QPC_PG_SIZE_PG_2M : 444 pbl->pg_size == ROCE_PG_SIZE_8M ? 445 CMDQ_INITIALIZE_FW_QPC_PG_SIZE_PG_8M : 446 pbl->pg_size == ROCE_PG_SIZE_1G ? 447 CMDQ_INITIALIZE_FW_QPC_PG_SIZE_PG_1G : 448 CMDQ_INITIALIZE_FW_QPC_PG_SIZE_PG_4K); 449 } 450 451 int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw, 452 struct bnxt_qplib_ctx *ctx, int is_virtfn) 453 { 454 struct cmdq_initialize_fw req; 455 struct creq_initialize_fw_resp resp; 456 u16 cmd_flags = 0, level; 457 int rc; 458 459 RCFW_CMD_PREP(req, INITIALIZE_FW, cmd_flags); 460 461 /* 462 * VFs need not setup the HW context area, PF 463 * shall setup this area for VF. Skipping the 464 * HW programming 465 */ 466 if (is_virtfn) 467 goto skip_ctx_setup; 468 469 level = ctx->qpc_tbl.level; 470 req.qpc_pg_size_qpc_lvl = (level << CMDQ_INITIALIZE_FW_QPC_LVL_SFT) | 471 __get_pbl_pg_idx(&ctx->qpc_tbl.pbl[level]); 472 level = ctx->mrw_tbl.level; 473 req.mrw_pg_size_mrw_lvl = (level << CMDQ_INITIALIZE_FW_MRW_LVL_SFT) | 474 __get_pbl_pg_idx(&ctx->mrw_tbl.pbl[level]); 475 level = ctx->srqc_tbl.level; 476 req.srq_pg_size_srq_lvl = (level << CMDQ_INITIALIZE_FW_SRQ_LVL_SFT) | 477 __get_pbl_pg_idx(&ctx->srqc_tbl.pbl[level]); 478 level = ctx->cq_tbl.level; 479 req.cq_pg_size_cq_lvl = (level << CMDQ_INITIALIZE_FW_CQ_LVL_SFT) | 480 __get_pbl_pg_idx(&ctx->cq_tbl.pbl[level]); 481 level = ctx->srqc_tbl.level; 482 req.srq_pg_size_srq_lvl = (level << CMDQ_INITIALIZE_FW_SRQ_LVL_SFT) | 483 __get_pbl_pg_idx(&ctx->srqc_tbl.pbl[level]); 484 level = ctx->cq_tbl.level; 485 req.cq_pg_size_cq_lvl = (level << CMDQ_INITIALIZE_FW_CQ_LVL_SFT) | 486 __get_pbl_pg_idx(&ctx->cq_tbl.pbl[level]); 487 level = ctx->tim_tbl.level; 488 req.tim_pg_size_tim_lvl = (level << CMDQ_INITIALIZE_FW_TIM_LVL_SFT) | 489 __get_pbl_pg_idx(&ctx->tim_tbl.pbl[level]); 490 level = ctx->tqm_pde_level; 491 req.tqm_pg_size_tqm_lvl = (level << CMDQ_INITIALIZE_FW_TQM_LVL_SFT) | 492 __get_pbl_pg_idx(&ctx->tqm_pde.pbl[level]); 493 494 req.qpc_page_dir = 495 cpu_to_le64(ctx->qpc_tbl.pbl[PBL_LVL_0].pg_map_arr[0]); 496 req.mrw_page_dir = 497 cpu_to_le64(ctx->mrw_tbl.pbl[PBL_LVL_0].pg_map_arr[0]); 498 req.srq_page_dir = 499 cpu_to_le64(ctx->srqc_tbl.pbl[PBL_LVL_0].pg_map_arr[0]); 500 req.cq_page_dir = 501 cpu_to_le64(ctx->cq_tbl.pbl[PBL_LVL_0].pg_map_arr[0]); 502 req.tim_page_dir = 503 cpu_to_le64(ctx->tim_tbl.pbl[PBL_LVL_0].pg_map_arr[0]); 504 req.tqm_page_dir = 505 cpu_to_le64(ctx->tqm_pde.pbl[PBL_LVL_0].pg_map_arr[0]); 506 507 req.number_of_qp = cpu_to_le32(ctx->qpc_tbl.max_elements); 508 req.number_of_mrw = cpu_to_le32(ctx->mrw_tbl.max_elements); 509 req.number_of_srq = cpu_to_le32(ctx->srqc_tbl.max_elements); 510 req.number_of_cq = cpu_to_le32(ctx->cq_tbl.max_elements); 511 512 req.max_qp_per_vf = cpu_to_le32(ctx->vf_res.max_qp_per_vf); 513 req.max_mrw_per_vf = cpu_to_le32(ctx->vf_res.max_mrw_per_vf); 514 req.max_srq_per_vf = cpu_to_le32(ctx->vf_res.max_srq_per_vf); 515 req.max_cq_per_vf = cpu_to_le32(ctx->vf_res.max_cq_per_vf); 516 req.max_gid_per_vf = cpu_to_le32(ctx->vf_res.max_gid_per_vf); 517 518 skip_ctx_setup: 519 req.stat_ctx_id = cpu_to_le32(ctx->stats.fw_id); 520 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp, 521 NULL, 0); 522 if (rc) 523 return rc; 524 set_bit(FIRMWARE_INITIALIZED_FLAG, &rcfw->flags); 525 return 0; 526 } 527 528 void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw) 529 { 530 kfree(rcfw->qp_tbl); 531 kfree(rcfw->crsqe_tbl); 532 bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->cmdq); 533 bnxt_qplib_free_hwq(rcfw->pdev, &rcfw->creq); 534 rcfw->pdev = NULL; 535 } 536 537 int bnxt_qplib_alloc_rcfw_channel(struct pci_dev *pdev, 538 struct bnxt_qplib_rcfw *rcfw, 539 int qp_tbl_sz) 540 { 541 rcfw->pdev = pdev; 542 rcfw->creq.max_elements = BNXT_QPLIB_CREQE_MAX_CNT; 543 if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->creq, NULL, 0, 544 &rcfw->creq.max_elements, 545 BNXT_QPLIB_CREQE_UNITS, 0, PAGE_SIZE, 546 HWQ_TYPE_L2_CMPL)) { 547 dev_err(&rcfw->pdev->dev, 548 "QPLIB: HW channel CREQ allocation failed"); 549 goto fail; 550 } 551 rcfw->cmdq.max_elements = BNXT_QPLIB_CMDQE_MAX_CNT; 552 if (bnxt_qplib_alloc_init_hwq(rcfw->pdev, &rcfw->cmdq, NULL, 0, 553 &rcfw->cmdq.max_elements, 554 BNXT_QPLIB_CMDQE_UNITS, 0, PAGE_SIZE, 555 HWQ_TYPE_CTX)) { 556 dev_err(&rcfw->pdev->dev, 557 "QPLIB: HW channel CMDQ allocation failed"); 558 goto fail; 559 } 560 561 rcfw->crsqe_tbl = kcalloc(rcfw->cmdq.max_elements, 562 sizeof(*rcfw->crsqe_tbl), GFP_KERNEL); 563 if (!rcfw->crsqe_tbl) 564 goto fail; 565 566 rcfw->qp_tbl_size = qp_tbl_sz; 567 rcfw->qp_tbl = kcalloc(qp_tbl_sz, sizeof(struct bnxt_qplib_qp_node), 568 GFP_KERNEL); 569 if (!rcfw->qp_tbl) 570 goto fail; 571 572 return 0; 573 574 fail: 575 bnxt_qplib_free_rcfw_channel(rcfw); 576 return -ENOMEM; 577 } 578 579 void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw) 580 { 581 unsigned long indx; 582 583 /* Make sure the HW channel is stopped! */ 584 synchronize_irq(rcfw->vector); 585 tasklet_disable(&rcfw->worker); 586 tasklet_kill(&rcfw->worker); 587 588 if (rcfw->requested) { 589 free_irq(rcfw->vector, rcfw); 590 rcfw->requested = false; 591 } 592 if (rcfw->cmdq_bar_reg_iomem) 593 iounmap(rcfw->cmdq_bar_reg_iomem); 594 rcfw->cmdq_bar_reg_iomem = NULL; 595 596 if (rcfw->creq_bar_reg_iomem) 597 iounmap(rcfw->creq_bar_reg_iomem); 598 rcfw->creq_bar_reg_iomem = NULL; 599 600 indx = find_first_bit(rcfw->cmdq_bitmap, rcfw->bmap_size); 601 if (indx != rcfw->bmap_size) 602 dev_err(&rcfw->pdev->dev, 603 "QPLIB: disabling RCFW with pending cmd-bit %lx", indx); 604 kfree(rcfw->cmdq_bitmap); 605 rcfw->bmap_size = 0; 606 607 rcfw->aeq_handler = NULL; 608 rcfw->vector = 0; 609 } 610 611 int bnxt_qplib_enable_rcfw_channel(struct pci_dev *pdev, 612 struct bnxt_qplib_rcfw *rcfw, 613 int msix_vector, 614 int cp_bar_reg_off, int virt_fn, 615 int (*aeq_handler)(struct bnxt_qplib_rcfw *, 616 struct creq_func_event *)) 617 { 618 resource_size_t res_base; 619 struct cmdq_init init; 620 u16 bmap_size; 621 int rc; 622 623 /* General */ 624 rcfw->seq_num = 0; 625 rcfw->flags = FIRMWARE_FIRST_FLAG; 626 bmap_size = BITS_TO_LONGS(RCFW_MAX_OUTSTANDING_CMD * 627 sizeof(unsigned long)); 628 rcfw->cmdq_bitmap = kzalloc(bmap_size, GFP_KERNEL); 629 if (!rcfw->cmdq_bitmap) 630 return -ENOMEM; 631 rcfw->bmap_size = bmap_size; 632 633 /* CMDQ */ 634 rcfw->cmdq_bar_reg = RCFW_COMM_PCI_BAR_REGION; 635 res_base = pci_resource_start(pdev, rcfw->cmdq_bar_reg); 636 if (!res_base) 637 return -ENOMEM; 638 639 rcfw->cmdq_bar_reg_iomem = ioremap_nocache(res_base + 640 RCFW_COMM_BASE_OFFSET, 641 RCFW_COMM_SIZE); 642 if (!rcfw->cmdq_bar_reg_iomem) { 643 dev_err(&rcfw->pdev->dev, 644 "QPLIB: CMDQ BAR region %d mapping failed", 645 rcfw->cmdq_bar_reg); 646 return -ENOMEM; 647 } 648 649 rcfw->cmdq_bar_reg_prod_off = virt_fn ? RCFW_VF_COMM_PROD_OFFSET : 650 RCFW_PF_COMM_PROD_OFFSET; 651 652 rcfw->cmdq_bar_reg_trig_off = RCFW_COMM_TRIG_OFFSET; 653 654 /* CREQ */ 655 rcfw->creq_bar_reg = RCFW_COMM_CONS_PCI_BAR_REGION; 656 res_base = pci_resource_start(pdev, rcfw->creq_bar_reg); 657 if (!res_base) 658 dev_err(&rcfw->pdev->dev, 659 "QPLIB: CREQ BAR region %d resc start is 0!", 660 rcfw->creq_bar_reg); 661 rcfw->creq_bar_reg_iomem = ioremap_nocache(res_base + cp_bar_reg_off, 662 4); 663 if (!rcfw->creq_bar_reg_iomem) { 664 dev_err(&rcfw->pdev->dev, 665 "QPLIB: CREQ BAR region %d mapping failed", 666 rcfw->creq_bar_reg); 667 return -ENOMEM; 668 } 669 rcfw->creq_qp_event_processed = 0; 670 rcfw->creq_func_event_processed = 0; 671 672 rcfw->vector = msix_vector; 673 if (aeq_handler) 674 rcfw->aeq_handler = aeq_handler; 675 676 tasklet_init(&rcfw->worker, bnxt_qplib_service_creq, 677 (unsigned long)rcfw); 678 679 rcfw->requested = false; 680 rc = request_irq(rcfw->vector, bnxt_qplib_creq_irq, 0, 681 "bnxt_qplib_creq", rcfw); 682 if (rc) { 683 dev_err(&rcfw->pdev->dev, 684 "QPLIB: Failed to request IRQ for CREQ rc = 0x%x", rc); 685 bnxt_qplib_disable_rcfw_channel(rcfw); 686 return rc; 687 } 688 rcfw->requested = true; 689 690 init_waitqueue_head(&rcfw->waitq); 691 692 CREQ_DB_REARM(rcfw->creq_bar_reg_iomem, 0, rcfw->creq.max_elements); 693 694 init.cmdq_pbl = cpu_to_le64(rcfw->cmdq.pbl[PBL_LVL_0].pg_map_arr[0]); 695 init.cmdq_size_cmdq_lvl = cpu_to_le16( 696 ((BNXT_QPLIB_CMDQE_MAX_CNT << CMDQ_INIT_CMDQ_SIZE_SFT) & 697 CMDQ_INIT_CMDQ_SIZE_MASK) | 698 ((rcfw->cmdq.level << CMDQ_INIT_CMDQ_LVL_SFT) & 699 CMDQ_INIT_CMDQ_LVL_MASK)); 700 init.creq_ring_id = cpu_to_le16(rcfw->creq_ring_id); 701 702 /* Write to the Bono mailbox register */ 703 __iowrite32_copy(rcfw->cmdq_bar_reg_iomem, &init, sizeof(init) / 4); 704 return 0; 705 } 706 707 struct bnxt_qplib_rcfw_sbuf *bnxt_qplib_rcfw_alloc_sbuf( 708 struct bnxt_qplib_rcfw *rcfw, 709 u32 size) 710 { 711 struct bnxt_qplib_rcfw_sbuf *sbuf; 712 713 sbuf = kzalloc(sizeof(*sbuf), GFP_ATOMIC); 714 if (!sbuf) 715 return NULL; 716 717 sbuf->size = size; 718 sbuf->sb = dma_zalloc_coherent(&rcfw->pdev->dev, sbuf->size, 719 &sbuf->dma_addr, GFP_ATOMIC); 720 if (!sbuf->sb) 721 goto bail; 722 723 return sbuf; 724 bail: 725 kfree(sbuf); 726 return NULL; 727 } 728 729 void bnxt_qplib_rcfw_free_sbuf(struct bnxt_qplib_rcfw *rcfw, 730 struct bnxt_qplib_rcfw_sbuf *sbuf) 731 { 732 if (sbuf->sb) 733 dma_free_coherent(&rcfw->pdev->dev, sbuf->size, 734 sbuf->sb, sbuf->dma_addr); 735 kfree(sbuf); 736 } 737