1270631Sjfv/******************************************************************************
2270631Sjfv
3270631Sjfv  Copyright (c) 2013-2014, Intel Corporation
4270631Sjfv  All rights reserved.
5270631Sjfv
6270631Sjfv  Redistribution and use in source and binary forms, with or without
7270631Sjfv  modification, are permitted provided that the following conditions are met:
8270631Sjfv
9270631Sjfv   1. Redistributions of source code must retain the above copyright notice,
10270631Sjfv      this list of conditions and the following disclaimer.
11270631Sjfv
12270631Sjfv   2. Redistributions in binary form must reproduce the above copyright
13270631Sjfv      notice, this list of conditions and the following disclaimer in the
14270631Sjfv      documentation and/or other materials provided with the distribution.
15270631Sjfv
16270631Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17270631Sjfv      contributors may be used to endorse or promote products derived from
18270631Sjfv      this software without specific prior written permission.
19270631Sjfv
20270631Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21270631Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22270631Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23270631Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24270631Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25270631Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26270631Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27270631Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28270631Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29270631Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30270631Sjfv  POSSIBILITY OF SUCH DAMAGE.
31270631Sjfv
32270631Sjfv******************************************************************************/
33270631Sjfv/*$FreeBSD$*/
34270631Sjfv
35270631Sjfv#include <machine/stdarg.h>
36270631Sjfv
37270631Sjfv#include "ixl.h"
38270631Sjfv
39270631Sjfv/********************************************************************
40270631Sjfv * Manage DMA'able memory.
41270631Sjfv *******************************************************************/
42270631Sjfvstatic void
43270631Sjfvi40e_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg, int error)
44270631Sjfv{
45270631Sjfv        if (error)
46270631Sjfv                return;
47270631Sjfv        *(bus_addr_t *) arg = segs->ds_addr;
48270631Sjfv        return;
49270631Sjfv}
50270631Sjfv
51270631Sjfvi40e_status
52272313Sbzi40e_allocate_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem, u32 size)
53270631Sjfv{
54272313Sbz	mem->va = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
55272313Sbz	return(mem->va == NULL);
56270631Sjfv}
57270631Sjfv
58270631Sjfvi40e_status
59272313Sbzi40e_free_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem)
60270631Sjfv{
61272313Sbz	free(mem->va, M_DEVBUF);
62270631Sjfv	return(0);
63270631Sjfv}
64270631Sjfv
65270631Sjfvi40e_status
66272313Sbzi40e_allocate_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem,
67272313Sbz	enum i40e_memory_type type __unused, u64 size, u32 alignment)
68270631Sjfv{
69270631Sjfv	device_t	dev = ((struct i40e_osdep *)hw->back)->dev;
70270631Sjfv	int		err;
71270631Sjfv
72270631Sjfv
73270631Sjfv	err = bus_dma_tag_create(bus_get_dma_tag(dev),	/* parent */
74270631Sjfv			       alignment, 0,	/* alignment, bounds */
75270631Sjfv			       BUS_SPACE_MAXADDR,	/* lowaddr */
76270631Sjfv			       BUS_SPACE_MAXADDR,	/* highaddr */
77270631Sjfv			       NULL, NULL,	/* filter, filterarg */
78270631Sjfv			       size,	/* maxsize */
79270631Sjfv			       1,	/* nsegments */
80270631Sjfv			       size,	/* maxsegsize */
81270631Sjfv			       BUS_DMA_ALLOCNOW, /* flags */
82270631Sjfv			       NULL,	/* lockfunc */
83270631Sjfv			       NULL,	/* lockfuncarg */
84272313Sbz			       &mem->tag);
85270631Sjfv	if (err != 0) {
86270631Sjfv		device_printf(dev,
87270631Sjfv		    "i40e_allocate_dma: bus_dma_tag_create failed, "
88270631Sjfv		    "error %u\n", err);
89270631Sjfv		goto fail_0;
90270631Sjfv	}
91272313Sbz	err = bus_dmamem_alloc(mem->tag, (void **)&mem->va,
92272313Sbz			     BUS_DMA_NOWAIT | BUS_DMA_ZERO, &mem->map);
93270631Sjfv	if (err != 0) {
94270631Sjfv		device_printf(dev,
95270631Sjfv		    "i40e_allocate_dma: bus_dmamem_alloc failed, "
96270631Sjfv		    "error %u\n", err);
97270631Sjfv		goto fail_1;
98270631Sjfv	}
99272313Sbz	err = bus_dmamap_load(mem->tag, mem->map, mem->va,
100270631Sjfv			    size,
101270631Sjfv			    i40e_dmamap_cb,
102272313Sbz			    &mem->pa,
103270631Sjfv			    BUS_DMA_NOWAIT);
104270631Sjfv	if (err != 0) {
105270631Sjfv		device_printf(dev,
106270631Sjfv		    "i40e_allocate_dma: bus_dmamap_load failed, "
107270631Sjfv		    "error %u\n", err);
108270631Sjfv		goto fail_2;
109270631Sjfv	}
110274360Sjfv	mem->nseg = 1;
111272313Sbz	mem->size = size;
112272313Sbz	bus_dmamap_sync(mem->tag, mem->map,
113270631Sjfv	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
114270631Sjfv	return (0);
115270631Sjfvfail_2:
116272313Sbz	bus_dmamem_free(mem->tag, mem->va, mem->map);
117270631Sjfvfail_1:
118272313Sbz	bus_dma_tag_destroy(mem->tag);
119270631Sjfvfail_0:
120272313Sbz	mem->map = NULL;
121272313Sbz	mem->tag = NULL;
122270631Sjfv	return (err);
123270631Sjfv}
124270631Sjfv
125270631Sjfvi40e_status
126272313Sbzi40e_free_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem)
127270631Sjfv{
128272313Sbz	bus_dmamap_sync(mem->tag, mem->map,
129270631Sjfv	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
130272313Sbz	bus_dmamap_unload(mem->tag, mem->map);
131272313Sbz	bus_dmamem_free(mem->tag, mem->va, mem->map);
132272313Sbz	bus_dma_tag_destroy(mem->tag);
133270631Sjfv	return (0);
134270631Sjfv}
135270631Sjfv
136270631Sjfvvoid
137270631Sjfvi40e_init_spinlock(struct i40e_spinlock *lock)
138270631Sjfv{
139270631Sjfv	mtx_init(&lock->mutex, "mutex",
140270631Sjfv	    MTX_NETWORK_LOCK, MTX_DEF | MTX_DUPOK);
141270631Sjfv}
142270631Sjfv
143270631Sjfvvoid
144270631Sjfvi40e_acquire_spinlock(struct i40e_spinlock *lock)
145270631Sjfv{
146270631Sjfv	mtx_lock(&lock->mutex);
147270631Sjfv}
148270631Sjfv
149270631Sjfvvoid
150270631Sjfvi40e_release_spinlock(struct i40e_spinlock *lock)
151270631Sjfv{
152270631Sjfv	mtx_unlock(&lock->mutex);
153270631Sjfv}
154270631Sjfv
155270631Sjfvvoid
156270631Sjfvi40e_destroy_spinlock(struct i40e_spinlock *lock)
157270631Sjfv{
158270631Sjfv	mtx_destroy(&lock->mutex);
159270631Sjfv}
160270631Sjfv
161270631Sjfv/*
162270631Sjfv** i40e_debug_d - OS dependent version of shared code debug printing
163270631Sjfv*/
164270631Sjfvvoid i40e_debug_d(void *hw, u32 mask, char *fmt, ...)
165270631Sjfv{
166270631Sjfv        char buf[512];
167270631Sjfv        va_list args;
168270631Sjfv
169270631Sjfv        if (!(mask & ((struct i40e_hw *)hw)->debug_mask))
170270631Sjfv                return;
171270631Sjfv
172270631Sjfv	va_start(args, fmt);
173270631Sjfv        vsnprintf(buf, sizeof(buf), fmt, args);
174270631Sjfv	va_end(args);
175270631Sjfv
176270631Sjfv        /* the debug string is already formatted with a newline */
177270631Sjfv        printf("%s", buf);
178270631Sjfv}
179270631Sjfv
180270631Sjfvu16
181270631Sjfvi40e_read_pci_cfg(struct i40e_hw *hw, u32 reg)
182270631Sjfv{
183270631Sjfv        u16 value;
184270631Sjfv
185270631Sjfv        value = pci_read_config(((struct i40e_osdep *)hw->back)->dev,
186270631Sjfv            reg, 2);
187270631Sjfv
188270631Sjfv        return (value);
189270631Sjfv}
190270631Sjfv
191270631Sjfvvoid
192270631Sjfvi40e_write_pci_cfg(struct i40e_hw *hw, u32 reg, u16 value)
193270631Sjfv{
194270631Sjfv        pci_write_config(((struct i40e_osdep *)hw->back)->dev,
195270631Sjfv            reg, value, 2);
196270631Sjfv
197270631Sjfv        return;
198270631Sjfv}
199270631Sjfv
200