1ca853deeSEric Joyner /* SPDX-License-Identifier: BSD-3-Clause */
2ca853deeSEric Joyner /* Copyright (c) 2021, Intel Corporation
3ca853deeSEric Joyner * All rights reserved.
4ca853deeSEric Joyner *
5ca853deeSEric Joyner * Redistribution and use in source and binary forms, with or without
6ca853deeSEric Joyner * modification, are permitted provided that the following conditions are met:
7ca853deeSEric Joyner *
8ca853deeSEric Joyner * 1. Redistributions of source code must retain the above copyright notice,
9ca853deeSEric Joyner * this list of conditions and the following disclaimer.
10ca853deeSEric Joyner *
11ca853deeSEric Joyner * 2. Redistributions in binary form must reproduce the above copyright
12ca853deeSEric Joyner * notice, this list of conditions and the following disclaimer in the
13ca853deeSEric Joyner * documentation and/or other materials provided with the distribution.
14ca853deeSEric Joyner *
15ca853deeSEric Joyner * 3. Neither the name of the Intel Corporation nor the names of its
16ca853deeSEric Joyner * contributors may be used to endorse or promote products derived from
17ca853deeSEric Joyner * this software without specific prior written permission.
18ca853deeSEric Joyner *
19ca853deeSEric Joyner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20ca853deeSEric Joyner * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21ca853deeSEric Joyner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22ca853deeSEric Joyner * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23ca853deeSEric Joyner * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24ca853deeSEric Joyner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25ca853deeSEric Joyner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26ca853deeSEric Joyner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27ca853deeSEric Joyner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28ca853deeSEric Joyner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29ca853deeSEric Joyner * POSSIBILITY OF SUCH DAMAGE.
30ca853deeSEric Joyner */
31ca853deeSEric Joyner
32ca853deeSEric Joyner /**
33ca853deeSEric Joyner * @file iavf_osdep.c
34ca853deeSEric Joyner * @brief OS compatibility layer
35ca853deeSEric Joyner *
36ca853deeSEric Joyner * Contains definitions for various functions used to provide an OS
37ca853deeSEric Joyner * independent layer for sharing code between drivers on different operating
38ca853deeSEric Joyner * systems.
39ca853deeSEric Joyner */
40*e453e498SBrooks Davis #include <sys/stdarg.h>
41ca853deeSEric Joyner
42ca853deeSEric Joyner #include "iavf_iflib.h"
43ca853deeSEric Joyner
44ca853deeSEric Joyner /********************************************************************
45ca853deeSEric Joyner * Manage DMA'able memory.
46ca853deeSEric Joyner *******************************************************************/
47ca853deeSEric Joyner
48ca853deeSEric Joyner /**
49ca853deeSEric Joyner * iavf_dmamap_cb - DMA mapping callback function
50ca853deeSEric Joyner * @arg: pointer to return the segment address
51ca853deeSEric Joyner * @segs: the segments array
52ca853deeSEric Joyner * @nseg: number of segments in the array
53ca853deeSEric Joyner * @error: error code
54ca853deeSEric Joyner *
55ca853deeSEric Joyner * Callback used by the bus DMA code to obtain the segment address.
56ca853deeSEric Joyner */
57ca853deeSEric Joyner static void
iavf_dmamap_cb(void * arg,bus_dma_segment_t * segs,int nseg __unused,int error)58ca853deeSEric Joyner iavf_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg __unused,
59ca853deeSEric Joyner int error)
60ca853deeSEric Joyner {
61ca853deeSEric Joyner if (error)
62ca853deeSEric Joyner return;
63ca853deeSEric Joyner *(bus_addr_t *) arg = segs->ds_addr;
64ca853deeSEric Joyner return;
65ca853deeSEric Joyner }
66ca853deeSEric Joyner
67ca853deeSEric Joyner /**
68ca853deeSEric Joyner * iavf_allocate_virt_mem - Allocate virtual memory
69ca853deeSEric Joyner * @hw: hardware structure
70ca853deeSEric Joyner * @mem: structure describing the memory allocation
71ca853deeSEric Joyner * @size: size of the allocation
72ca853deeSEric Joyner *
73ca853deeSEric Joyner * OS compatibility function to allocate virtual memory.
74ca853deeSEric Joyner *
75ca853deeSEric Joyner * @returns zero on success, or a status code on failure.
76ca853deeSEric Joyner */
77ca853deeSEric Joyner enum iavf_status
iavf_allocate_virt_mem(struct iavf_hw * hw __unused,struct iavf_virt_mem * mem,u32 size)78ca853deeSEric Joyner iavf_allocate_virt_mem(struct iavf_hw *hw __unused, struct iavf_virt_mem *mem,
79ca853deeSEric Joyner u32 size)
80ca853deeSEric Joyner {
81ca853deeSEric Joyner mem->va = malloc(size, M_IAVF, M_NOWAIT | M_ZERO);
82ca853deeSEric Joyner return(mem->va == NULL);
83ca853deeSEric Joyner }
84ca853deeSEric Joyner
85ca853deeSEric Joyner /**
86ca853deeSEric Joyner * iavf_free_virt_mem - Free virtual memory
87ca853deeSEric Joyner * @hw: hardware structure
88ca853deeSEric Joyner * @mem: structure describing the memory to free
89ca853deeSEric Joyner *
90ca853deeSEric Joyner * OS compatibility function to free virtual memory
91ca853deeSEric Joyner *
92ca853deeSEric Joyner * @returns zero.
93ca853deeSEric Joyner */
94ca853deeSEric Joyner enum iavf_status
iavf_free_virt_mem(struct iavf_hw * hw __unused,struct iavf_virt_mem * mem)95ca853deeSEric Joyner iavf_free_virt_mem(struct iavf_hw *hw __unused, struct iavf_virt_mem *mem)
96ca853deeSEric Joyner {
97ca853deeSEric Joyner free(mem->va, M_IAVF);
98ca853deeSEric Joyner mem->va = NULL;
99ca853deeSEric Joyner
100ca853deeSEric Joyner return(0);
101ca853deeSEric Joyner }
102ca853deeSEric Joyner
103ca853deeSEric Joyner /**
104ca853deeSEric Joyner * iavf_allocate_dma_mem - Allocate DMA memory
105ca853deeSEric Joyner * @hw: hardware structure
106ca853deeSEric Joyner * @mem: structure describing the memory allocation
107ca853deeSEric Joyner * @type: unused type parameter specifying the type of allocation
108ca853deeSEric Joyner * @size: size of the allocation
109ca853deeSEric Joyner * @alignment: alignment requirements for the allocation
110ca853deeSEric Joyner *
111ca853deeSEric Joyner * Allocates DMA memory by using bus_dma_tag_create to create a DMA tag, and
112ca853deeSEric Joyner * them bus_dmamem_alloc to allocate the associated memory.
113ca853deeSEric Joyner *
114ca853deeSEric Joyner * @returns zero on success, or a status code on failure.
115ca853deeSEric Joyner */
116ca853deeSEric Joyner enum iavf_status
iavf_allocate_dma_mem(struct iavf_hw * hw,struct iavf_dma_mem * mem,enum iavf_memory_type type __unused,u64 size,u32 alignment)117ca853deeSEric Joyner iavf_allocate_dma_mem(struct iavf_hw *hw, struct iavf_dma_mem *mem,
118ca853deeSEric Joyner enum iavf_memory_type type __unused, u64 size, u32 alignment)
119ca853deeSEric Joyner {
120ca853deeSEric Joyner device_t dev = ((struct iavf_osdep *)hw->back)->dev;
121ca853deeSEric Joyner int err;
122ca853deeSEric Joyner
123ca853deeSEric Joyner
124ca853deeSEric Joyner err = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
125ca853deeSEric Joyner alignment, 0, /* alignment, bounds */
126ca853deeSEric Joyner BUS_SPACE_MAXADDR, /* lowaddr */
127ca853deeSEric Joyner BUS_SPACE_MAXADDR, /* highaddr */
128ca853deeSEric Joyner NULL, NULL, /* filter, filterarg */
129ca853deeSEric Joyner size, /* maxsize */
130ca853deeSEric Joyner 1, /* nsegments */
131ca853deeSEric Joyner size, /* maxsegsize */
132ca853deeSEric Joyner BUS_DMA_ALLOCNOW, /* flags */
133ca853deeSEric Joyner NULL, /* lockfunc */
134ca853deeSEric Joyner NULL, /* lockfuncarg */
135ca853deeSEric Joyner &mem->tag);
136ca853deeSEric Joyner if (err != 0) {
137ca853deeSEric Joyner device_printf(dev,
138ca853deeSEric Joyner "iavf_allocate_dma: bus_dma_tag_create failed, "
139ca853deeSEric Joyner "error %u\n", err);
140ca853deeSEric Joyner goto fail_0;
141ca853deeSEric Joyner }
142ca853deeSEric Joyner err = bus_dmamem_alloc(mem->tag, (void **)&mem->va,
143ca853deeSEric Joyner BUS_DMA_NOWAIT | BUS_DMA_ZERO, &mem->map);
144ca853deeSEric Joyner if (err != 0) {
145ca853deeSEric Joyner device_printf(dev,
146ca853deeSEric Joyner "iavf_allocate_dma: bus_dmamem_alloc failed, "
147ca853deeSEric Joyner "error %u\n", err);
148ca853deeSEric Joyner goto fail_1;
149ca853deeSEric Joyner }
150ca853deeSEric Joyner err = bus_dmamap_load(mem->tag, mem->map, mem->va,
151ca853deeSEric Joyner size,
152ca853deeSEric Joyner iavf_dmamap_cb,
153ca853deeSEric Joyner &mem->pa,
154ca853deeSEric Joyner BUS_DMA_NOWAIT);
155ca853deeSEric Joyner if (err != 0) {
156ca853deeSEric Joyner device_printf(dev,
157ca853deeSEric Joyner "iavf_allocate_dma: bus_dmamap_load failed, "
158ca853deeSEric Joyner "error %u\n", err);
159ca853deeSEric Joyner goto fail_2;
160ca853deeSEric Joyner }
161ca853deeSEric Joyner mem->nseg = 1;
162ca853deeSEric Joyner mem->size = size;
163ca853deeSEric Joyner bus_dmamap_sync(mem->tag, mem->map,
164ca853deeSEric Joyner BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
165ca853deeSEric Joyner return (0);
166ca853deeSEric Joyner fail_2:
167ca853deeSEric Joyner bus_dmamem_free(mem->tag, mem->va, mem->map);
168ca853deeSEric Joyner fail_1:
169ca853deeSEric Joyner bus_dma_tag_destroy(mem->tag);
170ca853deeSEric Joyner fail_0:
171ca853deeSEric Joyner mem->map = NULL;
172ca853deeSEric Joyner mem->tag = NULL;
173ca853deeSEric Joyner return (err);
174ca853deeSEric Joyner }
175ca853deeSEric Joyner
176ca853deeSEric Joyner /**
177ca853deeSEric Joyner * iavf_free_dma_mem - Free DMA memory allocation
178ca853deeSEric Joyner * @hw: hardware structure
179ca853deeSEric Joyner * @mem: pointer to memory structure previously allocated
180ca853deeSEric Joyner *
181ca853deeSEric Joyner * Releases DMA memory that was previously allocated by iavf_allocate_dma_mem.
182ca853deeSEric Joyner *
183ca853deeSEric Joyner * @returns zero.
184ca853deeSEric Joyner */
185ca853deeSEric Joyner enum iavf_status
iavf_free_dma_mem(struct iavf_hw * hw __unused,struct iavf_dma_mem * mem)186ca853deeSEric Joyner iavf_free_dma_mem(struct iavf_hw *hw __unused, struct iavf_dma_mem *mem)
187ca853deeSEric Joyner {
188ca853deeSEric Joyner bus_dmamap_sync(mem->tag, mem->map,
189ca853deeSEric Joyner BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
190ca853deeSEric Joyner bus_dmamap_unload(mem->tag, mem->map);
191ca853deeSEric Joyner bus_dmamem_free(mem->tag, mem->va, mem->map);
192ca853deeSEric Joyner bus_dma_tag_destroy(mem->tag);
193ca853deeSEric Joyner return (0);
194ca853deeSEric Joyner }
195ca853deeSEric Joyner
196ca853deeSEric Joyner /**
197ca853deeSEric Joyner * iavf_init_spinlock - Initialize a spinlock
198ca853deeSEric Joyner * @lock: OS compatibility lock structure
199ca853deeSEric Joyner *
200ca853deeSEric Joyner * Use the mutex layer to initialize a spin lock that can be used via the OS
201ca853deeSEric Joyner * compatibility layer accessors.
202ca853deeSEric Joyner *
203ca853deeSEric Joyner * @remark we pass MTX_DUPOK because the mutex name will not be unique. An
204ca853deeSEric Joyner * alternative would be to somehow generate a name, such as by passing in the
205ca853deeSEric Joyner * __file__ and __line__ values from a macro.
206ca853deeSEric Joyner */
207ca853deeSEric Joyner void
iavf_init_spinlock(struct iavf_spinlock * lock)208ca853deeSEric Joyner iavf_init_spinlock(struct iavf_spinlock *lock)
209ca853deeSEric Joyner {
210ca853deeSEric Joyner mtx_init(&lock->mutex, "mutex",
211ca853deeSEric Joyner "iavf spinlock", MTX_DEF | MTX_DUPOK);
212ca853deeSEric Joyner }
213ca853deeSEric Joyner
214ca853deeSEric Joyner /**
215ca853deeSEric Joyner * iavf_acquire_spinlock - Acquire a spin lock
216ca853deeSEric Joyner * @lock: OS compatibility lock structure
217ca853deeSEric Joyner *
218ca853deeSEric Joyner * Acquire a spin lock using mtx_lock.
219ca853deeSEric Joyner */
220ca853deeSEric Joyner void
iavf_acquire_spinlock(struct iavf_spinlock * lock)221ca853deeSEric Joyner iavf_acquire_spinlock(struct iavf_spinlock *lock)
222ca853deeSEric Joyner {
223ca853deeSEric Joyner mtx_lock(&lock->mutex);
224ca853deeSEric Joyner }
225ca853deeSEric Joyner
226ca853deeSEric Joyner /**
227ca853deeSEric Joyner * iavf_release_spinlock - Release a spin lock
228ca853deeSEric Joyner * @lock: OS compatibility lock structure
229ca853deeSEric Joyner *
230ca853deeSEric Joyner * Release a spin lock using mtx_unlock.
231ca853deeSEric Joyner */
232ca853deeSEric Joyner void
iavf_release_spinlock(struct iavf_spinlock * lock)233ca853deeSEric Joyner iavf_release_spinlock(struct iavf_spinlock *lock)
234ca853deeSEric Joyner {
235ca853deeSEric Joyner mtx_unlock(&lock->mutex);
236ca853deeSEric Joyner }
237ca853deeSEric Joyner
238ca853deeSEric Joyner /**
239ca853deeSEric Joyner * iavf_destroy_spinlock - Destroy a spin lock
240ca853deeSEric Joyner * @lock: OS compatibility lock structure
241ca853deeSEric Joyner *
242ca853deeSEric Joyner * Destroy (deinitialize) a spin lock by calling mtx_destroy.
243ca853deeSEric Joyner *
244ca853deeSEric Joyner * @remark we only destroy the lock if it was initialized. This means that
245ca853deeSEric Joyner * calling iavf_destroy_spinlock on a lock that was already destroyed or was
246ca853deeSEric Joyner * never initialized is not considered a bug.
247ca853deeSEric Joyner */
248ca853deeSEric Joyner void
iavf_destroy_spinlock(struct iavf_spinlock * lock)249ca853deeSEric Joyner iavf_destroy_spinlock(struct iavf_spinlock *lock)
250ca853deeSEric Joyner {
251ca853deeSEric Joyner if (mtx_initialized(&lock->mutex))
252ca853deeSEric Joyner mtx_destroy(&lock->mutex);
253ca853deeSEric Joyner }
254ca853deeSEric Joyner
255ca853deeSEric Joyner /**
256ca853deeSEric Joyner * iavf_debug_shared - Log a debug message if enabled
257ca853deeSEric Joyner * @hw: device hardware structure
258ca853deeSEric Joyner * @mask: bit indicating the type of the message
259ca853deeSEric Joyner * @fmt: printf format string
260ca853deeSEric Joyner *
261ca853deeSEric Joyner * Checks if the mask is enabled in the hw->debug_mask. If so, prints
262ca853deeSEric Joyner * a message to the console using vprintf().
263ca853deeSEric Joyner */
264ca853deeSEric Joyner void
iavf_debug_shared(struct iavf_hw * hw,uint64_t mask,char * fmt,...)265ca853deeSEric Joyner iavf_debug_shared(struct iavf_hw *hw, uint64_t mask, char *fmt, ...)
266ca853deeSEric Joyner {
267ca853deeSEric Joyner va_list args;
268ca853deeSEric Joyner device_t dev;
269ca853deeSEric Joyner
270ca853deeSEric Joyner if (!(mask & ((struct iavf_hw *)hw)->debug_mask))
271ca853deeSEric Joyner return;
272ca853deeSEric Joyner
273ca853deeSEric Joyner dev = ((struct iavf_osdep *)hw->back)->dev;
274ca853deeSEric Joyner
275ca853deeSEric Joyner /* Re-implement device_printf() */
276ca853deeSEric Joyner device_print_prettyname(dev);
277ca853deeSEric Joyner va_start(args, fmt);
278ca853deeSEric Joyner vprintf(fmt, args);
279ca853deeSEric Joyner va_end(args);
280ca853deeSEric Joyner }
281ca853deeSEric Joyner
282ca853deeSEric Joyner /**
283ca853deeSEric Joyner * iavf_read_pci_cfg - Read a PCI config register
284ca853deeSEric Joyner * @hw: device hardware structure
285ca853deeSEric Joyner * @reg: the PCI register to read
286ca853deeSEric Joyner *
287ca853deeSEric Joyner * Calls pci_read_config to read the given PCI register from the PCI config
288ca853deeSEric Joyner * space.
289ca853deeSEric Joyner *
290ca853deeSEric Joyner * @returns the value of the register.
291ca853deeSEric Joyner */
292ca853deeSEric Joyner u16
iavf_read_pci_cfg(struct iavf_hw * hw,u32 reg)293ca853deeSEric Joyner iavf_read_pci_cfg(struct iavf_hw *hw, u32 reg)
294ca853deeSEric Joyner {
295ca853deeSEric Joyner u16 value;
296ca853deeSEric Joyner
297ca853deeSEric Joyner value = pci_read_config(((struct iavf_osdep *)hw->back)->dev,
298ca853deeSEric Joyner reg, 2);
299ca853deeSEric Joyner
300ca853deeSEric Joyner return (value);
301ca853deeSEric Joyner }
302ca853deeSEric Joyner
303ca853deeSEric Joyner /**
304ca853deeSEric Joyner * iavf_write_pci_cfg - Write a PCI config register
305ca853deeSEric Joyner * @hw: device hardware structure
306ca853deeSEric Joyner * @reg: the PCI register to write
307ca853deeSEric Joyner * @value: the value to write
308ca853deeSEric Joyner *
309ca853deeSEric Joyner * Calls pci_write_config to write to a given PCI register in the PCI config
310ca853deeSEric Joyner * space.
311ca853deeSEric Joyner */
312ca853deeSEric Joyner void
iavf_write_pci_cfg(struct iavf_hw * hw,u32 reg,u16 value)313ca853deeSEric Joyner iavf_write_pci_cfg(struct iavf_hw *hw, u32 reg, u16 value)
314ca853deeSEric Joyner {
315ca853deeSEric Joyner pci_write_config(((struct iavf_osdep *)hw->back)->dev,
316ca853deeSEric Joyner reg, value, 2);
317ca853deeSEric Joyner
318ca853deeSEric Joyner return;
319ca853deeSEric Joyner }
320ca853deeSEric Joyner
321ca853deeSEric Joyner /**
322ca853deeSEric Joyner * iavf_rd32 - Read a 32bit hardware register value
323ca853deeSEric Joyner * @hw: the private hardware structure
324ca853deeSEric Joyner * @reg: register address to read
325ca853deeSEric Joyner *
326ca853deeSEric Joyner * Read the specified 32bit register value from BAR0 and return its contents.
327ca853deeSEric Joyner *
328ca853deeSEric Joyner * @returns the value of the 32bit register.
329ca853deeSEric Joyner */
330ca853deeSEric Joyner inline uint32_t
iavf_rd32(struct iavf_hw * hw,uint32_t reg)331ca853deeSEric Joyner iavf_rd32(struct iavf_hw *hw, uint32_t reg)
332ca853deeSEric Joyner {
333ca853deeSEric Joyner struct iavf_osdep *osdep = (struct iavf_osdep *)hw->back;
334ca853deeSEric Joyner
335ca853deeSEric Joyner KASSERT(reg < osdep->mem_bus_space_size,
336ca853deeSEric Joyner ("iavf: register offset %#jx too large (max is %#jx)",
337ca853deeSEric Joyner (uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size));
338ca853deeSEric Joyner
339ca853deeSEric Joyner return (bus_space_read_4(osdep->mem_bus_space_tag,
340ca853deeSEric Joyner osdep->mem_bus_space_handle, reg));
341ca853deeSEric Joyner }
342ca853deeSEric Joyner
343ca853deeSEric Joyner /**
344ca853deeSEric Joyner * iavf_wr32 - Write a 32bit hardware register
345ca853deeSEric Joyner * @hw: the private hardware structure
346ca853deeSEric Joyner * @reg: the register address to write to
347ca853deeSEric Joyner * @val: the 32bit value to write
348ca853deeSEric Joyner *
349ca853deeSEric Joyner * Write the specified 32bit value to a register address in BAR0.
350ca853deeSEric Joyner */
351ca853deeSEric Joyner inline void
iavf_wr32(struct iavf_hw * hw,uint32_t reg,uint32_t val)352ca853deeSEric Joyner iavf_wr32(struct iavf_hw *hw, uint32_t reg, uint32_t val)
353ca853deeSEric Joyner {
354ca853deeSEric Joyner struct iavf_osdep *osdep = (struct iavf_osdep *)hw->back;
355ca853deeSEric Joyner
356ca853deeSEric Joyner KASSERT(reg < osdep->mem_bus_space_size,
357ca853deeSEric Joyner ("iavf: register offset %#jx too large (max is %#jx)",
358ca853deeSEric Joyner (uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size));
359ca853deeSEric Joyner
360ca853deeSEric Joyner bus_space_write_4(osdep->mem_bus_space_tag,
361ca853deeSEric Joyner osdep->mem_bus_space_handle, reg, val);
362ca853deeSEric Joyner }
363ca853deeSEric Joyner
364ca853deeSEric Joyner /**
365ca853deeSEric Joyner * iavf_flush - Flush register writes
366ca853deeSEric Joyner * @hw: private hardware structure
367ca853deeSEric Joyner *
368ca853deeSEric Joyner * Forces the completion of outstanding PCI register writes by reading from
369ca853deeSEric Joyner * a specific hardware register.
370ca853deeSEric Joyner */
371ca853deeSEric Joyner inline void
iavf_flush(struct iavf_hw * hw)372ca853deeSEric Joyner iavf_flush(struct iavf_hw *hw)
373ca853deeSEric Joyner {
374ca853deeSEric Joyner struct iavf_osdep *osdep = (struct iavf_osdep *)hw->back;
375ca853deeSEric Joyner
376ca853deeSEric Joyner rd32(hw, osdep->flush_reg);
377ca853deeSEric Joyner }
378ca853deeSEric Joyner
379ca853deeSEric Joyner /**
380ca853deeSEric Joyner * iavf_debug_core - Debug printf for core driver code
381ca853deeSEric Joyner * @dev: the device_t to log under
382ca853deeSEric Joyner * @enabled_mask: the mask of enabled messages
383ca853deeSEric Joyner * @mask: the mask of the requested message to print
384ca853deeSEric Joyner * @fmt: printf format string
385ca853deeSEric Joyner *
386ca853deeSEric Joyner * If enabled_mask has the bit from the mask set, print a message to the
387ca853deeSEric Joyner * console using the specified format. This is used to conditionally enable
388ca853deeSEric Joyner * log messages at run time by toggling the enabled_mask in the device
389ca853deeSEric Joyner * structure.
390ca853deeSEric Joyner */
391ca853deeSEric Joyner void
iavf_debug_core(device_t dev,u32 enabled_mask,u32 mask,char * fmt,...)392ca853deeSEric Joyner iavf_debug_core(device_t dev, u32 enabled_mask, u32 mask, char *fmt, ...)
393ca853deeSEric Joyner {
394ca853deeSEric Joyner va_list args;
395ca853deeSEric Joyner
396ca853deeSEric Joyner if (!(mask & enabled_mask))
397ca853deeSEric Joyner return;
398ca853deeSEric Joyner
399ca853deeSEric Joyner /* Re-implement device_printf() */
400ca853deeSEric Joyner device_print_prettyname(dev);
401ca853deeSEric Joyner va_start(args, fmt);
402ca853deeSEric Joyner vprintf(fmt, args);
403ca853deeSEric Joyner va_end(args);
404ca853deeSEric Joyner }
405