161ae650dSJack F Vogel /****************************************************************************** 261ae650dSJack F Vogel 3ac83ea83SEric Joyner Copyright (c) 2013-2015, Intel Corporation 461ae650dSJack F Vogel All rights reserved. 561ae650dSJack F Vogel 661ae650dSJack F Vogel Redistribution and use in source and binary forms, with or without 761ae650dSJack F Vogel modification, are permitted provided that the following conditions are met: 861ae650dSJack F Vogel 961ae650dSJack F Vogel 1. Redistributions of source code must retain the above copyright notice, 1061ae650dSJack F Vogel this list of conditions and the following disclaimer. 1161ae650dSJack F Vogel 1261ae650dSJack F Vogel 2. Redistributions in binary form must reproduce the above copyright 1361ae650dSJack F Vogel notice, this list of conditions and the following disclaimer in the 1461ae650dSJack F Vogel documentation and/or other materials provided with the distribution. 1561ae650dSJack F Vogel 1661ae650dSJack F Vogel 3. Neither the name of the Intel Corporation nor the names of its 1761ae650dSJack F Vogel contributors may be used to endorse or promote products derived from 1861ae650dSJack F Vogel this software without specific prior written permission. 1961ae650dSJack F Vogel 2061ae650dSJack F Vogel THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2161ae650dSJack F Vogel AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2261ae650dSJack F Vogel IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2361ae650dSJack F Vogel ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2461ae650dSJack F Vogel LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2561ae650dSJack F Vogel CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2661ae650dSJack F Vogel SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2761ae650dSJack F Vogel INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2861ae650dSJack F Vogel CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2961ae650dSJack F Vogel ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3061ae650dSJack F Vogel POSSIBILITY OF SUCH DAMAGE. 3161ae650dSJack F Vogel 3261ae650dSJack F Vogel ******************************************************************************/ 3361ae650dSJack F Vogel /*$FreeBSD$*/ 3461ae650dSJack F Vogel 35*4294f337SSean Bruno #include <sys/limits.h> 3661ae650dSJack F Vogel 3761ae650dSJack F Vogel #include "ixl.h" 3861ae650dSJack F Vogel 3961ae650dSJack F Vogel /******************************************************************** 4061ae650dSJack F Vogel * Manage DMA'able memory. 4161ae650dSJack F Vogel *******************************************************************/ 4261ae650dSJack F Vogel static void 4361ae650dSJack F Vogel i40e_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg, int error) 4461ae650dSJack F Vogel { 4561ae650dSJack F Vogel if (error) 4661ae650dSJack F Vogel return; 4761ae650dSJack F Vogel *(bus_addr_t *) arg = segs->ds_addr; 4861ae650dSJack F Vogel return; 4961ae650dSJack F Vogel } 5061ae650dSJack F Vogel 5161ae650dSJack F Vogel i40e_status 52d94ca7cfSBjoern A. Zeeb i40e_allocate_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem, u32 size) 5361ae650dSJack F Vogel { 54ea022094SBjoern A. Zeeb mem->va = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); 55ea022094SBjoern A. Zeeb return(mem->va == NULL); 5661ae650dSJack F Vogel } 5761ae650dSJack F Vogel 5861ae650dSJack F Vogel i40e_status 59d94ca7cfSBjoern A. Zeeb i40e_free_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem) 6061ae650dSJack F Vogel { 61ea022094SBjoern A. Zeeb free(mem->va, M_DEVBUF); 6261ae650dSJack F Vogel return(0); 6361ae650dSJack F Vogel } 6461ae650dSJack F Vogel 6561ae650dSJack F Vogel i40e_status 66d94ca7cfSBjoern A. Zeeb i40e_allocate_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem, 67d94ca7cfSBjoern A. Zeeb enum i40e_memory_type type __unused, u64 size, u32 alignment) 6861ae650dSJack F Vogel { 6961ae650dSJack F Vogel device_t dev = ((struct i40e_osdep *)hw->back)->dev; 7061ae650dSJack F Vogel int err; 7161ae650dSJack F Vogel 7261ae650dSJack F Vogel 7361ae650dSJack F Vogel err = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 7461ae650dSJack F Vogel alignment, 0, /* alignment, bounds */ 7561ae650dSJack F Vogel BUS_SPACE_MAXADDR, /* lowaddr */ 7661ae650dSJack F Vogel BUS_SPACE_MAXADDR, /* highaddr */ 7761ae650dSJack F Vogel NULL, NULL, /* filter, filterarg */ 7861ae650dSJack F Vogel size, /* maxsize */ 7961ae650dSJack F Vogel 1, /* nsegments */ 8061ae650dSJack F Vogel size, /* maxsegsize */ 8161ae650dSJack F Vogel BUS_DMA_ALLOCNOW, /* flags */ 8261ae650dSJack F Vogel NULL, /* lockfunc */ 8361ae650dSJack F Vogel NULL, /* lockfuncarg */ 84ea022094SBjoern A. Zeeb &mem->tag); 8561ae650dSJack F Vogel if (err != 0) { 8661ae650dSJack F Vogel device_printf(dev, 8761ae650dSJack F Vogel "i40e_allocate_dma: bus_dma_tag_create failed, " 8861ae650dSJack F Vogel "error %u\n", err); 8961ae650dSJack F Vogel goto fail_0; 9061ae650dSJack F Vogel } 91ea022094SBjoern A. Zeeb err = bus_dmamem_alloc(mem->tag, (void **)&mem->va, 92ea022094SBjoern A. Zeeb BUS_DMA_NOWAIT | BUS_DMA_ZERO, &mem->map); 9361ae650dSJack F Vogel if (err != 0) { 9461ae650dSJack F Vogel device_printf(dev, 9561ae650dSJack F Vogel "i40e_allocate_dma: bus_dmamem_alloc failed, " 9661ae650dSJack F Vogel "error %u\n", err); 9761ae650dSJack F Vogel goto fail_1; 9861ae650dSJack F Vogel } 99ea022094SBjoern A. Zeeb err = bus_dmamap_load(mem->tag, mem->map, mem->va, 10061ae650dSJack F Vogel size, 10161ae650dSJack F Vogel i40e_dmamap_cb, 102ea022094SBjoern A. Zeeb &mem->pa, 10361ae650dSJack F Vogel BUS_DMA_NOWAIT); 10461ae650dSJack F Vogel if (err != 0) { 10561ae650dSJack F Vogel device_printf(dev, 10661ae650dSJack F Vogel "i40e_allocate_dma: bus_dmamap_load failed, " 10761ae650dSJack F Vogel "error %u\n", err); 10861ae650dSJack F Vogel goto fail_2; 10961ae650dSJack F Vogel } 110e5100ee2SJack F Vogel mem->nseg = 1; 111ea022094SBjoern A. Zeeb mem->size = size; 112ea022094SBjoern A. Zeeb bus_dmamap_sync(mem->tag, mem->map, 11361ae650dSJack F Vogel BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 11461ae650dSJack F Vogel return (0); 11561ae650dSJack F Vogel fail_2: 116ea022094SBjoern A. Zeeb bus_dmamem_free(mem->tag, mem->va, mem->map); 11761ae650dSJack F Vogel fail_1: 118ea022094SBjoern A. Zeeb bus_dma_tag_destroy(mem->tag); 11961ae650dSJack F Vogel fail_0: 120ea022094SBjoern A. Zeeb mem->map = NULL; 121ea022094SBjoern A. Zeeb mem->tag = NULL; 12261ae650dSJack F Vogel return (err); 12361ae650dSJack F Vogel } 12461ae650dSJack F Vogel 12561ae650dSJack F Vogel i40e_status 126d94ca7cfSBjoern A. Zeeb i40e_free_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem) 12761ae650dSJack F Vogel { 128ea022094SBjoern A. Zeeb bus_dmamap_sync(mem->tag, mem->map, 12961ae650dSJack F Vogel BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 130ea022094SBjoern A. Zeeb bus_dmamap_unload(mem->tag, mem->map); 131ea022094SBjoern A. Zeeb bus_dmamem_free(mem->tag, mem->va, mem->map); 132ea022094SBjoern A. Zeeb bus_dma_tag_destroy(mem->tag); 13361ae650dSJack F Vogel return (0); 13461ae650dSJack F Vogel } 13561ae650dSJack F Vogel 13661ae650dSJack F Vogel void 13761ae650dSJack F Vogel i40e_init_spinlock(struct i40e_spinlock *lock) 13861ae650dSJack F Vogel { 13961ae650dSJack F Vogel mtx_init(&lock->mutex, "mutex", 140*4294f337SSean Bruno "ixl spinlock", MTX_DEF | MTX_DUPOK); 14161ae650dSJack F Vogel } 14261ae650dSJack F Vogel 14361ae650dSJack F Vogel void 14461ae650dSJack F Vogel i40e_acquire_spinlock(struct i40e_spinlock *lock) 14561ae650dSJack F Vogel { 14661ae650dSJack F Vogel mtx_lock(&lock->mutex); 14761ae650dSJack F Vogel } 14861ae650dSJack F Vogel 14961ae650dSJack F Vogel void 15061ae650dSJack F Vogel i40e_release_spinlock(struct i40e_spinlock *lock) 15161ae650dSJack F Vogel { 15261ae650dSJack F Vogel mtx_unlock(&lock->mutex); 15361ae650dSJack F Vogel } 15461ae650dSJack F Vogel 15561ae650dSJack F Vogel void 15661ae650dSJack F Vogel i40e_destroy_spinlock(struct i40e_spinlock *lock) 15761ae650dSJack F Vogel { 1586d011ad5SEric Joyner if (mtx_initialized(&lock->mutex)) 15961ae650dSJack F Vogel mtx_destroy(&lock->mutex); 16061ae650dSJack F Vogel } 16161ae650dSJack F Vogel 162*4294f337SSean Bruno void 163*4294f337SSean Bruno i40e_msec_pause(int msecs) 164*4294f337SSean Bruno { 165*4294f337SSean Bruno int ticks_to_pause = (msecs * hz) / 1000; 166*4294f337SSean Bruno int start_ticks = ticks; 167*4294f337SSean Bruno 168*4294f337SSean Bruno if (cold || SCHEDULER_STOPPED()) { 169*4294f337SSean Bruno i40e_msec_delay(msecs); 170*4294f337SSean Bruno return; 171*4294f337SSean Bruno } 172*4294f337SSean Bruno 173*4294f337SSean Bruno while (1) { 174*4294f337SSean Bruno kern_yield(PRI_USER); 175*4294f337SSean Bruno int yielded_ticks = ticks - start_ticks; 176*4294f337SSean Bruno if (yielded_ticks > ticks_to_pause) 177*4294f337SSean Bruno break; 178*4294f337SSean Bruno else if (yielded_ticks < 0 179*4294f337SSean Bruno && (yielded_ticks + INT_MAX + 1 > ticks_to_pause)) { 180*4294f337SSean Bruno break; 181*4294f337SSean Bruno } 182*4294f337SSean Bruno } 183*4294f337SSean Bruno } 184*4294f337SSean Bruno 18561ae650dSJack F Vogel /* 1866c426059SEric Joyner * Helper function for debug statement printing 18761ae650dSJack F Vogel */ 1886c426059SEric Joyner void 189*4294f337SSean Bruno i40e_debug_shared(struct i40e_hw *hw, enum i40e_debug_mask mask, char *fmt, ...) 19061ae650dSJack F Vogel { 19161ae650dSJack F Vogel va_list args; 19261ae650dSJack F Vogel 19361ae650dSJack F Vogel if (!(mask & ((struct i40e_hw *)hw)->debug_mask)) 19461ae650dSJack F Vogel return; 19561ae650dSJack F Vogel 19661ae650dSJack F Vogel va_start(args, fmt); 1976c426059SEric Joyner device_printf(((struct i40e_osdep *)hw->back)->dev, fmt, args); 19861ae650dSJack F Vogel va_end(args); 19961ae650dSJack F Vogel } 20061ae650dSJack F Vogel 20161ae650dSJack F Vogel u16 20261ae650dSJack F Vogel i40e_read_pci_cfg(struct i40e_hw *hw, u32 reg) 20361ae650dSJack F Vogel { 20461ae650dSJack F Vogel u16 value; 20561ae650dSJack F Vogel 20661ae650dSJack F Vogel value = pci_read_config(((struct i40e_osdep *)hw->back)->dev, 20761ae650dSJack F Vogel reg, 2); 20861ae650dSJack F Vogel 20961ae650dSJack F Vogel return (value); 21061ae650dSJack F Vogel } 21161ae650dSJack F Vogel 21261ae650dSJack F Vogel void 21361ae650dSJack F Vogel i40e_write_pci_cfg(struct i40e_hw *hw, u32 reg, u16 value) 21461ae650dSJack F Vogel { 21561ae650dSJack F Vogel pci_write_config(((struct i40e_osdep *)hw->back)->dev, 21661ae650dSJack F Vogel reg, value, 2); 21761ae650dSJack F Vogel 21861ae650dSJack F Vogel return; 21961ae650dSJack F Vogel } 22061ae650dSJack F Vogel 221