xref: /freebsd/sys/dev/ixl/i40e_osdep.c (revision ecaeac805b044f715c98960a8fbf19fe2b76ae6b)
1 /******************************************************************************
2 
3   Copyright (c) 2013-2018, Intel Corporation
4   All rights reserved.
5 
6   Redistribution and use in source and binary forms, with or without
7   modification, are permitted provided that the following conditions are met:
8 
9    1. Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11 
12    2. Redistributions in binary form must reproduce the above copyright
13       notice, this list of conditions and the following disclaimer in the
14       documentation and/or other materials provided with the distribution.
15 
16    3. Neither the name of the Intel Corporation nor the names of its
17       contributors may be used to endorse or promote products derived from
18       this software without specific prior written permission.
19 
20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   POSSIBILITY OF SUCH DAMAGE.
31 
32 ******************************************************************************/
33 /*$FreeBSD$*/
34 
35 #include <sys/limits.h>
36 #include <sys/time.h>
37 
38 #include "ixl.h"
39 
40 /********************************************************************
41  * Manage DMA'able memory.
42  *******************************************************************/
43 static void
44 i40e_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg, int error)
45 {
46         if (error)
47                 return;
48         *(bus_addr_t *) arg = segs->ds_addr;
49 }
50 
51 i40e_status
52 i40e_allocate_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem, u32 size)
53 {
54 	mem->va = malloc(size, M_IXL, M_NOWAIT | M_ZERO);
55 	return (mem->va == NULL);
56 }
57 
58 i40e_status
59 i40e_free_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem)
60 {
61 	free(mem->va, M_IXL);
62 	mem->va = NULL;
63 
64 	return (I40E_SUCCESS);
65 }
66 
67 i40e_status
68 i40e_allocate_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem,
69 	enum i40e_memory_type type __unused, u64 size, u32 alignment)
70 {
71 	device_t	dev = ((struct i40e_osdep *)hw->back)->dev;
72 	int		err;
73 
74 
75 	err = bus_dma_tag_create(bus_get_dma_tag(dev),	/* parent */
76 			       alignment, 0,	/* alignment, bounds */
77 			       BUS_SPACE_MAXADDR,	/* lowaddr */
78 			       BUS_SPACE_MAXADDR,	/* highaddr */
79 			       NULL, NULL,	/* filter, filterarg */
80 			       size,	/* maxsize */
81 			       1,	/* nsegments */
82 			       size,	/* maxsegsize */
83 			       BUS_DMA_ALLOCNOW, /* flags */
84 			       NULL,	/* lockfunc */
85 			       NULL,	/* lockfuncarg */
86 			       &mem->tag);
87 	if (err != 0) {
88 		device_printf(dev,
89 		    "i40e_allocate_dma: bus_dma_tag_create failed, "
90 		    "error %u\n", err);
91 		goto fail_0;
92 	}
93 	err = bus_dmamem_alloc(mem->tag, (void **)&mem->va,
94 			     BUS_DMA_NOWAIT | BUS_DMA_ZERO, &mem->map);
95 	if (err != 0) {
96 		device_printf(dev,
97 		    "i40e_allocate_dma: bus_dmamem_alloc failed, "
98 		    "error %u\n", err);
99 		goto fail_1;
100 	}
101 	err = bus_dmamap_load(mem->tag, mem->map, mem->va,
102 			    size,
103 			    i40e_dmamap_cb,
104 			    &mem->pa,
105 			    BUS_DMA_NOWAIT);
106 	if (err != 0) {
107 		device_printf(dev,
108 		    "i40e_allocate_dma: bus_dmamap_load failed, "
109 		    "error %u\n", err);
110 		goto fail_2;
111 	}
112 	mem->size = size;
113 	bus_dmamap_sync(mem->tag, mem->map,
114 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
115 	return (I40E_SUCCESS);
116 fail_2:
117 	bus_dmamem_free(mem->tag, mem->va, mem->map);
118 fail_1:
119 	bus_dma_tag_destroy(mem->tag);
120 fail_0:
121 	mem->map = NULL;
122 	mem->tag = NULL;
123 	return (err);
124 }
125 
126 i40e_status
127 i40e_free_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem)
128 {
129 	bus_dmamap_sync(mem->tag, mem->map,
130 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
131 	bus_dmamap_unload(mem->tag, mem->map);
132 	bus_dmamem_free(mem->tag, mem->va, mem->map);
133 	bus_dma_tag_destroy(mem->tag);
134 	return (I40E_SUCCESS);
135 }
136 
137 void
138 i40e_init_spinlock(struct i40e_spinlock *lock)
139 {
140 	mtx_init(&lock->mutex, "mutex",
141 	    "ixl spinlock", MTX_DEF | MTX_DUPOK);
142 }
143 
144 void
145 i40e_acquire_spinlock(struct i40e_spinlock *lock)
146 {
147 	mtx_lock(&lock->mutex);
148 }
149 
150 void
151 i40e_release_spinlock(struct i40e_spinlock *lock)
152 {
153 	mtx_unlock(&lock->mutex);
154 }
155 
156 void
157 i40e_destroy_spinlock(struct i40e_spinlock *lock)
158 {
159 	if (mtx_initialized(&lock->mutex))
160 		mtx_destroy(&lock->mutex);
161 }
162 
163 #ifndef MSEC_2_TICKS
164 #define MSEC_2_TICKS(m) max(1, (uint32_t)((hz == 1000) ? \
165 	  (m) : ((uint64_t)(m) * (uint64_t)hz)/(uint64_t)1000))
166 #endif
167 
168 void
169 i40e_msec_pause(int msecs)
170 {
171 	pause("i40e_msec_pause", MSEC_2_TICKS(msecs));
172 }
173 
174 /*
175  * Helper function for debug statement printing
176  */
177 void
178 i40e_debug_shared(struct i40e_hw *hw, enum i40e_debug_mask mask, char *fmt, ...)
179 {
180 	va_list args;
181 	device_t dev;
182 
183 	if (!(mask & ((struct i40e_hw *)hw)->debug_mask))
184 		return;
185 
186 	dev = ((struct i40e_osdep *)hw->back)->dev;
187 
188 	/* Re-implement device_printf() */
189 	device_print_prettyname(dev);
190 	va_start(args, fmt);
191 	vprintf(fmt, args);
192 	va_end(args);
193 }
194 
195 const char *
196 ixl_vc_opcode_str(uint16_t op)
197 {
198 	switch (op) {
199 	case VIRTCHNL_OP_VERSION:
200 		return ("VERSION");
201 	case VIRTCHNL_OP_RESET_VF:
202 		return ("RESET_VF");
203 	case VIRTCHNL_OP_GET_VF_RESOURCES:
204 		return ("GET_VF_RESOURCES");
205 	case VIRTCHNL_OP_CONFIG_TX_QUEUE:
206 		return ("CONFIG_TX_QUEUE");
207 	case VIRTCHNL_OP_CONFIG_RX_QUEUE:
208 		return ("CONFIG_RX_QUEUE");
209 	case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
210 		return ("CONFIG_VSI_QUEUES");
211 	case VIRTCHNL_OP_CONFIG_IRQ_MAP:
212 		return ("CONFIG_IRQ_MAP");
213 	case VIRTCHNL_OP_ENABLE_QUEUES:
214 		return ("ENABLE_QUEUES");
215 	case VIRTCHNL_OP_DISABLE_QUEUES:
216 		return ("DISABLE_QUEUES");
217 	case VIRTCHNL_OP_ADD_ETH_ADDR:
218 		return ("ADD_ETH_ADDR");
219 	case VIRTCHNL_OP_DEL_ETH_ADDR:
220 		return ("DEL_ETH_ADDR");
221 	case VIRTCHNL_OP_ADD_VLAN:
222 		return ("ADD_VLAN");
223 	case VIRTCHNL_OP_DEL_VLAN:
224 		return ("DEL_VLAN");
225 	case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
226 		return ("CONFIG_PROMISCUOUS_MODE");
227 	case VIRTCHNL_OP_GET_STATS:
228 		return ("GET_STATS");
229 	case VIRTCHNL_OP_RSVD:
230 		return ("RSVD");
231 	case VIRTCHNL_OP_EVENT:
232 		return ("EVENT");
233 	case VIRTCHNL_OP_CONFIG_RSS_KEY:
234 		return ("CONFIG_RSS_KEY");
235 	case VIRTCHNL_OP_CONFIG_RSS_LUT:
236 		return ("CONFIG_RSS_LUT");
237 	case VIRTCHNL_OP_GET_RSS_HENA_CAPS:
238 		return ("GET_RSS_HENA_CAPS");
239 	case VIRTCHNL_OP_SET_RSS_HENA:
240 		return ("SET_RSS_HENA");
241 	default:
242 		return ("UNKNOWN");
243 	}
244 }
245 
246 u16
247 i40e_read_pci_cfg(struct i40e_hw *hw, u32 reg)
248 {
249         u16 value;
250 
251         value = pci_read_config(((struct i40e_osdep *)hw->back)->dev,
252             reg, 2);
253 
254         return (value);
255 }
256 
257 void
258 i40e_write_pci_cfg(struct i40e_hw *hw, u32 reg, u16 value)
259 {
260         pci_write_config(((struct i40e_osdep *)hw->back)->dev,
261             reg, value, 2);
262 }
263 
264