1 #include "lm5710.h" 2 #include "everest_iscsi_constants.h" 3 #include "everest_l5cm_constants.h" 4 #include "577xx_int_offsets.h" 5 #include "bd_chain.h" 6 #include "command.h" 7 #include "lm_sp_req_mgr.h" 8 #include "lm_l4sp.h" 9 #include "lm_l4if.h" 10 #include "lm_l5if.h" 11 #include "mm_l5if.h" 12 #include "mm_l4if.h" 13 #include "mm.h" 14 15 16 17 u32_t lm_get_pbl_entries( 18 IN u32_t bufferSize 19 ) 20 { 21 return CEIL_DIV(bufferSize, LM_PAGE_SIZE); 22 } 23 24 25 26 lm_status_t lm_alloc_pbl_mem( 27 IN struct _lm_device_t *pdev, 28 IN u32_t pbl_entries, 29 OUT lm_address_t** pbl_virt, 30 OUT lm_address_t *pbl_phy, 31 OUT void** pbl_virt_table, 32 IN u8_t rt_mem, 33 OUT u32_t *pbl_size, 34 IN u8_t mm_cli_idx 35 ) 36 { 37 38 if (CHK_NULL(pdev) || (pbl_entries == 0) || 39 CHK_NULL(pbl_virt) || CHK_NULL(pbl_phy) || 40 CHK_NULL(pbl_size)) 41 { 42 /* allocPblMem - illegal pblSize */ 43 return LM_STATUS_INVALID_PARAMETER; 44 } 45 46 *pbl_size = pbl_entries * sizeof(lm_address_t); 47 48 if (rt_mem) 49 { 50 *pbl_virt = (lm_address_t *)mm_rt_alloc_phys_mem(pdev, 51 *pbl_size, 52 pbl_phy, 53 0, 54 mm_cli_idx); 55 if CHK_NULL(*pbl_virt) 56 { 57 *pbl_size = 0; 58 59 return LM_STATUS_RESOURCE; 60 } 61 62 *pbl_virt_table = (void *)mm_rt_alloc_mem(pdev, 63 pbl_entries * sizeof(void *), 64 mm_cli_idx); 65 66 if CHK_NULL(*pbl_virt_table) 67 { 68 *pbl_size = 0; 69 mm_rt_free_phys_mem(pdev, *pbl_size, *pbl_virt, *pbl_phy, mm_cli_idx); 70 *pbl_virt = NULL; 71 72 return LM_STATUS_RESOURCE; 73 } 74 } 75 else 76 { 77 *pbl_virt = (lm_address_t *)mm_alloc_phys_mem_align(pdev, 78 *pbl_size, 79 pbl_phy, 80 LM_PAGE_SIZE, 81 0, 82 mm_cli_idx); 83 if CHK_NULL(*pbl_virt) 84 { 85 *pbl_size = 0; 86 87 return LM_STATUS_RESOURCE; 88 } 89 90 *pbl_virt_table = (void *)mm_alloc_mem(pdev, 91 pbl_entries * sizeof(void *), 92 mm_cli_idx); 93 94 if CHK_NULL(*pbl_virt_table) 95 { 96 *pbl_size = 0; 97 *pbl_virt = NULL; 98 99 return LM_STATUS_RESOURCE; 100 } 101 } 102 103 return LM_STATUS_SUCCESS; 104 } 105 106 107 108 lm_status_t lm_create_pbl( 109 IN struct _lm_device_t *pdev, 110 IN void* buf_base_virt, 111 IN lm_address_t* buf_base_phy, 112 IN u32_t buffer_size, 113 OUT lm_address_t** pbl_virt, 114 OUT lm_address_t* pbl_phy, 115 OUT void** pbl_virt_table, 116 OUT u32_t *pbl_entries, 117 OUT u32_t *pbl_size, 118 IN u8_t rt_mem, 119 IN u8_t mm_cli_idx) 120 { 121 lm_status_t lm_status; 122 123 if (CHK_NULL(pdev) || CHK_NULL(buf_base_virt) || 124 CHK_NULL(buf_base_phy) || CHK_NULL(pbl_virt) || 125 CHK_NULL(pbl_phy) || CHK_NULL(pbl_virt_table) || 126 CHK_NULL(pbl_entries) || CHK_NULL(pbl_size)) 127 { 128 return LM_STATUS_INVALID_PARAMETER; 129 } 130 131 *pbl_entries = lm_get_pbl_entries(buffer_size); 132 133 lm_status = lm_alloc_pbl_mem(pdev, *pbl_entries, pbl_virt, pbl_phy, pbl_virt_table, rt_mem, pbl_size, mm_cli_idx); 134 if (lm_status != LM_STATUS_SUCCESS) 135 { 136 *pbl_entries = 0; 137 138 return lm_status; 139 } 140 141 lm_status = lm_bd_chain_pbl_set_ptrs(buf_base_virt, *buf_base_phy, *pbl_virt, *pbl_virt_table, *pbl_entries); 142 if (lm_status != LM_STATUS_SUCCESS) 143 { 144 if (rt_mem) 145 { 146 mm_rt_free_phys_mem(pdev, *pbl_size, *pbl_virt, *pbl_phy, mm_cli_idx); 147 mm_rt_free_mem(pdev, *pbl_virt_table, *pbl_entries * sizeof(void *), mm_cli_idx); 148 } 149 150 *pbl_entries = 0; 151 *pbl_size = 0; 152 153 return lm_status; 154 } 155 156 return LM_STATUS_SUCCESS; 157 } 158 159 160 161 lm_status_t 162 lm_l5_alloc_eq( 163 IN struct _lm_device_t *pdev, 164 IN lm_eq_chain_t *eq_chain, 165 IN lm_eq_addr_t *eq_addr_save, 166 IN u16_t page_cnt, 167 IN u8_t cli_idx) 168 { 169 u32_t mem_size = 0; 170 171 /* check arguments */ 172 if ((CHK_NULL(pdev) || CHK_NULL(eq_chain) || !page_cnt) || 173 (LM_CLI_IDX_FCOE != cli_idx) && (LM_CLI_IDX_ISCSI != cli_idx)) 174 { 175 return LM_STATUS_FAILURE; 176 } 177 178 DbgMessage(pdev, INFORMi | INFORMl5sp, "#lm_alloc_eq, eq_chain=%p, page_cnt=%d\n", eq_chain, page_cnt); 179 180 /* alloc the chain */ 181 mem_size = page_cnt * LM_PAGE_SIZE; 182 183 if(!eq_addr_save->b_allocated) 184 { 185 eq_chain->bd_chain.bd_chain_virt = mm_alloc_phys_mem(pdev, 186 mem_size, 187 &eq_chain->bd_chain.bd_chain_phy, 188 0, 189 cli_idx); 190 191 if (ERR_IF(!eq_chain->bd_chain.bd_chain_virt)) 192 { 193 DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE)); 194 return LM_STATUS_RESOURCE; 195 } 196 197 eq_addr_save->bd_chain_virt = eq_chain->bd_chain.bd_chain_virt ; 198 eq_addr_save->bd_chain_phy.as_u64 = eq_chain->bd_chain.bd_chain_phy.as_u64; 199 eq_addr_save->b_allocated = TRUE; 200 // For debugging 201 eq_addr_save->prev_mem_size = mem_size; 202 } 203 else 204 { 205 DbgBreakIf(mem_size != eq_addr_save->prev_mem_size); 206 eq_chain->bd_chain.bd_chain_virt = eq_addr_save->bd_chain_virt; 207 eq_chain->bd_chain.bd_chain_phy.as_u64 = eq_addr_save->bd_chain_phy.as_u64; 208 } 209 mm_memset(eq_chain->bd_chain.bd_chain_virt, 0, mem_size); 210 211 eq_chain->bd_chain.page_cnt = page_cnt; 212 213 214 return LM_STATUS_SUCCESS; 215 } /* lm_alloc_eq */ 216 217 218 219 lm_status_t 220 lm_sc_setup_eq( 221 IN struct _lm_device_t *pdev, 222 IN u32_t idx, 223 IN const u8_t is_chain_mode) 224 { 225 lm_bd_chain_t * bd_chain; 226 u16_t volatile * sb_indexes; 227 228 /* check arguments */ 229 if(CHK_NULL(pdev) || ERR_IF((ARRSIZE(pdev->iscsi_info.run_time.eq_chain) <= idx))) 230 { 231 return LM_STATUS_INVALID_PARAMETER; 232 } 233 234 DbgMessage(pdev, INFORMi|INFORMl5sp, "#lm_sc_setup_eq, idx=%d\n",idx); 235 236 bd_chain = &LM_SC_EQ(pdev, idx).bd_chain; 237 lm_bd_chain_setup(pdev, bd_chain, bd_chain->bd_chain_virt, 238 bd_chain->bd_chain_phy, (u16_t)bd_chain->page_cnt, sizeof(struct iscsi_kcqe), 1/*0*/, is_chain_mode); 239 240 /* verify that EQ size is not too large */ 241 if(bd_chain->capacity > MAX_EQ_SIZE_ISCSI(is_chain_mode)) 242 { 243 DbgBreakIf(bd_chain->capacity > MAX_EQ_SIZE_ISCSI(is_chain_mode)); 244 return LM_STATUS_FAILURE; 245 } 246 247 DbgMessage(pdev, INFORMi, "is eq %d, bd_chain %p, bd_left %d\n", 248 idx, 249 bd_chain->next_bd, 250 bd_chain->bd_left); 251 DbgMessage(pdev, INFORMi, " bd_chain_phy 0x%x%08x\n", 252 bd_chain->bd_chain_phy.as_u32.high, 253 bd_chain->bd_chain_phy.as_u32.low); 254 255 // Assign the EQ chain consumer pointer to the consumer index in the status block. 256 if( idx >= ARRSIZE(pdev->vars.status_blocks_arr) ) 257 { 258 DbgBreakIf( idx >= ARRSIZE(pdev->vars.status_blocks_arr) ); 259 return LM_STATUS_FAILURE; 260 } 261 262 sb_indexes = lm_get_sb_indexes(pdev, (u8_t)idx); 263 sb_indexes[HC_INDEX_ISCSI_EQ_CONS] = 0; 264 LM_SC_EQ(pdev, idx).hw_con_idx_ptr = sb_indexes + HC_INDEX_ISCSI_EQ_CONS; 265 /* 266 if (IS_E2(pdev)) { 267 pdev->vars.status_blocks_arr[idx].host_hc_status_block.e2_sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS] = 0; 268 LM_SC_EQ(pdev, idx).hw_con_idx_ptr = 269 &(pdev->vars.status_blocks_arr[idx].host_hc_status_block.e2_sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]); 270 } else { 271 pdev->vars.status_blocks_arr[idx].host_hc_status_block.e1x_sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS] = 0; 272 LM_SC_EQ(pdev, idx).hw_con_idx_ptr = 273 &(pdev->vars.status_blocks_arr[idx].host_hc_status_block.e1x_sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]); 274 } 275 */ 276 LM_SC_EQ(pdev, idx).hc_sb_info.hc_sb = STATUS_BLOCK_NORMAL_TYPE; //STATUS_BLOCK_CSTORM_TYPE; 277 LM_SC_EQ(pdev, idx).hc_sb_info.hc_index_value = HC_INDEX_ISCSI_EQ_CONS; 278 279 return LM_STATUS_SUCCESS; 280 } /* lm_sc_setup_eq */ 281 /** 282 * 283 * @description 284 * Allocate EQ PBL to pass to FW in init ramrod 285 * @param pdev 286 * @param eq_chain 287 * @param pbl 288 * @param eq_addr_save 289 * 290 * @return lm_status_t 291 */ 292 lm_status_t 293 lm_fc_alloc_eq_pbl( 294 IN struct _lm_device_t *pdev, 295 IN lm_eq_chain_t *eq_chain, 296 IN lm_fcoe_pbl_t *pbl, 297 IN lm_eq_addr_t *eq_addr_save) 298 { 299 lm_status_t lm_status = LM_STATUS_SUCCESS; 300 301 /* check arguments */ 302 if(CHK_NULL(pdev)) 303 { 304 return LM_STATUS_INVALID_PARAMETER; 305 } 306 307 DbgMessage(pdev, INFORMi|INFORMl5sp, "#lm_fc_alloc_eq_pbl\n"); 308 309 // For D3 case 310 if(FALSE == pbl->allocated) 311 { 312 lm_status = lm_create_pbl(pdev, 313 eq_chain->bd_chain.bd_chain_virt, 314 &(eq_chain->bd_chain.bd_chain_phy), 315 eq_addr_save->prev_mem_size, 316 &pbl->pbl_phys_table_virt, 317 &pbl->pbl_phys_table_phys, 318 &pbl->pbl_virt_table, 319 &pbl->pbl_entries, 320 &pbl->pbl_size, 321 FALSE, 322 LM_CLI_IDX_FCOE); 323 324 if (lm_status != LM_STATUS_SUCCESS) 325 { 326 mm_mem_zero(&(pbl) ,sizeof(lm_fcoe_pbl_t)); 327 return LM_STATUS_FAILURE; 328 } 329 pbl->allocated = TRUE; 330 } 331 return lm_status; 332 } 333 334 lm_status_t 335 lm_fc_setup_eq( 336 IN struct _lm_device_t *pdev, 337 IN u32_t idx, 338 IN const u8_t is_chain_mode) 339 { 340 lm_bd_chain_t * bd_chain; 341 lm_fcoe_pbl_t * pbl; 342 u16_t volatile * sb_indexes; 343 344 /* check arguments */ 345 if(CHK_NULL(pdev) || ERR_IF((ARRSIZE(pdev->fcoe_info.run_time.eq_chain) <= idx))) 346 { 347 return LM_STATUS_INVALID_PARAMETER; 348 } 349 350 DbgMessage(pdev, INFORMi|INFORMl5sp, "#lm_fc_setup_eq, idx=%d\n",idx); 351 352 bd_chain = &LM_FC_EQ(pdev, idx).bd_chain; 353 pbl = &LM_FC_PBL(pdev, idx); 354 lm_bd_chain_pbl_setup(pdev, bd_chain, bd_chain->bd_chain_virt, 355 bd_chain->bd_chain_phy, pbl->pbl_virt_table, pbl->pbl_phys_table_virt, 356 (u16_t)bd_chain->page_cnt, sizeof(struct fcoe_kcqe), 357 1/*0*/); /* EQ is considered full of blank entries */ 358 359 /* verify that EQ size is not too large */ 360 if (bd_chain->capacity > MAX_EQ_SIZE_FCOE(is_chain_mode)) 361 { 362 DbgBreakIf(bd_chain->capacity > MAX_EQ_SIZE_FCOE(is_chain_mode)); 363 return LM_STATUS_FAILURE; 364 } 365 366 DbgMessage(pdev, INFORMi, "fc eq %d, bd_chain %p, bd_left %d\n", 367 idx, 368 bd_chain->next_bd, 369 bd_chain->bd_left); 370 DbgMessage(pdev, INFORMi, " bd_chain_phy 0x%x%08x\n", 371 bd_chain->bd_chain_phy.as_u32.high, 372 bd_chain->bd_chain_phy.as_u32.low); 373 374 // Assign the EQ chain consumer pointer to the consumer index in the status block. 375 if (idx >= ARRSIZE(pdev->vars.status_blocks_arr)) 376 { 377 DbgBreakIf( idx >= ARRSIZE(pdev->vars.status_blocks_arr) ); 378 return LM_STATUS_FAILURE; 379 } 380 381 sb_indexes = lm_get_sb_indexes(pdev, (u8_t)idx); 382 sb_indexes[HC_INDEX_FCOE_EQ_CONS] = 0; 383 LM_FC_EQ(pdev, idx).hw_con_idx_ptr = sb_indexes + HC_INDEX_FCOE_EQ_CONS; 384 /* 385 if (IS_E2(pdev)) { 386 pdev->vars.status_blocks_arr[idx].host_hc_status_block.e2_sb->sb.index_values[HC_INDEX_FCOE_EQ_CONS] = 0; 387 LM_FC_EQ(pdev, idx).hw_con_idx_ptr = 388 &(pdev->vars.status_blocks_arr[idx].host_hc_status_block.e2_sb->sb.index_values[HC_INDEX_FCOE_EQ_CONS]); 389 } else { 390 pdev->vars.status_blocks_arr[idx].host_hc_status_block.e1x_sb->sb.index_values[HC_INDEX_FCOE_EQ_CONS] = 0; 391 LM_FC_EQ(pdev, idx).hw_con_idx_ptr = 392 &(pdev->vars.status_blocks_arr[idx].host_hc_status_block.e1x_sb->sb.index_values[HC_INDEX_FCOE_EQ_CONS]); 393 } 394 */ 395 LM_FC_EQ(pdev, idx).hc_sb_info.hc_sb = STATUS_BLOCK_NORMAL_SL_TYPE; //STATUS_BLOCK_USTORM_TYPE; 396 LM_FC_EQ(pdev, idx).hc_sb_info.hc_index_value = HC_INDEX_FCOE_EQ_CONS; 397 398 return LM_STATUS_SUCCESS; 399 } /* lm_fc_setup_eq */ 400 401 402 403 404 /** Description 405 * Callback function for cids being recylced 406 */ 407 void lm_sc_recycle_cid_cb( 408 struct _lm_device_t *pdev, 409 void *cookie, 410 s32_t cid) 411 { 412 lm_status_t lm_status; 413 lm_sp_req_common_t * sp_req = NULL; 414 lm_iscsi_state_t * iscsi = (lm_iscsi_state_t *)cookie; 415 416 if (CHK_NULL(pdev) || CHK_NULL(iscsi)) 417 { 418 DbgBreakIf(1); 419 return; 420 } 421 422 MM_ACQUIRE_TOE_LOCK(pdev); 423 424 /* un-block the manager... */ 425 lm_set_cid_state(pdev, iscsi->cid, LM_CID_STATE_VALID); 426 427 if (iscsi->hdr.status == STATE_STATUS_INIT_CONTEXT) 428 { 429 lm_status = lm_sc_init_iscsi_context(pdev, 430 iscsi, 431 &iscsi->pending_ofld1, 432 &iscsi->pending_ofld2, 433 &iscsi->pending_ofld3); 434 435 mm_sc_complete_offload_request(pdev, iscsi, lm_status); 436 } 437 438 /* we can now unblock any pending slow-paths */ 439 lm_sp_req_manager_unblock(pdev, cid, &sp_req); 440 441 MM_RELEASE_TOE_LOCK(pdev); 442 } 443 444 445 void lm_sc_comp_cb(struct _lm_device_t *pdev, struct sq_pending_command *pending) 446 { 447 struct iscsi_kcqe kcqe = {0}; 448 lm_iscsi_state_t *iscsi = NULL; 449 u32_t cid; 450 u8_t cmd; 451 452 453 if (CHK_NULL(pdev) || CHK_NULL(pending)) 454 { 455 return; 456 } 457 458 cmd = pending->cmd; 459 cid = pending->cid; 460 461 iscsi = lm_cid_cookie(pdev, ISCSI_CONNECTION_TYPE, cid); 462 463 if (iscsi) 464 { 465 kcqe.iscsi_conn_id = iscsi->iscsi_conn_id; 466 kcqe.iscsi_conn_context_id = HW_CID(pdev, cid); 467 } 468 469 kcqe.completion_status = LM_STATUS_SUCCESS; /* TODO_ER: Fixme: do we want this?? maybe ok since l5 is aware of er... */ 470 471 kcqe.op_code = cmd; /* In iSCSI they are the same */ 472 473 kcqe.flags |= (ISCSI_KWQE_LAYER_CODE << ISCSI_KWQE_HEADER_LAYER_CODE_SHIFT); 474 475 lm_sc_complete_slow_path_request(pdev, &kcqe); 476 } 477 478 lm_status_t 479 lm_sc_alloc_resc( 480 IN struct _lm_device_t *pdev 481 ) 482 { 483 u8_t mm_cli_idx = LM_RESOURCE_ISCSI; 484 u8_t *chk_buf = NULL; 485 u16_t i = 0; 486 487 if CHK_NULL(pdev) 488 { 489 return LM_STATUS_INVALID_PARAMETER; 490 } 491 492 mm_mem_zero(&pdev->iscsi_info, sizeof(lm_iscsi_info_t)); 493 494 /* Allocate global buffer */ 495 pdev->iscsi_info.bind.global_buff_base_virt = (u8_t*)mm_alloc_phys_mem(pdev, 496 ISCSI_GLOBAL_BUF_SIZE, 497 &pdev->iscsi_info.bind.global_buff_base_phy, 498 0, 499 mm_cli_idx); 500 if CHK_NULL(pdev->iscsi_info.bind.global_buff_base_virt) 501 { 502 return LM_STATUS_RESOURCE; 503 } 504 505 /* cid recycled cb registration */ 506 lm_cid_recycled_cb_register(pdev, ISCSI_CONNECTION_TYPE, lm_sc_recycle_cid_cb); 507 508 /* Sq-completion cb registration (sq that get completed internally in driver */ 509 lm_sq_comp_cb_register(pdev, ISCSI_CONNECTION_TYPE, lm_sc_comp_cb); 510 511 chk_buf = (u8_t *)(&(pdev->iscsi_info.eq_addr_save)); 512 // Except global_buff and pdev->iscsi_info all other fileds should be zero 513 for(i = 0 ;i < sizeof(pdev->iscsi_info.eq_addr_save) ;i++) 514 { 515 DbgBreakIf(0 != chk_buf[i]); 516 } 517 518 chk_buf = (u8_t *)(&(pdev->iscsi_info.run_time)); 519 // Except global_buff and pdev->iscsi_info all other fileds should be zero 520 for(i = 0 ;i < sizeof(pdev->iscsi_info.run_time) ;i++) 521 { 522 DbgBreakIf(0 != chk_buf[i]); 523 } 524 return LM_STATUS_SUCCESS; 525 } /* lm_sc_alloc_resc */ 526 527 /******************************************************************************* 528 * Description: 529 * 530 * Return: 531 ******************************************************************************/ 532 u16_t 533 lm_l5_eq_page_cnt( 534 IN struct _lm_device_t *pdev, 535 const u32_t max_func_cons, 536 const u16_t reserved_eq_elements, 537 const u16_t eqes_per_page, 538 const u16_t max_eq_pages 539 ) 540 { 541 u16_t eq_page_cnt = 0; 542 u16_t min_eq_size = 0; 543 544 /* Init EQs - create page chains */ 545 min_eq_size = (u16_t)(max_func_cons + reserved_eq_elements); 546 eq_page_cnt = CEIL_DIV(min_eq_size, (eqes_per_page)); 547 eq_page_cnt = min(eq_page_cnt, max_eq_pages); 548 549 return eq_page_cnt; 550 } 551 552 /******************************************************************************* 553 * Description: 554 * 555 * Return: 556 ******************************************************************************/ 557 lm_status_t 558 lm_fc_free_init_resc( 559 IN struct _lm_device_t *pdev 560 ) 561 { 562 lm_status_t lm_status = LM_STATUS_SUCCESS; 563 u16_t eq_sb_idx = 0; 564 u16_t eq_page_cnt = 0; 565 566 if (CHK_NULL(pdev)) 567 { 568 DbgBreakMsg("lm_fc_free_init_resc failed"); 569 return LM_STATUS_INVALID_PARAMETER; 570 } 571 572 mm_memset(&(pdev->fcoe_info.run_time), 0, sizeof(pdev->fcoe_info.run_time)); 573 return lm_status; 574 } 575 576 577 lm_status_t 578 lm_fc_clear_d0_resc( 579 IN struct _lm_device_t *pdev, 580 const u8_t cid 581 ) 582 { 583 lm_status_t lm_status = LM_STATUS_SUCCESS; 584 u8_t eq_idx = 0; 585 586 if CHK_NULL(pdev) 587 { 588 return LM_STATUS_INVALID_PARAMETER; 589 } 590 591 LM_FC_FOREACH_EQ_IDX(pdev, eq_idx) 592 { 593 lm_clear_chain_sb_cons_idx(pdev, eq_idx, &LM_FC_EQ(pdev, eq_idx).hc_sb_info, &LM_FC_EQ(pdev, eq_idx).hw_con_idx_ptr); 594 } 595 596 lm_status = lm_fc_free_init_resc(pdev); 597 598 return lm_status; 599 } /* lm_fc_clear_d0_resc */ 600 601 lm_status_t 602 lm_fc_clear_resc( 603 IN struct _lm_device_t *pdev 604 ) 605 { 606 lm_status_t lm_status = LM_STATUS_SUCCESS; 607 const u8_t cid = FCOE_CID(pdev); 608 609 if CHK_NULL(pdev) 610 { 611 return LM_STATUS_INVALID_PARAMETER; 612 } 613 614 lm_fc_clear_d0_resc( 615 pdev, 616 cid); 617 s_list_init(&LM_RXQ(pdev, cid).active_descq, NULL, NULL, 0); 618 s_list_init(&LM_RXQ(pdev, cid).common.free_descq, NULL, NULL, 0); 619 620 return lm_status; 621 } /* lm_fc_clear_resc */ 622 623 624 /******************************************************************************* 625 * Description: 626 * 627 * Return: 628 ******************************************************************************/ 629 lm_status_t 630 lm_sc_free_init_resc( 631 IN struct _lm_device_t *pdev 632 ) 633 { 634 lm_status_t lm_status = LM_STATUS_SUCCESS; 635 u16_t eq_sb_idx = 0; 636 u16_t eq_page_cnt = 0; 637 638 if (CHK_NULL(pdev)) 639 { 640 DbgBreakMsg("lm_sc_free_init_resc failed"); 641 return LM_STATUS_INVALID_PARAMETER; 642 } 643 644 mm_memset(&(pdev->iscsi_info.run_time), 0, sizeof(pdev->iscsi_info.run_time)); 645 return lm_status; 646 } 647 648 649 lm_status_t 650 lm_sc_clear_d0_resc( 651 IN struct _lm_device_t *pdev, 652 const u8_t cid 653 ) 654 { 655 lm_status_t lm_status = LM_STATUS_SUCCESS; 656 u8_t eq_idx = 0; 657 658 if CHK_NULL(pdev) 659 { 660 return LM_STATUS_INVALID_PARAMETER; 661 } 662 663 LM_SC_FOREACH_EQ_IDX(pdev, eq_idx) 664 { 665 lm_clear_chain_sb_cons_idx(pdev, eq_idx, &LM_SC_EQ(pdev, eq_idx).hc_sb_info, &LM_SC_EQ(pdev, eq_idx).hw_con_idx_ptr); 666 } 667 668 lm_status = lm_sc_free_init_resc(pdev); 669 670 return lm_status; 671 } /* lm_sc_clear_d0_resc */ 672 673 lm_status_t 674 lm_sc_clear_resc( 675 IN struct _lm_device_t *pdev 676 ) 677 { 678 lm_status_t lm_status = LM_STATUS_SUCCESS; 679 const u8_t cid = ISCSI_CID(pdev); 680 681 if CHK_NULL(pdev) 682 { 683 return LM_STATUS_INVALID_PARAMETER; 684 } 685 686 lm_sc_clear_d0_resc( 687 pdev, 688 cid); 689 s_list_init(&LM_RXQ(pdev, cid).active_descq, NULL, NULL, 0); 690 s_list_init(&LM_RXQ(pdev, cid).common.free_descq, NULL, NULL, 0); 691 692 return lm_status; 693 } /* lm_sc_clear_resc */ 694 695 696 697 lm_status_t 698 lm_sc_ooo_chain_establish( 699 IN struct _lm_device_t *pdev) 700 { 701 lm_status_t lm_status = LM_STATUS_SUCCESS; 702 const u32_t func = FUNC_ID(pdev); 703 704 if CHK_NULL(pdev) 705 { 706 lm_status = LM_STATUS_INVALID_PARAMETER; 707 return lm_status; 708 } 709 LM_INTMEM_WRITE32(pdev, 710 TSTORM_ISCSI_L2_ISCSI_OOO_CONS_OFFSET(func), 711 0, 712 BAR_TSTRORM_INTMEM); 713 714 LM_INTMEM_WRITE32(pdev, 715 TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(func), 716 HW_CID(pdev, OOO_CID(pdev)), 717 BAR_TSTRORM_INTMEM); 718 719 LM_INTMEM_WRITE32(pdev, 720 TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(func), 721 LM_FW_CLI_ID(pdev,OOO_CID(pdev)), 722 BAR_TSTRORM_INTMEM); 723 724 725 return lm_status; 726 } 727 728 729 /******************************************************************************* 730 * Description: 731 * 732 * Return: 733 ******************************************************************************/ 734 lm_status_t 735 lm_sc_init( 736 IN struct _lm_device_t *pdev, 737 IN struct iscsi_kwqe_init1 *req1, 738 IN struct iscsi_kwqe_init2 *req2 739 ) 740 { 741 lm_status_t lm_status; 742 u16_t eq_page_cnt; 743 u32_t hq_size_in_bytes; 744 u32_t hq_pbl_entries; 745 u32_t eq_idx; 746 u16_t eq_sb_idx; 747 u32_t page_size_bits; 748 u8_t delayed_ack_en = 0; 749 const u8_t is_chain_mode = TRUE; 750 const u32_t func = FUNC_ID(pdev); 751 struct tstorm_l5cm_tcp_flags tstorm_l5cm_tcp_flags_param = {0}; 752 753 if (CHK_NULL(req1) || CHK_NULL(req2)) 754 { 755 return LM_STATUS_FAILURE; 756 } 757 758 DbgMessage(pdev, INFORM, "### lm_sc_init\n"); 759 760 page_size_bits = GET_FIELD(req1->flags, ISCSI_KWQE_INIT1_PAGE_SIZE); 761 if (LM_PAGE_BITS - ISCSI_PAGE_BITS_SHIFT != page_size_bits) 762 { 763 DbgMessage(pdev, INFORM, "lm_sc_init: Illegal page size.\n"); 764 return LM_STATUS_FAILURE; 765 } 766 767 if(ISCSI_HSI_VERSION != req1->hsi_version) 768 { 769 return LM_STATUS_INVALID_PARAMETER; 770 } 771 772 delayed_ack_en = GET_FIELD(req1->flags, ISCSI_KWQE_INIT1_DELAYED_ACK_ENABLE); 773 774 pdev->iscsi_info.run_time.num_of_tasks = req1->num_tasks_per_conn; 775 pdev->iscsi_info.run_time.cq_size = req1->cq_num_wqes; 776 pdev->iscsi_info.run_time.num_of_cqs = req1->num_cqs; 777 778 /* the number of cqs is used to determine the number of eqs */ 779 if (pdev->iscsi_info.run_time.num_of_cqs > MAX_EQ_CHAIN) 780 { 781 DbgBreakIf(pdev->iscsi_info.run_time.num_of_cqs > MAX_EQ_CHAIN); 782 pdev->iscsi_info.run_time.num_of_cqs = MAX_EQ_CHAIN; 783 } 784 pdev->iscsi_info.run_time.l5_eq_chain_cnt = pdev->iscsi_info.run_time.num_of_cqs; 785 pdev->iscsi_info.run_time.l5_eq_max_chain_cnt = MAX_EQ_CHAIN; 786 // Only one EQ chain is supported. 787 788 if ((pdev->iscsi_info.run_time.l5_eq_chain_cnt > 1)|| 789 (pdev->params.sb_cnt < pdev->iscsi_info.run_time.l5_eq_chain_cnt)) 790 { 791 DbgMessage(pdev, INFORM, "lm_sc_init: l5_eq_chain_cnt=%d\n.\n",pdev->iscsi_info.run_time.l5_eq_chain_cnt); 792 DbgBreakMsg("lm_sc_init: pdev->iscsi_info.l5_eq_chain_cnt is bigger than 1.\n"); 793 return LM_STATUS_FAILURE; 794 } 795 DbgBreakIf(pdev->iscsi_info.run_time.l5_eq_chain_cnt > 1); 796 DbgBreakIf(pdev->params.sb_cnt < pdev->iscsi_info.run_time.l5_eq_chain_cnt); 797 /* TOE when RSS is disabled, ISCSI and FCOE will use the same NDSB. */ 798 pdev->iscsi_info.run_time.l5_eq_base_chain_idx = LM_NON_RSS_SB(pdev); 799 800 // if (!pdev->params.l4_enable_rss) { 801 // RESET_FLAGS(pdev->params.sb_cpu_affinity, 1 << LM_TOE_RSS_BASE_CHAIN_INDEX(&pdev->lmdev)); 802 // } 803 804 805 /* round up HQ size to fill an entire page */ 806 hq_size_in_bytes = req1->num_ccells_per_conn * sizeof(struct iscsi_hq_bd); 807 hq_pbl_entries = lm_get_pbl_entries(hq_size_in_bytes); 808 pdev->iscsi_info.run_time.hq_size = (u16_t)(hq_pbl_entries * (LM_PAGE_SIZE / sizeof(struct iscsi_hq_bd))); 809 810 /* Init EQs - create page chains */ 811 // The size of the EQ in iSCSI is <num iscsi connections> * 2 +slowpath. 812 // I.e. for each connection there should be room for 1 fastpath completion and 1 error notification. 813 eq_page_cnt = lm_l5_eq_page_cnt(pdev, 814 (u16_t)(pdev->params.max_func_iscsi_cons * 2), 815 RESERVED_ISCSI_EQ_ELEMENTS, 816 (ISCSI_EQES_PER_PAGE(is_chain_mode)), 817 MAX_EQ_PAGES);// Sub the next BD page. 818 819 LM_SC_FOREACH_EQ_IDX(pdev, eq_sb_idx) 820 { 821 lm_status = lm_l5_alloc_eq(pdev, &LM_SC_EQ(pdev, eq_sb_idx), &LM_EQ_ADDR_SAVE_SC(pdev, eq_sb_idx) , eq_page_cnt, LM_CLI_IDX_ISCSI); 822 if (lm_status != LM_STATUS_SUCCESS) 823 { 824 return lm_status; 825 } 826 827 lm_status = lm_sc_setup_eq(pdev, eq_sb_idx,is_chain_mode); 828 if (lm_status != LM_STATUS_SUCCESS) 829 { 830 return lm_status; 831 } 832 } 833 834 SET_FLAGS( tstorm_l5cm_tcp_flags_param.flags, delayed_ack_en << TSTORM_L5CM_TCP_FLAGS_DELAYED_ACK_EN_SHIFT); 835 836 // in case size change, we need to change LM_INTMEM_WRITEXX macro etc... 837 ASSERT_STATIC( sizeof(tstorm_l5cm_tcp_flags_param) == sizeof(u16_t) ); 838 839 /* Init internal RAM */ 840 ASSERT_STATIC(sizeof(struct regpair_t) == sizeof(lm_address_t)); 841 842 /* init Tstorm RAM */ 843 LM_INTMEM_WRITE16(pdev, TSTORM_ISCSI_RQ_SIZE_OFFSET(func), req1->rq_num_wqes, BAR_TSTRORM_INTMEM); 844 LM_INTMEM_WRITE16(pdev, TSTORM_ISCSI_PAGE_SIZE_OFFSET(func), LM_PAGE_SIZE, BAR_TSTRORM_INTMEM); 845 LM_INTMEM_WRITE8 (pdev, TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), LM_PAGE_BITS, BAR_TSTRORM_INTMEM); 846 LM_INTMEM_WRITE32(pdev, TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(func), 0x100000, BAR_TSTRORM_INTMEM); 847 LM_INTMEM_WRITE16(pdev, TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), req1->num_tasks_per_conn, BAR_TSTRORM_INTMEM); 848 LM_INTMEM_WRITE64(pdev, TSTORM_ISCSI_ERROR_BITMAP_OFFSET(func), *((u64_t *)&req2->error_bit_map), BAR_TSTRORM_INTMEM); 849 LM_INTMEM_WRITE16(pdev, TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(func), tstorm_l5cm_tcp_flags_param.flags, BAR_TSTRORM_INTMEM); 850 851 /* init Ustorm RAM */ 852 LM_INTMEM_WRITE16(pdev, USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(func), req1->rq_buffer_size, BAR_USTRORM_INTMEM); 853 LM_INTMEM_WRITE16(pdev, USTORM_ISCSI_PAGE_SIZE_OFFSET(func), LM_PAGE_SIZE, BAR_USTRORM_INTMEM); 854 LM_INTMEM_WRITE8 (pdev, USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), LM_PAGE_BITS, BAR_USTRORM_INTMEM); 855 LM_INTMEM_WRITE16(pdev, USTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), req1->num_tasks_per_conn, BAR_USTRORM_INTMEM); 856 LM_INTMEM_WRITE16(pdev, USTORM_ISCSI_RQ_SIZE_OFFSET(func), req1->rq_num_wqes, BAR_USTRORM_INTMEM); 857 LM_INTMEM_WRITE16(pdev, USTORM_ISCSI_CQ_SIZE_OFFSET(func), req1->cq_num_wqes, BAR_USTRORM_INTMEM); 858 LM_INTMEM_WRITE16(pdev, USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn, BAR_USTRORM_INTMEM); 859 LM_INTMEM_WRITE16(pdev, USTORM_ISCSI_R2TQ_SIZE_OFFSET(func), (u16_t)pdev->iscsi_info.run_time.num_of_tasks * ISCSI_MAX_NUM_OF_PENDING_R2TS, BAR_USTRORM_INTMEM); 860 LM_INTMEM_WRITE64(pdev, USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(func), pdev->iscsi_info.bind.global_buff_base_phy.as_u64, BAR_USTRORM_INTMEM); 861 LM_INTMEM_WRITE64(pdev, USTORM_ISCSI_ERROR_BITMAP_OFFSET(func), *((u64_t *)&req2->error_bit_map), BAR_USTRORM_INTMEM); 862 863 /* init Xstorm RAM */ 864 LM_INTMEM_WRITE16(pdev, XSTORM_ISCSI_PAGE_SIZE_OFFSET(func), LM_PAGE_SIZE, BAR_XSTRORM_INTMEM); 865 LM_INTMEM_WRITE8 (pdev, XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), LM_PAGE_BITS, BAR_XSTRORM_INTMEM); 866 LM_INTMEM_WRITE16(pdev, XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), req1->num_tasks_per_conn, BAR_XSTRORM_INTMEM); 867 LM_INTMEM_WRITE16(pdev, XSTORM_ISCSI_HQ_SIZE_OFFSET(func), pdev->iscsi_info.run_time.hq_size, BAR_XSTRORM_INTMEM); 868 LM_INTMEM_WRITE16(pdev, XSTORM_ISCSI_SQ_SIZE_OFFSET(func), req1->num_tasks_per_conn, BAR_XSTRORM_INTMEM); 869 LM_INTMEM_WRITE16(pdev, XSTORM_ISCSI_R2TQ_SIZE_OFFSET(func), req1->num_tasks_per_conn * ISCSI_MAX_NUM_OF_PENDING_R2TS, BAR_XSTRORM_INTMEM); 870 871 /* init Cstorm RAM */ 872 LM_INTMEM_WRITE16(pdev, CSTORM_ISCSI_PAGE_SIZE_OFFSET(func), LM_PAGE_SIZE, BAR_CSTRORM_INTMEM); 873 LM_INTMEM_WRITE8 (pdev, CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), LM_PAGE_BITS, BAR_CSTRORM_INTMEM); 874 LM_INTMEM_WRITE16(pdev, CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), req1->num_tasks_per_conn, BAR_CSTRORM_INTMEM); 875 LM_SC_FOREACH_EQ_IDX(pdev, eq_sb_idx) 876 { 877 eq_idx = eq_sb_idx - pdev->iscsi_info.run_time.l5_eq_base_chain_idx; 878 LM_INTMEM_WRITE16(pdev, CSTORM_ISCSI_EQ_PROD_OFFSET(func, eq_idx), lm_bd_chain_prod_idx(&LM_SC_EQ(pdev, eq_sb_idx).bd_chain), BAR_CSTRORM_INTMEM); 879 LM_INTMEM_WRITE16(pdev, CSTORM_ISCSI_EQ_CONS_OFFSET(func, eq_idx), 0 , BAR_CSTRORM_INTMEM); 880 LM_INTMEM_WRITE32(pdev, CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, eq_idx), lm_bd_chain_phys_addr(&LM_SC_EQ(pdev, eq_sb_idx).bd_chain, 1).as_u32.low, BAR_CSTRORM_INTMEM); 881 LM_INTMEM_WRITE32(pdev, 4 + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, eq_idx), lm_bd_chain_phys_addr(&LM_SC_EQ(pdev, eq_sb_idx).bd_chain, 1).as_u32.high, BAR_CSTRORM_INTMEM); 882 LM_INTMEM_WRITE32(pdev, CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, eq_idx), lm_bd_chain_phys_addr(&LM_SC_EQ(pdev, eq_sb_idx).bd_chain, 0).as_u32.low, BAR_CSTRORM_INTMEM); 883 LM_INTMEM_WRITE32(pdev, 4 + CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, eq_idx), lm_bd_chain_phys_addr(&LM_SC_EQ(pdev, eq_sb_idx).bd_chain, 0).as_u32.high, BAR_CSTRORM_INTMEM); 884 LM_INTMEM_WRITE8 (pdev, CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(func, eq_idx), 1, BAR_CSTRORM_INTMEM); // maybe move to init tool 885 LM_INTMEM_WRITE16(pdev, CSTORM_ISCSI_EQ_SB_NUM_OFFSET(func, eq_idx), LM_FW_SB_ID(pdev,eq_sb_idx), BAR_CSTRORM_INTMEM); 886 LM_INTMEM_WRITE8 (pdev, CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(func, eq_idx), HC_INDEX_ISCSI_EQ_CONS, BAR_CSTRORM_INTMEM); 887 } 888 LM_INTMEM_WRITE16(pdev, CSTORM_ISCSI_HQ_SIZE_OFFSET(func), pdev->iscsi_info.run_time.hq_size, BAR_CSTRORM_INTMEM); 889 LM_INTMEM_WRITE16(pdev, CSTORM_ISCSI_CQ_SIZE_OFFSET(func), req1->cq_num_wqes, BAR_CSTRORM_INTMEM); 890 LM_INTMEM_WRITE16(pdev, CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn, BAR_CSTRORM_INTMEM); 891 892 return LM_STATUS_SUCCESS; 893 } /* lm_sc_init */ 894 895 896 897 /* Get dma memory for init ramrod */ 898 STATIC lm_status_t 899 lm_fc_get_ramrod_phys_mem( 900 IN struct _lm_device_t *pdev) 901 { 902 903 if CHK_NULL(pdev->fcoe_info.bind.ramrod_mem_virt) 904 { 905 pdev->fcoe_info.bind.ramrod_mem_virt = 906 mm_alloc_phys_mem(pdev, 907 sizeof(lm_fcoe_slow_path_phys_data_t), 908 &pdev->fcoe_info.bind.ramrod_mem_phys, 909 0, 910 LM_CLI_IDX_FCOE); 911 912 if CHK_NULL(pdev->fcoe_info.bind.ramrod_mem_virt) 913 { 914 return LM_STATUS_RESOURCE; 915 } 916 } 917 return LM_STATUS_SUCCESS; 918 } 919 920 921 922 lm_status_t 923 lm_fc_init( 924 IN struct _lm_device_t *pdev, 925 IN struct fcoe_kwqe_init1 *init1, 926 IN struct fcoe_kwqe_init2 *init2, 927 IN struct fcoe_kwqe_init3 *init3) 928 { 929 lm_status_t lm_status; 930 lm_fcoe_slow_path_phys_data_t *ramrod_params; 931 u16_t eq_page_cnt; 932 u16_t eq_sb_idx; 933 u32_t func; 934 u32_t port; 935 const u8_t is_chain_mode = FALSE; 936 if (CHK_NULL(pdev) || CHK_NULL(init1) || CHK_NULL(init2) || CHK_NULL(init3)) 937 { 938 return LM_STATUS_INVALID_PARAMETER; 939 } 940 941 func = FUNC_ID(pdev); 942 port = PORT_ID(pdev); 943 944 DbgMessage(pdev, INFORM, "### lm_fc_init\n"); 945 946 pdev->fcoe_info.run_time.num_of_cqs = 1; // one EQ 947 948 // Only one EQ chain is supported. 949 if ((pdev->fcoe_info.run_time.num_of_cqs > 1)|| 950 (pdev->params.sb_cnt < pdev->fcoe_info.run_time.num_of_cqs)) 951 { 952 DbgMessage(pdev, INFORM, "lm_fc_init: num_of_cqs=%d\n.\n",pdev->fcoe_info.run_time.num_of_cqs); 953 DbgBreakMsg("lm_fc_init: pdev->fcoe_info.run_time.num_of_cqs is bigger than 1.\n"); 954 return LM_STATUS_INVALID_PARAMETER; 955 } 956 DbgBreakIf(pdev->fcoe_info.run_time.num_of_cqs > 1); 957 DbgBreakIf(pdev->params.sb_cnt < pdev->fcoe_info.run_time.num_of_cqs); 958 /* TOE when RSS is disabled, ISCSI and FCOE will use the same NDSB. */ 959 pdev->fcoe_info.run_time.fc_eq_base_chain_idx = LM_NON_RSS_SB(pdev); 960 961 if(CHK_NULL(pdev->fcoe_info.bind.ramrod_mem_virt)) 962 { 963 return LM_STATUS_RESOURCE; 964 } 965 ramrod_params = (lm_fcoe_slow_path_phys_data_t*)pdev->fcoe_info.bind.ramrod_mem_virt; 966 967 // Init EQs - create page chains 968 eq_page_cnt = lm_l5_eq_page_cnt(pdev, 969 (u16_t)pdev->params.max_func_fcoe_cons, 970 RESERVED_FCOE_EQ_ELEMENTS, 971 FCOE_EQES_PER_PAGE(is_chain_mode), 972 FCOE_MAX_EQ_PAGES_PER_FUNC); 973 974 975 LM_FC_FOREACH_EQ_IDX(pdev, eq_sb_idx) 976 { 977 lm_status = lm_l5_alloc_eq(pdev, &LM_FC_EQ(pdev, eq_sb_idx),&LM_EQ_ADDR_SAVE_FC(pdev, eq_sb_idx),eq_page_cnt, LM_CLI_IDX_FCOE); 978 if (lm_status != LM_STATUS_SUCCESS) 979 { 980 return lm_status; 981 } 982 983 lm_status = lm_fc_alloc_eq_pbl(pdev, &LM_FC_EQ(pdev, eq_sb_idx), &LM_FC_PBL(pdev, eq_sb_idx), 984 &LM_EQ_ADDR_SAVE_FC(pdev, eq_sb_idx)); 985 if (lm_status != LM_STATUS_SUCCESS) 986 { 987 return lm_status; 988 } 989 990 lm_status = lm_fc_setup_eq(pdev, eq_sb_idx,is_chain_mode); 991 if (lm_status != LM_STATUS_SUCCESS) 992 { 993 return lm_status; 994 } 995 } 996 997 /* Set up the ramrod params */ 998 mm_memset(ramrod_params, 0, sizeof(lm_fcoe_slow_path_phys_data_t)); 999 1000 memcpy(&ramrod_params->fcoe_init.init_kwqe1, init1, sizeof(struct fcoe_kwqe_init1)); 1001 memcpy(&ramrod_params->fcoe_init.init_kwqe2, init2, sizeof(struct fcoe_kwqe_init2)); 1002 memcpy(&ramrod_params->fcoe_init.init_kwqe3, init3, sizeof(struct fcoe_kwqe_init3)); 1003 1004 1005 /* waiting for new HSI */ 1006 ramrod_params->fcoe_init.eq_pbl_base.lo = mm_cpu_to_le32(LM_FC_PBL(pdev, pdev->fcoe_info.run_time.fc_eq_base_chain_idx).pbl_phys_table_phys.as_u32.low); 1007 ramrod_params->fcoe_init.eq_pbl_base.hi = mm_cpu_to_le32(LM_FC_PBL(pdev, pdev->fcoe_info.run_time.fc_eq_base_chain_idx).pbl_phys_table_phys.as_u32.high); 1008 ramrod_params->fcoe_init.eq_pbl_size = mm_cpu_to_le32(LM_FC_PBL(pdev, pdev->fcoe_info.run_time.fc_eq_base_chain_idx).pbl_entries); 1009 ramrod_params->fcoe_init.eq_prod = mm_cpu_to_le16(lm_bd_chain_prod_idx(&LM_FC_EQ(pdev, pdev->fcoe_info.run_time.fc_eq_base_chain_idx).bd_chain)); 1010 ramrod_params->fcoe_init.sb_num = mm_cpu_to_le16(LM_FW_SB_ID(pdev,pdev->fcoe_info.run_time.fc_eq_base_chain_idx)); 1011 ramrod_params->fcoe_init.sb_id = HC_INDEX_FCOE_EQ_CONS; 1012 1013 if (IS_SD_UFP_MODE(pdev)) 1014 { 1015 ramrod_params->fcoe_init.init_kwqe1.flags |= FCOE_KWQE_INIT1_CLASSIFY_FAILED_ALLOWED; 1016 } 1017 1018 lm_status = lm_command_post(pdev, 1019 LM_CLI_CID(pdev, LM_CLI_IDX_FCOE), /* cid */ 1020 FCOE_RAMROD_CMD_ID_INIT_FUNC, 1021 CMD_PRIORITY_NORMAL, 1022 FCOE_CONNECTION_TYPE, 1023 pdev->fcoe_info.bind.ramrod_mem_phys.as_u64); 1024 1025 if (lm_status != LM_STATUS_SUCCESS) 1026 { 1027 /* only one we know off... */ 1028 DbgBreakIf(lm_status != LM_STATUS_REQUEST_NOT_ACCEPTED); 1029 /* Command wasn't posted, so we need to complete it from here. */ 1030 1031 } 1032 1033 // completion is asynchronous 1034 1035 return LM_STATUS_SUCCESS; 1036 } /* lm_fc_init */ 1037 1038 1039 /** Description 1040 * Callback function for cids being recylced 1041 */ 1042 void 1043 lm_fc_recycle_cid_cb( 1044 struct _lm_device_t *pdev, 1045 void *cookie, 1046 s32_t cid) 1047 { 1048 lm_status_t lm_status; 1049 lm_sp_req_common_t *sp_req = NULL; 1050 lm_fcoe_state_t *fcoe = (lm_fcoe_state_t *)cookie; 1051 1052 if (CHK_NULL(pdev) || CHK_NULL(fcoe)) 1053 { 1054 DbgBreakIf(1); 1055 return; 1056 } 1057 1058 MM_ACQUIRE_TOE_LOCK(pdev); 1059 1060 /* un-block the manager... */ 1061 lm_set_cid_state(pdev, fcoe->cid, LM_CID_STATE_VALID); 1062 1063 lm_status = lm_fc_init_fcoe_context(pdev, fcoe); 1064 1065 lm_status = lm_fc_post_offload_ramrod(pdev, fcoe); 1066 1067 /* we can now unblock any pending slow-paths */ 1068 lm_sp_req_manager_unblock(pdev, cid, &sp_req); 1069 1070 MM_RELEASE_TOE_LOCK(pdev); 1071 } 1072 1073 void lm_fc_comp_cb(struct _lm_device_t *pdev, struct sq_pending_command *pending) 1074 { 1075 struct fcoe_kcqe kcqe = {0}; 1076 lm_fcoe_state_t *fcoe = NULL; 1077 u32_t cid; 1078 u8_t cmd; 1079 1080 1081 if (CHK_NULL(pdev) || CHK_NULL(pending)) 1082 { 1083 return; 1084 } 1085 1086 cmd = pending->cmd; 1087 cid = pending->cid; 1088 1089 fcoe = lm_cid_cookie(pdev, FCOE_CONNECTION_TYPE, cid); 1090 1091 if (fcoe) 1092 { 1093 kcqe.fcoe_conn_id = fcoe->fcoe_conn_id; 1094 kcqe.fcoe_conn_context_id = HW_CID(pdev, cid); 1095 } 1096 1097 kcqe.completion_status = LM_STATUS_SUCCESS; /* Fixme: do we want this?? maybe ok since l5 is aware of er... */ 1098 1099 switch (cmd) 1100 { 1101 case FCOE_RAMROD_CMD_ID_INIT_FUNC: 1102 kcqe.op_code = FCOE_KCQE_OPCODE_INIT_FUNC; 1103 break; 1104 1105 case FCOE_RAMROD_CMD_ID_DESTROY_FUNC: 1106 kcqe.op_code = FCOE_KCQE_OPCODE_DESTROY_FUNC; 1107 break; 1108 1109 case FCOE_RAMROD_CMD_ID_STAT_FUNC: 1110 kcqe.op_code = FCOE_KCQE_OPCODE_STAT_FUNC; 1111 break; 1112 1113 case FCOE_RAMROD_CMD_ID_OFFLOAD_CONN: 1114 kcqe.op_code = FCOE_KCQE_OPCODE_OFFLOAD_CONN; 1115 break; 1116 1117 case FCOE_RAMROD_CMD_ID_ENABLE_CONN: 1118 kcqe.op_code = FCOE_KCQE_OPCODE_ENABLE_CONN; 1119 break; 1120 1121 case FCOE_RAMROD_CMD_ID_DISABLE_CONN: 1122 kcqe.op_code = FCOE_KCQE_OPCODE_DISABLE_CONN; 1123 break; 1124 1125 case FCOE_RAMROD_CMD_ID_TERMINATE_CONN: 1126 kcqe.op_code = FCOE_RAMROD_CMD_ID_TERMINATE_CONN; 1127 break; 1128 } 1129 1130 lm_fc_complete_slow_path_request(pdev, &kcqe); 1131 } 1132 1133 /** 1134 * @description 1135 * Returns the max FCOE task supported. 1136 * In oreder to know the max task enabled refer to 1137 * pdev->params.max_fcoe_task 1138 * @param pdev 1139 * 1140 * @return u32_t 1141 */ 1142 u32_t 1143 lm_fc_max_fcoe_task_sup( 1144 IN struct _lm_device_t *pdev) 1145 { 1146 u32_t max_fcoe_task = MAX_NUM_FCOE_TASKS_PER_ENGINE; 1147 1148 /* FCOE supports a maximum of MAX_FCOE_FUNCS_PER_ENGINE per engine. 1149 * Incase of mf / 4-port mode it means we can have more than one fcoe function 1150 * on an engine - in which case we'll need to divide the number of tasks between them. 1151 * However, in single function mode, on a 2-port chip (i.e. one function on the engine) 1152 * the fcoe function will have all the tasks allocated to it 1153 */ 1154 if (IS_MULTI_VNIC(pdev) || (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4)) 1155 { 1156 max_fcoe_task = max_fcoe_task / MAX_FCOE_FUNCS_PER_ENGINE; 1157 } 1158 1159 return max_fcoe_task; 1160 } 1161 /** 1162 * 1163 * 1164 * @description 1165 * 1166 * @param pdev 1167 * 1168 * @return STATIC void 1169 */ 1170 STATIC void 1171 lm_fc_init_vars( 1172 IN struct _lm_device_t *pdev) 1173 { 1174 1175 if CHK_NULL(pdev) 1176 { 1177 return ; 1178 } 1179 1180 mm_mem_zero(&pdev->fcoe_info, sizeof(lm_fcoe_info_t)); 1181 } 1182 /** 1183 * 1184 * 1185 * @description 1186 * 1187 * @param pdev 1188 * 1189 * @return lm_status_t 1190 */ 1191 lm_status_t 1192 lm_fc_alloc_resc( 1193 IN struct _lm_device_t *pdev) 1194 { 1195 lm_status_t lm_status = LM_STATUS_SUCCESS; 1196 if CHK_NULL(pdev) 1197 { 1198 return LM_STATUS_INVALID_PARAMETER; 1199 } 1200 lm_fc_init_vars(pdev); 1201 /* cid recycled cb registration */ 1202 lm_cid_recycled_cb_register(pdev, FCOE_CONNECTION_TYPE, lm_fc_recycle_cid_cb); 1203 1204 /* Sq-completion cb registration (sq that get completed internally in driver */ 1205 lm_sq_comp_cb_register(pdev, FCOE_CONNECTION_TYPE, lm_fc_comp_cb); 1206 /* Get physical memory for RAMROD commands */ 1207 lm_status = lm_fc_get_ramrod_phys_mem(pdev); 1208 1209 if (lm_status != LM_STATUS_SUCCESS) 1210 { 1211 return lm_status; 1212 } 1213 return LM_STATUS_SUCCESS; 1214 } /* lm_fc_alloc_resc */ 1215 1216 1217 1218 1219 lm_status_t lm_sc_complete_l4_ofld_request(lm_device_t *pdev, struct iscsi_kcqe *kcqe) 1220 { 1221 u32_t comp_status = 0; 1222 lm_tcp_state_t *tcp; 1223 u32_t cid; 1224 1225 if (CHK_NULL(pdev) || CHK_NULL(kcqe)) 1226 { 1227 return LM_STATUS_INVALID_PARAMETER; 1228 } 1229 1230 cid = SW_CID(kcqe->iscsi_conn_context_id); 1231 tcp = lm_cid_cookie(pdev, TOE_CONNECTION_TYPE, cid); 1232 DbgBreakIf(!tcp); 1233 1234 if (kcqe->completion_status & ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE) 1235 { 1236 /* currently there is no specific completion status handling, only success / fail */ 1237 /* but originally the flags are those of toe_initiate_offload_ramrod_data */ 1238 comp_status = 1; 1239 } 1240 1241 /* toe lock is taken inside */ 1242 lm_tcp_comp_initiate_offload_request(pdev, tcp, comp_status); 1243 1244 return LM_STATUS_SUCCESS; 1245 } 1246 1247 lm_status_t lm_sc_complete_l4_upload_request(lm_device_t *pdev, u8_t op_code, u32_t cid) 1248 { 1249 lm_status_t lm_status = LM_STATUS_SUCCESS; 1250 lm_tcp_state_t * tcp = NULL; 1251 1252 tcp = lm_cid_cookie(pdev, TOE_CONNECTION_TYPE, cid); 1253 if (NULL == tcp) 1254 { 1255 return LM_STATUS_FAILURE; 1256 } 1257 1258 switch (op_code) 1259 { 1260 case L5CM_RAMROD_CMD_ID_SEARCHER_DELETE: 1261 if (mm_sc_is_omgr_enabled(pdev)) 1262 { 1263 lm_empty_ramrod_eth(pdev, OOO_CID(pdev), cid, NULL, 0 /*d/c*/); 1264 } 1265 else 1266 { 1267 lm_tcp_searcher_ramrod_complete(pdev, tcp); 1268 } 1269 break; 1270 case RAMROD_CMD_ID_ETH_EMPTY: 1271 lm_tcp_searcher_ramrod_complete(pdev, tcp); 1272 break; 1273 case L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD: 1274 lm_tcp_terminate_ramrod_complete(pdev, tcp); 1275 break; 1276 case L5CM_RAMROD_CMD_ID_QUERY: 1277 lm_tcp_query_ramrod_complete(pdev, tcp); 1278 break; 1279 default: 1280 DbgMessage(pdev, WARN, "lm_sc_complete_l4_upload_request: Invalid op_code 0x%x.\n", op_code); 1281 return LM_STATUS_INVALID_PARAMETER; 1282 } 1283 1284 return LM_STATUS_SUCCESS; 1285 } 1286 1287 1288 1289 lm_status_t lm_sc_complete_slow_path_request(lm_device_t *pdev, struct iscsi_kcqe *kcqe) 1290 { 1291 lm_status_t lm_status = LM_STATUS_FAILURE; 1292 u8_t op_code = 0; 1293 1294 if (CHK_NULL(pdev) || CHK_NULL(kcqe)) 1295 { 1296 return LM_STATUS_INVALID_PARAMETER; 1297 } 1298 1299 op_code = kcqe->op_code; /* Store the opcode, the function below may modify it (internal searcher), need to keep for sq_complete later on */ 1300 1301 switch (kcqe->op_code) 1302 { 1303 /* case ISCSI_KCQE_OPCODE_INIT: 1304 lm_status = mm_sc_complete_init_request(pdev, kcqe); 1305 if (lm_status != LM_STATUS_SUCCESS) 1306 { 1307 DbgMessage(pdev, WARN, "lm_sc_complete_slow_path_request: lm_sc_complete_init_request failed.\n"); 1308 } 1309 break; 1310 */ case L5CM_RAMROD_CMD_ID_ADD_NEW_CONNECTION: 1311 lm_status = lm_sc_complete_l4_ofld_request(pdev, kcqe); 1312 if (lm_status != LM_STATUS_SUCCESS) 1313 { 1314 DbgMessage(pdev, WARN, "lm_sc_complete_slow_path_request: lm_sc_complete_l4_ofld_request failed.\n"); 1315 } 1316 break; 1317 case ISCSI_KCQE_OPCODE_UPDATE_CONN: 1318 lm_status = mm_sc_complete_update_request(pdev, kcqe); 1319 if (lm_status != LM_STATUS_SUCCESS) 1320 { 1321 DbgMessage(pdev, WARN, "lm_sc_complete_slow_path_request: lm_sc_complete_update_request failed.\n"); 1322 } 1323 break; 1324 case L5CM_RAMROD_CMD_ID_SEARCHER_DELETE: 1325 case L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD: 1326 case L5CM_RAMROD_CMD_ID_QUERY: 1327 lm_status = lm_sc_complete_l4_upload_request(pdev, kcqe->op_code, SW_CID(kcqe->iscsi_conn_context_id)); 1328 break; 1329 default: 1330 DbgMessage(pdev, WARN, "lm_sc_complete_slow_path_request: Invalid op_code 0x%x.\n", kcqe->op_code); 1331 } 1332 1333 lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, op_code, 1334 ISCSI_CONNECTION_TYPE, SW_CID(kcqe->iscsi_conn_context_id)); 1335 1336 return lm_status; 1337 } 1338 1339 1340 /* Handle FC related ramrod completions */ 1341 lm_status_t 1342 lm_fc_complete_slow_path_request( 1343 IN struct _lm_device_t *pdev, 1344 IN struct fcoe_kcqe *kcqe) 1345 { 1346 lm_status_t lm_status = LM_STATUS_FAILURE; 1347 lm_fcoe_state_t *fcoe = NULL; 1348 const u8_t priority = CMD_PRIORITY_NORMAL; 1349 const enum connection_type con_type = FCOE_CONNECTION_TYPE; 1350 u32_t cid = 0; 1351 u32_t sw_cid = 0; 1352 u8_t fcoe_commnad = 0; 1353 u8_t b_valid = TRUE; 1354 1355 if (CHK_NULL(pdev) || CHK_NULL(kcqe)) 1356 { 1357 return LM_STATUS_INVALID_PARAMETER; 1358 } 1359 1360 switch (kcqe->op_code) 1361 { 1362 case FCOE_KCQE_OPCODE_INIT_FUNC: 1363 { 1364 fcoe_commnad = FCOE_RAMROD_CMD_ID_INIT_FUNC; 1365 lm_status = mm_fc_complete_init_request(pdev, kcqe); 1366 cid = LM_CLI_CID(pdev, LM_CLI_IDX_FCOE); 1367 break; 1368 } 1369 case FCOE_KCQE_OPCODE_OFFLOAD_CONN: 1370 { 1371 fcoe_commnad = FCOE_RAMROD_CMD_ID_OFFLOAD_CONN; 1372 1373 DbgBreakIf(0 != mm_le32_to_cpu(kcqe->completion_status)); /* offload should never fail */ 1374 1375 sw_cid = SW_CID(mm_le32_to_cpu(kcqe->fcoe_conn_context_id)); 1376 fcoe = lm_cid_cookie(pdev, con_type, sw_cid); 1377 1378 if(!fcoe) 1379 { 1380 lm_status = LM_STATUS_RESOURCE; 1381 DbgBreakIf(!fcoe); 1382 break; 1383 } 1384 1385 cid = fcoe->cid; 1386 lm_status = mm_fc_complete_ofld_request(pdev, fcoe, kcqe); 1387 break; 1388 } 1389 case FCOE_KCQE_OPCODE_ENABLE_CONN: 1390 { 1391 fcoe_commnad = FCOE_RAMROD_CMD_ID_ENABLE_CONN; 1392 1393 DbgBreakIf(0 != mm_le32_to_cpu(kcqe->completion_status)); /* enable should never fail */ 1394 1395 sw_cid = SW_CID(mm_le32_to_cpu(kcqe->fcoe_conn_context_id)); 1396 fcoe = lm_cid_cookie(pdev, con_type, sw_cid); 1397 1398 if(!fcoe) 1399 { 1400 lm_status = LM_STATUS_RESOURCE; 1401 DbgBreakIf(!fcoe); 1402 break; 1403 } 1404 cid = fcoe->cid; 1405 1406 lm_status = mm_fc_complete_enable_request(pdev, fcoe, kcqe); 1407 break; 1408 } 1409 case FCOE_KCQE_OPCODE_DISABLE_CONN: 1410 { 1411 fcoe_commnad = FCOE_RAMROD_CMD_ID_DISABLE_CONN; 1412 1413 /* Disable is complete, now we need to send the terminate ramrod */ 1414 DbgBreakIf(0 != mm_le32_to_cpu(kcqe->completion_status)); /* disable should never fail */ 1415 1416 sw_cid = SW_CID(mm_le32_to_cpu(kcqe->fcoe_conn_context_id)); 1417 fcoe = lm_cid_cookie(pdev, con_type, sw_cid); 1418 1419 if(!fcoe) 1420 { 1421 lm_status = LM_STATUS_RESOURCE; 1422 DbgBreakIf(!fcoe); 1423 break; 1424 } 1425 1426 cid = fcoe->cid; 1427 lm_status = mm_fc_complete_disable_request(pdev, fcoe, kcqe); 1428 break; 1429 } 1430 case FCOE_KCQE_OPCODE_DESTROY_FUNC: 1431 { 1432 fcoe_commnad = FCOE_RAMROD_CMD_ID_DESTROY_FUNC; 1433 lm_status = mm_fc_complete_destroy_request(pdev, kcqe); 1434 cid = LM_CLI_CID(pdev, LM_CLI_IDX_FCOE); 1435 break; 1436 } 1437 case FCOE_KCQE_OPCODE_STAT_FUNC: 1438 { 1439 fcoe_commnad = FCOE_RAMROD_CMD_ID_STAT_FUNC; 1440 lm_status = mm_fc_complete_stat_request(pdev, kcqe); 1441 cid = LM_CLI_CID(pdev, LM_CLI_IDX_FCOE); 1442 break; 1443 } 1444 case FCOE_RAMROD_CMD_ID_TERMINATE_CONN: /* Internal VBD not passed up... */ 1445 { 1446 fcoe_commnad = FCOE_RAMROD_CMD_ID_TERMINATE_CONN; 1447 1448 /* Terminate is complete, now we need to send the CFC delete ramrod */ 1449 DbgBreakIf(0 != mm_le32_to_cpu(kcqe->completion_status)); /* terminate should never fail */ 1450 1451 sw_cid = SW_CID(mm_le32_to_cpu(kcqe->fcoe_conn_context_id)); 1452 1453 fcoe = lm_cid_cookie(pdev, con_type, sw_cid); 1454 1455 if(!fcoe) 1456 { 1457 lm_status = LM_STATUS_RESOURCE; 1458 DbgBreakIf(!fcoe); 1459 break; 1460 } 1461 1462 cid = fcoe->cid; 1463 1464 lm_status = mm_fc_complete_terminate_request(pdev, fcoe, kcqe); 1465 break; 1466 } 1467 default: 1468 { 1469 DbgMessage(pdev, WARN, "lm_fc_complete_slow_path_request: Invalid op_code 0x%x.\n", kcqe->op_code); 1470 b_valid = FALSE; 1471 break; 1472 } 1473 } 1474 1475 if( b_valid ) 1476 { 1477 lm_sq_complete(pdev, priority, fcoe_commnad, con_type, cid); 1478 } 1479 1480 return lm_status; 1481 } 1482 1483 u8_t lm_sc_is_eq_completion(lm_device_t *pdev, u8_t sb_idx) 1484 { 1485 u8_t result = FALSE; 1486 lm_eq_chain_t *eq = NULL; 1487 1488 DbgBreakIf(!(pdev && ARRSIZE(pdev->iscsi_info.run_time.eq_chain) > sb_idx)); 1489 1490 eq = &LM_SC_EQ(pdev, sb_idx); 1491 1492 if (eq->hw_con_idx_ptr && 1493 mm_le16_to_cpu(*eq->hw_con_idx_ptr) != lm_bd_chain_cons_idx(&eq->bd_chain) ) 1494 { 1495 result = TRUE; 1496 } 1497 DbgMessage(pdev, INFORMl5, "lm_sc_is_rx_completion(): result is:%s\n", result? "TRUE" : "FALSE"); 1498 1499 return result; 1500 } 1501 1502 1503 1504 u8_t 1505 lm_fc_is_eq_completion(lm_device_t *pdev, u8_t sb_idx) 1506 { 1507 u8_t result = FALSE; 1508 lm_eq_chain_t *eq = NULL; 1509 1510 DbgBreakIf(!(pdev && ARRSIZE(pdev->fcoe_info.run_time.eq_chain) > sb_idx)); 1511 1512 eq = &LM_FC_EQ(pdev, sb_idx); 1513 1514 if (eq->hw_con_idx_ptr && 1515 mm_le16_to_cpu(*eq->hw_con_idx_ptr) != lm_bd_chain_cons_idx(&eq->bd_chain)) 1516 { 1517 result = TRUE; 1518 } 1519 1520 DbgMessage(pdev, INFORMl5, "lm_fc_is_rx_completion(): result is:%s\n", result? "TRUE" : "FALSE"); 1521 1522 return result; 1523 } 1524 1525 1526 1527 lm_status_t 1528 lm_sc_handle_tcp_event( 1529 IN lm_device_t *pdev, 1530 IN u32_t cid, 1531 IN u32_t op_code 1532 ) 1533 { 1534 lm_tcp_state_t *tcp = NULL; 1535 1536 if CHK_NULL(pdev) 1537 { 1538 return LM_STATUS_INVALID_PARAMETER; 1539 } 1540 1541 tcp = lm_cid_cookie(pdev, TOE_CONNECTION_TYPE, cid); 1542 if CHK_NULL(tcp) 1543 { 1544 return LM_STATUS_INVALID_PARAMETER; 1545 } 1546 1547 switch (op_code) 1548 { 1549 case ISCSI_KCQE_OPCODE_TCP_FIN: 1550 tcp->tcp_state_calc.fin_reception_time = mm_get_current_time(pdev); 1551 break; 1552 case ISCSI_KCQE_OPCODE_TCP_RESET: 1553 tcp->tcp_state_calc.con_rst_flag = TRUE; 1554 break; 1555 default: 1556 DbgMessage(pdev, WARN, "lm_sc_handle_tcp_event: Invalid op_code 0x%x\n", op_code); 1557 return LM_STATUS_INVALID_PARAMETER; 1558 } 1559 1560 return LM_STATUS_SUCCESS; 1561 } 1562 1563 lm_status_t 1564 lm_sc_comp_l5_request( 1565 IN lm_device_t *pdev, 1566 IN lm_eq_chain_t *eq_chain, 1567 INOUT struct iscsi_kcqe **l5_kcqe_start, 1568 INOUT u16_t *l5_kcqe_num) 1569 { 1570 lm_status_t lm_status; 1571 1572 if (CHK_NULL(pdev) || CHK_NULL(eq_chain) || CHK_NULL(l5_kcqe_start) || CHK_NULL(l5_kcqe_num)) 1573 { 1574 return LM_STATUS_INVALID_PARAMETER; 1575 } 1576 1577 lm_status = mm_sc_comp_l5_request(pdev, *l5_kcqe_start, *l5_kcqe_num); 1578 if (lm_status != LM_STATUS_SUCCESS) 1579 { 1580 DbgMessage(pdev, WARN, "lm_sc_service_eq_intr: mm_sc_comp_l5_request failed.\n"); 1581 } 1582 1583 lm_bd_chain_bds_produced(&eq_chain->bd_chain, *l5_kcqe_num); 1584 *l5_kcqe_num = 0; 1585 *l5_kcqe_start = NULL; 1586 1587 return lm_status; 1588 } 1589 1590 1591 1592 lm_status_t 1593 lm_fc_comp_request( 1594 IN lm_device_t *pdev, 1595 IN lm_eq_chain_t *eq_chain, 1596 INOUT struct fcoe_kcqe **fcoe_kcqe_start, 1597 INOUT u16_t *fcoe_kcqe_num) 1598 { 1599 lm_status_t lm_status; 1600 1601 if (CHK_NULL(pdev) || CHK_NULL(eq_chain) || CHK_NULL(fcoe_kcqe_start) || CHK_NULL(fcoe_kcqe_num)) 1602 { 1603 return LM_STATUS_INVALID_PARAMETER; 1604 } 1605 1606 lm_status = mm_fc_comp_request(pdev, *fcoe_kcqe_start, *fcoe_kcqe_num); 1607 if (lm_status != LM_STATUS_SUCCESS) 1608 { 1609 DbgMessage(pdev, WARN, "lm_fc_service_eq_intr: lm_fc_comp_request failed.\n"); 1610 } 1611 1612 lm_bd_chain_bds_produced(&eq_chain->bd_chain, *fcoe_kcqe_num); 1613 *fcoe_kcqe_num = 0; 1614 *fcoe_kcqe_start = NULL; 1615 1616 return lm_status; 1617 } 1618 1619 1620 1621 1622 void 1623 lm_sc_service_eq_intr( 1624 IN struct _lm_device_t *pdev, 1625 IN u8_t sb_idx) 1626 { 1627 lm_status_t lm_status; 1628 lm_eq_chain_t *eq_chain = NULL; 1629 struct iscsi_kcqe *kcqe = NULL; 1630 struct iscsi_kcqe *l5_kcqe_start = NULL; 1631 u16_t l5_kcqe_num = 0; 1632 u16_t eq_new_idx = 0; 1633 u16_t eq_old_idx = 0; 1634 u32_t eq_num = 0; 1635 u32_t cid = 0; 1636 1637 1638 if (CHK_NULL(pdev) || (ARRSIZE(pdev->iscsi_info.run_time.eq_chain) <= sb_idx)) 1639 { 1640 DbgBreakIf(ARRSIZE(pdev->iscsi_info.run_time.eq_chain) <= sb_idx); 1641 DbgBreakIf(!pdev); 1642 return; 1643 } 1644 1645 eq_chain = &LM_SC_EQ(pdev, sb_idx); 1646 1647 eq_new_idx = mm_le16_to_cpu(*(eq_chain->hw_con_idx_ptr)); 1648 eq_old_idx = lm_bd_chain_cons_idx(&eq_chain->bd_chain); 1649 DbgBreakIf(S16_SUB(eq_new_idx, eq_old_idx) < 0); 1650 1651 while (eq_old_idx != eq_new_idx) 1652 { 1653 DbgBreakIf(S16_SUB(eq_new_idx, eq_old_idx) <= 0); 1654 1655 /* get next consumed kcqe */ 1656 kcqe = (struct iscsi_kcqe *)lm_bd_chain_consume_bd_contiguous(&eq_chain->bd_chain); 1657 1658 /* we got to the end of the page, if we have some kcqe that we need to indicate, */ 1659 /* do it now, cause we can't assume that the memorey of the pages is contiguous */ 1660 if (kcqe == NULL) 1661 { 1662 if (l5_kcqe_num != 0) 1663 { 1664 lm_status = lm_sc_comp_l5_request(pdev, eq_chain, &l5_kcqe_start, &l5_kcqe_num); 1665 } 1666 1667 /* check cons index again */ 1668 eq_old_idx = lm_bd_chain_cons_idx(&eq_chain->bd_chain); 1669 1670 if (eq_old_idx != eq_new_idx) 1671 { 1672 /* get next consumed cqe */ 1673 kcqe = (struct iscsi_kcqe *)lm_bd_chain_consume_bd_contiguous(&eq_chain->bd_chain); 1674 1675 if (CHK_NULL(kcqe)) 1676 { 1677 /* shouldn't have happened, got second null from the bd */ 1678 DbgBreakIf(!kcqe); 1679 break; 1680 } 1681 } 1682 else 1683 { 1684 /* the new kcqe was the last one we got, break */ 1685 break; 1686 } 1687 } 1688 1689 switch (kcqe->op_code) 1690 { 1691 case ISCSI_RAMROD_CMD_ID_INIT: 1692 case L5CM_RAMROD_CMD_ID_ADD_NEW_CONNECTION: 1693 case ISCSI_RAMROD_CMD_ID_UPDATE_CONN: 1694 case L5CM_RAMROD_CMD_ID_SEARCHER_DELETE: 1695 case L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD: 1696 case L5CM_RAMROD_CMD_ID_QUERY: 1697 1698 /* first, complete fast path and error indication, if any */ 1699 if (l5_kcqe_num != 0) 1700 { 1701 lm_status = lm_sc_comp_l5_request(pdev, eq_chain, &l5_kcqe_start, &l5_kcqe_num); 1702 } 1703 1704 lm_status = lm_sc_complete_slow_path_request(pdev, kcqe); 1705 if (lm_status != LM_STATUS_SUCCESS) 1706 { 1707 DbgMessage(pdev, WARN, "lm_sc_service_eq_intr: mm_sc_comp_l5_request failed.\n"); 1708 } 1709 1710 lm_bd_chain_bds_produced(&eq_chain->bd_chain, 1); 1711 break; 1712 1713 case ISCSI_KCQE_OPCODE_TCP_FIN: 1714 case ISCSI_KCQE_OPCODE_TCP_RESET: 1715 cid = SW_CID(kcqe->iscsi_conn_context_id); 1716 1717 lm_sc_handle_tcp_event(pdev, cid, kcqe->op_code); 1718 /* Fast path events, no break on purpose */ 1719 default: 1720 if (l5_kcqe_start == NULL) 1721 { 1722 l5_kcqe_start = kcqe; 1723 } 1724 1725 l5_kcqe_num++; 1726 break; 1727 } 1728 1729 eq_old_idx = lm_bd_chain_cons_idx(&eq_chain->bd_chain); 1730 } 1731 1732 /* complete left fast path events */ 1733 if (l5_kcqe_num != 0) 1734 { 1735 lm_status = lm_sc_comp_l5_request(pdev, eq_chain, &l5_kcqe_start, &l5_kcqe_num); 1736 } 1737 1738 /* update EQ prod in RAM */ 1739 eq_num = sb_idx - pdev->iscsi_info.run_time.l5_eq_base_chain_idx; 1740 LM_INTMEM_WRITE16(pdev, CSTORM_ISCSI_EQ_PROD_OFFSET(FUNC_ID(pdev), eq_num), lm_bd_chain_prod_idx(&eq_chain->bd_chain), BAR_CSTRORM_INTMEM); 1741 } 1742 1743 1744 1745 void 1746 lm_fc_service_eq_intr(lm_device_t *pdev, u8_t sb_idx) 1747 { 1748 lm_status_t lm_status; 1749 lm_eq_chain_t *eq_chain = NULL; 1750 struct fcoe_kcqe *kcqe = NULL; 1751 struct fcoe_kcqe *fcoe_kcqe_start= NULL; 1752 u16_t fcoe_kcqe_num = 0; 1753 u16_t eq_new_idx = 0; 1754 u16_t eq_old_idx = 0; 1755 1756 if (CHK_NULL(pdev) || (ARRSIZE(pdev->fcoe_info.run_time.eq_chain) <= sb_idx)) 1757 { 1758 DbgBreakIf(ARRSIZE(pdev->fcoe_info.run_time.eq_chain) <= sb_idx); 1759 DbgBreakIf(!pdev); 1760 return; 1761 } 1762 1763 eq_chain = &LM_FC_EQ(pdev, sb_idx); 1764 1765 eq_new_idx = mm_le16_to_cpu(*(eq_chain->hw_con_idx_ptr)); 1766 eq_old_idx = lm_bd_chain_cons_idx(&eq_chain->bd_chain); 1767 DbgBreakIf(S16_SUB(eq_new_idx, eq_old_idx) < 0); 1768 1769 while (eq_old_idx != eq_new_idx) 1770 { 1771 DbgBreakIf(S16_SUB(eq_new_idx, eq_old_idx) <= 0); 1772 1773 /* get next consumed kcqe */ 1774 kcqe = (struct fcoe_kcqe *)lm_bd_chain_consume_bd_contiguous(&eq_chain->bd_chain); 1775 1776 /* we got to the end of the page, if we have some kcqe that we need to indicate, */ 1777 /* do it now, cause we can't assume that the memorey of the pages is contiguous */ 1778 if (kcqe == NULL) 1779 { 1780 if (fcoe_kcqe_num != 0) 1781 { 1782 lm_status = lm_fc_comp_request(pdev, 1783 eq_chain, 1784 &fcoe_kcqe_start, 1785 &fcoe_kcqe_num); 1786 } 1787 1788 /* check cons index again */ 1789 eq_old_idx = lm_bd_chain_cons_idx(&eq_chain->bd_chain); 1790 1791 if (eq_old_idx != eq_new_idx) 1792 { 1793 /* get next consumed cqe */ 1794 kcqe = (struct fcoe_kcqe *)lm_bd_chain_consume_bd(&eq_chain->bd_chain); 1795 1796 if (CHK_NULL(kcqe)) 1797 { 1798 /* shouldn't have happened, got second null from the bd */ 1799 DbgBreakIf(!kcqe); 1800 break; 1801 } 1802 } 1803 else 1804 { 1805 /* the new kcqe was the last one we got, break */ 1806 break; 1807 } 1808 } 1809 1810 /* first, complete fast path completion notification and error indication, if any */ 1811 if (fcoe_kcqe_num != 0) 1812 { 1813 lm_status = lm_fc_comp_request(pdev, 1814 eq_chain, 1815 &fcoe_kcqe_start, 1816 &fcoe_kcqe_num); 1817 } 1818 1819 switch (kcqe->op_code) 1820 { 1821 case FCOE_KCQE_OPCODE_INIT_FUNC: 1822 case FCOE_KCQE_OPCODE_OFFLOAD_CONN: 1823 case FCOE_KCQE_OPCODE_ENABLE_CONN: 1824 case FCOE_KCQE_OPCODE_DISABLE_CONN: 1825 case FCOE_KCQE_OPCODE_DESTROY_FUNC: 1826 case FCOE_KCQE_OPCODE_STAT_FUNC: 1827 case FCOE_RAMROD_CMD_ID_TERMINATE_CONN: 1828 { 1829 lm_status = lm_fc_complete_slow_path_request(pdev, kcqe); 1830 if (lm_status != LM_STATUS_SUCCESS) 1831 { 1832 DbgMessage(pdev, WARN, "lm_fc_service_eq_intr: lm_fc_complete_slow_path_request failed.\n"); 1833 } 1834 1835 lm_bd_chain_bds_produced(&eq_chain->bd_chain, 1); 1836 break; 1837 } 1838 1839 default: 1840 { 1841 if (fcoe_kcqe_start == NULL) 1842 { 1843 fcoe_kcqe_start = kcqe; 1844 } 1845 1846 fcoe_kcqe_num++; 1847 break; 1848 } 1849 } 1850 1851 eq_old_idx = lm_bd_chain_cons_idx(&eq_chain->bd_chain); 1852 } 1853 1854 /* complete left fast path events */ 1855 if (fcoe_kcqe_num != 0) 1856 { 1857 lm_status = lm_fc_comp_request(pdev, eq_chain, &fcoe_kcqe_start, &fcoe_kcqe_num); 1858 } 1859 1860 /* update EQ prod in RAM */ 1861 LM_INTMEM_WRITE16(pdev, USTORM_FCOE_EQ_PROD_OFFSET(FUNC_ID(pdev)), lm_bd_chain_prod_idx(&eq_chain->bd_chain), BAR_USTRORM_INTMEM); 1862 } 1863 1864 1865 lm_status_t 1866 lm_sc_alloc_con_phys_mem( 1867 IN struct _lm_device_t *pdev, 1868 IN lm_iscsi_state_t *iscsi) 1869 { 1870 lm_status_t lm_status = LM_STATUS_SUCCESS; 1871 u32_t mem_size = sizeof(*iscsi->sp_req_data.virt_addr); 1872 u8_t mm_cli_idx = LM_RESOURCE_ISCSI; 1873 1874 1875 /* Allocate slopwath request data */ 1876 iscsi->sp_req_data.virt_addr = mm_rt_alloc_phys_mem(pdev, 1877 mem_size, 1878 &iscsi->sp_req_data.phys_addr, 1879 0, 1880 mm_cli_idx); 1881 if CHK_NULL(iscsi->sp_req_data.virt_addr) 1882 { /* can't allocate task array */ 1883 return LM_STATUS_RESOURCE; 1884 } 1885 1886 mm_memset(iscsi->sp_req_data.virt_addr, 0, mem_size); 1887 1888 /* Allocate task array */ 1889 iscsi->task_array.base_size = pdev->iscsi_info.run_time.num_of_tasks * sizeof(struct iscsi_task_context_entry); 1890 iscsi->task_array.base_virt = mm_rt_alloc_phys_mem(pdev, 1891 iscsi->task_array.base_size, 1892 &iscsi->task_array.base_phy, 1893 0, 1894 mm_cli_idx); 1895 if CHK_NULL(iscsi->task_array.base_virt) 1896 { /* can't allocate task array */ 1897 return LM_STATUS_RESOURCE; 1898 } 1899 1900 mm_memset(iscsi->task_array.base_virt, 0, iscsi->task_array.base_size); 1901 1902 lm_status = lm_create_pbl(pdev, 1903 iscsi->task_array.base_virt, 1904 &iscsi->task_array.base_phy, 1905 iscsi->task_array.base_size, 1906 &iscsi->task_array.pbl_phys_table_virt, 1907 &iscsi->task_array.pbl_phys_table_phys, 1908 &iscsi->task_array.pbl_virt_table, 1909 &iscsi->task_array.pbl_entries, 1910 &iscsi->task_array.pbl_size, 1911 TRUE, 1912 LM_RESOURCE_ISCSI); 1913 if (lm_status != LM_STATUS_SUCCESS) 1914 { 1915 return lm_status; 1916 } 1917 1918 /* Allocate R2TQ */ 1919 iscsi->r2tq.base_size = pdev->iscsi_info.run_time.num_of_tasks * ISCSI_MAX_NUM_OF_PENDING_R2TS * ISCSI_R2TQE_SIZE; 1920 iscsi->r2tq.base_virt = mm_rt_alloc_phys_mem(pdev, 1921 iscsi->r2tq.base_size, 1922 &iscsi->r2tq.base_phy, 1923 0, 1924 mm_cli_idx); 1925 if CHK_NULL(iscsi->r2tq.base_virt) 1926 { /* can't allocate R2TQ */ 1927 return LM_STATUS_RESOURCE; 1928 } 1929 1930 mm_memset(iscsi->r2tq.base_virt, 0, iscsi->r2tq.base_size); 1931 1932 lm_status = lm_create_pbl(pdev, 1933 iscsi->r2tq.base_virt, 1934 &iscsi->r2tq.base_phy, 1935 iscsi->r2tq.base_size, 1936 &iscsi->r2tq.pbl_phys_table_virt, 1937 &iscsi->r2tq.pbl_phys_table_phys, 1938 &iscsi->r2tq.pbl_virt_table, 1939 &iscsi->r2tq.pbl_entries, 1940 &iscsi->r2tq.pbl_size, 1941 TRUE, 1942 LM_RESOURCE_ISCSI); 1943 if (lm_status != LM_STATUS_SUCCESS) 1944 { 1945 return lm_status; 1946 } 1947 1948 /* Allocate HQ */ 1949 iscsi->hq.base_size = pdev->iscsi_info.run_time.hq_size * sizeof(struct iscsi_hq_bd); 1950 iscsi->hq.base_virt = mm_rt_alloc_phys_mem(pdev, 1951 iscsi->hq.base_size, 1952 &iscsi->hq.base_phy, 1953 0, 1954 mm_cli_idx); 1955 if CHK_NULL(iscsi->hq.base_virt) 1956 { /* can't allocate HQ */ 1957 1958 return LM_STATUS_RESOURCE; 1959 } 1960 1961 mm_memset(iscsi->hq.base_virt, 0, iscsi->hq.base_size); 1962 1963 lm_status = lm_create_pbl(pdev, 1964 iscsi->hq.base_virt, 1965 &iscsi->hq.base_phy, 1966 iscsi->hq.base_size, 1967 &iscsi->hq.pbl_phys_table_virt, 1968 &iscsi->hq.pbl_phys_table_phys, 1969 &iscsi->hq.pbl_virt_table, 1970 &iscsi->hq.pbl_entries, 1971 &iscsi->hq.pbl_size, 1972 TRUE, 1973 LM_RESOURCE_ISCSI); 1974 if (lm_status != LM_STATUS_SUCCESS) 1975 { 1976 return lm_status; 1977 } 1978 1979 return lm_status; 1980 1981 } 1982 /******************************************************************************* 1983 * Description: 1984 * 1985 * Return: 1986 ******************************************************************************/ 1987 lm_status_t 1988 lm_sc_alloc_con_resc( 1989 IN struct _lm_device_t *pdev, 1990 IN lm_iscsi_state_t *iscsi, 1991 IN struct iscsi_kwqe_conn_offload1 *req1, 1992 IN struct iscsi_kwqe_conn_offload2 *req2, 1993 IN struct iscsi_kwqe_conn_offload3 *req3 1994 ) 1995 { 1996 lm_status_t lm_status; 1997 s32_t cid; 1998 1999 if (CHK_NULL(pdev) || CHK_NULL(iscsi) || CHK_NULL(req1) || CHK_NULL(req2) || CHK_NULL(req3)) 2000 { 2001 return LM_STATUS_INVALID_PARAMETER; 2002 } 2003 2004 DbgMessage(pdev, INFORM, "### lm_sc_alloc_con_resc\n"); 2005 2006 /* save the miniport's conn id */ 2007 iscsi->iscsi_conn_id = req1->iscsi_conn_id; 2008 2009 /* Boot connections physical resources are allocated during bind, and not during offload... */ 2010 if (!iscsi->b_resources_allocated) 2011 { 2012 lm_status = lm_sc_alloc_con_phys_mem(pdev, iscsi); 2013 if (lm_status != LM_STATUS_SUCCESS) 2014 { 2015 lm_sc_free_con_resc(pdev, iscsi); 2016 return lm_status; 2017 } 2018 iscsi->b_resources_allocated = TRUE; 2019 } 2020 2021 2022 /* Allocate CID */ 2023 lm_status = lm_allocate_cid(pdev, ISCSI_CONNECTION_TYPE, (void *)iscsi, &cid); 2024 if (lm_status == LM_STATUS_PENDING) 2025 { 2026 lm_sp_req_manager_block(pdev, (u32_t)cid); 2027 } 2028 else if (lm_status != LM_STATUS_SUCCESS) 2029 { 2030 /* failed to allocate CID */ 2031 lm_sc_free_con_resc(pdev, iscsi); 2032 2033 return lm_status; 2034 } 2035 2036 /* save the returned cid */ 2037 iscsi->cid = (u32_t)cid; 2038 2039 /* the allocated slow path request phys data for iscsi will be used in the tcp_state.sp_data, for the query request */ 2040 lm_status = lm_sp_req_manager_set_sp_data(pdev, iscsi->cid, iscsi->sp_req_data.virt_addr, iscsi->sp_req_data.phys_addr); 2041 if (lm_status != LM_STATUS_SUCCESS) 2042 { 2043 lm_sc_free_con_resc(pdev, iscsi); 2044 2045 return lm_status; 2046 } 2047 2048 if (lm_cid_state(pdev, iscsi->cid) == LM_CID_STATE_PENDING) { 2049 return LM_STATUS_PENDING; /* Too soon to initialize context */ 2050 } 2051 2052 return LM_STATUS_SUCCESS; 2053 } /* lm_sc_alloc_con_resc */ 2054 2055 2056 void lm_sc_free_con_phys_mem( 2057 IN struct _lm_device_t *pdev, 2058 IN lm_iscsi_state_t *iscsi 2059 ) 2060 { 2061 u8_t mm_cli_idx = LM_RESOURCE_ISCSI; 2062 2063 if (iscsi->sp_req_data.virt_addr) 2064 { 2065 mm_rt_free_phys_mem(pdev, sizeof(*iscsi->sp_req_data.virt_addr), iscsi->sp_req_data.virt_addr, iscsi->sp_req_data.phys_addr, mm_cli_idx); 2066 iscsi->sp_req_data.virt_addr = NULL; 2067 } 2068 if (iscsi->task_array.base_virt) { 2069 mm_rt_free_phys_mem(pdev, iscsi->task_array.base_size, iscsi->task_array.base_virt, iscsi->task_array.base_phy, mm_cli_idx); 2070 iscsi->task_array.base_virt = NULL; 2071 } 2072 if (iscsi->task_array.pbl_phys_table_virt) { 2073 mm_rt_free_phys_mem(pdev, iscsi->task_array.pbl_size, iscsi->task_array.pbl_phys_table_virt, iscsi->task_array.pbl_phys_table_phys, mm_cli_idx); 2074 iscsi->task_array.pbl_phys_table_virt = NULL; 2075 } 2076 if (iscsi->task_array.pbl_virt_table) { 2077 mm_rt_free_mem(pdev, iscsi->task_array.pbl_virt_table, iscsi->task_array.pbl_entries * sizeof(void *), mm_cli_idx); 2078 iscsi->task_array.pbl_virt_table = NULL; 2079 } 2080 if (iscsi->r2tq.base_virt) { 2081 mm_rt_free_phys_mem(pdev, iscsi->r2tq.base_size, iscsi->r2tq.base_virt, iscsi->r2tq.base_phy, mm_cli_idx); 2082 iscsi->r2tq.base_virt = NULL; 2083 } 2084 if (iscsi->r2tq.pbl_phys_table_virt) { 2085 mm_rt_free_phys_mem(pdev, iscsi->r2tq.pbl_size, iscsi->r2tq.pbl_phys_table_virt, iscsi->r2tq.pbl_phys_table_phys, mm_cli_idx); 2086 iscsi->r2tq.pbl_phys_table_virt = NULL; 2087 } 2088 if (iscsi->r2tq.pbl_virt_table) { 2089 mm_rt_free_mem(pdev, iscsi->r2tq.pbl_virt_table, iscsi->r2tq.pbl_entries * sizeof(void *), mm_cli_idx); 2090 iscsi->r2tq.pbl_virt_table = NULL; 2091 } 2092 if (iscsi->hq.base_virt) { 2093 mm_rt_free_phys_mem(pdev, iscsi->hq.base_size, iscsi->hq.base_virt, iscsi->hq.base_phy, mm_cli_idx); 2094 iscsi->hq.base_virt = NULL; 2095 } 2096 if (iscsi->hq.pbl_phys_table_virt) { 2097 mm_rt_free_phys_mem(pdev, iscsi->hq.pbl_size, iscsi->hq.pbl_phys_table_virt, iscsi->hq.pbl_phys_table_phys, mm_cli_idx); 2098 iscsi->hq.pbl_phys_table_virt = NULL; 2099 } 2100 if (iscsi->hq.pbl_virt_table) { 2101 mm_rt_free_mem(pdev, iscsi->hq.pbl_virt_table, iscsi->hq.pbl_entries * sizeof(void *), mm_cli_idx); 2102 iscsi->hq.pbl_virt_table = NULL; 2103 } 2104 2105 } 2106 /******************************************************************************* 2107 * Description: 2108 * 2109 * Return: 2110 ******************************************************************************/ 2111 lm_status_t lm_sc_free_con_resc( 2112 IN struct _lm_device_t *pdev, 2113 IN lm_iscsi_state_t *iscsi 2114 ) 2115 { 2116 u8_t notify_fw = 1; 2117 2118 if (CHK_NULL(pdev) || CHK_NULL(iscsi)) 2119 { 2120 return LM_STATUS_INVALID_PARAMETER; 2121 } 2122 2123 if (iscsi->cid != 0) { 2124 if (iscsi->hdr.status == STATE_STATUS_INIT_OFFLOAD_ERR) { 2125 notify_fw = 0; 2126 } 2127 lm_free_cid_resc(pdev, ISCSI_CONNECTION_TYPE, iscsi->cid, notify_fw); 2128 iscsi->cid = 0; 2129 } 2130 2131 if (!iscsi->b_keep_resources) 2132 { 2133 lm_sc_free_con_phys_mem(pdev, iscsi); 2134 } 2135 2136 return LM_STATUS_SUCCESS; 2137 } 2138 2139 2140 /* Free the ramrod memory and the CID */ 2141 lm_status_t 2142 lm_fc_free_con_resc( 2143 IN struct _lm_device_t *pdev, 2144 IN lm_fcoe_state_t *fcoe) 2145 { 2146 u8_t notify_fw = 1; 2147 2148 if (CHK_NULL(pdev) || CHK_NULL(fcoe)) 2149 { 2150 return LM_STATUS_INVALID_PARAMETER; 2151 } 2152 2153 if (fcoe->cid != 0) 2154 { 2155 if (fcoe->hdr.status == STATE_STATUS_INIT_OFFLOAD_ERR) 2156 { 2157 notify_fw = 0; 2158 } 2159 2160 lm_free_cid_resc(pdev, FCOE_CONNECTION_TYPE, fcoe->cid, notify_fw); 2161 2162 fcoe->hdr.state_blk = NULL; 2163 fcoe->cid = 0; 2164 fcoe->ctx_virt = NULL; 2165 fcoe->ctx_phys.as_u64 = 0; 2166 } 2167 2168 return LM_STATUS_SUCCESS; 2169 } 2170 2171 2172 2173 /******************************************************************************* 2174 * Description: 2175 * 2176 * Return: 2177 ******************************************************************************/ 2178 lm_status_t lm_sc_init_iscsi_context( 2179 IN struct _lm_device_t *pdev, 2180 IN lm_iscsi_state_t *iscsi, 2181 struct iscsi_kwqe_conn_offload1 *req1, 2182 struct iscsi_kwqe_conn_offload2 *req2, 2183 struct iscsi_kwqe_conn_offload3 *req3 2184 ) 2185 { 2186 struct iscsi_context *ctx; 2187 u32_t cid; 2188 u32_t cq_size_in_bytes; 2189 u32_t single_cq_pbl_entries; 2190 u32_t i; 2191 u16_t conn_id; 2192 lm_address_t pbl_base; 2193 2194 if (CHK_NULL(pdev) || CHK_NULL(iscsi) || CHK_NULL(req1) || CHK_NULL(req2) || CHK_NULL(req3)) 2195 { 2196 return LM_STATUS_INVALID_PARAMETER; 2197 } 2198 2199 2200 conn_id = req1->iscsi_conn_id; 2201 cid = iscsi->cid; 2202 2203 DbgMessage(pdev, INFORM, "### lm_sc_init_iscsi_context\n"); 2204 2205 if (req2->num_additional_wqes != 1) 2206 { 2207 return LM_STATUS_INVALID_PARAMETER; 2208 } 2209 2210 /* get context */ 2211 iscsi->ctx_virt = (struct iscsi_context *)lm_get_context(pdev, iscsi->cid); 2212 DbgBreakIf(!iscsi->ctx_virt); 2213 iscsi->ctx_phys.as_u64 = lm_get_context_phys(pdev, iscsi->cid); 2214 DbgBreakIf(!iscsi->ctx_phys.as_u64); 2215 DbgMessage(pdev, VERBOSEl5sp, 2216 "iscsi->ctx_virt=%p, iscsi->ctx_phys_high=%x, iscsi->ctx_phys_low=%x\n", 2217 iscsi->ctx_virt, iscsi->ctx_phys.as_u32.high, iscsi->ctx_phys.as_u32.low); 2218 2219 ctx = iscsi->ctx_virt; 2220 2221 mm_memset(ctx, 0, sizeof(struct iscsi_context)); 2222 2223 // init xstorm aggregative context 2224 ctx->xstorm_ag_context.hq_prod = 1; //this value represents actual hq_prod + 1 2225 2226 // init xstorm storm context 2227 //iscsi context 2228 ctx->xstorm_st_context.iscsi.first_burst_length = ISCSI_DEFAULT_FIRST_BURST_LENGTH; 2229 ctx->xstorm_st_context.iscsi.max_send_pdu_length = ISCSI_DEFAULT_MAX_PDU_LENGTH; 2230 2231 /* advance the SQ pbl_base cause it's pointing the SQ_DB */ 2232 pbl_base.as_u32.low = req1->sq_page_table_addr_lo; 2233 pbl_base.as_u32.high = req1->sq_page_table_addr_hi; 2234 LM_INC64(&pbl_base, ISCSI_SQ_DB_SIZE); 2235 ctx->xstorm_st_context.iscsi.sq_pbl_base.lo = pbl_base.as_u32.low; 2236 ctx->xstorm_st_context.iscsi.sq_pbl_base.hi = pbl_base.as_u32.high; 2237 2238 //!!DP 2239 ctx->xstorm_st_context.iscsi.sq_curr_pbe.lo = req2->sq_first_pte.lo; 2240 ctx->xstorm_st_context.iscsi.sq_curr_pbe.hi = req2->sq_first_pte.hi; 2241 2242 ctx->xstorm_st_context.iscsi.hq_pbl_base.lo = iscsi->hq.pbl_phys_table_phys.as_u32.low; 2243 ctx->xstorm_st_context.iscsi.hq_pbl_base.hi = iscsi->hq.pbl_phys_table_phys.as_u32.high; 2244 ctx->xstorm_st_context.iscsi.hq_curr_pbe_base.lo = iscsi->hq.pbl_phys_table_virt[0].as_u32.low; 2245 ctx->xstorm_st_context.iscsi.hq_curr_pbe_base.hi = iscsi->hq.pbl_phys_table_virt[0].as_u32.high; 2246 2247 ctx->xstorm_st_context.iscsi.r2tq_pbl_base.lo = iscsi->r2tq.pbl_phys_table_phys.as_u32.low; 2248 ctx->xstorm_st_context.iscsi.r2tq_pbl_base.hi = iscsi->r2tq.pbl_phys_table_phys.as_u32.high; 2249 ctx->xstorm_st_context.iscsi.r2tq_curr_pbe_base.lo = iscsi->r2tq.pbl_phys_table_virt[0].as_u32.low; 2250 ctx->xstorm_st_context.iscsi.r2tq_curr_pbe_base.hi = iscsi->r2tq.pbl_phys_table_virt[0].as_u32.high; 2251 2252 ctx->xstorm_st_context.iscsi.task_pbl_base.lo = iscsi->task_array.pbl_phys_table_phys.as_u32.low; 2253 ctx->xstorm_st_context.iscsi.task_pbl_base.hi = iscsi->task_array.pbl_phys_table_phys.as_u32.high; 2254 ctx->xstorm_st_context.iscsi.task_pbl_cache_idx = ISCSI_PBL_NOT_CACHED; 2255 //ctx->xstorm_st_context.iscsi.max_outstanding_r2ts = ISCSI_DEFAULT_MAX_OUTSTANDING_R2T; 2256 SET_FIELD(ctx->xstorm_st_context.iscsi.flags.flags, XSTORM_ISCSI_CONTEXT_FLAGS_B_IMMEDIATE_DATA, ISCSI_DEFAULT_IMMEDIATE_DATA); 2257 SET_FIELD(ctx->xstorm_st_context.iscsi.flags.flags, XSTORM_ISCSI_CONTEXT_FLAGS_B_INITIAL_R2T, ISCSI_DEFAULT_INITIAL_R2T); 2258 SET_FIELD(ctx->xstorm_st_context.iscsi.flags.flags, XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_HEADER_DIGEST, ISCSI_DEFAULT_HEADER_DIGEST); 2259 SET_FIELD(ctx->xstorm_st_context.iscsi.flags.flags, XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_DATA_DIGEST, ISCSI_DEFAULT_DATA_DIGEST); 2260 2261 // init tstorm storm context 2262 ctx->tstorm_st_context.iscsi.hdr_bytes_2_fetch = ISCSI_HEADER_SIZE + (ISCSI_DEFAULT_HEADER_DIGEST ? ISCSI_DIGEST_SIZE : 0); 2263 SET_FIELD(ctx->tstorm_st_context.iscsi.flags, TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN, ISCSI_DEFAULT_HEADER_DIGEST); 2264 SET_FIELD(ctx->tstorm_st_context.iscsi.flags, TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN, ISCSI_DEFAULT_DATA_DIGEST); 2265 ctx->tstorm_st_context.iscsi.rq_db_phy_addr.lo = req2->rq_page_table_addr_lo; 2266 ctx->tstorm_st_context.iscsi.rq_db_phy_addr.hi = req2->rq_page_table_addr_hi; 2267 ctx->tstorm_st_context.iscsi.iscsi_conn_id = conn_id; 2268 2269 //To enable the timer block. 2270 SET_FIELD(ctx->timers_context.flags, TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG, 1); 2271 2272 // init ustorm storm context 2273 cq_size_in_bytes = pdev->iscsi_info.run_time.cq_size * ISCSI_CQE_SIZE; 2274 single_cq_pbl_entries = lm_get_pbl_entries(cq_size_in_bytes); 2275 2276 ctx->ustorm_st_context.task_pbe_cache_index = ISCSI_PBL_NOT_CACHED; 2277 ctx->ustorm_st_context.task_pdu_cache_index = ISCSI_PDU_HEADER_NOT_CACHED; 2278 2279 /* advance the RQ pbl_base cause it's pointing the RQ_DB */ 2280 pbl_base.as_u32.low = req2->rq_page_table_addr_lo; 2281 pbl_base.as_u32.high = req2->rq_page_table_addr_hi; 2282 LM_INC64(&pbl_base, ISCSI_RQ_DB_SIZE); 2283 ctx->ustorm_st_context.ring.rq.pbl_base.lo = pbl_base.as_u32.low; 2284 ctx->ustorm_st_context.ring.rq.pbl_base.hi = pbl_base.as_u32.high; 2285 2286 //!!DP 2287 /* qp_first_pte[0] will contain the first PTE of the RQ */ 2288 ctx->ustorm_st_context.ring.rq.curr_pbe.lo = req3->qp_first_pte[0].lo; 2289 ctx->ustorm_st_context.ring.rq.curr_pbe.hi = req3->qp_first_pte[0].hi; 2290 2291 ctx->ustorm_st_context.ring.r2tq.pbl_base.lo = iscsi->r2tq.pbl_phys_table_phys.as_u32.low; 2292 ctx->ustorm_st_context.ring.r2tq.pbl_base.hi = iscsi->r2tq.pbl_phys_table_phys.as_u32.high; 2293 ctx->ustorm_st_context.ring.r2tq.curr_pbe.lo = iscsi->r2tq.pbl_phys_table_virt[0].as_u32.low; 2294 ctx->ustorm_st_context.ring.r2tq.curr_pbe.hi = iscsi->r2tq.pbl_phys_table_virt[0].as_u32.high; 2295 2296 /* Set up the first CQ, the first PTE info is contained in req2 */ 2297 pbl_base.as_u32.low = req1->cq_page_table_addr_lo; 2298 pbl_base.as_u32.high = req1->cq_page_table_addr_hi; 2299 LM_INC64(&pbl_base, ISCSI_CQ_DB_SIZE); 2300 ctx->ustorm_st_context.ring.cq_pbl_base.lo = pbl_base.as_u32.low; 2301 ctx->ustorm_st_context.ring.cq_pbl_base.hi = pbl_base.as_u32.high; 2302 ctx->ustorm_st_context.ring.cq[0].cq_sn = ISCSI_INITIAL_SN; 2303 ctx->ustorm_st_context.ring.cq[0].curr_pbe.lo = req2->cq_first_pte.lo; 2304 ctx->ustorm_st_context.ring.cq[0].curr_pbe.hi = req2->cq_first_pte.hi; 2305 2306 if (1 != pdev->iscsi_info.run_time.num_of_cqs) 2307 { 2308 /* For now we only support a single CQ */ 2309 return LM_STATUS_INVALID_PARAMETER; 2310 2311 #if 0 2312 /* Set up additional CQs */ 2313 for (i = 1; i < pdev->iscsi_info.run_time.num_of_cqs; i++) // 8 x CQ curr_pbe 2314 { 2315 ctx->ustorm_st_context.ring.cq[i].cq_sn = ISCSI_INITIAL_SN; 2316 2317 curr_pbl_base.as_u32.low = pbl_base.as_u32.low; 2318 curr_pbl_base.as_u32.high = pbl_base.as_u32.high; 2319 2320 LM_INC64(&curr_pbl_base, i * single_cq_pbl_entries * sizeof(lm_address_t)); 2321 #if 0 2322 fix this if we ever want to use > 1 CQ 2323 2324 curr_pbe = (lm_address_t *)mm_map_io_space(curr_pbl_base, sizeof(lm_address_t)); 2325 if CHK_NULL(curr_pbe) 2326 { 2327 return LM_STATUS_INVALID_PARAMETER; 2328 } 2329 ctx->ustorm_st_context.ring.cq[i].curr_pbe.lo = curr_pbe->as_u32.low; 2330 ctx->ustorm_st_context.ring.cq[i].curr_pbe.hi = curr_pbe->as_u32.high; 2331 mm_unmap_io_space(curr_pbe, sizeof(lm_address_t)); 2332 2333 #endif 2334 } 2335 #endif 2336 } 2337 2338 ctx->ustorm_st_context.task_pbl_base.lo = iscsi->task_array.pbl_phys_table_phys.as_u32.low; 2339 ctx->ustorm_st_context.task_pbl_base.hi = iscsi->task_array.pbl_phys_table_phys.as_u32.high; 2340 ctx->ustorm_st_context.tce_phy_addr.lo = iscsi->task_array.pbl_phys_table_virt[0].as_u32.low; 2341 ctx->ustorm_st_context.tce_phy_addr.hi = iscsi->task_array.pbl_phys_table_virt[0].as_u32.high; 2342 ctx->ustorm_st_context.iscsi_conn_id = conn_id; 2343 SET_FIELD(ctx->ustorm_st_context.negotiated_rx, USTORM_ISCSI_ST_CONTEXT_MAX_RECV_PDU_LENGTH, ISCSI_DEFAULT_MAX_PDU_LENGTH); 2344 SET_FIELD(ctx->ustorm_st_context.negotiated_rx_and_flags, USTORM_ISCSI_ST_CONTEXT_MAX_BURST_LENGTH, ISCSI_DEFAULT_MAX_BURST_LENGTH); 2345 SET_FIELD(ctx->ustorm_st_context.negotiated_rx, USTORM_ISCSI_ST_CONTEXT_MAX_OUTSTANDING_R2TS, ISCSI_DEFAULT_MAX_OUTSTANDING_R2T); 2346 SET_FIELD(ctx->ustorm_st_context.negotiated_rx_and_flags, USTORM_ISCSI_ST_CONTEXT_B_HDR_DIGEST_EN, ISCSI_DEFAULT_HEADER_DIGEST); 2347 SET_FIELD(ctx->ustorm_st_context.negotiated_rx_and_flags, USTORM_ISCSI_ST_CONTEXT_B_DATA_DIGEST_EN, ISCSI_DEFAULT_DATA_DIGEST); 2348 ctx->ustorm_st_context.num_cqs = pdev->iscsi_info.run_time.num_of_cqs; 2349 2350 // init cstorm storm context 2351 ctx->cstorm_st_context.hq_pbl_base.lo = iscsi->hq.pbl_phys_table_phys.as_u32.low; 2352 ctx->cstorm_st_context.hq_pbl_base.hi = iscsi->hq.pbl_phys_table_phys.as_u32.high; 2353 ctx->cstorm_st_context.hq_curr_pbe.lo = iscsi->hq.pbl_phys_table_virt[0].as_u32.low; 2354 ctx->cstorm_st_context.hq_curr_pbe.hi = iscsi->hq.pbl_phys_table_virt[0].as_u32.high; 2355 2356 ctx->cstorm_st_context.task_pbl_base.lo = iscsi->task_array.pbl_phys_table_phys.as_u32.low; 2357 ctx->cstorm_st_context.task_pbl_base.hi = iscsi->task_array.pbl_phys_table_phys.as_u32.high; 2358 ctx->cstorm_st_context.cq_db_base.lo = req1->cq_page_table_addr_lo; 2359 ctx->cstorm_st_context.cq_db_base.hi = req1->cq_page_table_addr_hi; 2360 ctx->cstorm_st_context.iscsi_conn_id = conn_id; 2361 ctx->cstorm_st_context.cq_proc_en_bit_map = (1 << pdev->iscsi_info.run_time.num_of_cqs) - 1; 2362 SET_FIELD(ctx->cstorm_st_context.flags, CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN, ISCSI_DEFAULT_HEADER_DIGEST); 2363 SET_FIELD(ctx->cstorm_st_context.flags, CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN, ISCSI_DEFAULT_DATA_DIGEST); 2364 for (i = 0; i < pdev->iscsi_info.run_time.num_of_cqs; i++) 2365 { 2366 ctx->cstorm_st_context.cq_c_prod_sqn_arr.sqn[i] = ISCSI_INITIAL_SN; 2367 ctx->cstorm_st_context.cq_c_sqn_2_notify_arr.sqn[i] = ISCSI_INITIAL_SN; 2368 } 2369 2370 /* now we need to configure the cdu-validation data */ 2371 lm_set_cdu_validation_data(pdev, iscsi->cid, FALSE /* don't invalidate */); 2372 2373 return LM_STATUS_SUCCESS; 2374 } 2375 2376 2377 lm_status_t 2378 lm_fc_init_fcoe_context( 2379 IN struct _lm_device_t *pdev, 2380 IN lm_fcoe_state_t *fcoe) 2381 { 2382 struct fcoe_context *ctx; 2383 u32_t cid; 2384 u16_t conn_id; 2385 2386 if (CHK_NULL(pdev) || CHK_NULL(fcoe)) 2387 { 2388 return LM_STATUS_INVALID_PARAMETER; 2389 } 2390 2391 conn_id = fcoe->ofld1.fcoe_conn_id; 2392 cid = fcoe->cid; 2393 2394 DbgMessage(pdev, INFORM, "### lm_fc_init_fcoe_context\n"); 2395 2396 /* get context */ 2397 fcoe->ctx_virt = (struct fcoe_context *)lm_get_context(pdev, fcoe->cid); 2398 DbgBreakIf(!fcoe->ctx_virt); 2399 fcoe->ctx_phys.as_u64 = lm_get_context_phys(pdev, fcoe->cid); 2400 DbgBreakIf(!fcoe->ctx_phys.as_u64); 2401 DbgMessage(pdev, VERBOSEl5sp, 2402 "fcoe->ctx_virt=%p, fcoe->ctx_phys_high=%x, fcoe->ctx_phys_low=%x\n", 2403 fcoe->ctx_virt, fcoe->ctx_phys.as_u32.high, fcoe->ctx_phys.as_u32.low); 2404 2405 ctx = fcoe->ctx_virt; 2406 2407 mm_memset(ctx, 0, sizeof(struct fcoe_context)); 2408 2409 /* now we need to configure the cdu-validation data */ 2410 lm_set_cdu_validation_data(pdev, fcoe->cid, FALSE /* don't invalidate */); 2411 2412 return LM_STATUS_SUCCESS; 2413 } 2414 2415 2416 2417 lm_status_t 2418 lm_fc_alloc_con_resc( 2419 IN struct _lm_device_t *pdev, 2420 IN lm_fcoe_state_t *fcoe) 2421 { 2422 lm_status_t lm_status = LM_STATUS_SUCCESS; 2423 s32_t cid = 0; 2424 2425 if (CHK_NULL(pdev) || CHK_NULL(fcoe)) 2426 { 2427 return LM_STATUS_INVALID_PARAMETER; 2428 } 2429 2430 DbgMessage(pdev, INFORM, "### lm_fc_alloc_con_resc\n"); 2431 2432 /* save the miniport's conn id */ 2433 fcoe->fcoe_conn_id = fcoe->ofld1.fcoe_conn_id; 2434 2435 /* Allocate CID */ 2436 lm_status = lm_allocate_cid(pdev, FCOE_CONNECTION_TYPE, (void *)fcoe, &cid); 2437 if (lm_status == LM_STATUS_PENDING) 2438 { 2439 lm_sp_req_manager_block(pdev, (u32_t)cid); 2440 } 2441 else if (lm_status != LM_STATUS_SUCCESS) 2442 { 2443 /* failed to allocate CID */ 2444 lm_fc_free_con_resc(pdev, fcoe); 2445 return lm_status; 2446 } 2447 2448 /* save the returned cid */ 2449 fcoe->cid = (u32_t)cid; 2450 2451 if (lm_cid_state(pdev, fcoe->cid) == LM_CID_STATE_PENDING) 2452 { 2453 return LM_STATUS_PENDING; /* Too soon to initialize context */ 2454 } 2455 2456 return LM_STATUS_SUCCESS; 2457 } /* lm_fc_alloc_con_resc */ 2458 2459 2460 2461 lm_status_t 2462 lm_fc_post_offload_ramrod( 2463 struct _lm_device_t *pdev, 2464 lm_fcoe_state_t *fcoe) 2465 { 2466 lm_fcoe_slow_path_phys_data_t *ramrod_params; 2467 lm_status_t lm_status; 2468 2469 ramrod_params = (lm_fcoe_slow_path_phys_data_t*)pdev->fcoe_info.bind.ramrod_mem_virt; 2470 2471 mm_memset(ramrod_params, 0, sizeof(lm_fcoe_slow_path_phys_data_t)); 2472 2473 memcpy(&ramrod_params->fcoe_ofld.offload_kwqe1, &fcoe->ofld1, sizeof(struct fcoe_kwqe_conn_offload1)); 2474 memcpy(&ramrod_params->fcoe_ofld.offload_kwqe2, &fcoe->ofld2, sizeof(struct fcoe_kwqe_conn_offload2)); 2475 memcpy(&ramrod_params->fcoe_ofld.offload_kwqe3, &fcoe->ofld3, sizeof(struct fcoe_kwqe_conn_offload3)); 2476 memcpy(&ramrod_params->fcoe_ofld.offload_kwqe4, &fcoe->ofld4, sizeof(struct fcoe_kwqe_conn_offload4)); 2477 2478 lm_status = lm_command_post(pdev, 2479 fcoe->cid, 2480 FCOE_RAMROD_CMD_ID_OFFLOAD_CONN, 2481 CMD_PRIORITY_NORMAL, 2482 FCOE_CONNECTION_TYPE, 2483 pdev->fcoe_info.bind.ramrod_mem_phys.as_u64); 2484 2485 return lm_status; 2486 } 2487 2488 2489 2490 lm_status_t 2491 lm_fc_post_enable_ramrod( 2492 struct _lm_device_t *pdev, 2493 lm_fcoe_state_t *fcoe, 2494 struct fcoe_kwqe_conn_enable_disable *enable) 2495 { 2496 lm_fcoe_slow_path_phys_data_t *ramrod_params; 2497 lm_status_t lm_status; 2498 2499 ramrod_params = (lm_fcoe_slow_path_phys_data_t*)pdev->fcoe_info.bind.ramrod_mem_virt; 2500 2501 mm_memset(ramrod_params, 0, sizeof(lm_fcoe_slow_path_phys_data_t)); 2502 2503 memcpy(&ramrod_params->fcoe_enable.enable_disable_kwqe, enable, sizeof(struct fcoe_kwqe_conn_enable_disable)); 2504 2505 lm_status = lm_command_post(pdev, 2506 fcoe->cid, 2507 FCOE_RAMROD_CMD_ID_ENABLE_CONN, 2508 CMD_PRIORITY_NORMAL, 2509 FCOE_CONNECTION_TYPE, 2510 pdev->fcoe_info.bind.ramrod_mem_phys.as_u64); 2511 2512 return lm_status; 2513 } 2514 2515 2516 2517 lm_status_t 2518 lm_fc_post_disable_ramrod( 2519 struct _lm_device_t *pdev, 2520 lm_fcoe_state_t *fcoe, 2521 struct fcoe_kwqe_conn_enable_disable *disable) 2522 { 2523 lm_fcoe_slow_path_phys_data_t *ramrod_params; 2524 lm_status_t lm_status; 2525 2526 ramrod_params = (lm_fcoe_slow_path_phys_data_t*)pdev->fcoe_info.bind.ramrod_mem_virt; 2527 2528 mm_memset(ramrod_params, 0, sizeof(lm_fcoe_slow_path_phys_data_t)); 2529 2530 memcpy(&ramrod_params->fcoe_enable.enable_disable_kwqe, disable, sizeof *disable); 2531 2532 lm_status = lm_command_post(pdev, 2533 fcoe->cid, 2534 FCOE_RAMROD_CMD_ID_DISABLE_CONN, 2535 CMD_PRIORITY_NORMAL, 2536 FCOE_CONNECTION_TYPE, 2537 pdev->fcoe_info.bind.ramrod_mem_phys.as_u64); 2538 2539 return lm_status; 2540 } 2541 2542 lm_status_t 2543 lm_fc_post_destroy_ramrod( 2544 struct _lm_device_t *pdev) 2545 { 2546 lm_status_t lm_status; 2547 2548 lm_status = lm_command_post(pdev, 2549 LM_CLI_CID(pdev, LM_CLI_IDX_FCOE), /* cid */ 2550 FCOE_RAMROD_CMD_ID_DESTROY_FUNC, 2551 CMD_PRIORITY_NORMAL, 2552 FCOE_CONNECTION_TYPE, 2553 0); 2554 2555 return lm_status; 2556 } 2557 2558 2559 lm_status_t 2560 lm_fc_post_stat_ramrod( 2561 struct _lm_device_t *pdev, 2562 struct fcoe_kwqe_stat *stat) 2563 { 2564 lm_status_t lm_status = LM_STATUS_SUCCESS; 2565 2566 lm_fcoe_slow_path_phys_data_t *ramrod_params; 2567 2568 if(CHK_NULL(pdev->fcoe_info.bind.ramrod_mem_virt)) 2569 { 2570 return LM_STATUS_RESOURCE; 2571 } 2572 ramrod_params = (lm_fcoe_slow_path_phys_data_t*)pdev->fcoe_info.bind.ramrod_mem_virt; 2573 2574 mm_memset(ramrod_params, 0, sizeof(lm_fcoe_slow_path_phys_data_t)); 2575 2576 memcpy(&ramrod_params->fcoe_stat.stat_kwqe, stat, sizeof(struct fcoe_kwqe_stat)); 2577 2578 lm_status = lm_command_post(pdev, 2579 LM_CLI_CID(pdev, LM_CLI_IDX_FCOE), /* cid */ 2580 FCOE_RAMROD_CMD_ID_STAT_FUNC, 2581 CMD_PRIORITY_NORMAL, 2582 FCOE_CONNECTION_TYPE, 2583 pdev->fcoe_info.bind.ramrod_mem_phys.as_u64); 2584 2585 return lm_status; 2586 } 2587 2588 lm_status_t 2589 lm_fc_post_terminate_ramrod( 2590 struct _lm_device_t *pdev, 2591 lm_fcoe_state_t *fcoe) 2592 { 2593 lm_status_t lm_status; 2594 2595 lm_status = lm_command_post(pdev, 2596 fcoe->cid, 2597 FCOE_RAMROD_CMD_ID_TERMINATE_CONN, 2598 CMD_PRIORITY_NORMAL, 2599 FCOE_CONNECTION_TYPE, 2600 0); 2601 2602 return lm_status; 2603 } 2604