xref: /freebsd/sys/dev/ixl/i40e_osdep.c (revision cb6b8299fdda0ccd5c9c9b0d29cd9c005f6d780b)
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