1/*
2 *   BSD LICENSE
3 *
4 *   Copyright(c) 2017 Cavium, Inc.. All rights reserved.
5 *   All rights reserved.
6 *
7 *   Redistribution and use in source and binary forms, with or without
8 *   modification, are permitted provided that the following conditions
9 *   are met:
10 *
11 *     * Redistributions of source code must retain the above copyright
12 *       notice, this list of conditions and the following disclaimer.
13 *     * Redistributions in binary form must reproduce the above copyright
14 *       notice, this list of conditions and the following disclaimer in
15 *       the documentation and/or other materials provided with the
16 *       distribution.
17 *     * Neither the name of Cavium, Inc. nor the names of its
18 *       contributors may be used to endorse or promote products derived
19 *       from this software without specific prior written permission.
20 *
21 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 *   OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33/*$FreeBSD$*/
34
35/* \file  lio_network.h
36 * \brief Host NIC Driver: Structure and Macro definitions used by NIC Module.
37 */
38
39#ifndef __LIO_NETWORK_H__
40#define __LIO_NETWORK_H__
41
42#include "lio_rss.h"
43
44#define LIO_MIN_MTU_SIZE	72
45#define LIO_MAX_MTU_SIZE	(LIO_MAX_FRM_SIZE - LIO_FRM_HEADER_SIZE)
46
47#define LIO_MAX_SG		64
48#define LIO_MAX_FRAME_SIZE	60000
49
50struct lio_fw_stats_resp {
51	uint64_t	rh;
52	struct octeon_link_stats stats;
53	uint64_t	status;
54};
55
56/* LiquidIO per-interface network private data */
57struct lio {
58	/* State of the interface. Rx/Tx happens only in the RUNNING state.  */
59	int	ifstate;
60
61	/*
62	 * Octeon Interface index number. This device will be represented as
63	 * oct<ifidx> in the system.
64	 */
65	int	ifidx;
66
67	/* Octeon Input queue to use to transmit for this network interface. */
68	int	txq;
69
70	/*
71	 * Octeon Output queue from which pkts arrive
72	 * for this network interface.
73	 */
74	int	rxq;
75
76	/* Guards each glist */
77	struct mtx	*glist_lock;
78
79#define LIO_DEFAULT_STATS_INTERVAL 10000
80	/* callout timer for stats */
81	struct callout	stats_timer;
82
83	/* Stats Update Interval in milli Seconds */
84	uint16_t	stats_interval;
85
86	/* IRQ coalescing driver stats */
87	struct octeon_intrmod_cfg intrmod_cfg;
88
89	/* Array of gather component linked lists */
90	struct lio_stailq_head	*ghead;
91	void	**glists_virt_base;
92	vm_paddr_t	*glists_dma_base;
93	uint32_t	glist_entry_size;
94
95	/* Pointer to the octeon device structure. */
96	struct octeon_device	*oct_dev;
97
98	struct ifnet	*ifp;
99	struct ifmedia	ifmedia;
100	int		if_flags;
101
102	/* Link information sent by the core application for this interface. */
103	struct octeon_link_info	linfo;
104
105	/* counter of link changes */
106	uint64_t	link_changes;
107
108	/* Size of Tx queue for this octeon device. */
109	uint32_t	tx_qsize;
110
111	/* Size of Rx queue for this octeon device. */
112	uint32_t	rx_qsize;
113
114	/* Size of MTU this octeon device. */
115	uint32_t	mtu;
116
117	/* msg level flag per interface. */
118	uint32_t	msg_enable;
119
120	/* Interface info */
121	uint32_t	intf_open;
122
123	/* task queue for  rx oom status */
124	struct lio_tq	rx_status_tq;
125
126	/* VLAN Filtering related */
127	eventhandler_tag	vlan_attach;
128	eventhandler_tag	vlan_detach;
129#ifdef RSS
130	struct lio_rss_params_set rss_set;
131#endif	/* RSS */
132};
133
134#define LIO_MAX_CORES	12
135
136/*
137 * \brief Enable or disable feature
138 * @param ifp       pointer to network device
139 * @param cmd       Command that just requires acknowledgment
140 * @param param1    Parameter to command
141 */
142int	lio_set_feature(struct ifnet *ifp, int cmd, uint16_t param1);
143
144/*
145 * \brief Link control command completion callback
146 * @param nctrl_ptr pointer to control packet structure
147 *
148 * This routine is called by the callback function when a ctrl pkt sent to
149 * core app completes. The nctrl_ptr contains a copy of the command type
150 * and data sent to the core app. This routine is only called if the ctrl
151 * pkt was sent successfully to the core app.
152 */
153void	lio_ctrl_cmd_completion(void *nctrl_ptr);
154
155int	lio_setup_io_queues(struct octeon_device *octeon_dev, int ifidx,
156			    uint32_t num_iqs, uint32_t num_oqs);
157
158int	lio_setup_interrupt(struct octeon_device *oct, uint32_t num_ioqs);
159
160static inline void *
161lio_recv_buffer_alloc(uint32_t size)
162{
163	struct mbuf	*mb = NULL;
164
165	mb = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size);
166	if (mb != NULL)
167		mb->m_pkthdr.len = mb->m_len = size;
168
169	return ((void *)mb);
170}
171
172static inline void
173lio_recv_buffer_free(void *buffer)
174{
175
176	m_freem((struct mbuf *)buffer);
177}
178
179static inline int
180lio_get_order(unsigned long size)
181{
182	int	order;
183
184	size = (size - 1) >> PAGE_SHIFT;
185	order = 0;
186	while (size) {
187		order++;
188		size >>= 1;
189	}
190
191	return (order);
192}
193
194static inline void *
195lio_dma_alloc(size_t size, vm_paddr_t *dma_handle)
196{
197	size_t	align;
198	void	*mem;
199
200	align = PAGE_SIZE << lio_get_order(size);
201	mem = (void *)kmem_alloc_contig(size, M_WAITOK, 0, ~0ul, align, 0,
202	    VM_MEMATTR_DEFAULT);
203	if (mem != NULL)
204		*dma_handle = vtophys(mem);
205	else
206		*dma_handle = 0;
207
208	return (mem);
209}
210
211static inline void
212lio_dma_free(size_t size, void *cpu_addr)
213{
214
215	kmem_free((vm_offset_t)cpu_addr, size);
216}
217
218static inline uint64_t
219lio_map_ring(device_t dev, void *buf, uint32_t size)
220{
221	vm_paddr_t	dma_addr;
222
223	dma_addr = vtophys(((struct mbuf *)buf)->m_data);
224	return ((uint64_t)dma_addr);
225}
226
227/*
228 * \brief check interface state
229 * @param lio per-network private data
230 * @param state_flag flag state to check
231 */
232static inline int
233lio_ifstate_check(struct lio *lio, int state_flag)
234{
235
236	return (atomic_load_acq_int(&lio->ifstate) & state_flag);
237}
238
239/*
240 * \brief set interface state
241 * @param lio per-network private data
242 * @param state_flag flag state to set
243 */
244static inline void
245lio_ifstate_set(struct lio *lio, int state_flag)
246{
247
248	atomic_store_rel_int(&lio->ifstate,
249			     (atomic_load_acq_int(&lio->ifstate) | state_flag));
250}
251
252/*
253 * \brief clear interface state
254 * @param lio per-network private data
255 * @param state_flag flag state to clear
256 */
257static inline void
258lio_ifstate_reset(struct lio *lio, int state_flag)
259{
260
261	atomic_store_rel_int(&lio->ifstate,
262			     (atomic_load_acq_int(&lio->ifstate) &
263			      ~(state_flag)));
264}
265
266/*
267 * \brief wait for all pending requests to complete
268 * @param oct Pointer to Octeon device
269 *
270 * Called during shutdown sequence
271 */
272static inline int
273lio_wait_for_pending_requests(struct octeon_device *oct)
274{
275	int	i, pcount = 0;
276
277	for (i = 0; i < 100; i++) {
278		pcount = atomic_load_acq_int(
279				     &oct->response_list[LIO_ORDERED_SC_LIST].
280					     pending_req_count);
281		if (pcount)
282			lio_sleep_timeout(100);
283		else
284			break;
285	}
286
287	if (pcount)
288		return (1);
289
290	return (0);
291}
292
293#endif	/* __LIO_NETWORK_H__ */
294