1/* QLogic qed NIC Driver 2 * Copyright (c) 2015 QLogic Corporation 3 * 4 * This software is available under the terms of the GNU General Public License 5 * (GPL) Version 2, available from the file COPYING in the main directory of 6 * this source tree. 7 */ 8 9#include <linux/types.h> 10#include <linux/io.h> 11#include <linux/delay.h> 12#include <linux/dma-mapping.h> 13#include <linux/errno.h> 14#include <linux/kernel.h> 15#include <linux/list.h> 16#include <linux/mutex.h> 17#include <linux/pci.h> 18#include <linux/slab.h> 19#include <linux/spinlock.h> 20#include <linux/string.h> 21#include <linux/qed/qed_chain.h> 22#include "qed.h" 23#include "qed_hsi.h" 24#include "qed_hw.h" 25#include "qed_reg_addr.h" 26 27#define QED_BAR_ACQUIRE_TIMEOUT 1000 28 29/* Invalid values */ 30#define QED_BAR_INVALID_OFFSET (cpu_to_le32(-1)) 31 32struct qed_ptt { 33 struct list_head list_entry; 34 unsigned int idx; 35 struct pxp_ptt_entry pxp; 36}; 37 38struct qed_ptt_pool { 39 struct list_head free_list; 40 spinlock_t lock; /* ptt synchronized access */ 41 struct qed_ptt ptts[PXP_EXTERNAL_BAR_PF_WINDOW_NUM]; 42}; 43 44int qed_ptt_pool_alloc(struct qed_hwfn *p_hwfn) 45{ 46 struct qed_ptt_pool *p_pool = kmalloc(sizeof(*p_pool), 47 GFP_ATOMIC); 48 int i; 49 50 if (!p_pool) 51 return -ENOMEM; 52 53 INIT_LIST_HEAD(&p_pool->free_list); 54 for (i = 0; i < PXP_EXTERNAL_BAR_PF_WINDOW_NUM; i++) { 55 p_pool->ptts[i].idx = i; 56 p_pool->ptts[i].pxp.offset = QED_BAR_INVALID_OFFSET; 57 p_pool->ptts[i].pxp.pretend.control = 0; 58 if (i >= RESERVED_PTT_MAX) 59 list_add(&p_pool->ptts[i].list_entry, 60 &p_pool->free_list); 61 } 62 63 p_hwfn->p_ptt_pool = p_pool; 64 spin_lock_init(&p_pool->lock); 65 66 return 0; 67} 68 69void qed_ptt_invalidate(struct qed_hwfn *p_hwfn) 70{ 71 struct qed_ptt *p_ptt; 72 int i; 73 74 for (i = 0; i < PXP_EXTERNAL_BAR_PF_WINDOW_NUM; i++) { 75 p_ptt = &p_hwfn->p_ptt_pool->ptts[i]; 76 p_ptt->pxp.offset = QED_BAR_INVALID_OFFSET; 77 } 78} 79 80void qed_ptt_pool_free(struct qed_hwfn *p_hwfn) 81{ 82 kfree(p_hwfn->p_ptt_pool); 83 p_hwfn->p_ptt_pool = NULL; 84} 85 86struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn) 87{ 88 struct qed_ptt *p_ptt; 89 unsigned int i; 90 91 /* Take the free PTT from the list */ 92 for (i = 0; i < QED_BAR_ACQUIRE_TIMEOUT; i++) { 93 spin_lock_bh(&p_hwfn->p_ptt_pool->lock); 94 95 if (!list_empty(&p_hwfn->p_ptt_pool->free_list)) { 96 p_ptt = list_first_entry(&p_hwfn->p_ptt_pool->free_list, 97 struct qed_ptt, list_entry); 98 list_del(&p_ptt->list_entry); 99 100 spin_unlock_bh(&p_hwfn->p_ptt_pool->lock); 101 102 DP_VERBOSE(p_hwfn, NETIF_MSG_HW, 103 "allocated ptt %d\n", p_ptt->idx); 104 return p_ptt; 105 } 106 107 spin_unlock_bh(&p_hwfn->p_ptt_pool->lock); 108 usleep_range(1000, 2000); 109 } 110 111 DP_NOTICE(p_hwfn, "PTT acquire timeout - failed to allocate PTT\n"); 112 return NULL; 113} 114 115void qed_ptt_release(struct qed_hwfn *p_hwfn, 116 struct qed_ptt *p_ptt) 117{ 118 spin_lock_bh(&p_hwfn->p_ptt_pool->lock); 119 list_add(&p_ptt->list_entry, &p_hwfn->p_ptt_pool->free_list); 120 spin_unlock_bh(&p_hwfn->p_ptt_pool->lock); 121} 122 123u32 qed_ptt_get_hw_addr(struct qed_hwfn *p_hwfn, 124 struct qed_ptt *p_ptt) 125{ 126 /* The HW is using DWORDS and we need to translate it to Bytes */ 127 return le32_to_cpu(p_ptt->pxp.offset) << 2; 128} 129 130static u32 qed_ptt_config_addr(struct qed_ptt *p_ptt) 131{ 132 return PXP_PF_WINDOW_ADMIN_PER_PF_START + 133 p_ptt->idx * sizeof(struct pxp_ptt_entry); 134} 135 136u32 qed_ptt_get_bar_addr(struct qed_ptt *p_ptt) 137{ 138 return PXP_EXTERNAL_BAR_PF_WINDOW_START + 139 p_ptt->idx * PXP_EXTERNAL_BAR_PF_WINDOW_SINGLE_SIZE; 140} 141 142void qed_ptt_set_win(struct qed_hwfn *p_hwfn, 143 struct qed_ptt *p_ptt, 144 u32 new_hw_addr) 145{ 146 u32 prev_hw_addr; 147 148 prev_hw_addr = qed_ptt_get_hw_addr(p_hwfn, p_ptt); 149 150 if (new_hw_addr == prev_hw_addr) 151 return; 152 153 /* Update PTT entery in admin window */ 154 DP_VERBOSE(p_hwfn, NETIF_MSG_HW, 155 "Updating PTT entry %d to offset 0x%x\n", 156 p_ptt->idx, new_hw_addr); 157 158 /* The HW is using DWORDS and the address is in Bytes */ 159 p_ptt->pxp.offset = cpu_to_le32(new_hw_addr >> 2); 160 161 REG_WR(p_hwfn, 162 qed_ptt_config_addr(p_ptt) + 163 offsetof(struct pxp_ptt_entry, offset), 164 le32_to_cpu(p_ptt->pxp.offset)); 165} 166 167static u32 qed_set_ptt(struct qed_hwfn *p_hwfn, 168 struct qed_ptt *p_ptt, 169 u32 hw_addr) 170{ 171 u32 win_hw_addr = qed_ptt_get_hw_addr(p_hwfn, p_ptt); 172 u32 offset; 173 174 offset = hw_addr - win_hw_addr; 175 176 /* Verify the address is within the window */ 177 if (hw_addr < win_hw_addr || 178 offset >= PXP_EXTERNAL_BAR_PF_WINDOW_SINGLE_SIZE) { 179 qed_ptt_set_win(p_hwfn, p_ptt, hw_addr); 180 offset = 0; 181 } 182 183 return qed_ptt_get_bar_addr(p_ptt) + offset; 184} 185 186struct qed_ptt *qed_get_reserved_ptt(struct qed_hwfn *p_hwfn, 187 enum reserved_ptts ptt_idx) 188{ 189 if (ptt_idx >= RESERVED_PTT_MAX) { 190 DP_NOTICE(p_hwfn, 191 "Requested PTT %d is out of range\n", ptt_idx); 192 return NULL; 193 } 194 195 return &p_hwfn->p_ptt_pool->ptts[ptt_idx]; 196} 197 198void qed_wr(struct qed_hwfn *p_hwfn, 199 struct qed_ptt *p_ptt, 200 u32 hw_addr, u32 val) 201{ 202 u32 bar_addr = qed_set_ptt(p_hwfn, p_ptt, hw_addr); 203 204 REG_WR(p_hwfn, bar_addr, val); 205 DP_VERBOSE(p_hwfn, NETIF_MSG_HW, 206 "bar_addr 0x%x, hw_addr 0x%x, val 0x%x\n", 207 bar_addr, hw_addr, val); 208} 209 210u32 qed_rd(struct qed_hwfn *p_hwfn, 211 struct qed_ptt *p_ptt, 212 u32 hw_addr) 213{ 214 u32 bar_addr = qed_set_ptt(p_hwfn, p_ptt, hw_addr); 215 u32 val = REG_RD(p_hwfn, bar_addr); 216 217 DP_VERBOSE(p_hwfn, NETIF_MSG_HW, 218 "bar_addr 0x%x, hw_addr 0x%x, val 0x%x\n", 219 bar_addr, hw_addr, val); 220 221 return val; 222} 223 224static void qed_memcpy_hw(struct qed_hwfn *p_hwfn, 225 struct qed_ptt *p_ptt, 226 void *addr, 227 u32 hw_addr, 228 size_t n, 229 bool to_device) 230{ 231 u32 dw_count, *host_addr, hw_offset; 232 size_t quota, done = 0; 233 u32 __iomem *reg_addr; 234 235 while (done < n) { 236 quota = min_t(size_t, n - done, 237 PXP_EXTERNAL_BAR_PF_WINDOW_SINGLE_SIZE); 238 239 qed_ptt_set_win(p_hwfn, p_ptt, hw_addr + done); 240 hw_offset = qed_ptt_get_bar_addr(p_ptt); 241 242 dw_count = quota / 4; 243 host_addr = (u32 *)((u8 *)addr + done); 244 reg_addr = (u32 __iomem *)REG_ADDR(p_hwfn, hw_offset); 245 if (to_device) 246 while (dw_count--) 247 DIRECT_REG_WR(reg_addr++, *host_addr++); 248 else 249 while (dw_count--) 250 *host_addr++ = DIRECT_REG_RD(reg_addr++); 251 252 done += quota; 253 } 254} 255 256void qed_memcpy_from(struct qed_hwfn *p_hwfn, 257 struct qed_ptt *p_ptt, 258 void *dest, u32 hw_addr, size_t n) 259{ 260 DP_VERBOSE(p_hwfn, NETIF_MSG_HW, 261 "hw_addr 0x%x, dest %p hw_addr 0x%x, size %lu\n", 262 hw_addr, dest, hw_addr, (unsigned long)n); 263 264 qed_memcpy_hw(p_hwfn, p_ptt, dest, hw_addr, n, false); 265} 266 267void qed_memcpy_to(struct qed_hwfn *p_hwfn, 268 struct qed_ptt *p_ptt, 269 u32 hw_addr, void *src, size_t n) 270{ 271 DP_VERBOSE(p_hwfn, NETIF_MSG_HW, 272 "hw_addr 0x%x, hw_addr 0x%x, src %p size %lu\n", 273 hw_addr, hw_addr, src, (unsigned long)n); 274 275 qed_memcpy_hw(p_hwfn, p_ptt, src, hw_addr, n, true); 276} 277 278void qed_fid_pretend(struct qed_hwfn *p_hwfn, 279 struct qed_ptt *p_ptt, 280 u16 fid) 281{ 282 u16 control = 0; 283 284 SET_FIELD(control, PXP_PRETEND_CMD_IS_CONCRETE, 1); 285 SET_FIELD(control, PXP_PRETEND_CMD_PRETEND_FUNCTION, 1); 286 287 /* Every pretend undos previous pretends, including 288 * previous port pretend. 289 */ 290 SET_FIELD(control, PXP_PRETEND_CMD_PORT, 0); 291 SET_FIELD(control, PXP_PRETEND_CMD_USE_PORT, 0); 292 SET_FIELD(control, PXP_PRETEND_CMD_PRETEND_PORT, 1); 293 294 if (!GET_FIELD(fid, PXP_CONCRETE_FID_VFVALID)) 295 fid = GET_FIELD(fid, PXP_CONCRETE_FID_PFID); 296 297 p_ptt->pxp.pretend.control = cpu_to_le16(control); 298 p_ptt->pxp.pretend.fid.concrete_fid.fid = cpu_to_le16(fid); 299 300 REG_WR(p_hwfn, 301 qed_ptt_config_addr(p_ptt) + 302 offsetof(struct pxp_ptt_entry, pretend), 303 *(u32 *)&p_ptt->pxp.pretend); 304} 305 306void qed_port_pretend(struct qed_hwfn *p_hwfn, 307 struct qed_ptt *p_ptt, 308 u8 port_id) 309{ 310 u16 control = 0; 311 312 SET_FIELD(control, PXP_PRETEND_CMD_PORT, port_id); 313 SET_FIELD(control, PXP_PRETEND_CMD_USE_PORT, 1); 314 SET_FIELD(control, PXP_PRETEND_CMD_PRETEND_PORT, 1); 315 316 p_ptt->pxp.pretend.control = cpu_to_le16(control); 317 318 REG_WR(p_hwfn, 319 qed_ptt_config_addr(p_ptt) + 320 offsetof(struct pxp_ptt_entry, pretend), 321 *(u32 *)&p_ptt->pxp.pretend); 322} 323 324void qed_port_unpretend(struct qed_hwfn *p_hwfn, 325 struct qed_ptt *p_ptt) 326{ 327 u16 control = 0; 328 329 SET_FIELD(control, PXP_PRETEND_CMD_PORT, 0); 330 SET_FIELD(control, PXP_PRETEND_CMD_USE_PORT, 0); 331 SET_FIELD(control, PXP_PRETEND_CMD_PRETEND_PORT, 1); 332 333 p_ptt->pxp.pretend.control = cpu_to_le16(control); 334 335 REG_WR(p_hwfn, 336 qed_ptt_config_addr(p_ptt) + 337 offsetof(struct pxp_ptt_entry, pretend), 338 *(u32 *)&p_ptt->pxp.pretend); 339} 340 341/* DMAE */ 342static void qed_dmae_opcode(struct qed_hwfn *p_hwfn, 343 const u8 is_src_type_grc, 344 const u8 is_dst_type_grc, 345 struct qed_dmae_params *p_params) 346{ 347 u32 opcode = 0; 348 u16 opcodeB = 0; 349 350 /* Whether the source is the PCIe or the GRC. 351 * 0- The source is the PCIe 352 * 1- The source is the GRC. 353 */ 354 opcode |= (is_src_type_grc ? DMAE_CMD_SRC_MASK_GRC 355 : DMAE_CMD_SRC_MASK_PCIE) << 356 DMAE_CMD_SRC_SHIFT; 357 opcode |= ((p_hwfn->rel_pf_id & DMAE_CMD_SRC_PF_ID_MASK) << 358 DMAE_CMD_SRC_PF_ID_SHIFT); 359 360 /* The destination of the DMA can be: 0-None 1-PCIe 2-GRC 3-None */ 361 opcode |= (is_dst_type_grc ? DMAE_CMD_DST_MASK_GRC 362 : DMAE_CMD_DST_MASK_PCIE) << 363 DMAE_CMD_DST_SHIFT; 364 opcode |= ((p_hwfn->rel_pf_id & DMAE_CMD_DST_PF_ID_MASK) << 365 DMAE_CMD_DST_PF_ID_SHIFT); 366 367 /* Whether to write a completion word to the completion destination: 368 * 0-Do not write a completion word 369 * 1-Write the completion word 370 */ 371 opcode |= (DMAE_CMD_COMP_WORD_EN_MASK << DMAE_CMD_COMP_WORD_EN_SHIFT); 372 opcode |= (DMAE_CMD_SRC_ADDR_RESET_MASK << 373 DMAE_CMD_SRC_ADDR_RESET_SHIFT); 374 375 if (p_params->flags & QED_DMAE_FLAG_COMPLETION_DST) 376 opcode |= (1 << DMAE_CMD_COMP_FUNC_SHIFT); 377 378 opcode |= (DMAE_CMD_ENDIANITY << DMAE_CMD_ENDIANITY_MODE_SHIFT); 379 380 opcode |= ((p_hwfn->port_id) << DMAE_CMD_PORT_ID_SHIFT); 381 382 /* reset source address in next go */ 383 opcode |= (DMAE_CMD_SRC_ADDR_RESET_MASK << 384 DMAE_CMD_SRC_ADDR_RESET_SHIFT); 385 386 /* reset dest address in next go */ 387 opcode |= (DMAE_CMD_DST_ADDR_RESET_MASK << 388 DMAE_CMD_DST_ADDR_RESET_SHIFT); 389 390 opcodeB |= (DMAE_CMD_SRC_VF_ID_MASK << 391 DMAE_CMD_SRC_VF_ID_SHIFT); 392 393 opcodeB |= (DMAE_CMD_DST_VF_ID_MASK << 394 DMAE_CMD_DST_VF_ID_SHIFT); 395 396 p_hwfn->dmae_info.p_dmae_cmd->opcode = cpu_to_le32(opcode); 397 p_hwfn->dmae_info.p_dmae_cmd->opcode_b = cpu_to_le16(opcodeB); 398} 399 400u32 qed_dmae_idx_to_go_cmd(u8 idx) 401{ 402 /* All the DMAE 'go' registers form an array in internal memory */ 403 return DMAE_REG_GO_C0 + (idx << 2); 404} 405 406static int 407qed_dmae_post_command(struct qed_hwfn *p_hwfn, 408 struct qed_ptt *p_ptt) 409{ 410 struct dmae_cmd *command = p_hwfn->dmae_info.p_dmae_cmd; 411 u8 idx_cmd = p_hwfn->dmae_info.channel, i; 412 int qed_status = 0; 413 414 /* verify address is not NULL */ 415 if ((((command->dst_addr_lo == 0) && (command->dst_addr_hi == 0)) || 416 ((command->src_addr_lo == 0) && (command->src_addr_hi == 0)))) { 417 DP_NOTICE(p_hwfn, 418 "source or destination address 0 idx_cmd=%d\n" 419 "opcode = [0x%08x,0x%04x] len=0x%x src=0x%x:%x dst=0x%x:%x\n", 420 idx_cmd, 421 le32_to_cpu(command->opcode), 422 le16_to_cpu(command->opcode_b), 423 le16_to_cpu(command->length), 424 le32_to_cpu(command->src_addr_hi), 425 le32_to_cpu(command->src_addr_lo), 426 le32_to_cpu(command->dst_addr_hi), 427 le32_to_cpu(command->dst_addr_lo)); 428 429 return -EINVAL; 430 } 431 432 DP_VERBOSE(p_hwfn, 433 NETIF_MSG_HW, 434 "Posting DMAE command [idx %d]: opcode = [0x%08x,0x%04x] len=0x%x src=0x%x:%x dst=0x%x:%x\n", 435 idx_cmd, 436 le32_to_cpu(command->opcode), 437 le16_to_cpu(command->opcode_b), 438 le16_to_cpu(command->length), 439 le32_to_cpu(command->src_addr_hi), 440 le32_to_cpu(command->src_addr_lo), 441 le32_to_cpu(command->dst_addr_hi), 442 le32_to_cpu(command->dst_addr_lo)); 443 444 /* Copy the command to DMAE - need to do it before every call 445 * for source/dest address no reset. 446 * The first 9 DWs are the command registers, the 10 DW is the 447 * GO register, and the rest are result registers 448 * (which are read only by the client). 449 */ 450 for (i = 0; i < DMAE_CMD_SIZE; i++) { 451 u32 data = (i < DMAE_CMD_SIZE_TO_FILL) ? 452 *(((u32 *)command) + i) : 0; 453 454 qed_wr(p_hwfn, p_ptt, 455 DMAE_REG_CMD_MEM + 456 (idx_cmd * DMAE_CMD_SIZE * sizeof(u32)) + 457 (i * sizeof(u32)), data); 458 } 459 460 qed_wr(p_hwfn, p_ptt, 461 qed_dmae_idx_to_go_cmd(idx_cmd), 462 DMAE_GO_VALUE); 463 464 return qed_status; 465} 466 467int qed_dmae_info_alloc(struct qed_hwfn *p_hwfn) 468{ 469 dma_addr_t *p_addr = &p_hwfn->dmae_info.completion_word_phys_addr; 470 struct dmae_cmd **p_cmd = &p_hwfn->dmae_info.p_dmae_cmd; 471 u32 **p_buff = &p_hwfn->dmae_info.p_intermediate_buffer; 472 u32 **p_comp = &p_hwfn->dmae_info.p_completion_word; 473 474 *p_comp = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 475 sizeof(u32), 476 p_addr, 477 GFP_KERNEL); 478 if (!*p_comp) { 479 DP_NOTICE(p_hwfn, "Failed to allocate `p_completion_word'\n"); 480 goto err; 481 } 482 483 p_addr = &p_hwfn->dmae_info.dmae_cmd_phys_addr; 484 *p_cmd = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 485 sizeof(struct dmae_cmd), 486 p_addr, GFP_KERNEL); 487 if (!*p_cmd) { 488 DP_NOTICE(p_hwfn, "Failed to allocate `struct dmae_cmd'\n"); 489 goto err; 490 } 491 492 p_addr = &p_hwfn->dmae_info.intermediate_buffer_phys_addr; 493 *p_buff = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 494 sizeof(u32) * DMAE_MAX_RW_SIZE, 495 p_addr, GFP_KERNEL); 496 if (!*p_buff) { 497 DP_NOTICE(p_hwfn, "Failed to allocate `intermediate_buffer'\n"); 498 goto err; 499 } 500 501 p_hwfn->dmae_info.channel = p_hwfn->rel_pf_id; 502 503 return 0; 504err: 505 qed_dmae_info_free(p_hwfn); 506 return -ENOMEM; 507} 508 509void qed_dmae_info_free(struct qed_hwfn *p_hwfn) 510{ 511 dma_addr_t p_phys; 512 513 /* Just make sure no one is in the middle */ 514 mutex_lock(&p_hwfn->dmae_info.mutex); 515 516 if (p_hwfn->dmae_info.p_completion_word) { 517 p_phys = p_hwfn->dmae_info.completion_word_phys_addr; 518 dma_free_coherent(&p_hwfn->cdev->pdev->dev, 519 sizeof(u32), 520 p_hwfn->dmae_info.p_completion_word, 521 p_phys); 522 p_hwfn->dmae_info.p_completion_word = NULL; 523 } 524 525 if (p_hwfn->dmae_info.p_dmae_cmd) { 526 p_phys = p_hwfn->dmae_info.dmae_cmd_phys_addr; 527 dma_free_coherent(&p_hwfn->cdev->pdev->dev, 528 sizeof(struct dmae_cmd), 529 p_hwfn->dmae_info.p_dmae_cmd, 530 p_phys); 531 p_hwfn->dmae_info.p_dmae_cmd = NULL; 532 } 533 534 if (p_hwfn->dmae_info.p_intermediate_buffer) { 535 p_phys = p_hwfn->dmae_info.intermediate_buffer_phys_addr; 536 dma_free_coherent(&p_hwfn->cdev->pdev->dev, 537 sizeof(u32) * DMAE_MAX_RW_SIZE, 538 p_hwfn->dmae_info.p_intermediate_buffer, 539 p_phys); 540 p_hwfn->dmae_info.p_intermediate_buffer = NULL; 541 } 542 543 mutex_unlock(&p_hwfn->dmae_info.mutex); 544} 545 546static int qed_dmae_operation_wait(struct qed_hwfn *p_hwfn) 547{ 548 u32 wait_cnt = 0; 549 u32 wait_cnt_limit = 10000; 550 551 int qed_status = 0; 552 553 barrier(); 554 while (*p_hwfn->dmae_info.p_completion_word != DMAE_COMPLETION_VAL) { 555 udelay(DMAE_MIN_WAIT_TIME); 556 if (++wait_cnt > wait_cnt_limit) { 557 DP_NOTICE(p_hwfn->cdev, 558 "Timed-out waiting for operation to complete. Completion word is 0x%08x expected 0x%08x.\n", 559 *p_hwfn->dmae_info.p_completion_word, 560 DMAE_COMPLETION_VAL); 561 qed_status = -EBUSY; 562 break; 563 } 564 565 /* to sync the completion_word since we are not 566 * using the volatile keyword for p_completion_word 567 */ 568 barrier(); 569 } 570 571 if (qed_status == 0) 572 *p_hwfn->dmae_info.p_completion_word = 0; 573 574 return qed_status; 575} 576 577static int qed_dmae_execute_sub_operation(struct qed_hwfn *p_hwfn, 578 struct qed_ptt *p_ptt, 579 u64 src_addr, 580 u64 dst_addr, 581 u8 src_type, 582 u8 dst_type, 583 u32 length) 584{ 585 dma_addr_t phys = p_hwfn->dmae_info.intermediate_buffer_phys_addr; 586 struct dmae_cmd *cmd = p_hwfn->dmae_info.p_dmae_cmd; 587 int qed_status = 0; 588 589 switch (src_type) { 590 case QED_DMAE_ADDRESS_GRC: 591 case QED_DMAE_ADDRESS_HOST_PHYS: 592 cmd->src_addr_hi = cpu_to_le32(upper_32_bits(src_addr)); 593 cmd->src_addr_lo = cpu_to_le32(lower_32_bits(src_addr)); 594 break; 595 /* for virtual source addresses we use the intermediate buffer. */ 596 case QED_DMAE_ADDRESS_HOST_VIRT: 597 cmd->src_addr_hi = cpu_to_le32(upper_32_bits(phys)); 598 cmd->src_addr_lo = cpu_to_le32(lower_32_bits(phys)); 599 memcpy(&p_hwfn->dmae_info.p_intermediate_buffer[0], 600 (void *)(uintptr_t)src_addr, 601 length * sizeof(u32)); 602 break; 603 default: 604 return -EINVAL; 605 } 606 607 switch (dst_type) { 608 case QED_DMAE_ADDRESS_GRC: 609 case QED_DMAE_ADDRESS_HOST_PHYS: 610 cmd->dst_addr_hi = cpu_to_le32(upper_32_bits(dst_addr)); 611 cmd->dst_addr_lo = cpu_to_le32(lower_32_bits(dst_addr)); 612 break; 613 /* for virtual source addresses we use the intermediate buffer. */ 614 case QED_DMAE_ADDRESS_HOST_VIRT: 615 cmd->dst_addr_hi = cpu_to_le32(upper_32_bits(phys)); 616 cmd->dst_addr_lo = cpu_to_le32(lower_32_bits(phys)); 617 break; 618 default: 619 return -EINVAL; 620 } 621 622 cmd->length = cpu_to_le16((u16)length); 623 624 qed_dmae_post_command(p_hwfn, p_ptt); 625 626 qed_status = qed_dmae_operation_wait(p_hwfn); 627 628 if (qed_status) { 629 DP_NOTICE(p_hwfn, 630 "qed_dmae_host2grc: Wait Failed. source_addr 0x%llx, grc_addr 0x%llx, size_in_dwords 0x%x\n", 631 src_addr, 632 dst_addr, 633 length); 634 return qed_status; 635 } 636 637 if (dst_type == QED_DMAE_ADDRESS_HOST_VIRT) 638 memcpy((void *)(uintptr_t)(dst_addr), 639 &p_hwfn->dmae_info.p_intermediate_buffer[0], 640 length * sizeof(u32)); 641 642 return 0; 643} 644 645static int qed_dmae_execute_command(struct qed_hwfn *p_hwfn, 646 struct qed_ptt *p_ptt, 647 u64 src_addr, u64 dst_addr, 648 u8 src_type, u8 dst_type, 649 u32 size_in_dwords, 650 struct qed_dmae_params *p_params) 651{ 652 dma_addr_t phys = p_hwfn->dmae_info.completion_word_phys_addr; 653 u16 length_cur = 0, i = 0, cnt_split = 0, length_mod = 0; 654 struct dmae_cmd *cmd = p_hwfn->dmae_info.p_dmae_cmd; 655 u64 src_addr_split = 0, dst_addr_split = 0; 656 u16 length_limit = DMAE_MAX_RW_SIZE; 657 int qed_status = 0; 658 u32 offset = 0; 659 660 qed_dmae_opcode(p_hwfn, 661 (src_type == QED_DMAE_ADDRESS_GRC), 662 (dst_type == QED_DMAE_ADDRESS_GRC), 663 p_params); 664 665 cmd->comp_addr_lo = cpu_to_le32(lower_32_bits(phys)); 666 cmd->comp_addr_hi = cpu_to_le32(upper_32_bits(phys)); 667 cmd->comp_val = cpu_to_le32(DMAE_COMPLETION_VAL); 668 669 /* Check if the grc_addr is valid like < MAX_GRC_OFFSET */ 670 cnt_split = size_in_dwords / length_limit; 671 length_mod = size_in_dwords % length_limit; 672 673 src_addr_split = src_addr; 674 dst_addr_split = dst_addr; 675 676 for (i = 0; i <= cnt_split; i++) { 677 offset = length_limit * i; 678 679 if (!(p_params->flags & QED_DMAE_FLAG_RW_REPL_SRC)) { 680 if (src_type == QED_DMAE_ADDRESS_GRC) 681 src_addr_split = src_addr + offset; 682 else 683 src_addr_split = src_addr + (offset * 4); 684 } 685 686 if (dst_type == QED_DMAE_ADDRESS_GRC) 687 dst_addr_split = dst_addr + offset; 688 else 689 dst_addr_split = dst_addr + (offset * 4); 690 691 length_cur = (cnt_split == i) ? length_mod : length_limit; 692 693 /* might be zero on last iteration */ 694 if (!length_cur) 695 continue; 696 697 qed_status = qed_dmae_execute_sub_operation(p_hwfn, 698 p_ptt, 699 src_addr_split, 700 dst_addr_split, 701 src_type, 702 dst_type, 703 length_cur); 704 if (qed_status) { 705 DP_NOTICE(p_hwfn, 706 "qed_dmae_execute_sub_operation Failed with error 0x%x. source_addr 0x%llx, destination addr 0x%llx, size_in_dwords 0x%x\n", 707 qed_status, 708 src_addr, 709 dst_addr, 710 length_cur); 711 break; 712 } 713 } 714 715 return qed_status; 716} 717 718int qed_dmae_host2grc(struct qed_hwfn *p_hwfn, 719 struct qed_ptt *p_ptt, 720 u64 source_addr, 721 u32 grc_addr, 722 u32 size_in_dwords, 723 u32 flags) 724{ 725 u32 grc_addr_in_dw = grc_addr / sizeof(u32); 726 struct qed_dmae_params params; 727 int rc; 728 729 memset(¶ms, 0, sizeof(struct qed_dmae_params)); 730 params.flags = flags; 731 732 mutex_lock(&p_hwfn->dmae_info.mutex); 733 734 rc = qed_dmae_execute_command(p_hwfn, p_ptt, source_addr, 735 grc_addr_in_dw, 736 QED_DMAE_ADDRESS_HOST_VIRT, 737 QED_DMAE_ADDRESS_GRC, 738 size_in_dwords, ¶ms); 739 740 mutex_unlock(&p_hwfn->dmae_info.mutex); 741 742 return rc; 743} 744 745u16 qed_get_qm_pq(struct qed_hwfn *p_hwfn, 746 enum protocol_type proto, 747 union qed_qm_pq_params *p_params) 748{ 749 u16 pq_id = 0; 750 751 if ((proto == PROTOCOLID_CORE || proto == PROTOCOLID_ETH) && 752 !p_params) { 753 DP_NOTICE(p_hwfn, 754 "Protocol %d received NULL PQ params\n", 755 proto); 756 return 0; 757 } 758 759 switch (proto) { 760 case PROTOCOLID_CORE: 761 if (p_params->core.tc == LB_TC) 762 pq_id = p_hwfn->qm_info.pure_lb_pq; 763 else 764 pq_id = p_hwfn->qm_info.offload_pq; 765 break; 766 case PROTOCOLID_ETH: 767 pq_id = p_params->eth.tc; 768 break; 769 default: 770 pq_id = 0; 771 } 772 773 pq_id = CM_TX_PQ_BASE + pq_id + RESC_START(p_hwfn, QED_PQ); 774 775 return pq_id; 776} 777