static int efab_vi_rm_mmap_io(struct efrm_vi *virs, unsigned long *bytes, void *opaque, int *map_num, unsigned long *offset) { int rc; int len; int instance; int base; unsigned vi_stride; struct efhw_nic *nic; nic = efrm_client_get_nic(virs->rs.rs_client); instance = virs->rs.rs_instance; len = CI_MIN(*bytes, CI_PAGE_SIZE); *bytes -=len; /* Make sure we can get away with a single page here. */ switch (nic->devtype.arch) { case EFHW_ARCH_FALCON: ci_assert_lt(falcon_tx_dma_page_offset(instance), CI_PAGE_SIZE); ci_assert_lt(falcon_rx_dma_page_offset(instance), CI_PAGE_SIZE); ci_assert_equal(falcon_tx_dma_page_base(instance), falcon_rx_dma_page_base(instance)); base = falcon_tx_dma_page_base(instance); break; case EFHW_ARCH_EF10: vi_stride = nic->vi_stride; ci_assert_lt(ef10_tx_dma_page_offset(vi_stride, instance), CI_PAGE_SIZE); ci_assert_lt(ef10_rx_dma_page_offset(vi_stride, instance), CI_PAGE_SIZE); ci_assert_equal(ef10_tx_dma_page_base(vi_stride, instance), ef10_rx_dma_page_base(vi_stride, instance)); base = ef10_tx_dma_page_base(vi_stride, instance); break; default: EFCH_ERR("%s: ERROR: unknown nic type (%d)", __FUNCTION__, nic->devtype.arch); base = 0; /* To quiet the compiler */ BUG(); } rc = ci_mmap_bar(nic, base, len, opaque, map_num, offset, 0); if (rc < 0 ) { EFCH_ERR("%s: ERROR: ci_mmap_bar failed rc=%d", __FUNCTION__, rc); return rc; } return 0; }
static int efab_vi_rm_mmap_pio(struct efrm_vi *virs, unsigned long *bytes, void *opaque, int *map_num, unsigned long *offset) { int rc; int len; int instance; struct efhw_nic *nic; int bar_off; nic = efrm_client_get_nic(virs->rs.rs_client); if( nic->devtype.arch != EFHW_ARCH_EF10 ) { EFRM_ERR("%s: Only ef10 supports PIO." " Expected arch=%d but got %d\n", __FUNCTION__, EFHW_ARCH_EF10, nic->devtype.arch); return -EINVAL; } instance = virs->rs.rs_instance; /* Map the control page. */ len = CI_MIN(*bytes, CI_PAGE_SIZE); *bytes -= len; bar_off = (ef10_tx_dma_page_base(nic->vi_stride, instance) + 4096) & PAGE_MASK; rc = ci_mmap_bar(nic, bar_off, len, opaque, map_num, offset, 1); if( rc < 0 ) EFCH_ERR("%s: ERROR: ci_mmap_bar failed rc=%d", __FUNCTION__, rc); return rc; }
static int efab_vi_rm_mmap_ctpio(struct efrm_vi *virs, unsigned long *bytes, void *opaque, int *map_num, unsigned long *offset) { int rc; int len; int instance; struct efhw_nic *nic; int bar_off; /* The CTPIO region is 12K from the start of the VI's aperture. */ const int CTPIO_OFFSET = 12 * 1024; instance = virs->rs.rs_instance; if( ! (virs->flags & EFHW_VI_TX_CTPIO) ) { EFRM_ERR("%s: CTPIO is not enabled on VI instance %d\n", __FUNCTION__, instance); return -EINVAL; } /* Map the CTPIO region, which is 12K from the start of the VI's aperture. */ len = CI_MIN(*bytes, CI_PAGE_SIZE); *bytes -= len; nic = efrm_client_get_nic(virs->rs.rs_client); ci_assert_ge(nic->vi_stride, CTPIO_OFFSET + len); bar_off = (ef10_tx_dma_page_base(nic->vi_stride, instance) + CTPIO_OFFSET) & PAGE_MASK; rc = ci_mmap_bar(nic, bar_off, len, opaque, map_num, offset, 1); if( rc < 0 ) EFCH_ERR("%s: ERROR: ci_mmap_bar failed rc=%d", __FUNCTION__, rc); 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; }