161ae650dSJack F Vogel /****************************************************************************** 261ae650dSJack F Vogel 3*ceebc2f3SEric Joyner Copyright (c) 2013-2017, 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); 62*ceebc2f3SEric Joyner mem->va = NULL; 63*ceebc2f3SEric Joyner 6461ae650dSJack F Vogel return(0); 6561ae650dSJack F Vogel } 6661ae650dSJack F Vogel 6761ae650dSJack F Vogel i40e_status 68d94ca7cfSBjoern A. Zeeb i40e_allocate_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem, 69d94ca7cfSBjoern A. Zeeb enum i40e_memory_type type __unused, u64 size, u32 alignment) 7061ae650dSJack F Vogel { 7161ae650dSJack F Vogel device_t dev = ((struct i40e_osdep *)hw->back)->dev; 7261ae650dSJack F Vogel int err; 7361ae650dSJack F Vogel 7461ae650dSJack F Vogel 7561ae650dSJack F Vogel err = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 7661ae650dSJack F Vogel alignment, 0, /* alignment, bounds */ 7761ae650dSJack F Vogel BUS_SPACE_MAXADDR, /* lowaddr */ 7861ae650dSJack F Vogel BUS_SPACE_MAXADDR, /* highaddr */ 7961ae650dSJack F Vogel NULL, NULL, /* filter, filterarg */ 8061ae650dSJack F Vogel size, /* maxsize */ 8161ae650dSJack F Vogel 1, /* nsegments */ 8261ae650dSJack F Vogel size, /* maxsegsize */ 8361ae650dSJack F Vogel BUS_DMA_ALLOCNOW, /* flags */ 8461ae650dSJack F Vogel NULL, /* lockfunc */ 8561ae650dSJack F Vogel NULL, /* lockfuncarg */ 86ea022094SBjoern A. Zeeb &mem->tag); 8761ae650dSJack F Vogel if (err != 0) { 8861ae650dSJack F Vogel device_printf(dev, 8961ae650dSJack F Vogel "i40e_allocate_dma: bus_dma_tag_create failed, " 9061ae650dSJack F Vogel "error %u\n", err); 9161ae650dSJack F Vogel goto fail_0; 9261ae650dSJack F Vogel } 93ea022094SBjoern A. Zeeb err = bus_dmamem_alloc(mem->tag, (void **)&mem->va, 94ea022094SBjoern A. Zeeb BUS_DMA_NOWAIT | BUS_DMA_ZERO, &mem->map); 9561ae650dSJack F Vogel if (err != 0) { 9661ae650dSJack F Vogel device_printf(dev, 9761ae650dSJack F Vogel "i40e_allocate_dma: bus_dmamem_alloc failed, " 9861ae650dSJack F Vogel "error %u\n", err); 9961ae650dSJack F Vogel goto fail_1; 10061ae650dSJack F Vogel } 101ea022094SBjoern A. Zeeb err = bus_dmamap_load(mem->tag, mem->map, mem->va, 10261ae650dSJack F Vogel size, 10361ae650dSJack F Vogel i40e_dmamap_cb, 104ea022094SBjoern A. Zeeb &mem->pa, 10561ae650dSJack F Vogel BUS_DMA_NOWAIT); 10661ae650dSJack F Vogel if (err != 0) { 10761ae650dSJack F Vogel device_printf(dev, 10861ae650dSJack F Vogel "i40e_allocate_dma: bus_dmamap_load failed, " 10961ae650dSJack F Vogel "error %u\n", err); 11061ae650dSJack F Vogel goto fail_2; 11161ae650dSJack F Vogel } 112e5100ee2SJack F Vogel mem->nseg = 1; 113ea022094SBjoern A. Zeeb mem->size = size; 114ea022094SBjoern A. Zeeb bus_dmamap_sync(mem->tag, mem->map, 11561ae650dSJack F Vogel BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 11661ae650dSJack F Vogel return (0); 11761ae650dSJack F Vogel fail_2: 118ea022094SBjoern A. Zeeb bus_dmamem_free(mem->tag, mem->va, mem->map); 11961ae650dSJack F Vogel fail_1: 120ea022094SBjoern A. Zeeb bus_dma_tag_destroy(mem->tag); 12161ae650dSJack F Vogel fail_0: 122ea022094SBjoern A. Zeeb mem->map = NULL; 123ea022094SBjoern A. Zeeb mem->tag = NULL; 12461ae650dSJack F Vogel return (err); 12561ae650dSJack F Vogel } 12661ae650dSJack F Vogel 12761ae650dSJack F Vogel i40e_status 128d94ca7cfSBjoern A. Zeeb i40e_free_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem) 12961ae650dSJack F Vogel { 130ea022094SBjoern A. Zeeb bus_dmamap_sync(mem->tag, mem->map, 13161ae650dSJack F Vogel BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 132ea022094SBjoern A. Zeeb bus_dmamap_unload(mem->tag, mem->map); 133ea022094SBjoern A. Zeeb bus_dmamem_free(mem->tag, mem->va, mem->map); 134ea022094SBjoern A. Zeeb bus_dma_tag_destroy(mem->tag); 13561ae650dSJack F Vogel return (0); 13661ae650dSJack F Vogel } 13761ae650dSJack F Vogel 13861ae650dSJack F Vogel void 13961ae650dSJack F Vogel i40e_init_spinlock(struct i40e_spinlock *lock) 14061ae650dSJack F Vogel { 14161ae650dSJack F Vogel mtx_init(&lock->mutex, "mutex", 1424294f337SSean Bruno "ixl spinlock", MTX_DEF | MTX_DUPOK); 14361ae650dSJack F Vogel } 14461ae650dSJack F Vogel 14561ae650dSJack F Vogel void 14661ae650dSJack F Vogel i40e_acquire_spinlock(struct i40e_spinlock *lock) 14761ae650dSJack F Vogel { 14861ae650dSJack F Vogel mtx_lock(&lock->mutex); 14961ae650dSJack F Vogel } 15061ae650dSJack F Vogel 15161ae650dSJack F Vogel void 15261ae650dSJack F Vogel i40e_release_spinlock(struct i40e_spinlock *lock) 15361ae650dSJack F Vogel { 15461ae650dSJack F Vogel mtx_unlock(&lock->mutex); 15561ae650dSJack F Vogel } 15661ae650dSJack F Vogel 15761ae650dSJack F Vogel void 15861ae650dSJack F Vogel i40e_destroy_spinlock(struct i40e_spinlock *lock) 15961ae650dSJack F Vogel { 1606d011ad5SEric Joyner if (mtx_initialized(&lock->mutex)) 16161ae650dSJack F Vogel mtx_destroy(&lock->mutex); 16261ae650dSJack F Vogel } 16361ae650dSJack F Vogel 1644294f337SSean Bruno void 1654294f337SSean Bruno i40e_msec_pause(int msecs) 1664294f337SSean Bruno { 1674294f337SSean Bruno int ticks_to_pause = (msecs * hz) / 1000; 1684294f337SSean Bruno int start_ticks = ticks; 1694294f337SSean Bruno 1704294f337SSean Bruno if (cold || SCHEDULER_STOPPED()) { 1714294f337SSean Bruno i40e_msec_delay(msecs); 1724294f337SSean Bruno return; 1734294f337SSean Bruno } 1744294f337SSean Bruno 1754294f337SSean Bruno while (1) { 1764294f337SSean Bruno kern_yield(PRI_USER); 1774294f337SSean Bruno int yielded_ticks = ticks - start_ticks; 1784294f337SSean Bruno if (yielded_ticks > ticks_to_pause) 1794294f337SSean Bruno break; 1804294f337SSean Bruno else if (yielded_ticks < 0 1814294f337SSean Bruno && (yielded_ticks + INT_MAX + 1 > ticks_to_pause)) { 1824294f337SSean Bruno break; 1834294f337SSean Bruno } 1844294f337SSean Bruno } 1854294f337SSean Bruno } 1864294f337SSean Bruno 18761ae650dSJack F Vogel /* 1886c426059SEric Joyner * Helper function for debug statement printing 18961ae650dSJack F Vogel */ 1906c426059SEric Joyner void 1914294f337SSean Bruno i40e_debug_shared(struct i40e_hw *hw, enum i40e_debug_mask mask, char *fmt, ...) 19261ae650dSJack F Vogel { 19361ae650dSJack F Vogel va_list args; 194cb6b8299SEric Joyner device_t dev; 19561ae650dSJack F Vogel 19661ae650dSJack F Vogel if (!(mask & ((struct i40e_hw *)hw)->debug_mask)) 19761ae650dSJack F Vogel return; 19861ae650dSJack F Vogel 199cb6b8299SEric Joyner dev = ((struct i40e_osdep *)hw->back)->dev; 200cb6b8299SEric Joyner 201cb6b8299SEric Joyner /* Re-implement device_printf() */ 202cb6b8299SEric Joyner device_print_prettyname(dev); 20361ae650dSJack F Vogel va_start(args, fmt); 204cb6b8299SEric Joyner vprintf(fmt, args); 20561ae650dSJack F Vogel va_end(args); 20661ae650dSJack F Vogel } 20761ae650dSJack F Vogel 208cb6b8299SEric Joyner const char * 209cb6b8299SEric Joyner ixl_vc_opcode_str(uint16_t op) 210cb6b8299SEric Joyner { 211cb6b8299SEric Joyner switch (op) { 212*ceebc2f3SEric Joyner case VIRTCHNL_OP_VERSION: 213cb6b8299SEric Joyner return ("VERSION"); 214*ceebc2f3SEric Joyner case VIRTCHNL_OP_RESET_VF: 215cb6b8299SEric Joyner return ("RESET_VF"); 216*ceebc2f3SEric Joyner case VIRTCHNL_OP_GET_VF_RESOURCES: 217cb6b8299SEric Joyner return ("GET_VF_RESOURCES"); 218*ceebc2f3SEric Joyner case VIRTCHNL_OP_CONFIG_TX_QUEUE: 219cb6b8299SEric Joyner return ("CONFIG_TX_QUEUE"); 220*ceebc2f3SEric Joyner case VIRTCHNL_OP_CONFIG_RX_QUEUE: 221cb6b8299SEric Joyner return ("CONFIG_RX_QUEUE"); 222*ceebc2f3SEric Joyner case VIRTCHNL_OP_CONFIG_VSI_QUEUES: 223cb6b8299SEric Joyner return ("CONFIG_VSI_QUEUES"); 224*ceebc2f3SEric Joyner case VIRTCHNL_OP_CONFIG_IRQ_MAP: 225cb6b8299SEric Joyner return ("CONFIG_IRQ_MAP"); 226*ceebc2f3SEric Joyner case VIRTCHNL_OP_ENABLE_QUEUES: 227cb6b8299SEric Joyner return ("ENABLE_QUEUES"); 228*ceebc2f3SEric Joyner case VIRTCHNL_OP_DISABLE_QUEUES: 229cb6b8299SEric Joyner return ("DISABLE_QUEUES"); 230*ceebc2f3SEric Joyner case VIRTCHNL_OP_ADD_ETH_ADDR: 231*ceebc2f3SEric Joyner return ("ADD_ETH_ADDR"); 232*ceebc2f3SEric Joyner case VIRTCHNL_OP_DEL_ETH_ADDR: 233*ceebc2f3SEric Joyner return ("DEL_ETH_ADDR"); 234*ceebc2f3SEric Joyner case VIRTCHNL_OP_ADD_VLAN: 235cb6b8299SEric Joyner return ("ADD_VLAN"); 236*ceebc2f3SEric Joyner case VIRTCHNL_OP_DEL_VLAN: 237cb6b8299SEric Joyner return ("DEL_VLAN"); 238*ceebc2f3SEric Joyner case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: 239cb6b8299SEric Joyner return ("CONFIG_PROMISCUOUS_MODE"); 240*ceebc2f3SEric Joyner case VIRTCHNL_OP_GET_STATS: 241cb6b8299SEric Joyner return ("GET_STATS"); 242*ceebc2f3SEric Joyner case VIRTCHNL_OP_RSVD: 243*ceebc2f3SEric Joyner return ("RSVD"); 244*ceebc2f3SEric Joyner case VIRTCHNL_OP_EVENT: 245cb6b8299SEric Joyner return ("EVENT"); 246*ceebc2f3SEric Joyner case VIRTCHNL_OP_CONFIG_RSS_KEY: 247cb6b8299SEric Joyner return ("CONFIG_RSS_KEY"); 248*ceebc2f3SEric Joyner case VIRTCHNL_OP_CONFIG_RSS_LUT: 249cb6b8299SEric Joyner return ("CONFIG_RSS_LUT"); 250*ceebc2f3SEric Joyner case VIRTCHNL_OP_GET_RSS_HENA_CAPS: 251cb6b8299SEric Joyner return ("GET_RSS_HENA_CAPS"); 252*ceebc2f3SEric Joyner case VIRTCHNL_OP_SET_RSS_HENA: 253cb6b8299SEric Joyner return ("SET_RSS_HENA"); 254cb6b8299SEric Joyner default: 255cb6b8299SEric Joyner return ("UNKNOWN"); 256cb6b8299SEric Joyner } 257cb6b8299SEric Joyner } 258cb6b8299SEric Joyner 25961ae650dSJack F Vogel u16 26061ae650dSJack F Vogel i40e_read_pci_cfg(struct i40e_hw *hw, u32 reg) 26161ae650dSJack F Vogel { 26261ae650dSJack F Vogel u16 value; 26361ae650dSJack F Vogel 26461ae650dSJack F Vogel value = pci_read_config(((struct i40e_osdep *)hw->back)->dev, 26561ae650dSJack F Vogel reg, 2); 26661ae650dSJack F Vogel 26761ae650dSJack F Vogel return (value); 26861ae650dSJack F Vogel } 26961ae650dSJack F Vogel 27061ae650dSJack F Vogel void 27161ae650dSJack F Vogel i40e_write_pci_cfg(struct i40e_hw *hw, u32 reg, u16 value) 27261ae650dSJack F Vogel { 27361ae650dSJack F Vogel pci_write_config(((struct i40e_osdep *)hw->back)->dev, 27461ae650dSJack F Vogel reg, value, 2); 27561ae650dSJack F Vogel 27661ae650dSJack F Vogel return; 27761ae650dSJack F Vogel } 27861ae650dSJack F Vogel 279