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 
lm_get_pbl_entries(IN u32_t bufferSize)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 
lm_alloc_pbl_mem(IN struct _lm_device_t * pdev,IN u32_t pbl_entries,OUT lm_address_t ** pbl_virt,OUT lm_address_t * pbl_phy,OUT void ** pbl_virt_table,IN u8_t rt_mem,OUT u32_t * pbl_size,IN u8_t mm_cli_idx)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 
lm_create_pbl(IN struct _lm_device_t * pdev,IN void * buf_base_virt,IN lm_address_t * buf_base_phy,IN u32_t buffer_size,OUT lm_address_t ** pbl_virt,OUT lm_address_t * pbl_phy,OUT void ** pbl_virt_table,OUT u32_t * pbl_entries,OUT u32_t * pbl_size,IN u8_t rt_mem,IN u8_t mm_cli_idx)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
lm_l5_alloc_eq(IN struct _lm_device_t * pdev,IN lm_eq_chain_t * eq_chain,IN lm_eq_addr_t * eq_addr_save,IN u16_t page_cnt,IN u8_t cli_idx)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
lm_sc_setup_eq(IN struct _lm_device_t * pdev,IN u32_t idx,IN const u8_t is_chain_mode)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
lm_fc_alloc_eq_pbl(IN struct _lm_device_t * pdev,IN lm_eq_chain_t * eq_chain,IN lm_fcoe_pbl_t * pbl,IN lm_eq_addr_t * eq_addr_save)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
lm_fc_setup_eq(IN struct _lm_device_t * pdev,IN u32_t idx,IN const u8_t is_chain_mode)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  */
lm_sc_recycle_cid_cb(struct _lm_device_t * pdev,void * cookie,s32_t cid)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 
lm_sc_comp_cb(struct _lm_device_t * pdev,struct sq_pending_command * pending)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
lm_sc_alloc_resc(IN struct _lm_device_t * pdev)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
lm_l5_eq_page_cnt(IN struct _lm_device_t * pdev,const u32_t max_func_cons,const u16_t reserved_eq_elements,const u16_t eqes_per_page,const u16_t max_eq_pages)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
lm_fc_free_init_resc(IN struct _lm_device_t * pdev)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
lm_fc_clear_d0_resc(IN struct _lm_device_t * pdev,const u8_t cid)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
lm_fc_clear_resc(IN struct _lm_device_t * pdev)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
lm_sc_free_init_resc(IN struct _lm_device_t * pdev)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
lm_sc_clear_d0_resc(IN struct _lm_device_t * pdev,const u8_t cid)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
lm_sc_clear_resc(IN struct _lm_device_t * pdev)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
lm_sc_ooo_chain_establish(IN struct _lm_device_t * pdev)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
lm_sc_init(IN struct _lm_device_t * pdev,IN struct iscsi_kwqe_init1 * req1,IN struct iscsi_kwqe_init2 * req2)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
lm_fc_get_ramrod_phys_mem(IN struct _lm_device_t * pdev)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
lm_fc_init(IN struct _lm_device_t * pdev,IN struct fcoe_kwqe_init1 * init1,IN struct fcoe_kwqe_init2 * init2,IN struct fcoe_kwqe_init3 * init3)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
lm_fc_recycle_cid_cb(struct _lm_device_t * pdev,void * cookie,s32_t cid)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 
lm_fc_comp_cb(struct _lm_device_t * pdev,struct sq_pending_command * pending)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
lm_fc_max_fcoe_task_sup(IN struct _lm_device_t * pdev)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
lm_fc_init_vars(IN struct _lm_device_t * pdev)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
lm_fc_alloc_resc(IN struct _lm_device_t * pdev)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 
lm_sc_complete_l4_ofld_request(lm_device_t * pdev,struct iscsi_kcqe * kcqe)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 
lm_sc_complete_l4_upload_request(lm_device_t * pdev,u8_t op_code,u32_t cid)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 
lm_sc_complete_slow_path_request(lm_device_t * pdev,struct iscsi_kcqe * kcqe)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
lm_fc_complete_slow_path_request(IN struct _lm_device_t * pdev,IN struct fcoe_kcqe * kcqe)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 
lm_sc_is_eq_completion(lm_device_t * pdev,u8_t sb_idx)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
lm_fc_is_eq_completion(lm_device_t * pdev,u8_t sb_idx)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
lm_sc_handle_tcp_event(IN lm_device_t * pdev,IN u32_t cid,IN u32_t op_code)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
lm_sc_comp_l5_request(IN lm_device_t * pdev,IN lm_eq_chain_t * eq_chain,INOUT struct iscsi_kcqe ** l5_kcqe_start,INOUT u16_t * l5_kcqe_num)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
lm_fc_comp_request(IN lm_device_t * pdev,IN lm_eq_chain_t * eq_chain,INOUT struct fcoe_kcqe ** fcoe_kcqe_start,INOUT u16_t * fcoe_kcqe_num)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
lm_sc_service_eq_intr(IN struct _lm_device_t * pdev,IN u8_t sb_idx)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             /* FALLTHROUGH */
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
lm_fc_service_eq_intr(lm_device_t * pdev,u8_t sb_idx)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
lm_sc_alloc_con_phys_mem(IN struct _lm_device_t * pdev,IN lm_iscsi_state_t * iscsi)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
lm_sc_alloc_con_resc(IN struct _lm_device_t * pdev,IN lm_iscsi_state_t * iscsi,IN struct iscsi_kwqe_conn_offload1 * req1,IN struct iscsi_kwqe_conn_offload2 * req2,IN struct iscsi_kwqe_conn_offload3 * req3)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 
lm_sc_free_con_phys_mem(IN struct _lm_device_t * pdev,IN lm_iscsi_state_t * iscsi)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  ******************************************************************************/
lm_sc_free_con_resc(IN struct _lm_device_t * pdev,IN lm_iscsi_state_t * iscsi)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
lm_fc_free_con_resc(IN struct _lm_device_t * pdev,IN lm_fcoe_state_t * fcoe)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  ******************************************************************************/
lm_sc_init_iscsi_context(IN struct _lm_device_t * pdev,IN lm_iscsi_state_t * iscsi,struct iscsi_kwqe_conn_offload1 * req1,struct iscsi_kwqe_conn_offload2 * req2,struct iscsi_kwqe_conn_offload3 * req3)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
lm_fc_init_fcoe_context(IN struct _lm_device_t * pdev,IN lm_fcoe_state_t * fcoe)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
lm_fc_alloc_con_resc(IN struct _lm_device_t * pdev,IN lm_fcoe_state_t * fcoe)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
lm_fc_post_offload_ramrod(struct _lm_device_t * pdev,lm_fcoe_state_t * fcoe)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
lm_fc_post_enable_ramrod(struct _lm_device_t * pdev,lm_fcoe_state_t * fcoe,struct fcoe_kwqe_conn_enable_disable * enable)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
lm_fc_post_disable_ramrod(struct _lm_device_t * pdev,lm_fcoe_state_t * fcoe,struct fcoe_kwqe_conn_enable_disable * disable)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
lm_fc_post_destroy_ramrod(struct _lm_device_t * pdev)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
lm_fc_post_stat_ramrod(struct _lm_device_t * pdev,struct fcoe_kwqe_stat * stat)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
lm_fc_post_terminate_ramrod(struct _lm_device_t * pdev,lm_fcoe_state_t * fcoe)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