int efx_vi_alloc(struct efx_vi_state **vih_out, int ifindex) { struct efx_vi_state *efx_state; int rc; efx_state = kmalloc(sizeof(struct efx_vi_state), GFP_KERNEL); if (!efx_state) { EFRM_ERR("%s: failed to allocate memory for efx_vi_state", __func__); rc = -ENOMEM; goto fail; } efx_state->ifindex = ifindex; rc = efrm_client_get(ifindex, NULL, NULL, &efx_state->efrm_client); if (rc < 0) { EFRM_ERR("%s: efrm_client_get(%d) failed: %d", __func__, ifindex, rc); rc = -ENODEV; goto fail_no_ifindex; } efx_state->nic = efrm_client_get_nic(efx_state->efrm_client); init_completion(&efx_state->flush_completion); /* basically allocate_pt_endpoint() */ rc = alloc_ep(efx_state); if (rc) { EFRM_ERR("%s: alloc_ep failed: %d", __func__, rc); goto fail_no_pt; } #if EFX_VI_STATIC_FILTERS /* Statically allocate a set of filter resources - removes the restriction on not being able to use efx_vi_filter() from in_atomic() */ rc = efx_vi_alloc_static_filters(efx_state); if (rc) goto fail_no_filters; #endif *vih_out = efx_state; return 0; #if EFX_VI_STATIC_FILTERS fail_no_filters: free_ep(efx_state); #endif fail_no_pt: efrm_client_put(efx_state->efrm_client); fail_no_ifindex: kfree(efx_state); fail: return rc; }
static int vi_set_rm_alloc(ci_resource_alloc_t* alloc_, ci_resource_table_t* priv_opt, efch_resource_t* rs, int intf_ver_id) { struct efch_vi_set_alloc* alloc = &alloc_->u.vi_set; struct efrm_client *client; struct efrm_vi_set* vi_set; struct efrm_pd* pd; unsigned vi_props; int rc; if( intf_ver_id >= 1 && alloc->in_pd_fd >= 0 ) { struct efrm_resource* rs; rc = efch_lookup_rs(alloc->in_pd_fd, alloc->in_pd_rs_id, EFRM_RESOURCE_PD, &rs); if( rc < 0 ) { EFCH_ERR("%s: ERROR: could not find PD fd=%d id="EFCH_RESOURCE_ID_FMT " rc=%d", __FUNCTION__, alloc->in_pd_fd, EFCH_RESOURCE_ID_PRI_ARG(alloc->in_pd_rs_id), rc); goto fail1; } pd = efrm_pd_from_resource(rs); client = rs->rs_client; efrm_client_add_ref(client); } else { rc = efrm_client_get(alloc->in_ifindex, NULL, NULL, &client); if( rc != 0 ) { EFCH_ERR("%s: ERROR: ifindex=%d not found rc=%d", __FUNCTION__, alloc->in_ifindex, rc); goto fail1; } rc = efrm_pd_alloc(&pd, client, NULL/*vf_opt*/, 0/*phys_addr_mode*/); if( rc != 0 ) { EFCH_ERR("%s: ERROR: efrm_pd_alloc(ifindex=%d) failed (rc=%d)", __FUNCTION__, alloc->in_ifindex, rc); goto fail2; } } vi_props = 0; rc = efrm_vi_set_alloc(pd, alloc->in_n_vis, vi_props, &vi_set); if( rc != 0 ) goto fail3; efrm_client_put(client); efrm_pd_release(pd); efch_filter_list_init(&rs->vi_set.fl); rs->vi_set.sniff_flags = 0; rs->rs_base = efrm_vi_set_to_resource(vi_set); return 0; fail3: efrm_pd_release(pd); fail2: efrm_client_put(client); fail1: return rc; }