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 354294f337SSean 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", 1404294f337SSean 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 1624294f337SSean Bruno void 1634294f337SSean Bruno i40e_msec_pause(int msecs) 1644294f337SSean Bruno { 1654294f337SSean Bruno int ticks_to_pause = (msecs * hz) / 1000; 1664294f337SSean Bruno int start_ticks = ticks; 1674294f337SSean Bruno 1684294f337SSean Bruno if (cold || SCHEDULER_STOPPED()) { 1694294f337SSean Bruno i40e_msec_delay(msecs); 1704294f337SSean Bruno return; 1714294f337SSean Bruno } 1724294f337SSean Bruno 1734294f337SSean Bruno while (1) { 1744294f337SSean Bruno kern_yield(PRI_USER); 1754294f337SSean Bruno int yielded_ticks = ticks - start_ticks; 1764294f337SSean Bruno if (yielded_ticks > ticks_to_pause) 1774294f337SSean Bruno break; 1784294f337SSean Bruno else if (yielded_ticks < 0 1794294f337SSean Bruno && (yielded_ticks + INT_MAX + 1 > ticks_to_pause)) { 1804294f337SSean Bruno break; 1814294f337SSean Bruno } 1824294f337SSean Bruno } 1834294f337SSean Bruno } 1844294f337SSean Bruno 18561ae650dSJack F Vogel /* 1866c426059SEric Joyner * Helper function for debug statement printing 18761ae650dSJack F Vogel */ 1886c426059SEric Joyner void 1894294f337SSean Bruno i40e_debug_shared(struct i40e_hw *hw, enum i40e_debug_mask mask, char *fmt, ...) 19061ae650dSJack F Vogel { 19161ae650dSJack F Vogel va_list args; 192*cb6b8299SEric Joyner device_t dev; 19361ae650dSJack F Vogel 19461ae650dSJack F Vogel if (!(mask & ((struct i40e_hw *)hw)->debug_mask)) 19561ae650dSJack F Vogel return; 19661ae650dSJack F Vogel 197*cb6b8299SEric Joyner dev = ((struct i40e_osdep *)hw->back)->dev; 198*cb6b8299SEric Joyner 199*cb6b8299SEric Joyner /* Re-implement device_printf() */ 200*cb6b8299SEric Joyner device_print_prettyname(dev); 20161ae650dSJack F Vogel va_start(args, fmt); 202*cb6b8299SEric Joyner vprintf(fmt, args); 20361ae650dSJack F Vogel va_end(args); 20461ae650dSJack F Vogel } 20561ae650dSJack F Vogel 206*cb6b8299SEric Joyner const char * 207*cb6b8299SEric Joyner ixl_vc_opcode_str(uint16_t op) 208*cb6b8299SEric Joyner { 209*cb6b8299SEric Joyner switch (op) { 210*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_VERSION: 211*cb6b8299SEric Joyner return ("VERSION"); 212*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_RESET_VF: 213*cb6b8299SEric Joyner return ("RESET_VF"); 214*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_GET_VF_RESOURCES: 215*cb6b8299SEric Joyner return ("GET_VF_RESOURCES"); 216*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_CONFIG_TX_QUEUE: 217*cb6b8299SEric Joyner return ("CONFIG_TX_QUEUE"); 218*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_CONFIG_RX_QUEUE: 219*cb6b8299SEric Joyner return ("CONFIG_RX_QUEUE"); 220*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES: 221*cb6b8299SEric Joyner return ("CONFIG_VSI_QUEUES"); 222*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP: 223*cb6b8299SEric Joyner return ("CONFIG_IRQ_MAP"); 224*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_ENABLE_QUEUES: 225*cb6b8299SEric Joyner return ("ENABLE_QUEUES"); 226*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_DISABLE_QUEUES: 227*cb6b8299SEric Joyner return ("DISABLE_QUEUES"); 228*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS: 229*cb6b8299SEric Joyner return ("ADD_ETHER_ADDRESS"); 230*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS: 231*cb6b8299SEric Joyner return ("DEL_ETHER_ADDRESS"); 232*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_ADD_VLAN: 233*cb6b8299SEric Joyner return ("ADD_VLAN"); 234*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_DEL_VLAN: 235*cb6b8299SEric Joyner return ("DEL_VLAN"); 236*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: 237*cb6b8299SEric Joyner return ("CONFIG_PROMISCUOUS_MODE"); 238*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_GET_STATS: 239*cb6b8299SEric Joyner return ("GET_STATS"); 240*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_FCOE: 241*cb6b8299SEric Joyner return ("FCOE"); 242*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_EVENT: 243*cb6b8299SEric Joyner return ("EVENT"); 244*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_CONFIG_RSS_KEY: 245*cb6b8299SEric Joyner return ("CONFIG_RSS_KEY"); 246*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_CONFIG_RSS_LUT: 247*cb6b8299SEric Joyner return ("CONFIG_RSS_LUT"); 248*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS: 249*cb6b8299SEric Joyner return ("GET_RSS_HENA_CAPS"); 250*cb6b8299SEric Joyner case I40E_VIRTCHNL_OP_SET_RSS_HENA: 251*cb6b8299SEric Joyner return ("SET_RSS_HENA"); 252*cb6b8299SEric Joyner default: 253*cb6b8299SEric Joyner return ("UNKNOWN"); 254*cb6b8299SEric Joyner } 255*cb6b8299SEric Joyner } 256*cb6b8299SEric Joyner 25761ae650dSJack F Vogel u16 25861ae650dSJack F Vogel i40e_read_pci_cfg(struct i40e_hw *hw, u32 reg) 25961ae650dSJack F Vogel { 26061ae650dSJack F Vogel u16 value; 26161ae650dSJack F Vogel 26261ae650dSJack F Vogel value = pci_read_config(((struct i40e_osdep *)hw->back)->dev, 26361ae650dSJack F Vogel reg, 2); 26461ae650dSJack F Vogel 26561ae650dSJack F Vogel return (value); 26661ae650dSJack F Vogel } 26761ae650dSJack F Vogel 26861ae650dSJack F Vogel void 26961ae650dSJack F Vogel i40e_write_pci_cfg(struct i40e_hw *hw, u32 reg, u16 value) 27061ae650dSJack F Vogel { 27161ae650dSJack F Vogel pci_write_config(((struct i40e_osdep *)hw->back)->dev, 27261ae650dSJack F Vogel reg, value, 2); 27361ae650dSJack F Vogel 27461ae650dSJack F Vogel return; 27561ae650dSJack F Vogel } 27661ae650dSJack F Vogel 277