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