1d14abf15SRobert Mustacchi 
2d14abf15SRobert Mustacchi /*
3d14abf15SRobert Mustacchi functions for managing Chip per-connection context
4d14abf15SRobert Mustacchi */
5d14abf15SRobert Mustacchi #include "context.h"
6d14abf15SRobert Mustacchi #include "command.h"
7d14abf15SRobert Mustacchi #include "cdu_def.h"
8d14abf15SRobert Mustacchi #include "bd_chain.h"
9d14abf15SRobert Mustacchi 
10d14abf15SRobert Mustacchi /* returns a pionter to a connections chip context*/
lm_get_context(struct _lm_device_t * pdev,u32_t cid)11d14abf15SRobert Mustacchi void * lm_get_context(struct _lm_device_t *pdev, u32_t cid){
12d14abf15SRobert Mustacchi 
13d14abf15SRobert Mustacchi     void * ret = NULL;
14d14abf15SRobert Mustacchi     u32_t page,off;
15d14abf15SRobert Mustacchi 
16d14abf15SRobert Mustacchi     DbgBreakIf(cid > pdev->params.max_func_connections);
17d14abf15SRobert Mustacchi     DbgBreakIf(pdev->context_info->array[cid].invalid != LM_CONTEXT_VALID);
18d14abf15SRobert Mustacchi 
19d14abf15SRobert Mustacchi     /* calculate which context page the CID is on*/
20d14abf15SRobert Mustacchi     page = cid / (pdev->params.num_context_in_page);
21d14abf15SRobert Mustacchi 
22d14abf15SRobert Mustacchi     /* calculate at what offset inside the page CID is on*/
23d14abf15SRobert Mustacchi     off = cid % (pdev->params.num_context_in_page);
24d14abf15SRobert Mustacchi 
25d14abf15SRobert Mustacchi     /* now goto page,off */
26d14abf15SRobert Mustacchi     ret = (void*)((char*)pdev->vars.context_cdu_virt_addr_table[page] + (pdev->params.context_line_size * off));
27d14abf15SRobert Mustacchi     /* warrning, this assumes context line size is in chars, need to check!!!*/
28d14abf15SRobert Mustacchi 
29d14abf15SRobert Mustacchi     return ret;
30d14abf15SRobert Mustacchi }
31d14abf15SRobert Mustacchi 
32d14abf15SRobert Mustacchi /* same as above but returns phys address in 64 bit pointer */
lm_get_context_phys(struct _lm_device_t * pdev,u32_t cid)33d14abf15SRobert Mustacchi u64_t lm_get_context_phys(struct _lm_device_t *pdev, u32_t cid){
34d14abf15SRobert Mustacchi 
35d14abf15SRobert Mustacchi     u64_t ret = 0;
36d14abf15SRobert Mustacchi     u32_t page,off;
37d14abf15SRobert Mustacchi 
38d14abf15SRobert Mustacchi     DbgBreakIf(cid > pdev->params.max_func_connections);
39d14abf15SRobert Mustacchi     DbgBreakIf(pdev->context_info->array[cid].invalid != LM_CONTEXT_VALID);
40d14abf15SRobert Mustacchi 
41d14abf15SRobert Mustacchi     /* calculate which context page the CID is on*/
42d14abf15SRobert Mustacchi     page = cid / (pdev->params.num_context_in_page);
43d14abf15SRobert Mustacchi 
44d14abf15SRobert Mustacchi     /* calculate at what offset inside the page CID is on*/
45d14abf15SRobert Mustacchi     off = cid % (pdev->params.num_context_in_page);
46d14abf15SRobert Mustacchi 
47d14abf15SRobert Mustacchi     /* now goto page,off */
48d14abf15SRobert Mustacchi     ret = (pdev->vars.context_cdu_phys_addr_table[page].as_u64 + (pdev->params.context_line_size * off));
49d14abf15SRobert Mustacchi     /* warrning, this assumes context line size is in chars, need to check!!!*/
50d14abf15SRobert Mustacchi 
51d14abf15SRobert Mustacchi     return ret;
52d14abf15SRobert Mustacchi }
53d14abf15SRobert Mustacchi 
54d14abf15SRobert Mustacchi extern u32_t LOG2(u32_t v);
lm_setup_searcher_hash_info(struct _lm_device_t * pdev)55d14abf15SRobert Mustacchi static lm_status_t lm_setup_searcher_hash_info(struct _lm_device_t *pdev)
56d14abf15SRobert Mustacchi {
57d14abf15SRobert Mustacchi     u32_t                    num_con    = 0 ;
58d14abf15SRobert Mustacchi     u32_t                    alloc_size = 0 ;
59d14abf15SRobert Mustacchi     lm_context_info_t*       context    = NULL;
60d14abf15SRobert Mustacchi     lm_searcher_hash_info_t* hash_info  = NULL;
61d14abf15SRobert Mustacchi     int                      offset     = 0 ;
62d14abf15SRobert Mustacchi 
63d14abf15SRobert Mustacchi     /* sanity */
64d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) || CHK_NULL( pdev->context_info ) )
65d14abf15SRobert Mustacchi     {
66d14abf15SRobert Mustacchi         DbgBreakMsg("Invalid Parameters") ;
67d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER ;
68d14abf15SRobert Mustacchi     }
69d14abf15SRobert Mustacchi     context   = pdev->context_info;
70d14abf15SRobert Mustacchi     hash_info = &context->searcher_hash;
71d14abf15SRobert Mustacchi 
72d14abf15SRobert Mustacchi     DbgBreakIf(!pdev->params.max_func_connections);
73d14abf15SRobert Mustacchi 
74d14abf15SRobert Mustacchi     if CHK_NULL( hash_info->searcher_table)
75d14abf15SRobert Mustacchi     {
76d14abf15SRobert Mustacchi         DbgBreakIf(!( hash_info->searcher_table));
77d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
78d14abf15SRobert Mustacchi     }
79d14abf15SRobert Mustacchi     num_con    = pdev->params.max_func_connections;
80d14abf15SRobert Mustacchi     alloc_size = sizeof(lm_searcher_hash_entry_t) * num_con;
81d14abf15SRobert Mustacchi     mm_mem_zero(hash_info->searcher_table, alloc_size);
82d14abf15SRobert Mustacchi 
83d14abf15SRobert Mustacchi     /* init value for searcher key */
84d14abf15SRobert Mustacchi     // TODO: for now a fixed key, need to change at runtime
85d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[0])  = 0x63285672;
86d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[4])  = 0x24B8F2CC;
87d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[8])  = 0x223AEF9B;
88d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[12]) = 0x26001E3A;
89d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[16]) = 0x7AE91116;
90d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[20]) = 0x5CE5230B;
91d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[24]) = 0x298D8ADF;
92d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[28]) = 0x6EB0FF09;
93d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[32]) = 0x1830F82F;
94d14abf15SRobert Mustacchi     *(u32_t *)(&hash_info->searcher_key[36]) = 0x1E46BE7;
95d14abf15SRobert Mustacchi 
96d14abf15SRobert Mustacchi     /* Microsoft's example key */
97d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[0]) = 0xda565a6d;
98d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[4]) = 0xc20e5b25;
99d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[8]) = 0x3d256741;
100d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[12]) = 0xb08fa343;
101d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[16]) = 0xcb2bcad0;
102d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[20]) = 0xb4307bae;
103d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[24]) = 0xa32dcb77;
104d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[28]) = 0x0cf23080;
105d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[32]) = 0x3bb7426a;
106d14abf15SRobert Mustacchi //      *(u32_t *)(&hash_info->searcher_key[36]) = 0xfa01acbe;
107d14abf15SRobert Mustacchi 
108d14abf15SRobert Mustacchi     /* init searcher_key_bits array */
109d14abf15SRobert Mustacchi     for (offset = 0; offset < 10; offset++)
110d14abf15SRobert Mustacchi     {
111d14abf15SRobert Mustacchi         int j,k;
112d14abf15SRobert Mustacchi         u32_t bitsOffset = 32*offset;
113d14abf15SRobert Mustacchi         u8_t _byte;
114d14abf15SRobert Mustacchi 
115d14abf15SRobert Mustacchi         for (j= 0; j < 4; j++)
116d14abf15SRobert Mustacchi         {
117d14abf15SRobert Mustacchi             _byte  = (u8_t)((*(u32_t *)(&hash_info->searcher_key[offset*4]) >> (j*8)) & 0xff);
118d14abf15SRobert Mustacchi             for (k = 0; k < 8; k++)
119d14abf15SRobert Mustacchi             {
120d14abf15SRobert Mustacchi                 hash_info->searcher_key_bits[bitsOffset+(j*8)+k] = ((_byte<<(k%8))& 0x80) ? 1 : 0;
121d14abf15SRobert Mustacchi             }
122d14abf15SRobert Mustacchi         }
123d14abf15SRobert Mustacchi     }
124d14abf15SRobert Mustacchi 
125d14abf15SRobert Mustacchi     /* init value for num hash bits */
126d14abf15SRobert Mustacchi     hash_info->num_hash_bits = (u8_t)LOG2(num_con);
127d14abf15SRobert Mustacchi 
128d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS ;
129d14abf15SRobert Mustacchi }
130d14abf15SRobert Mustacchi 
lm_alloc_searcher_hash_info(struct _lm_device_t * pdev)131d14abf15SRobert Mustacchi static lm_status_t lm_alloc_searcher_hash_info(struct _lm_device_t *pdev)
132d14abf15SRobert Mustacchi {
133d14abf15SRobert Mustacchi     u32_t                    num_con    = 0 ;
134d14abf15SRobert Mustacchi     u32_t                    alloc_size = 0 ;
135d14abf15SRobert Mustacchi     lm_searcher_hash_info_t* hash_info  = NULL ;
136d14abf15SRobert Mustacchi     u8_t                     mm_cli_idx = 0 ;
137d14abf15SRobert Mustacchi 
138d14abf15SRobert Mustacchi     if CHK_NULL(pdev)
139d14abf15SRobert Mustacchi     {
140d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER ;
141d14abf15SRobert Mustacchi     }
142d14abf15SRobert Mustacchi 
143d14abf15SRobert Mustacchi     mm_cli_idx = LM_RESOURCE_COMMON;//!!DP mm_cli_idx_to_um_idx(LM_CLI_IDX_MAX);
144d14abf15SRobert Mustacchi 
145d14abf15SRobert Mustacchi     /* searcher is defined with per-function #connections */
146d14abf15SRobert Mustacchi     num_con    = pdev->params.max_func_connections;
147d14abf15SRobert Mustacchi     alloc_size = sizeof(lm_searcher_hash_entry_t) * num_con;
148d14abf15SRobert Mustacchi 
149d14abf15SRobert Mustacchi     hash_info  = &pdev->context_info->searcher_hash;
150d14abf15SRobert Mustacchi 
151d14abf15SRobert Mustacchi     if CHK_NULL(hash_info)
152d14abf15SRobert Mustacchi     {
153d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER ;
154d14abf15SRobert Mustacchi     }
155d14abf15SRobert Mustacchi 
156d14abf15SRobert Mustacchi     /* allocate searcher mirror hash table */
157d14abf15SRobert Mustacchi     hash_info->searcher_table = mm_alloc_mem(pdev, alloc_size, mm_cli_idx);
158d14abf15SRobert Mustacchi 
159d14abf15SRobert Mustacchi     if CHK_NULL( hash_info->searcher_table )
160d14abf15SRobert Mustacchi     {
161d14abf15SRobert Mustacchi         DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
162d14abf15SRobert Mustacchi         return  LM_STATUS_RESOURCE ;
163d14abf15SRobert Mustacchi     }
164d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS ;
165d14abf15SRobert Mustacchi }
166d14abf15SRobert Mustacchi 
lm_init_cid_resc(struct _lm_device_t * pdev,u32_t cid)167d14abf15SRobert Mustacchi lm_status_t lm_init_cid_resc(struct _lm_device_t *pdev, u32_t cid)
168d14abf15SRobert Mustacchi {
169d14abf15SRobert Mustacchi     lm_cid_resc_t *cid_resc = NULL;
170d14abf15SRobert Mustacchi     int            i        = 0;
171d14abf15SRobert Mustacchi 
172d14abf15SRobert Mustacchi     if CHK_NULL(pdev)
173d14abf15SRobert Mustacchi     {
174d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
175d14abf15SRobert Mustacchi     }
176d14abf15SRobert Mustacchi 
177d14abf15SRobert Mustacchi     cid_resc = &pdev->context_info->array[cid].cid_resc;
178d14abf15SRobert Mustacchi     if CHK_NULL(cid_resc)
179d14abf15SRobert Mustacchi     {
180d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
181d14abf15SRobert Mustacchi     }
182d14abf15SRobert Mustacchi 
183d14abf15SRobert Mustacchi     for (i = 0; i < ARRSIZE(cid_resc->cookies); i++)
184d14abf15SRobert Mustacchi     {
185d14abf15SRobert Mustacchi         cid_resc->cookies[i] = NULL;
186d14abf15SRobert Mustacchi     }
187d14abf15SRobert Mustacchi 
188d14abf15SRobert Mustacchi     cid_resc->cid_pending = LM_CID_STATE_VALID;
189d14abf15SRobert Mustacchi     lm_sp_req_manager_init(pdev, cid);
190d14abf15SRobert Mustacchi 
191d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
192d14abf15SRobert Mustacchi }
193d14abf15SRobert Mustacchi 
lm_setup_context_pool(struct _lm_device_t * pdev)194d14abf15SRobert Mustacchi lm_status_t lm_setup_context_pool(struct _lm_device_t *pdev)
195d14abf15SRobert Mustacchi {
196d14abf15SRobert Mustacchi     u32_t                     num_con         = 0;
197d14abf15SRobert Mustacchi     lm_context_info_t *       context         = NULL ;
198d14abf15SRobert Mustacchi     u32_t                     i,j;
199d14abf15SRobert Mustacchi     struct lm_context_cookie* array           = NULL ;
200d14abf15SRobert Mustacchi     lm_searcher_hash_entry_t* searcher_table  = NULL ;
201d14abf15SRobert Mustacchi 
202d14abf15SRobert Mustacchi     if CHK_NULL(pdev)
203d14abf15SRobert Mustacchi     {
204d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
205d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
206d14abf15SRobert Mustacchi     }
207d14abf15SRobert Mustacchi 
208d14abf15SRobert Mustacchi     context = pdev->context_info;
209d14abf15SRobert Mustacchi 
210d14abf15SRobert Mustacchi     if CHK_NULL(context)
211d14abf15SRobert Mustacchi     {
212d14abf15SRobert Mustacchi         DbgBreakIf( context == NULL );
213d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
214d14abf15SRobert Mustacchi     }
215d14abf15SRobert Mustacchi 
216d14abf15SRobert Mustacchi     num_con = pdev->params.max_func_connections;
217d14abf15SRobert Mustacchi 
218d14abf15SRobert Mustacchi     array           = context->array ;
219d14abf15SRobert Mustacchi     searcher_table  = context->searcher_hash.searcher_table ;
220d14abf15SRobert Mustacchi 
221d14abf15SRobert Mustacchi     mm_mem_zero( context, sizeof(lm_context_info_t) ) ;
222d14abf15SRobert Mustacchi 
223d14abf15SRobert Mustacchi     context->array                        = array ;
224d14abf15SRobert Mustacchi     context->searcher_hash.searcher_table = searcher_table ;
225d14abf15SRobert Mustacchi 
226d14abf15SRobert Mustacchi     context->proto_start[ETH_CONNECTION_TYPE]   = 0;
227d14abf15SRobert Mustacchi     context->proto_end  [ETH_CONNECTION_TYPE]   = pdev->params.max_eth_including_vfs_conns - 1;
228d14abf15SRobert Mustacchi     context->proto_start[TOE_CONNECTION_TYPE]   = context->proto_end  [ETH_CONNECTION_TYPE]   + 1;
229d14abf15SRobert Mustacchi     context->proto_end  [TOE_CONNECTION_TYPE]   = context->proto_start[TOE_CONNECTION_TYPE]   + pdev->params.max_func_toe_cons - 1;
230d14abf15SRobert Mustacchi     context->proto_start[RDMA_CONNECTION_TYPE]  = context->proto_end  [TOE_CONNECTION_TYPE]   + 1;
231d14abf15SRobert Mustacchi     context->proto_end  [RDMA_CONNECTION_TYPE]  = context->proto_start[RDMA_CONNECTION_TYPE]  + pdev->params.max_func_rdma_cons - 1;
232d14abf15SRobert Mustacchi     context->proto_start[ISCSI_CONNECTION_TYPE] = context->proto_end  [RDMA_CONNECTION_TYPE]  + 1;
233d14abf15SRobert Mustacchi     context->proto_end  [ISCSI_CONNECTION_TYPE] = context->proto_start[ISCSI_CONNECTION_TYPE] + pdev->params.max_func_iscsi_cons - 1;
234d14abf15SRobert Mustacchi     context->proto_start[FCOE_CONNECTION_TYPE]  = context->proto_end  [ISCSI_CONNECTION_TYPE] + 1;
235d14abf15SRobert Mustacchi     context->proto_end  [FCOE_CONNECTION_TYPE]  = context->proto_start[FCOE_CONNECTION_TYPE]  + pdev->params.max_func_fcoe_cons - 1;
236d14abf15SRobert Mustacchi     DbgBreakIf(context->proto_end[MAX_PROTO - 1] > pdev->params.max_func_connections -1);
237d14abf15SRobert Mustacchi 
238d14abf15SRobert Mustacchi     if CHK_NULL(context->array)
239d14abf15SRobert Mustacchi     {
240d14abf15SRobert Mustacchi         DbgBreakIf(!( context->array));
241d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
242d14abf15SRobert Mustacchi     }
243d14abf15SRobert Mustacchi 
244d14abf15SRobert Mustacchi     mm_mem_zero(context->array, sizeof(struct lm_context_cookie)*num_con);
245d14abf15SRobert Mustacchi 
246d14abf15SRobert Mustacchi     ASSERT_STATIC( ARRSIZE(context->proto_start) == ARRSIZE(context->proto_end) );
247d14abf15SRobert Mustacchi 
248d14abf15SRobert Mustacchi     /* zero cookies and populate the free lists */
249d14abf15SRobert Mustacchi     for (i = 0; i < ARRSIZE(context->proto_start); i++ )
250d14abf15SRobert Mustacchi     {
251d14abf15SRobert Mustacchi         for (j = context->proto_start[i]; j <= context->proto_end[i]; j++)
252d14abf15SRobert Mustacchi         {
253d14abf15SRobert Mustacchi             context->array[j].next    = j+1;
254d14abf15SRobert Mustacchi             context->array[j].invalid = LM_CONTEXT_VALID;
255d14abf15SRobert Mustacchi             context->array[j].ip_type = 0;
256d14abf15SRobert Mustacchi             context->array[j].h_val   = 0;
257d14abf15SRobert Mustacchi             lm_init_cid_resc(pdev, j);
258d14abf15SRobert Mustacchi         }
259d14abf15SRobert Mustacchi         /* set the first free item if max_func_XX_cons > 0 */
260d14abf15SRobert Mustacchi         if (context->proto_start[i] <= context->proto_end[i]) {
261d14abf15SRobert Mustacchi             context->proto_ffree[i] = context->proto_start[i];
262d14abf15SRobert Mustacchi         }
263d14abf15SRobert Mustacchi         else
264d14abf15SRobert Mustacchi         {
265d14abf15SRobert Mustacchi             context->proto_ffree[i] = 0;
266d14abf15SRobert Mustacchi         }
267d14abf15SRobert Mustacchi         context->proto_pending[i] = 0;
268d14abf15SRobert Mustacchi         /* put 0 (end of freelist in the last entry for the proto */
269d14abf15SRobert Mustacchi         context->array[context->proto_end[i]].next = 0;
270d14abf15SRobert Mustacchi     }
271d14abf15SRobert Mustacchi     //The ETH cid doorbell space was remapped just fixing the pointers.
272d14abf15SRobert Mustacchi     for (j = context->proto_start[ETH_CONNECTION_TYPE]; j <= context->proto_end[ETH_CONNECTION_TYPE]; j++)
273d14abf15SRobert Mustacchi     {
274d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
275d14abf15SRobert Mustacchi         if (IS_CHANNEL_VFDEV(pdev)) {
276d14abf15SRobert Mustacchi             context->array[j].cid_resc.mapped_cid_bar_addr =
277d14abf15SRobert Mustacchi                 (volatile void *)((u8_t*)pdev->vars.mapped_bar_addr[BAR_0] + j*lm_vf_get_doorbell_size(pdev) + VF_BAR0_DB_OFFSET);
278d14abf15SRobert Mustacchi #ifdef __SunOS
279d14abf15SRobert Mustacchi             context->array[j].cid_resc.reg_handle = pdev->vars.reg_handle[BAR_0];
280d14abf15SRobert Mustacchi #endif /* __SunOS */
281d14abf15SRobert Mustacchi         } else
282d14abf15SRobert Mustacchi #endif /* VF_INVOLVED */
283d14abf15SRobert Mustacchi         {
284d14abf15SRobert Mustacchi             context->array[j].cid_resc.mapped_cid_bar_addr =
285d14abf15SRobert Mustacchi                 (volatile void *)((u8_t*)pdev->vars.mapped_bar_addr[BAR_1] + j*LM_DQ_CID_SIZE);
286d14abf15SRobert Mustacchi #ifdef __SunOS
287d14abf15SRobert Mustacchi             context->array[j].cid_resc.reg_handle = pdev->vars.reg_handle[BAR_1];
288d14abf15SRobert Mustacchi #endif /* __SunOS */
289d14abf15SRobert Mustacchi         }
290d14abf15SRobert Mustacchi     }
291d14abf15SRobert Mustacchi     return lm_setup_searcher_hash_info(pdev) ;
292d14abf15SRobert Mustacchi }
293d14abf15SRobert Mustacchi 
294d14abf15SRobert Mustacchi /* context pool initializer */
lm_alloc_context_pool(struct _lm_device_t * pdev)295d14abf15SRobert Mustacchi lm_status_t lm_alloc_context_pool(struct _lm_device_t *pdev){
296d14abf15SRobert Mustacchi 
297d14abf15SRobert Mustacchi     u32_t               num_con    = 0 ;
298d14abf15SRobert Mustacchi     lm_context_info_t * context    = NULL ;
299d14abf15SRobert Mustacchi     u8_t                mm_cli_idx = 0;
300d14abf15SRobert Mustacchi 
301d14abf15SRobert Mustacchi     if CHK_NULL(pdev)
302d14abf15SRobert Mustacchi     {
303d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
304d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER ;
305d14abf15SRobert Mustacchi     }
306d14abf15SRobert Mustacchi 
307d14abf15SRobert Mustacchi     /* must not be called if allready initialized */
308d14abf15SRobert Mustacchi     if ERR_IF( NULL != pdev->context_info )
309d14abf15SRobert Mustacchi     {
310d14abf15SRobert Mustacchi         DbgBreakIf( pdev->context_info != NULL ) ;
311d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE ;
312d14abf15SRobert Mustacchi     }
313d14abf15SRobert Mustacchi 
314d14abf15SRobert Mustacchi     mm_cli_idx = LM_RESOURCE_COMMON;//!!DP mm_cli_idx_to_um_idx(LM_CLI_IDX_MAX);
315d14abf15SRobert Mustacchi 
316d14abf15SRobert Mustacchi     /* number of context is per-function, the cdu has a per-port register that can be set to be higher than the max_func_connections, but
317d14abf15SRobert Mustacchi      * the amount of memory actually allocated for the CDU matches max_func_connections. */
318d14abf15SRobert Mustacchi     num_con = pdev->params.max_func_connections ;
319d14abf15SRobert Mustacchi 
320d14abf15SRobert Mustacchi     /* allocate context info and cookie array */
321d14abf15SRobert Mustacchi     context = mm_alloc_mem(pdev, sizeof(lm_context_info_t), mm_cli_idx);
322d14abf15SRobert Mustacchi     if CHK_NULL(context)
323d14abf15SRobert Mustacchi     {
324d14abf15SRobert Mustacchi         DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
325d14abf15SRobert Mustacchi         return LM_STATUS_RESOURCE ;
326d14abf15SRobert Mustacchi     }
327d14abf15SRobert Mustacchi 
328d14abf15SRobert Mustacchi     /* allocate list entries */
329d14abf15SRobert Mustacchi     context->array = mm_alloc_mem(pdev, sizeof(struct lm_context_cookie)*num_con, mm_cli_idx);
330d14abf15SRobert Mustacchi     if CHK_NULL(context->array)
331d14abf15SRobert Mustacchi     {
332d14abf15SRobert Mustacchi         DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
333d14abf15SRobert Mustacchi         return LM_STATUS_RESOURCE ;
334d14abf15SRobert Mustacchi     }
335d14abf15SRobert Mustacchi 
336d14abf15SRobert Mustacchi     /* initilize the lock */
337d14abf15SRobert Mustacchi 
338d14abf15SRobert Mustacchi     /* put the context where it belongs */
339d14abf15SRobert Mustacchi     pdev->context_info = context;
340d14abf15SRobert Mustacchi 
341d14abf15SRobert Mustacchi     /* init searcher hash info */
342d14abf15SRobert Mustacchi     return lm_alloc_searcher_hash_info(pdev);
343d14abf15SRobert Mustacchi     /* return success */
344d14abf15SRobert Mustacchi }
345d14abf15SRobert Mustacchi 
346d14abf15SRobert Mustacchi /* context pool release function */
lm_release_context_pool(struct _lm_device_t * pdev)347d14abf15SRobert Mustacchi void lm_release_context_pool(struct _lm_device_t *pdev){
348d14abf15SRobert Mustacchi 
349d14abf15SRobert Mustacchi     lm_context_info_t* context = NULL;
350d14abf15SRobert Mustacchi     u32_t i, j;
351d14abf15SRobert Mustacchi 
352d14abf15SRobert Mustacchi     /* must only be called if initialized */
353d14abf15SRobert Mustacchi     DbgBreakIf( pdev->context_info == NULL );
354d14abf15SRobert Mustacchi 
355d14abf15SRobert Mustacchi     /* first make a copy and kill the original refference */
356d14abf15SRobert Mustacchi     context            = pdev->context_info;
357d14abf15SRobert Mustacchi     pdev->context_info = NULL;
358d14abf15SRobert Mustacchi 
359d14abf15SRobert Mustacchi     /* free context cookie array
360d14abf15SRobert Mustacchi        sanity check: scan it and make sure it is empty */
361d14abf15SRobert Mustacchi     for (i=0; i<(pdev->params.max_func_connections); i++  )
362d14abf15SRobert Mustacchi     {
363d14abf15SRobert Mustacchi         for (j = 0; j < MAX_PROTO; j++)
364d14abf15SRobert Mustacchi         {
365d14abf15SRobert Mustacchi             DbgBreakIf( context->array[i].cid_resc.cookies[j] != NULL );
366d14abf15SRobert Mustacchi         }
367d14abf15SRobert Mustacchi 
368d14abf15SRobert Mustacchi         /* NirV: can't call from here, context_info is NULL */
369d14abf15SRobert Mustacchi         /*DbgBreakIf(lm_sp_req_manager_shutdown(pdev, i) != LM_STATUS_SUCCESS);*/
370d14abf15SRobert Mustacchi     }
371d14abf15SRobert Mustacchi     /* mm_free_mem(context->array); */
372d14abf15SRobert Mustacchi 
373d14abf15SRobert Mustacchi     /* sanity check - searcher mirror hash must be empty */
374d14abf15SRobert Mustacchi     DbgBreakIf(context->searcher_hash.num_tuples);
375d14abf15SRobert Mustacchi 
376d14abf15SRobert Mustacchi     /* de-initilize the lock? if in debug mode we can leave it taken to chatch errors */
377d14abf15SRobert Mustacchi 
378d14abf15SRobert Mustacchi     /* free context info */
379d14abf15SRobert Mustacchi     /* mm_free_mem(context); */
380d14abf15SRobert Mustacchi 
381d14abf15SRobert Mustacchi 
382d14abf15SRobert Mustacchi     /* return success */
383d14abf15SRobert Mustacchi 
384d14abf15SRobert Mustacchi }
385d14abf15SRobert Mustacchi 
_lm_searcher_mirror_hash_calc(lm_searcher_hash_info_t * hash_info,lm_4tuple_t * tuple)386d14abf15SRobert Mustacchi static u32_t _lm_searcher_mirror_hash_calc(lm_searcher_hash_info_t *hash_info, lm_4tuple_t *tuple)
387d14abf15SRobert Mustacchi {
388d14abf15SRobert Mustacchi     u8_t  in_str[MAX_SEARCHER_IN_STR] = {0};
389d14abf15SRobert Mustacchi     u8_t* in_str_bits                 = hash_info->searcher_in_str_bits;
390d14abf15SRobert Mustacchi     u8_t* key_bits                    = hash_info->searcher_key_bits;
391d14abf15SRobert Mustacchi     u32_t in_bits                     = 0;
392d14abf15SRobert Mustacchi     u32_t result                      = 0;
393d14abf15SRobert Mustacchi     u16_t i                           = 0;
394d14abf15SRobert Mustacchi     u16_t j                           = 0;
395d14abf15SRobert Mustacchi 
396d14abf15SRobert Mustacchi     /* prepare input string */
397d14abf15SRobert Mustacchi     if (tuple->ip_type == LM_IP_TYPE_V4)
398d14abf15SRobert Mustacchi     {
399d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[0])  = HTON32(tuple->src_ip[0]);
400d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[4])  = HTON32(tuple->dst_ip[0]);
401d14abf15SRobert Mustacchi         *(u16_t *)(&in_str[8])  = tuple->src_port;
402d14abf15SRobert Mustacchi         *(u16_t *)(&in_str[10]) = tuple->dst_port;
403d14abf15SRobert Mustacchi         in_bits = 12 * 8;
404d14abf15SRobert Mustacchi     }
405d14abf15SRobert Mustacchi     else
406d14abf15SRobert Mustacchi     {
407d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[0])   = HTON32(tuple->src_ip[0]);
408d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[4])   = HTON32(tuple->src_ip[1]);
409d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[8])   = HTON32(tuple->src_ip[2]);
410d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[12])  = HTON32(tuple->src_ip[3]);
411d14abf15SRobert Mustacchi 
412d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[16])  = HTON32(tuple->dst_ip[0]);
413d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[20])  = HTON32(tuple->dst_ip[1]);
414d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[24])  = HTON32(tuple->dst_ip[2]);
415d14abf15SRobert Mustacchi         *(u32_t *)(&in_str[28])  = HTON32(tuple->dst_ip[3]);
416d14abf15SRobert Mustacchi 
417d14abf15SRobert Mustacchi         *(u16_t *)(&in_str[32]) = tuple->src_port;
418d14abf15SRobert Mustacchi         *(u16_t *)(&in_str[34]) = tuple->dst_port;
419d14abf15SRobert Mustacchi         in_bits = 36 * 8;
420d14abf15SRobert Mustacchi     }
421d14abf15SRobert Mustacchi 
422d14abf15SRobert Mustacchi     /* prepare searcher_in_str_bits from in_str */
423d14abf15SRobert Mustacchi     for (i = 0; i < in_bits; i++)
424d14abf15SRobert Mustacchi     {
425d14abf15SRobert Mustacchi         /* 0x80 - the leftmost bit. */
426d14abf15SRobert Mustacchi         in_str_bits[i] = ((in_str[i/8]<<(i%8)) & 0x80) ? 1 : 0;
427d14abf15SRobert Mustacchi     }
428d14abf15SRobert Mustacchi 
429d14abf15SRobert Mustacchi     /* calc ToeplitzHash */
430d14abf15SRobert Mustacchi     for (i = 0; i < 32; i++)
431d14abf15SRobert Mustacchi     {
432d14abf15SRobert Mustacchi         u8_t h = 0;
433d14abf15SRobert Mustacchi 
434d14abf15SRobert Mustacchi         for (j = 0; j < in_bits; j++)
435d14abf15SRobert Mustacchi         {
436d14abf15SRobert Mustacchi             h ^= key_bits[i+j] & in_str_bits[j];
437d14abf15SRobert Mustacchi         }
438d14abf15SRobert Mustacchi 
439d14abf15SRobert Mustacchi         result |= (h<<(32-i-1));
440d14abf15SRobert Mustacchi     }
441d14abf15SRobert Mustacchi 
442d14abf15SRobert Mustacchi     return result;
443d14abf15SRobert Mustacchi }
444d14abf15SRobert Mustacchi 
445d14abf15SRobert Mustacchi /* assumption: CID lock NOT taken by caller */
lm_searcher_mirror_hash_insert(struct _lm_device_t * pdev,u32_t cid,lm_4tuple_t * tuple)446d14abf15SRobert Mustacchi lm_status_t lm_searcher_mirror_hash_insert(struct _lm_device_t *pdev, u32_t cid, lm_4tuple_t *tuple)
447d14abf15SRobert Mustacchi {
448d14abf15SRobert Mustacchi     lm_context_info_t        *context    = NULL;
449d14abf15SRobert Mustacchi     lm_searcher_hash_entry_t *hash_entry = NULL;
450d14abf15SRobert Mustacchi     u32_t                    h_val       = 0;
451d14abf15SRobert Mustacchi     u8_t temp_ipv6, temp_ipv4, temp_depth_ipv4, is_ipv4;
452d14abf15SRobert Mustacchi     lm_status_t              lm_status   = LM_STATUS_SUCCESS;
453d14abf15SRobert Mustacchi     #define SRC_HASH_DEPTH_TH 15 /* that is searcher's default MaxNumHops - 1 */
454d14abf15SRobert Mustacchi 
455d14abf15SRobert Mustacchi     /* take spinlock */
456d14abf15SRobert Mustacchi     MM_ACQUIRE_CID_LOCK(pdev);
457d14abf15SRobert Mustacchi 
458d14abf15SRobert Mustacchi     context = pdev->context_info;
459d14abf15SRobert Mustacchi     is_ipv4 = (tuple->ip_type == LM_IP_TYPE_V4 ? 1 : 0);
460d14abf15SRobert Mustacchi 
461d14abf15SRobert Mustacchi     /* calc hash val */
462d14abf15SRobert Mustacchi     h_val = _lm_searcher_mirror_hash_calc(&context->searcher_hash, tuple);
463d14abf15SRobert Mustacchi 
464d14abf15SRobert Mustacchi     /* take only num_hash_bits LSBs */
465d14abf15SRobert Mustacchi     h_val &= ((1 << context->searcher_hash.num_hash_bits) - 1);
466d14abf15SRobert Mustacchi 
467d14abf15SRobert Mustacchi     /* init num_hash_bits in the searcher: if the h_val is all FFFFs - set it to 0 */
468d14abf15SRobert Mustacchi     if (h_val == ((1 << context->searcher_hash.num_hash_bits) - 1)) {
469d14abf15SRobert Mustacchi         h_val = 0;
470d14abf15SRobert Mustacchi     }
471d14abf15SRobert Mustacchi 
472d14abf15SRobert Mustacchi     /* get the hash entry */
473d14abf15SRobert Mustacchi     hash_entry = &context->searcher_hash.searcher_table[h_val];
474d14abf15SRobert Mustacchi 
475d14abf15SRobert Mustacchi     /* start the alg. to find if there is a place available in that entry */
476d14abf15SRobert Mustacchi     temp_ipv6 = hash_entry->num_ipv6 + (is_ipv4 ? 0 : 1);
477d14abf15SRobert Mustacchi     temp_ipv4 = hash_entry->num_ipv4 + is_ipv4;
478d14abf15SRobert Mustacchi 
479d14abf15SRobert Mustacchi     /* tempDepthIpv4 = max ( depthIpv4(H), roundup(tempIpv4/2) ) */
480d14abf15SRobert Mustacchi     temp_depth_ipv4 = (temp_ipv4 / 2) + (temp_ipv4 % 2);
481d14abf15SRobert Mustacchi     if (temp_depth_ipv4 < hash_entry->depth_ipv4) {
482d14abf15SRobert Mustacchi         temp_depth_ipv4 = hash_entry->depth_ipv4;
483d14abf15SRobert Mustacchi     }
484d14abf15SRobert Mustacchi 
485d14abf15SRobert Mustacchi     if (temp_depth_ipv4 + temp_ipv6 > SRC_HASH_DEPTH_TH) {
486d14abf15SRobert Mustacchi         /* each hash entry has SRC_HASH_DEPTH_TH available places.
487d14abf15SRobert Mustacchi          * each place can contain 1 ipv6 connection or 2 ipv4 connections */
488d14abf15SRobert Mustacchi         DbgBreakMsg("Reached searcher hash limit\n");
489d14abf15SRobert Mustacchi         lm_status = LM_STATUS_FAILURE;
490d14abf15SRobert Mustacchi     } else {
491d14abf15SRobert Mustacchi         hash_entry->num_ipv6 = temp_ipv6;
492d14abf15SRobert Mustacchi         hash_entry->num_ipv4 = temp_ipv4;
493d14abf15SRobert Mustacchi         hash_entry->depth_ipv4 = temp_depth_ipv4;
494d14abf15SRobert Mustacchi 
495d14abf15SRobert Mustacchi         /* for debug, save the max depth reached */
496d14abf15SRobert Mustacchi         if (context->searcher_hash.hash_depth_reached < hash_entry->depth_ipv4 + hash_entry->num_ipv6) {
497d14abf15SRobert Mustacchi             context->searcher_hash.hash_depth_reached = hash_entry->depth_ipv4 + hash_entry->num_ipv6;
498d14abf15SRobert Mustacchi         }
499d14abf15SRobert Mustacchi         context->searcher_hash.num_tuples++;
500d14abf15SRobert Mustacchi 
501d14abf15SRobert Mustacchi         /* remeber the IP type and h_val to know where and how much
502d14abf15SRobert Mustacchi          * to decrease upon CID recycling */
503d14abf15SRobert Mustacchi         DbgBreakIf(context->array[cid].ip_type); /* cid can't be inserted twice */
504d14abf15SRobert Mustacchi         context->array[cid].ip_type = tuple->ip_type;
505d14abf15SRobert Mustacchi         context->array[cid].h_val = h_val;
506d14abf15SRobert Mustacchi     }
507d14abf15SRobert Mustacchi 
508d14abf15SRobert Mustacchi     /* release spinlock */
509d14abf15SRobert Mustacchi     MM_RELEASE_CID_LOCK(pdev);
510d14abf15SRobert Mustacchi 
511d14abf15SRobert Mustacchi     return lm_status;
512d14abf15SRobert Mustacchi }
513d14abf15SRobert Mustacchi 
514d14abf15SRobert Mustacchi /* assumption: CID lock NOT taken by caller */
lm_searcher_mirror_hash_remove(struct _lm_device_t * pdev,u32_t cid)515d14abf15SRobert Mustacchi void lm_searcher_mirror_hash_remove(struct _lm_device_t *pdev, u32_t cid)
516d14abf15SRobert Mustacchi {
517d14abf15SRobert Mustacchi     lm_context_info_t        *context    = NULL;
518d14abf15SRobert Mustacchi     lm_searcher_hash_entry_t *hash_entry = NULL;
519d14abf15SRobert Mustacchi     u32_t                    h_val       = 0;
520d14abf15SRobert Mustacchi 
521d14abf15SRobert Mustacchi     /* take spinlock */
522d14abf15SRobert Mustacchi     MM_ACQUIRE_CID_LOCK(pdev);
523d14abf15SRobert Mustacchi 
524d14abf15SRobert Mustacchi     context = pdev->context_info;
525d14abf15SRobert Mustacchi 
526d14abf15SRobert Mustacchi     if(!context->array[cid].ip_type) {
527d14abf15SRobert Mustacchi         /* i.e lm_searcher_mirror_hash_insert was not called for this cid */
528d14abf15SRobert Mustacchi         DbgMessage(pdev, WARN,
529d14abf15SRobert Mustacchi                    "not removing CID %d from SRC hash (hash insert was not called for this cid)\n"
530d14abf15SRobert Mustacchi                    ,cid);
531d14abf15SRobert Mustacchi 
532d14abf15SRobert Mustacchi         /* release spinlock */
533d14abf15SRobert Mustacchi         MM_RELEASE_CID_LOCK(pdev);
534d14abf15SRobert Mustacchi 
535d14abf15SRobert Mustacchi         return;
536d14abf15SRobert Mustacchi     }
537d14abf15SRobert Mustacchi 
538d14abf15SRobert Mustacchi     h_val = context->array[cid].h_val;
539d14abf15SRobert Mustacchi     hash_entry = &context->searcher_hash.searcher_table[h_val];
540d14abf15SRobert Mustacchi 
541d14abf15SRobert Mustacchi     if (context->array[cid].ip_type == LM_IP_TYPE_V6) {
542d14abf15SRobert Mustacchi         DbgBreakIf(!hash_entry->num_ipv6);
543d14abf15SRobert Mustacchi         hash_entry->num_ipv6--;
544d14abf15SRobert Mustacchi     }
545d14abf15SRobert Mustacchi     else
546d14abf15SRobert Mustacchi     {
547d14abf15SRobert Mustacchi         DbgBreakIf(!hash_entry->num_ipv4);
548d14abf15SRobert Mustacchi         hash_entry->num_ipv4--;
549d14abf15SRobert Mustacchi         if (hash_entry->num_ipv4 < hash_entry->depth_ipv4)
550d14abf15SRobert Mustacchi         {
551d14abf15SRobert Mustacchi             hash_entry->depth_ipv4 = hash_entry->num_ipv4;
552d14abf15SRobert Mustacchi         }
553d14abf15SRobert Mustacchi     }
554d14abf15SRobert Mustacchi 
555d14abf15SRobert Mustacchi     /* for debug */
556d14abf15SRobert Mustacchi     context->searcher_hash.num_tuples--;
557d14abf15SRobert Mustacchi 
558d14abf15SRobert Mustacchi     /* clear the entry of the context */
559d14abf15SRobert Mustacchi     context->array[cid].ip_type = 0;
560d14abf15SRobert Mustacchi     context->array[cid].h_val = 0;
561d14abf15SRobert Mustacchi 
562d14abf15SRobert Mustacchi     /* release spinlock */
563d14abf15SRobert Mustacchi     MM_RELEASE_CID_LOCK(pdev);
564d14abf15SRobert Mustacchi }
565d14abf15SRobert Mustacchi 
566d14abf15SRobert Mustacchi /*  allocate a free context by type
567d14abf15SRobert Mustacchi     returns CID in the out_cid param
568d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS for available cid
569d14abf15SRobert Mustacchi     LM_STATUS_RESOURCE if no cids are available
570d14abf15SRobert Mustacchi     LM_STATUS_PENDING if there is a pending cfc-delete cid
571d14abf15SRobert Mustacchi     takes the list spinlock */
lm_allocate_cid(struct _lm_device_t * pdev,u32_t type,void * cookie,s32_t * out_cid)572d14abf15SRobert Mustacchi lm_status_t lm_allocate_cid(struct _lm_device_t *pdev, u32_t type, void * cookie, s32_t * out_cid){
573d14abf15SRobert Mustacchi 
574d14abf15SRobert Mustacchi     lm_context_info_t  *context  = NULL;
575d14abf15SRobert Mustacchi     lm_status_t        lm_status = LM_STATUS_SUCCESS;
576d14abf15SRobert Mustacchi     u32_t              cid       = (u32_t)-1;
577d14abf15SRobert Mustacchi     lm_address_t       phy_addr  = {{0}} ;
578d14abf15SRobert Mustacchi 
579d14abf15SRobert Mustacchi     if ( CHK_NULL(out_cid) ||
580d14abf15SRobert Mustacchi          CHK_NULL(pdev) ||
581d14abf15SRobert Mustacchi          CHK_NULL(pdev->context_info) ||
582d14abf15SRobert Mustacchi          CHK_NULL(pdev->context_info->array) ||
583d14abf15SRobert Mustacchi          CHK_NULL(cookie) ||
584d14abf15SRobert Mustacchi          ERR_IF(type >= ARRSIZE(pdev->context_info->proto_pending)) )
585d14abf15SRobert Mustacchi 
586d14abf15SRobert Mustacchi     {
587d14abf15SRobert Mustacchi         DbgBreakIf(!out_cid) ;
588d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
589d14abf15SRobert Mustacchi         DbgBreakIf(!pdev->context_info);
590d14abf15SRobert Mustacchi         DbgBreakIf(!pdev->context_info->array);
591d14abf15SRobert Mustacchi         DbgBreakIf(!cookie);
592d14abf15SRobert Mustacchi         DbgBreakIf(type >= ARRSIZE(pdev->context_info->proto_pending)) ;
593d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER ;
594d14abf15SRobert Mustacchi     }
595d14abf15SRobert Mustacchi 
596d14abf15SRobert Mustacchi     context = pdev->context_info;
597d14abf15SRobert Mustacchi     *out_cid = 0;
598d14abf15SRobert Mustacchi     /* take spinlock */
599d14abf15SRobert Mustacchi     MM_ACQUIRE_CID_LOCK(pdev);
600d14abf15SRobert Mustacchi 
601d14abf15SRobert Mustacchi     // if the free list is empty return error
602d14abf15SRobert Mustacchi     if (context->proto_ffree[type]==0) {
603d14abf15SRobert Mustacchi         if ((pdev->params.cid_allocation_mode == LM_CID_ALLOC_REGULAR) || (context->proto_pending[type] == 0)) {
604d14abf15SRobert Mustacchi             // if the free list is empty AND the pending list is empty return error OR
605d14abf15SRobert Mustacchi             // the free list is empty and we're in the regular allocating mode
606d14abf15SRobert Mustacchi             lm_status = LM_STATUS_RESOURCE;
607d14abf15SRobert Mustacchi         }
608d14abf15SRobert Mustacchi         else
609d14abf15SRobert Mustacchi         {
610d14abf15SRobert Mustacchi             /* pop pendinglist entry and place cookie */
611d14abf15SRobert Mustacchi             /* we only use the cid to connect between the pending connection and this cid, but
612d14abf15SRobert Mustacchi              * the connection can't know of this cid before it is acually freed, for this reason
613d14abf15SRobert Mustacchi              * we return cid = 0, which means, 'pending' */
614d14abf15SRobert Mustacchi             cid = context->proto_pending[type];
615d14abf15SRobert Mustacchi             context->proto_pending[type] = context->array[cid].next;
616d14abf15SRobert Mustacchi             context->array[cid].next = 0;
617d14abf15SRobert Mustacchi             context->array[cid].cid_resc.cookies[type] = cookie;
618d14abf15SRobert Mustacchi             context->array[cid].cid_resc.cid_pending = LM_CID_STATE_PENDING;
619d14abf15SRobert Mustacchi             lm_sp_req_manager_init(pdev, cid);
620d14abf15SRobert Mustacchi             *out_cid = cid;
621d14abf15SRobert Mustacchi 
622d14abf15SRobert Mustacchi             /* make sure the first cid previous is set correctly*/
623d14abf15SRobert Mustacchi             cid = context->proto_pending[type];
624d14abf15SRobert Mustacchi             if (cid) {
625d14abf15SRobert Mustacchi                 context->array[cid].prev = 0;
626d14abf15SRobert Mustacchi             }
627d14abf15SRobert Mustacchi             lm_status = LM_STATUS_PENDING;
628d14abf15SRobert Mustacchi         }
629d14abf15SRobert Mustacchi     }else{
630d14abf15SRobert Mustacchi         /* pop freelist entry and place cookie*/
631d14abf15SRobert Mustacchi         cid = context->proto_ffree[type];
632d14abf15SRobert Mustacchi         context->proto_ffree[type] = context->array[cid].next;
633d14abf15SRobert Mustacchi         context->array[cid].next = 0;
634d14abf15SRobert Mustacchi         context->array[cid].prev = 0;
635d14abf15SRobert Mustacchi         context->array[cid].cid_resc.cookies[type] = cookie;
636d14abf15SRobert Mustacchi         lm_sp_req_manager_init(pdev, cid);
637d14abf15SRobert Mustacchi         *out_cid = cid;
638d14abf15SRobert Mustacchi         lm_status = LM_STATUS_SUCCESS;
639d14abf15SRobert Mustacchi     }
640d14abf15SRobert Mustacchi 
641d14abf15SRobert Mustacchi     MM_RELEASE_CID_LOCK(pdev);
642d14abf15SRobert Mustacchi 
643d14abf15SRobert Mustacchi     if(LM_STATUS_SUCCESS == lm_status)
644d14abf15SRobert Mustacchi     {
645d14abf15SRobert Mustacchi         //If the function allocated a new free CID, (not pending) the function MmMapIoSpace will be called
646d14abf15SRobert Mustacchi         //to map the specific physical cid doorbell space to a virtual address.
647d14abf15SRobert Mustacchi         //In case of a pending CID, the map doorbell space will not be remapped. The pending CID will use
648d14abf15SRobert Mustacchi         //the old mapping cid doorbell space.
649d14abf15SRobert Mustacchi         phy_addr.as_u32.low = (pdev->hw_info.mem_base[BAR_1].as_u32.low) & 0xfffffff0;
650d14abf15SRobert Mustacchi         phy_addr.as_u32.high = pdev->hw_info.mem_base[BAR_1].as_u32.high;
651d14abf15SRobert Mustacchi 
652d14abf15SRobert Mustacchi         LM_INC64(&phy_addr,(cid*LM_DQ_CID_SIZE));
653d14abf15SRobert Mustacchi 
654d14abf15SRobert Mustacchi #ifdef __SunOS
655d14abf15SRobert Mustacchi 
656d14abf15SRobert Mustacchi         context->array[cid].cid_resc.mapped_cid_bar_addr =
657d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
658d14abf15SRobert Mustacchi             (volatile void *)((u8_t*)pdev->vars.mapped_bar_addr[BAR_1] + cid*LM_DQ_CID_SIZE);
659d14abf15SRobert Mustacchi         context->array[cid].cid_resc.reg_handle = pdev->vars.reg_handle[BAR_1];
660d14abf15SRobert Mustacchi #else /* !VF_INVOLVED */
661d14abf15SRobert Mustacchi             (volatile void *)mm_map_io_space_solaris(pdev,
662d14abf15SRobert Mustacchi                                                      phy_addr,
663d14abf15SRobert Mustacchi                                                      BAR_1,
664d14abf15SRobert Mustacchi                                                      (cid * LM_DQ_CID_SIZE),
665d14abf15SRobert Mustacchi                                                      LM_DQ_CID_SIZE,
666d14abf15SRobert Mustacchi                                                      &context->array[cid].cid_resc.reg_handle);
667d14abf15SRobert Mustacchi #endif /* VF_INVOLVED */
668d14abf15SRobert Mustacchi 
669d14abf15SRobert Mustacchi #else /* !__SunOS */
670d14abf15SRobert Mustacchi 
671d14abf15SRobert Mustacchi         context->array[cid].cid_resc.mapped_cid_bar_addr =
672d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
673d14abf15SRobert Mustacchi             (volatile void *)((u8_t*)pdev->vars.mapped_bar_addr[BAR_1] + cid*LM_DQ_CID_SIZE);
674d14abf15SRobert Mustacchi #else /* !VF_INVOLVED */
675d14abf15SRobert Mustacchi             (volatile void *)mm_map_io_space(pdev, phy_addr, LM_DQ_CID_SIZE);
676d14abf15SRobert Mustacchi #endif /* VF_INVOLVED */
677d14abf15SRobert Mustacchi 
678d14abf15SRobert Mustacchi #endif /* __SunOS */
679d14abf15SRobert Mustacchi 
680d14abf15SRobert Mustacchi         // If the mapping failed we will return LM_STATUS_RESOURCE and return the cid resource.
681d14abf15SRobert Mustacchi         if CHK_NULL(context->array[cid].cid_resc.mapped_cid_bar_addr)
682d14abf15SRobert Mustacchi         {
683d14abf15SRobert Mustacchi             DbgMessage(pdev, FATAL, "lm_allocate_cid: mm_map_io_space failed. address low=%d address high=%d\n", phy_addr.as_u32.low,phy_addr.as_u32.high );
684d14abf15SRobert Mustacchi 
685d14abf15SRobert Mustacchi             /* take spinlock */
686d14abf15SRobert Mustacchi             MM_ACQUIRE_CID_LOCK(pdev);
687d14abf15SRobert Mustacchi             /* return the cid to free list */
688d14abf15SRobert Mustacchi             context->array[cid].next = pdev->context_info->proto_ffree[type];
689d14abf15SRobert Mustacchi             context->proto_ffree[type] = cid;
690d14abf15SRobert Mustacchi             context->array[cid].invalid = LM_CONTEXT_VALID;
691d14abf15SRobert Mustacchi             MM_RELEASE_CID_LOCK(pdev);
692d14abf15SRobert Mustacchi 
693d14abf15SRobert Mustacchi             lm_status = LM_STATUS_RESOURCE;
694d14abf15SRobert Mustacchi             *out_cid =0;
695d14abf15SRobert Mustacchi         }
696d14abf15SRobert Mustacchi     }
697d14abf15SRobert Mustacchi     return lm_status;
698d14abf15SRobert Mustacchi }
699d14abf15SRobert Mustacchi 
lm_cfc_delete(struct _lm_device_t * pdev,void * param)700d14abf15SRobert Mustacchi void lm_cfc_delete(struct _lm_device_t *pdev, void *param)
701d14abf15SRobert Mustacchi {
702*dd980e63SToomas Soome     u32_t cid             = (u32_t)(uintptr_t)param;
703d14abf15SRobert Mustacchi     u8_t  flr_in_progress = lm_fl_reset_is_inprogress(pdev);
704d14abf15SRobert Mustacchi 
705d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
706d14abf15SRobert Mustacchi          ERR_IF(cid > pdev->params.max_func_connections) ||
707d14abf15SRobert Mustacchi          ERR_IF(pdev->context_info->array[cid].invalid != LM_CONTEXT_INVALID_WAIT) )
708d14abf15SRobert Mustacchi     {
709d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
710d14abf15SRobert Mustacchi         DbgBreakIf(cid > pdev->params.max_func_connections);
711d14abf15SRobert Mustacchi 
712d14abf15SRobert Mustacchi         if (!flr_in_progress)
713d14abf15SRobert Mustacchi         {
714d14abf15SRobert Mustacchi             DbgBreakIf(pdev->context_info->array[cid].invalid != LM_CONTEXT_INVALID_WAIT);
715d14abf15SRobert Mustacchi         }
716d14abf15SRobert Mustacchi         else
717d14abf15SRobert Mustacchi         {
718d14abf15SRobert Mustacchi             DbgMessage(pdev, FATAL, "lm_cfc_delete: invalid %d for cid=%d\n", pdev->context_info->array[cid].invalid,cid);
719d14abf15SRobert Mustacchi 
720d14abf15SRobert Mustacchi             if (pdev->context_info->array[cid].invalid != LM_CONTEXT_INVALID_DELETE)
721d14abf15SRobert Mustacchi             {
722d14abf15SRobert Mustacchi                 DbgBreakIf(1);
723d14abf15SRobert Mustacchi             }
724d14abf15SRobert Mustacchi         }
725d14abf15SRobert Mustacchi     }
726d14abf15SRobert Mustacchi 
727d14abf15SRobert Mustacchi     DbgMessage(pdev, WARN, "lm_cfc_delete: cid=0x%x\n",cid);
728d14abf15SRobert Mustacchi     pdev->context_info->array[cid].invalid = LM_CONTEXT_INVALID_DELETE;
729d14abf15SRobert Mustacchi 
730d14abf15SRobert Mustacchi     if (lm_fl_reset_is_inprogress(pdev))
731d14abf15SRobert Mustacchi     {
732d14abf15SRobert Mustacchi          lm_recycle_cid(pdev, cid);
733d14abf15SRobert Mustacchi     }
734d14abf15SRobert Mustacchi     else
735d14abf15SRobert Mustacchi     {
736d14abf15SRobert Mustacchi         /* use common bit */
737d14abf15SRobert Mustacchi         lm_command_post(pdev,
738d14abf15SRobert Mustacchi                         cid,
739d14abf15SRobert Mustacchi                         RAMROD_CMD_ID_COMMON_CFC_DEL,
740d14abf15SRobert Mustacchi                         CMD_PRIORITY_NORMAL,
741d14abf15SRobert Mustacchi                         NONE_CONNECTION_TYPE,
742d14abf15SRobert Mustacchi                         0 );
743d14abf15SRobert Mustacchi     }
744d14abf15SRobert Mustacchi     return;
745d14abf15SRobert Mustacchi }
746d14abf15SRobert Mustacchi 
747d14abf15SRobert Mustacchi /* free a context
748d14abf15SRobert Mustacchi    takes the list spinlock */
lm_free_cid(struct _lm_device_t * pdev,u32_t type,u32_t cid,u8_t notify_fw)749d14abf15SRobert Mustacchi void lm_free_cid(struct _lm_device_t *pdev, u32_t type, u32_t cid, u8_t notify_fw){
750d14abf15SRobert Mustacchi     u32_t delay_time  = 0;
751d14abf15SRobert Mustacchi     u32_t curr_cid    = 0;
752d14abf15SRobert Mustacchi     u8_t  recycle_now = 0;
753d14abf15SRobert Mustacchi     u8_t  proto_idx   = 0;
754d14abf15SRobert Mustacchi 
755d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
756d14abf15SRobert Mustacchi          CHK_NULL(pdev->context_info) ||
757d14abf15SRobert Mustacchi          ERR_IF(type >= ARRSIZE(pdev->context_info->proto_end)) ||
758d14abf15SRobert Mustacchi          ERR_IF(cid > (pdev->context_info->proto_end[type])) ||
759d14abf15SRobert Mustacchi          ERR_IF(cid < (pdev->context_info->proto_start[type])) ||
760d14abf15SRobert Mustacchi          (!lm_fl_reset_is_inprogress(pdev) && (pdev->context_info->array[cid].invalid != LM_CONTEXT_VALID)))
761d14abf15SRobert Mustacchi     {
762d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
763d14abf15SRobert Mustacchi         DbgBreakIf(!pdev->context_info);
764d14abf15SRobert Mustacchi         DbgBreakIf(type >= ARRSIZE(pdev->context_info->proto_end));
765d14abf15SRobert Mustacchi         DbgBreakIf(cid > (pdev->context_info->proto_end[type]));
766d14abf15SRobert Mustacchi         DbgBreakIf(cid < (pdev->context_info->proto_start[type]));
767d14abf15SRobert Mustacchi         DbgBreakIf(pdev->context_info->array[cid].invalid != LM_CONTEXT_VALID);
768d14abf15SRobert Mustacchi         return;
769d14abf15SRobert Mustacchi     }
770d14abf15SRobert Mustacchi     MM_ACQUIRE_CID_LOCK(pdev);
771d14abf15SRobert Mustacchi 
772d14abf15SRobert Mustacchi     for (proto_idx = 0; proto_idx < MAX_PROTO; proto_idx++)
773d14abf15SRobert Mustacchi     {
774d14abf15SRobert Mustacchi         DbgBreakIf(pdev->context_info->array[cid].cid_resc.cookies[proto_idx]);
775d14abf15SRobert Mustacchi     }
776d14abf15SRobert Mustacchi 
777d14abf15SRobert Mustacchi     lm_sp_req_manager_shutdown(pdev, cid);
778d14abf15SRobert Mustacchi 
779d14abf15SRobert Mustacchi     if (notify_fw)
780d14abf15SRobert Mustacchi     {
781d14abf15SRobert Mustacchi         /* Vladz: Added in order to optimize CID release in DOS */
782d14abf15SRobert Mustacchi #if !(defined(DOS) || defined(__LINUX))
783d14abf15SRobert Mustacchi         delay_time = LM_FREE_CID_DELAY_TIME(pdev);
784d14abf15SRobert Mustacchi #else
785d14abf15SRobert Mustacchi         delay_time = 0;
786d14abf15SRobert Mustacchi #endif
787d14abf15SRobert Mustacchi 
788d14abf15SRobert Mustacchi         pdev->context_info->array[cid].invalid = LM_CONTEXT_INVALID_WAIT;
789d14abf15SRobert Mustacchi 
790d14abf15SRobert Mustacchi         recycle_now = FALSE;
791d14abf15SRobert Mustacchi         /* add the cid to proto-pending: it'll be freed soon when cfc-delete is done */
792d14abf15SRobert Mustacchi         curr_cid = pdev->context_info->proto_pending[type];
793d14abf15SRobert Mustacchi         pdev->context_info->array[cid].next = curr_cid;
794d14abf15SRobert Mustacchi         pdev->context_info->array[cid].prev = 0;
795d14abf15SRobert Mustacchi         if (curr_cid != 0)
796d14abf15SRobert Mustacchi         {
797d14abf15SRobert Mustacchi             pdev->context_info->array[curr_cid].prev = cid;
798d14abf15SRobert Mustacchi         }
799d14abf15SRobert Mustacchi         pdev->context_info->proto_pending[type] = cid;
800d14abf15SRobert Mustacchi     }
801d14abf15SRobert Mustacchi     else
802d14abf15SRobert Mustacchi     {
803d14abf15SRobert Mustacchi         pdev->context_info->array[cid].invalid = LM_CONTEXT_INVALID_DELETE;
804d14abf15SRobert Mustacchi         recycle_now = TRUE;
805d14abf15SRobert Mustacchi         /* If we're recylcing now, there's no point in adding it to the pending list */
806d14abf15SRobert Mustacchi     }
807d14abf15SRobert Mustacchi 
808d14abf15SRobert Mustacchi     MM_RELEASE_CID_LOCK(pdev);
809d14abf15SRobert Mustacchi 
810d14abf15SRobert Mustacchi     if (recycle_now) {
811d14abf15SRobert Mustacchi         lm_recycle_cid(pdev, cid);
812d14abf15SRobert Mustacchi     }
813d14abf15SRobert Mustacchi     else
814d14abf15SRobert Mustacchi     {
815d14abf15SRobert Mustacchi         if (type == TOE_CONNECTION_TYPE)
816d14abf15SRobert Mustacchi         {
817d14abf15SRobert Mustacchi             DbgMessage(pdev, WARN, "lm_free_cid: CFC delete: cid=0x%x\n",cid);
818*dd980e63SToomas Soome             lm_cfc_delete(pdev,(void *)(uintptr_t)cid);
819d14abf15SRobert Mustacchi         }
820d14abf15SRobert Mustacchi         else
821d14abf15SRobert Mustacchi         {
822d14abf15SRobert Mustacchi             DbgMessage(pdev, WARN, "lm_free_cid: schedule CFC delete: cid=0x%x\n",cid);
823*dd980e63SToomas Soome             mm_schedule_task(pdev,delay_time,lm_cfc_delete,
824*dd980e63SToomas Soome 		(void *)(uintptr_t)cid);
825d14abf15SRobert Mustacchi         }
826d14abf15SRobert Mustacchi     }
827d14abf15SRobert Mustacchi 
828d14abf15SRobert Mustacchi }
829d14abf15SRobert Mustacchi 
lm_recycle_cid(struct _lm_device_t * pdev,u32_t cid)830d14abf15SRobert Mustacchi void lm_recycle_cid(struct _lm_device_t *pdev, u32_t cid){
831d14abf15SRobert Mustacchi 
832d14abf15SRobert Mustacchi     u32_t type = MAX_PROTO+1;
833d14abf15SRobert Mustacchi     u32_t prev_cid, next_cid;
834d14abf15SRobert Mustacchi     u32_t i;
835d14abf15SRobert Mustacchi     u8_t  call_cb = TRUE;
836d14abf15SRobert Mustacchi 
837d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
838d14abf15SRobert Mustacchi          ERR_IF(pdev->context_info->array[cid].invalid != LM_CONTEXT_INVALID_DELETE) ||
839d14abf15SRobert Mustacchi          ERR_IF(cid > pdev->params.max_func_connections) )
840d14abf15SRobert Mustacchi     {
841d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
842d14abf15SRobert Mustacchi         DbgBreakIf(pdev->context_info->array[cid].invalid != LM_CONTEXT_INVALID_DELETE);
843d14abf15SRobert Mustacchi         DbgBreakIf(cid > pdev->params.max_func_connections);
844d14abf15SRobert Mustacchi         return;
845d14abf15SRobert Mustacchi     }
846d14abf15SRobert Mustacchi 
847d14abf15SRobert Mustacchi     for (i=0; i < MAX_PROTO; i++ ) {
848d14abf15SRobert Mustacchi         if ((cid >= pdev->context_info->proto_start[i]) && (cid <= pdev->context_info->proto_end[i]))
849d14abf15SRobert Mustacchi         {
850d14abf15SRobert Mustacchi             type = i;
851d14abf15SRobert Mustacchi             break;
852d14abf15SRobert Mustacchi         }
853d14abf15SRobert Mustacchi     }
854d14abf15SRobert Mustacchi     if ERR_IF(type >= ARRSIZE(pdev->context_info->proto_pending))
855d14abf15SRobert Mustacchi     {
856d14abf15SRobert Mustacchi         DbgBreakIf(type >= ARRSIZE(pdev->context_info->proto_pending)) ;
857d14abf15SRobert Mustacchi         return;
858d14abf15SRobert Mustacchi     }
859d14abf15SRobert Mustacchi     /* take spinlock */
860d14abf15SRobert Mustacchi     MM_ACQUIRE_CID_LOCK(pdev);
861d14abf15SRobert Mustacchi #ifdef _VBD_
862d14abf15SRobert Mustacchi     if ((type == TOE_CONNECTION_TYPE) && (pdev->ofld_info.l4_params.ticks_per_second != 0))
863d14abf15SRobert Mustacchi     {
864d14abf15SRobert Mustacchi         pdev->vars.last_recycling_timestamp = mm_get_current_time(pdev) * 1000 / pdev->ofld_info.l4_params.ticks_per_second; /*time in ms*/
865d14abf15SRobert Mustacchi     }
866d14abf15SRobert Mustacchi #endif
867d14abf15SRobert Mustacchi     /* If no cookie is waiting on this cid extract from pending and push enrty into the freelist */
868d14abf15SRobert Mustacchi     if (pdev->context_info->array[cid].cid_resc.cid_pending == FALSE) {
869d14abf15SRobert Mustacchi         /* take the cid out of the proto_pending cids if it's there */
870d14abf15SRobert Mustacchi         prev_cid = pdev->context_info->array[cid].prev;
871d14abf15SRobert Mustacchi         next_cid = pdev->context_info->array[cid].next;
872d14abf15SRobert Mustacchi         if (prev_cid) {
873d14abf15SRobert Mustacchi             pdev->context_info->array[prev_cid].next = next_cid;
874d14abf15SRobert Mustacchi         }
875d14abf15SRobert Mustacchi         if (next_cid) {
876d14abf15SRobert Mustacchi             pdev->context_info->array[next_cid].prev = prev_cid;
877d14abf15SRobert Mustacchi         }
878d14abf15SRobert Mustacchi         if (pdev->context_info->proto_pending[type] == cid) {
879d14abf15SRobert Mustacchi             DbgBreakIf(prev_cid != 0);
880d14abf15SRobert Mustacchi             pdev->context_info->proto_pending[type] = next_cid;
881d14abf15SRobert Mustacchi         }
882d14abf15SRobert Mustacchi         pdev->context_info->array[cid].prev = pdev->context_info->array[cid].next = 0;
883d14abf15SRobert Mustacchi         /* add to free list */
884d14abf15SRobert Mustacchi         pdev->context_info->array[cid].next = pdev->context_info->proto_ffree[type];
885d14abf15SRobert Mustacchi         pdev->context_info->array[cid].invalid = LM_CONTEXT_VALID;
886d14abf15SRobert Mustacchi         pdev->context_info->array[cid].cfc_delete_cnt = 0;
887d14abf15SRobert Mustacchi         pdev->context_info->proto_ffree[type] = cid;
888d14abf15SRobert Mustacchi         call_cb = FALSE; /* no one is waiting on this... */
889d14abf15SRobert Mustacchi         //free virtual memory for cids not in use.
890d14abf15SRobert Mustacchi #ifndef VF_INVOLVED
891d14abf15SRobert Mustacchi         mm_unmap_io_space(pdev,(void *)pdev->context_info->array[cid].cid_resc.mapped_cid_bar_addr, LM_DQ_CID_SIZE);
892d14abf15SRobert Mustacchi #endif
893d14abf15SRobert Mustacchi     }
894d14abf15SRobert Mustacchi     else
895d14abf15SRobert Mustacchi     {
896d14abf15SRobert Mustacchi         /* No need to extract from pending - it's not there. */
897d14abf15SRobert Mustacchi 
898d14abf15SRobert Mustacchi         /* NirV: we still can't set cid_resc.cid_pending to false, */
899d14abf15SRobert Mustacchi         /* will be possible only in the callback */
900d14abf15SRobert Mustacchi 
901d14abf15SRobert Mustacchi         pdev->context_info->array[cid].invalid = LM_CONTEXT_VALID;
902d14abf15SRobert Mustacchi         call_cb = TRUE;
903d14abf15SRobert Mustacchi     }
904d14abf15SRobert Mustacchi 
905d14abf15SRobert Mustacchi     /* time to clear the active bit (cdu-validation ) we can only do this after cfc-delete has completed, at this point, invalid==LM_CONTEXT_VALID */
906d14abf15SRobert Mustacchi     lm_set_cdu_validation_data(pdev, cid, TRUE /* Invalidate */);
907d14abf15SRobert Mustacchi 
908d14abf15SRobert Mustacchi 
909d14abf15SRobert Mustacchi     /* rlease spinlock */
910d14abf15SRobert Mustacchi     MM_RELEASE_CID_LOCK(pdev);
911d14abf15SRobert Mustacchi 
912d14abf15SRobert Mustacchi     /* call here the cid recycle callback of that
913d14abf15SRobert Mustacchi        protocol type if such cb exists*/
914d14abf15SRobert Mustacchi     if (pdev->cid_recycled_callbacks[type] && call_cb) {
915d14abf15SRobert Mustacchi         pdev->cid_recycled_callbacks[type](pdev, pdev->context_info->array[cid].cid_resc.cookies[type], cid);
916d14abf15SRobert Mustacchi     }
917d14abf15SRobert Mustacchi 
918d14abf15SRobert Mustacchi     return;
919d14abf15SRobert Mustacchi }
920d14abf15SRobert Mustacchi 
921d14abf15SRobert Mustacchi /* lookup the protocol cookie for a given CID
922d14abf15SRobert Mustacchi    does not take a lock
923d14abf15SRobert Mustacchi    will DbgBreakIf( if the CID is not allocated. */
lm_cid_cookie(struct _lm_device_t * pdev,u32_t type,u32_t cid)924d14abf15SRobert Mustacchi void * lm_cid_cookie(struct _lm_device_t *pdev, u32_t type, u32_t cid){
925d14abf15SRobert Mustacchi 
926d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
927d14abf15SRobert Mustacchi          CHK_NULL(pdev->context_info) ||
928d14abf15SRobert Mustacchi          ERR_IF(type >= MAX_PROTO) ||
929d14abf15SRobert Mustacchi          ERR_IF(cid > (pdev->context_info->proto_end[MAX_PROTO - 1])) ||
930d14abf15SRobert Mustacchi          CHK_NULL(pdev->context_info->array[cid].cid_resc.cookies[type]) ||
931d14abf15SRobert Mustacchi          ERR_IF(pdev->context_info->array[cid].invalid != LM_CONTEXT_VALID) )
932d14abf15SRobert Mustacchi     {
933d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
934d14abf15SRobert Mustacchi         DbgBreakIf(!pdev->context_info);
935d14abf15SRobert Mustacchi         DbgBreakIf(type >= MAX_PROTO);
936d14abf15SRobert Mustacchi         DbgBreakIf(cid > (pdev->context_info->proto_end[MAX_PROTO - 1]));
937d14abf15SRobert Mustacchi         DbgBreakIf(pdev->context_info->array[cid].invalid != LM_CONTEXT_VALID);
938d14abf15SRobert Mustacchi     }
939d14abf15SRobert Mustacchi 
940d14abf15SRobert Mustacchi     if (pdev->context_info->array[cid].cid_resc.cookies[type] == NULL)
941d14abf15SRobert Mustacchi     {
942d14abf15SRobert Mustacchi         return NULL;
943d14abf15SRobert Mustacchi     }
944d14abf15SRobert Mustacchi 
945d14abf15SRobert Mustacchi 
946d14abf15SRobert Mustacchi     /* if the cid is pending, return null */
947d14abf15SRobert Mustacchi     if (pdev->context_info->array[cid].cid_resc.cid_pending != LM_CID_STATE_VALID)
948d14abf15SRobert Mustacchi     {
949d14abf15SRobert Mustacchi         return NULL;
950d14abf15SRobert Mustacchi     }
951d14abf15SRobert Mustacchi 
952d14abf15SRobert Mustacchi     return pdev->context_info->array[cid].cid_resc.cookies[type];
953d14abf15SRobert Mustacchi }
954d14abf15SRobert Mustacchi 
955d14abf15SRobert Mustacchi /* lookup the protocol cid_resc for a given CID
956d14abf15SRobert Mustacchi    does not take a lock
957d14abf15SRobert Mustacchi    will DbgBreakIf( if the CID is not allocated */
lm_cid_resc(struct _lm_device_t * pdev,u32_t cid)958d14abf15SRobert Mustacchi lm_cid_resc_t * lm_cid_resc(struct _lm_device_t *pdev, u32_t cid){
959d14abf15SRobert Mustacchi 
960d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
961d14abf15SRobert Mustacchi          CHK_NULL(pdev->context_info) ||
962d14abf15SRobert Mustacchi          ERR_IF(cid > (pdev->context_info->proto_end[MAX_PROTO - 1])) )
963d14abf15SRobert Mustacchi     {
964d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
965d14abf15SRobert Mustacchi         DbgBreakIf(!pdev->context_info);
966d14abf15SRobert Mustacchi         DbgBreakIf(cid > (pdev->context_info->proto_end[MAX_PROTO - 1]));
967d14abf15SRobert Mustacchi     }
968d14abf15SRobert Mustacchi 
969d14abf15SRobert Mustacchi     return &pdev->context_info->array[cid].cid_resc;
970d14abf15SRobert Mustacchi }
971d14abf15SRobert Mustacchi 
lm_map_cid_to_proto(struct _lm_device_t * pdev,u32_t cid)972d14abf15SRobert Mustacchi u8_t lm_map_cid_to_proto(struct _lm_device_t * pdev, u32_t cid)
973d14abf15SRobert Mustacchi {
974d14abf15SRobert Mustacchi     u8_t type = MAX_PROTO+1;
975d14abf15SRobert Mustacchi     u8_t i;
976d14abf15SRobert Mustacchi 
977d14abf15SRobert Mustacchi     if (!pdev || cid > pdev->params.max_func_connections) {
978d14abf15SRobert Mustacchi         return type;
979d14abf15SRobert Mustacchi     }
980d14abf15SRobert Mustacchi 
981d14abf15SRobert Mustacchi     for (i=0; i < MAX_PROTO; i++ ) {
982d14abf15SRobert Mustacchi         if ((cid >= pdev->context_info->proto_start[i]) && (cid <= pdev->context_info->proto_end[i]))  {
983d14abf15SRobert Mustacchi             type = i;
984d14abf15SRobert Mustacchi             break;
985d14abf15SRobert Mustacchi         }
986d14abf15SRobert Mustacchi     }
987d14abf15SRobert Mustacchi     return type;
988d14abf15SRobert Mustacchi }
989d14abf15SRobert Mustacchi 
lm_init_connection_context(struct _lm_device_t * pdev,u32_t const sw_cid,u8_t sb_id)990d14abf15SRobert Mustacchi void lm_init_connection_context(struct _lm_device_t *pdev, u32_t const sw_cid, u8_t sb_id)
991d14abf15SRobert Mustacchi {
992d14abf15SRobert Mustacchi     struct eth_context * context      = NULL;
993d14abf15SRobert Mustacchi 
994d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
995d14abf15SRobert Mustacchi          ERR_IF(sw_cid < PFDEV(pdev)->context_info->proto_start[ETH_CONNECTION_TYPE]) ||
996d14abf15SRobert Mustacchi          ERR_IF(sw_cid > PFDEV(pdev)->context_info->proto_end[ETH_CONNECTION_TYPE]) )
997d14abf15SRobert Mustacchi     {
998d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
999d14abf15SRobert Mustacchi         DbgBreakIf(sw_cid < PFDEV(pdev)->context_info->proto_start[ETH_CONNECTION_TYPE]); /* first legal NIC CID */
1000d14abf15SRobert Mustacchi         DbgBreakIf(sw_cid > PFDEV(pdev)->context_info->proto_end[ETH_CONNECTION_TYPE]);   /* last legal NIC CID */
1001d14abf15SRobert Mustacchi     }
1002d14abf15SRobert Mustacchi 
1003d14abf15SRobert Mustacchi     context = lm_get_context(PFDEV(pdev), VF_TO_PF_CID(pdev,sw_cid));
1004d14abf15SRobert Mustacchi 
1005d14abf15SRobert Mustacchi     mm_mem_zero( context, sizeof(struct eth_context) ) ;
1006d14abf15SRobert Mustacchi 
1007d14abf15SRobert Mustacchi     /* calculate the cdu-validation value. */
1008d14abf15SRobert Mustacchi     lm_set_cdu_validation_data(pdev, VF_TO_PF_CID(pdev,sw_cid), FALSE /* don't invalidate */);
1009d14abf15SRobert Mustacchi 
1010d14abf15SRobert Mustacchi }
1011d14abf15SRobert Mustacchi 
1012d14abf15SRobert Mustacchi lm_status_t
lm_set_cid_resc(IN struct _lm_device_t * pdev,IN u32_t type,IN void * cookie,IN u32_t cid)1013d14abf15SRobert Mustacchi lm_set_cid_resc(
1014d14abf15SRobert Mustacchi     IN struct _lm_device_t *pdev,
1015d14abf15SRobert Mustacchi     IN u32_t type,
1016d14abf15SRobert Mustacchi     IN void *cookie,
1017d14abf15SRobert Mustacchi     IN u32_t cid)
1018d14abf15SRobert Mustacchi {
1019d14abf15SRobert Mustacchi     lm_status_t     lm_status  = LM_STATUS_SUCCESS;
1020d14abf15SRobert Mustacchi     lm_cid_resc_t   *cid_resc  = NULL;
1021d14abf15SRobert Mustacchi 
1022d14abf15SRobert Mustacchi     if CHK_NULL(pdev)
1023d14abf15SRobert Mustacchi     {
1024d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1025d14abf15SRobert Mustacchi     }
1026d14abf15SRobert Mustacchi 
1027d14abf15SRobert Mustacchi     /* take spinlock */
1028d14abf15SRobert Mustacchi     MM_ACQUIRE_CID_LOCK(pdev);
1029d14abf15SRobert Mustacchi 
1030d14abf15SRobert Mustacchi     cid_resc = lm_cid_resc(pdev, cid);
1031d14abf15SRobert Mustacchi 
1032d14abf15SRobert Mustacchi     if CHK_NULL(cid_resc)
1033d14abf15SRobert Mustacchi     {
1034d14abf15SRobert Mustacchi         MM_RELEASE_CID_LOCK(pdev);
1035d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1036d14abf15SRobert Mustacchi     }
1037d14abf15SRobert Mustacchi 
1038d14abf15SRobert Mustacchi     cid_resc->cookies[type] = cookie;
1039d14abf15SRobert Mustacchi 
1040d14abf15SRobert Mustacchi     /* rlease spinlock */
1041d14abf15SRobert Mustacchi     MM_RELEASE_CID_LOCK(pdev);
1042d14abf15SRobert Mustacchi 
1043d14abf15SRobert Mustacchi     return lm_status;
1044d14abf15SRobert Mustacchi }
1045d14abf15SRobert Mustacchi 
1046d14abf15SRobert Mustacchi lm_status_t
lm_free_cid_resc(IN struct _lm_device_t * pdev,IN u32_t type,IN u32_t cid,IN u8_t notify_fw)1047d14abf15SRobert Mustacchi lm_free_cid_resc(
1048d14abf15SRobert Mustacchi     IN    struct _lm_device_t *pdev,
1049d14abf15SRobert Mustacchi     IN    u32_t type,
1050d14abf15SRobert Mustacchi     IN    u32_t cid,
1051d14abf15SRobert Mustacchi     IN    u8_t notify_fw)
1052d14abf15SRobert Mustacchi {
1053d14abf15SRobert Mustacchi     lm_cid_resc_t   *cid_resc = NULL;
1054d14abf15SRobert Mustacchi     u8_t            proto_idx = 0;
1055d14abf15SRobert Mustacchi 
1056d14abf15SRobert Mustacchi 
1057d14abf15SRobert Mustacchi     if (CHK_NULL(pdev) || (cid == 0))
1058d14abf15SRobert Mustacchi     {
1059d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1060d14abf15SRobert Mustacchi     }
1061d14abf15SRobert Mustacchi 
1062d14abf15SRobert Mustacchi     /* take spinlock */
1063d14abf15SRobert Mustacchi     MM_ACQUIRE_CID_LOCK(pdev);
1064d14abf15SRobert Mustacchi 
1065d14abf15SRobert Mustacchi     cid_resc = lm_cid_resc(pdev, cid);
1066d14abf15SRobert Mustacchi 
1067d14abf15SRobert Mustacchi     if CHK_NULL(cid_resc)
1068d14abf15SRobert Mustacchi     {
1069d14abf15SRobert Mustacchi         MM_RELEASE_CID_LOCK(pdev);
1070d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1071d14abf15SRobert Mustacchi     }
1072d14abf15SRobert Mustacchi 
1073d14abf15SRobert Mustacchi     cid_resc->cookies[type] = NULL;
1074d14abf15SRobert Mustacchi 
1075d14abf15SRobert Mustacchi     while ((proto_idx < MAX_PROTO) && (cid_resc->cookies[proto_idx] == NULL))
1076d14abf15SRobert Mustacchi     {
1077d14abf15SRobert Mustacchi         proto_idx++;
1078d14abf15SRobert Mustacchi     }
1079d14abf15SRobert Mustacchi     /* rlease spinlock */
1080d14abf15SRobert Mustacchi     MM_RELEASE_CID_LOCK(pdev);
1081d14abf15SRobert Mustacchi 
1082d14abf15SRobert Mustacchi     if (proto_idx == MAX_PROTO)
1083d14abf15SRobert Mustacchi     {
1084d14abf15SRobert Mustacchi         /* We'll call lm_map_cid_to_proto() to compute the appropriate type that was associated with that CID,
1085d14abf15SRobert Mustacchi          * this is done to avoid assert upon race scenarios in which the last cookie resource that gets freed is not from the type of the CID */
1086d14abf15SRobert Mustacchi         lm_free_cid(pdev, lm_map_cid_to_proto(pdev, cid), cid, notify_fw);
1087d14abf15SRobert Mustacchi     }
1088d14abf15SRobert Mustacchi 
1089d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
1090d14abf15SRobert Mustacchi }
1091d14abf15SRobert Mustacchi 
1092d14abf15SRobert Mustacchi 
1093d14abf15SRobert Mustacchi 
1094d14abf15SRobert Mustacchi lm_sp_req_manager_t *
lm_cid_sp_req_mgr(IN struct _lm_device_t * pdev,IN u32_t cid)1095d14abf15SRobert Mustacchi lm_cid_sp_req_mgr(
1096d14abf15SRobert Mustacchi     IN struct _lm_device_t *pdev,
1097d14abf15SRobert Mustacchi     IN u32_t cid
1098d14abf15SRobert Mustacchi     )
1099d14abf15SRobert Mustacchi {
1100d14abf15SRobert Mustacchi     lm_cid_resc_t   *cid_resc   = NULL;
1101d14abf15SRobert Mustacchi 
1102d14abf15SRobert Mustacchi     if CHK_NULL(pdev)
1103d14abf15SRobert Mustacchi     {
1104d14abf15SRobert Mustacchi         return NULL;
1105d14abf15SRobert Mustacchi     }
1106d14abf15SRobert Mustacchi 
1107d14abf15SRobert Mustacchi     cid_resc = lm_cid_resc(pdev, cid);
1108d14abf15SRobert Mustacchi 
1109d14abf15SRobert Mustacchi     if CHK_NULL(cid_resc)
1110d14abf15SRobert Mustacchi     {
1111d14abf15SRobert Mustacchi         return NULL;
1112d14abf15SRobert Mustacchi     }
1113d14abf15SRobert Mustacchi 
1114d14abf15SRobert Mustacchi     return &cid_resc->sp_req_mgr;
1115d14abf15SRobert Mustacchi }
1116d14abf15SRobert Mustacchi 
1117d14abf15SRobert Mustacchi 
1118d14abf15SRobert Mustacchi 
1119d14abf15SRobert Mustacchi lm_cid_state_enum
lm_cid_state(IN struct _lm_device_t * pdev,IN u32_t cid)1120d14abf15SRobert Mustacchi lm_cid_state(
1121d14abf15SRobert Mustacchi     IN struct _lm_device_t *pdev,
1122d14abf15SRobert Mustacchi     IN u32_t cid
1123d14abf15SRobert Mustacchi     )
1124d14abf15SRobert Mustacchi {
1125d14abf15SRobert Mustacchi     lm_cid_resc_t   *cid_resc   = NULL;
1126d14abf15SRobert Mustacchi 
1127d14abf15SRobert Mustacchi     if CHK_NULL(pdev)
1128d14abf15SRobert Mustacchi     {
1129d14abf15SRobert Mustacchi         return LM_CID_STATE_ERROR;
1130d14abf15SRobert Mustacchi     }
1131d14abf15SRobert Mustacchi 
1132d14abf15SRobert Mustacchi     cid_resc = lm_cid_resc(pdev, cid);
1133d14abf15SRobert Mustacchi 
1134d14abf15SRobert Mustacchi     if CHK_NULL(cid_resc)
1135d14abf15SRobert Mustacchi     {
1136d14abf15SRobert Mustacchi         return LM_CID_STATE_ERROR;
1137d14abf15SRobert Mustacchi     }
1138d14abf15SRobert Mustacchi 
1139d14abf15SRobert Mustacchi     return (lm_cid_state_enum)cid_resc->cid_pending;
1140d14abf15SRobert Mustacchi }
1141d14abf15SRobert Mustacchi 
1142d14abf15SRobert Mustacchi 
1143d14abf15SRobert Mustacchi 
1144d14abf15SRobert Mustacchi lm_status_t
lm_set_cid_state(IN struct _lm_device_t * pdev,IN u32_t cid,IN lm_cid_state_enum state)1145d14abf15SRobert Mustacchi lm_set_cid_state(
1146d14abf15SRobert Mustacchi     IN struct _lm_device_t *pdev,
1147d14abf15SRobert Mustacchi     IN u32_t cid,
1148d14abf15SRobert Mustacchi     IN lm_cid_state_enum state
1149d14abf15SRobert Mustacchi     )
1150d14abf15SRobert Mustacchi {
1151d14abf15SRobert Mustacchi     lm_cid_resc_t   *cid_resc   = NULL;
1152d14abf15SRobert Mustacchi 
1153d14abf15SRobert Mustacchi     if CHK_NULL(pdev)
1154d14abf15SRobert Mustacchi     {
1155d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1156d14abf15SRobert Mustacchi     }
1157d14abf15SRobert Mustacchi 
1158d14abf15SRobert Mustacchi     /* take spinlock */
1159d14abf15SRobert Mustacchi     MM_ACQUIRE_CID_LOCK(pdev);
1160d14abf15SRobert Mustacchi 
1161d14abf15SRobert Mustacchi     cid_resc = lm_cid_resc(pdev, cid);
1162d14abf15SRobert Mustacchi 
1163d14abf15SRobert Mustacchi     if CHK_NULL(cid_resc)
1164d14abf15SRobert Mustacchi     {
1165d14abf15SRobert Mustacchi         MM_RELEASE_CID_LOCK(pdev);
1166d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1167d14abf15SRobert Mustacchi     }
1168d14abf15SRobert Mustacchi 
1169d14abf15SRobert Mustacchi     cid_resc->cid_pending = state;
1170d14abf15SRobert Mustacchi 
1171d14abf15SRobert Mustacchi     /* rlease spinlock */
1172d14abf15SRobert Mustacchi     MM_RELEASE_CID_LOCK(pdev);
1173d14abf15SRobert Mustacchi 
1174d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
1175d14abf15SRobert Mustacchi }
1176d14abf15SRobert Mustacchi 
1177d14abf15SRobert Mustacchi /**
1178d14abf15SRobert Mustacchi  * sets the CDU validation data to be valid for a given cid
1179d14abf15SRobert Mustacchi  *
1180d14abf15SRobert Mustacchi  * @param pdev - the physical device handle
1181d14abf15SRobert Mustacchi  * @param cid - the context of this cid will be initialized with the cdu validataion data
1182d14abf15SRobert Mustacchi  *
1183d14abf15SRobert Mustacchi  * @return lm_status_t
1184d14abf15SRobert Mustacchi  */
lm_set_cdu_validation_data(struct _lm_device_t * pdev,s32_t cid,u8_t invalidate)1185d14abf15SRobert Mustacchi lm_status_t lm_set_cdu_validation_data(struct _lm_device_t *pdev, s32_t cid, u8_t invalidate)
1186d14abf15SRobert Mustacchi {
1187d14abf15SRobert Mustacchi     lm_status_t lm_status = LM_STATUS_SUCCESS;
1188d14abf15SRobert Mustacchi     void        *context        = NULL;
1189d14abf15SRobert Mustacchi     u8_t        *cdu_reserved   = NULL; /* Pointer to the actual location of cdu_reserved field according to protocol */
1190d14abf15SRobert Mustacchi     u8_t        *cdu_usage      = NULL; /* Pointer to the actual location of cdu_usage field according to protocol */
1191d14abf15SRobert Mustacchi     u8_t        proto_type      = 0;
1192d14abf15SRobert Mustacchi 
1193d14abf15SRobert Mustacchi     context = lm_get_context(PFDEV(pdev), cid);
1194d14abf15SRobert Mustacchi 
1195d14abf15SRobert Mustacchi     if (!context) {
1196d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
1197d14abf15SRobert Mustacchi     }
1198d14abf15SRobert Mustacchi 
1199d14abf15SRobert Mustacchi     proto_type = lm_map_cid_to_proto(PFDEV(pdev), cid);
1200d14abf15SRobert Mustacchi 
1201d14abf15SRobert Mustacchi     switch (proto_type) {
1202d14abf15SRobert Mustacchi     case TOE_CONNECTION_TYPE:
1203d14abf15SRobert Mustacchi         cdu_reserved = &((struct toe_context *)context)->xstorm_ag_context.cdu_reserved;
1204d14abf15SRobert Mustacchi         cdu_usage = &(((struct toe_context *)context)->ustorm_ag_context.cdu_usage);
1205d14abf15SRobert Mustacchi         break;
1206d14abf15SRobert Mustacchi     case ETH_CONNECTION_TYPE:
1207d14abf15SRobert Mustacchi         cdu_reserved = &(((struct eth_context *)context)->xstorm_ag_context.cdu_reserved);
1208d14abf15SRobert Mustacchi         cdu_usage =  &(((struct eth_context *)context)->ustorm_ag_context.cdu_usage);
1209d14abf15SRobert Mustacchi         break;
1210d14abf15SRobert Mustacchi     case ISCSI_CONNECTION_TYPE:
1211d14abf15SRobert Mustacchi         cdu_reserved = &(((struct iscsi_context *)context)->xstorm_ag_context.cdu_reserved);
1212d14abf15SRobert Mustacchi         cdu_usage = &(((struct iscsi_context *)context)->ustorm_ag_context.cdu_usage);
1213d14abf15SRobert Mustacchi         break;
1214d14abf15SRobert Mustacchi     case FCOE_CONNECTION_TYPE:
1215d14abf15SRobert Mustacchi         cdu_reserved = &(((struct fcoe_context *)context)->xstorm_ag_context.cdu_reserved);
1216d14abf15SRobert Mustacchi         cdu_usage = &(((struct fcoe_context *)context)->ustorm_ag_context.cdu_usage);
1217d14abf15SRobert Mustacchi         break;
1218d14abf15SRobert Mustacchi     default:
1219d14abf15SRobert Mustacchi         lm_status = LM_STATUS_FAILURE;
1220d14abf15SRobert Mustacchi         break;
1221d14abf15SRobert Mustacchi     }
1222d14abf15SRobert Mustacchi 
1223d14abf15SRobert Mustacchi     if (cdu_reserved && cdu_usage) {
1224d14abf15SRobert Mustacchi         if (invalidate) {
1225d14abf15SRobert Mustacchi             *cdu_reserved = CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(*cdu_reserved);
1226d14abf15SRobert Mustacchi             *cdu_usage    = CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(*cdu_usage);
1227d14abf15SRobert Mustacchi         } else {
1228d14abf15SRobert Mustacchi             *cdu_reserved = CDU_RSRVD_VALUE_TYPE_A(HW_CID(pdev, cid), CDU_REGION_NUMBER_XCM_AG, proto_type);
1229d14abf15SRobert Mustacchi             *cdu_usage    = CDU_RSRVD_VALUE_TYPE_A(HW_CID(pdev, cid), CDU_REGION_NUMBER_UCM_AG, proto_type);
1230d14abf15SRobert Mustacchi         }
1231d14abf15SRobert Mustacchi     }
1232d14abf15SRobert Mustacchi 
1233d14abf15SRobert Mustacchi     return lm_status;
1234d14abf15SRobert Mustacchi }
1235d14abf15SRobert Mustacchi 
1236d14abf15SRobert Mustacchi 
lm_get_context_size(struct _lm_device_t * pdev,s32_t * context_size)1237d14abf15SRobert Mustacchi lm_status_t lm_get_context_size(struct _lm_device_t *pdev, s32_t * context_size)
1238d14abf15SRobert Mustacchi {
1239d14abf15SRobert Mustacchi     *context_size = LM_CONTEXT_SIZE;
1240d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
1241d14abf15SRobert Mustacchi }
1242d14abf15SRobert Mustacchi 
lm_set_con_state(struct _lm_device_t * pdev,u32_t cid,u32_t state)1243d14abf15SRobert Mustacchi lm_status_t lm_set_con_state(struct _lm_device_t *pdev, u32_t cid, u32_t state)
1244d14abf15SRobert Mustacchi {
1245d14abf15SRobert Mustacchi     lm_cid_resc_t * cid_resc = lm_cid_resc(pdev, cid);
1246d14abf15SRobert Mustacchi 
1247d14abf15SRobert Mustacchi     if CHK_NULL(cid_resc)
1248d14abf15SRobert Mustacchi     {
1249d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1250d14abf15SRobert Mustacchi     }
1251d14abf15SRobert Mustacchi 
1252d14abf15SRobert Mustacchi     cid_resc->con_state = state;
1253*dd980e63SToomas Soome 
1254d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
1255d14abf15SRobert Mustacchi }
1256d14abf15SRobert Mustacchi 
lm_get_con_state(struct _lm_device_t * pdev,u32_t cid)1257d14abf15SRobert Mustacchi u32_t lm_get_con_state(struct _lm_device_t *pdev, u32_t cid)
1258d14abf15SRobert Mustacchi {
1259d14abf15SRobert Mustacchi     const lm_cid_resc_t * cid_resc = lm_cid_resc(pdev, cid);
1260d14abf15SRobert Mustacchi 
1261d14abf15SRobert Mustacchi     if CHK_NULL(cid_resc)
1262d14abf15SRobert Mustacchi     {
1263d14abf15SRobert Mustacchi         return LM_CON_STATE_CLOSE;
1264d14abf15SRobert Mustacchi     }
1265d14abf15SRobert Mustacchi 
1266d14abf15SRobert Mustacchi     return cid_resc->con_state;
1267d14abf15SRobert Mustacchi }
1268d14abf15SRobert Mustacchi 
1269d14abf15SRobert Mustacchi 
1270