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; }
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 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; }