1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Emulex.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Driver specific data structures and function prototypes
29  */
30 
31 #ifndef	_OCE_IMPL_H_
32 #define	_OCE_IMPL_H_
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #include <sys/types.h>
39 #include <sys/dditypes.h>
40 #include <sys/kstat.h>
41 #include <sys/ddi_intr.h>
42 #include <sys/cmn_err.h>
43 #include <sys/byteorder.h>
44 #include <sys/mac_provider.h>
45 #include <sys/mac_ether.h>
46 #include <sys/vlan.h>
47 #include <sys/bitmap.h>
48 #include <sys/ddidmareq.h>
49 #include <sys/kmem.h>
50 #include <sys/ddi.h>
51 #include <sys/sunddi.h>
52 #include <sys/modctl.h>
53 #include <sys/devops.h>
54 #include <sys/systm.h>
55 #include <sys/conf.h>
56 #include <sys/dlpi.h>
57 #include <sys/ethernet.h>
58 #include <sys/strsun.h>
59 #include <sys/pattr.h>
60 #include <sys/strsubr.h>
61 #include <sys/ddifm.h>
62 #include <sys/fm/protocol.h>
63 #include <sys/fm/util.h>
64 #include <sys/fm/io/ddi.h>
65 #include <sys/note.h>
66 #include <oce_hw.h>
67 #include <oce_hw_eth.h>
68 #include <oce_io.h>
69 #include <oce_buf.h>
70 #include <oce_utils.h>
71 #include <oce_version.h>
72 
73 #define	OCE_MIN_MTU	1500
74 #define	OCE_MAX_MTU	9000
75 #define	OCE_MAX_MCA	32
76 #define	OCE_RQ_MAX_FRAME_SZ 9018
77 
78 #define	OCE_MAX_EQ	8
79 #define	OCE_MAX_CQ	1024
80 #define	OCE_MAX_WQ	8
81 #define	OCE_WQ_NUM_BUFFERS	2048
82 #define	OCE_WQ_BUF_SIZE	2048
83 #define	OCE_LSO_MAX_SIZE (32 * 1024)
84 #define	OCE_DEFAULT_BCOPY_LIMIT	1024
85 #define	OCE_DEFAULT_WQ_EQD	16
86 
87 #define	OCE_MAX_RQ		8
88 #define	OCE_MAX_RQ_POSTS	255
89 #define	OCE_RQ_NUM_BUFFERS	2048
90 #define	OCE_RQ_BUF_SIZE		2048
91 #define	OCE_DEFAULT_RECHARGE_THRESHOLD	OCE_MAX_RQ_POSTS
92 #define	OCE_NUM_USED_VECTORS    2
93 #define	OCE_DMA_ALIGNMENT   0x1000ull
94 
95 #define	OCE_DEFAULT_TX_RING_SIZE    256
96 #define	OCE_DEFAULT_RX_RING_SIZE    1024
97 
98 #define	OCE_INVAL_IF_ID			-1
99 
100 #define	OCE_DEFAULT_IF_CAP	(MBX_RX_IFACE_FLAGS_PROMISCUOUS	| \
101 			MBX_RX_IFACE_FLAGS_BROADCAST		| \
102 			MBX_RX_IFACE_FLAGS_UNTAGGED		| \
103 			MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS	| \
104 			MBX_RX_IFACE_FLAGS_PASS_L3L4)
105 
106 #define	OCE_DEFAULT_IF_CAP_EN	(MBX_RX_IFACE_FLAGS_BROADCAST	| \
107 				MBX_RX_IFACE_FLAGS_UNTAGGED	| \
108 				MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS	| \
109 				MBX_RX_IFACE_FLAGS_PASS_L3L4)
110 
111 #define	OCE_RX_FILTER_GLOBAL_FLAGS	(NTWK_RX_FILTER_IP_CKSUM | \
112 					NTWK_RX_FILTER_TCP_CKSUM | \
113 					NTWK_RX_FILTER_UDP_CKSUM | \
114 					NTWK_RX_FILTER_STRIP_CRC)
115 
116 
117 #define	OCE_FM_CAPABILITY		DDI_FM_EREPORT_CAPABLE	|	\
118 					DDI_FM_ACCCHK_CAPABLE	|	\
119 					DDI_FM_DMACHK_CAPABLE
120 
121 /* flow control definitions */
122 #define	OCE_FC_NONE	0x00000000
123 #define	OCE_FC_TX	0x00000001
124 #define	OCE_FC_RX	0x00000002
125 #define	OCE_DEFAULT_FLOW_CONTROL	(OCE_FC_TX | OCE_FC_RX)
126 
127 /* PCI Information */
128 #define	OCE_DEV_CFG_BAR	0x01
129 #define	OCE_PCI_CSR_BAR	0x02
130 #define	OCE_PCI_DB_BAR	0x03
131 
132 /* macros for device IO */
133 #define	OCE_READ_REG32(handle, addr) ddi_get32(handle, addr)
134 #define	OCE_WRITE_REG32(handle, addr, value) ddi_put32(handle, addr, value)
135 
136 #define	OCE_CSR_READ32(dev, offset) \
137 	OCE_READ_REG32((dev)->csr_handle, \
138 	    (uint32_t *)(void *)((dev)->csr_addr + offset))
139 
140 #define	OCE_CSR_WRITE32(dev, offset, value) \
141 	OCE_WRITE_REG32((dev)->csr_handle, \
142 	    (uint32_t *)(void *)((dev)->csr_addr + offset), value)
143 
144 #define	OCE_DB_READ32(dev, offset) \
145 	OCE_READ_REG32((dev)->db_handle, \
146 	    (uint32_t *)(void *)((dev)->db_addr + offset))
147 
148 #define	OCE_DB_WRITE32(dev, offset, value) \
149 	OCE_WRITE_REG32((dev)->db_handle, \
150 		(uint32_t *)(void *)((dev)->db_addr + offset), value)
151 
152 #define	OCE_CFG_READ32(dev, offset) \
153 	OCE_READ_REG32((dev)->dev_cfg_handle, \
154 	    (uint32_t *)(void *)((dev)->dev_cfg_addr + offset))
155 
156 #define	OCE_CFG_WRITE32(dev, offset, value) \
157 	OCE_WRITE_REG32((dev)->dev_cfg_handle, \
158 	    (uint32_t *)(void *)((dev)->dev_cfg_addr + offset), value)
159 
160 #define	OCE_PCI_FUNC(dev) \
161 	((OCE_CFG_READ32(dev, PCICFG_INTR_CTRL) \
162 	    >> HOSTINTR_PFUNC_SHIFT) & HOSTINTR_PFUNC_MASK)
163 
164 #define	DEV_LOCK(dev)	{ oce_chip_di(dev); mutex_enter(&dev->dev_lock); }
165 
166 #define	DEV_UNLOCK(dev)	{ mutex_exit(&dev->dev_lock); oce_chip_ei(dev); }
167 
168 enum oce_ring_size {
169 	RING_SIZE_256  = 256,
170 	RING_SIZE_512  = 512,
171 	RING_SIZE_1024 = 1024,
172 	RING_SIZE_2048 = 2048
173 };
174 
175 enum oce_driver_state {
176 	STATE_INIT		= 0x2,
177 	STATE_MAC_STARTED	= 0x4,
178 	STATE_QUIESCE		= 0x8,
179 	STATE_MAC_STOPPING	= 0x10
180 };
181 
182 struct oce_dev {
183 	uint32_t dev_id;		/* device ID or instance number */
184 	int32_t if_id; 			/* IF ID */
185 	uint8_t fn; 			/* function number */
186 	uint8_t fw_version[32]; 	/* fw version string */
187 	enum oce_driver_state state; 	/* state */
188 	struct oce_mq *mq;		/* MQ ring */
189 	oce_dma_buf_t *bmbx;		/* Bootstrap MailBox	*/
190 	kmutex_t bmbx_lock;		/* Bootstrap Lock	*/
191 	uint16_t mod_mask;		/* Log Mask 	*/
192 	int16_t severity;		/* Log level	*/
193 	struct oce_wq *wq[OCE_MAX_WQ];	/* TXQ Array */
194 	struct oce_rq *rq[OCE_MAX_RQ];	/* RXQ Array */
195 	struct oce_cq *cq[OCE_MAX_CQ];	/* Completion Queues */
196 	struct oce_eq *eq[OCE_MAX_EQ];	/* Event Queues	*/
197 	uint32_t bcopy_limit;		/* BCOPY Limit */
198 
199 	uint32_t cookie;
200 
201 	clock_t stat_ticks;
202 	uint32_t in_stats;
203 
204 	/* Add implementation specific stuff here */
205 	int num_bars;
206 	ddi_acc_handle_t cfg_handle;	/* PCI Config Space Regs */
207 	caddr_t csr_addr;
208 	ddi_acc_handle_t csr_handle;	/* MMIO Control Status Regs */
209 	caddr_t db_addr;
210 	ddi_acc_handle_t db_handle;	/* MMIO DoorBell Area */
211 	caddr_t dev_cfg_addr;
212 	ddi_acc_handle_t dev_cfg_handle;	/* MMIO CONFIG SPACE */
213 	mac_handle_t mac_handle;	/* MAC HANDLE	*/
214 
215 	/* device info structure for device tree node */
216 	dev_info_t *dip;
217 	kstat_t *oce_kstats;		/* NIC STATS */
218 	oce_dma_buf_t *stats_dbuf;	/* STATS BUFFER */
219 	struct mbx_get_nic_stats *hw_stats;
220 	/* dev stats */
221 	uint32_t tx_errors;
222 	uint32_t tx_noxmtbuf;
223 
224 	/* link status */
225 	struct link_status link;
226 
227 	/* flow control settings */
228 	uint32_t flow_control;
229 
230 	/* the type of interrupts supported */
231 	int intr_types;
232 	/* number of vectors used */
233 	int num_vectors;
234 	/* interrupt priority */
235 	uint_t intr_pri;
236 	int intr_cap;
237 	/* intr handler table */
238 	ddi_intr_handle_t *htable;
239 
240 	/* lock for device */
241 	kmutex_t dev_lock;
242 
243 	/* hardware mac address */
244 	uint8_t mac_addr[ETHERADDRL];
245 
246 	/* Current Multicast address table that we have set to h/w */
247 	uint16_t num_mca;
248 	struct ether_addr multi_cast[OCE_MAX_MCA];
249 
250 	/* device configuration */
251 	uint32_t pmac_id; /* used to add or remove mac */
252 	uint8_t unicast_addr[ETHERADDRL];
253 	uint32_t mtu;
254 	enum oce_ring_size tx_ring_size;
255 	enum oce_ring_size rx_ring_size;
256 	boolean_t lso_capable;
257 	boolean_t promisc;
258 	uint32_t if_cap_flags;
259 	int32_t  fm_caps;
260 	uint32_t  attach_state;
261 	boolean_t suspended;
262 	uint32_t  neqs;	/* No of event queues */
263 	uint32_t  nwqs;	/* No of Work Queues */
264 	uint32_t  nrqs;	/* No of Receive Queues */
265 
266 	/* fw config: only relevant fields */
267 	uint32_t    config_number;
268 	uint32_t    asic_revision;
269 	uint32_t    port_id;
270 	uint32_t    function_mode;
271 };
272 
273 /* GLD handler functions */
274 int oce_m_start(void *arg);
275 void oce_m_stop(void *arg);
276 mblk_t *oce_m_send(void *arg, mblk_t *pkt);
277 int oce_m_promiscuous(void *arg, boolean_t enable);
278 int oce_m_multicast(void *arg, boolean_t add, const uint8_t *mca);
279 int oce_m_unicast(void *arg, const uint8_t *uca);
280 boolean_t oce_m_getcap(void *arg, mac_capab_t cap, void *data);
281 void oce_m_ioctl(void *arg, queue_t *wq, mblk_t *mp);
282 int oce_m_setprop(void *arg, const char *name, mac_prop_id_t id,
283     uint_t size, const void *val);
284 int oce_m_getprop(void *arg, const char *name, mac_prop_id_t id,
285     uint_t flags, uint_t size, void *val, uint_t *perm);
286 int oce_m_stat(void *arg, uint_t stat, uint64_t *val);
287 
288 /* Hardware start/stop functions */
289 int oce_start(struct oce_dev *dev);
290 void oce_stop(struct oce_dev *dev);
291 
292 /* FMA support Functions */
293 void oce_fm_init(struct oce_dev *dev);
294 void oce_fm_fini(struct oce_dev *dev);
295 void oce_set_dma_fma_flags(int fm_caps);
296 void oce_set_reg_fma_flags(int fm_caps);
297 void oce_set_tx_map_dma_fma_flags(int fm_caps);
298 void oce_fm_ereport(struct oce_dev *dev, char *detail);
299 int  oce_fm_check_acc_handle(struct oce_dev *dev,
300     ddi_acc_handle_t acc_handle);
301 int  oce_fm_check_dma_handle(struct oce_dev *dev,
302     ddi_dma_handle_t dma_handle);
303 
304 /* Interrupt handling */
305 int oce_setup_intr(struct oce_dev *dev);
306 int oce_teardown_intr(struct oce_dev *dev);
307 int oce_setup_handlers(struct oce_dev *dev);
308 void oce_remove_handler(struct oce_dev *dev);
309 void oce_ei(struct oce_dev *dev);
310 void oce_di(struct oce_dev *dev);
311 void oce_chip_ei(struct oce_dev *dev);
312 void oce_chip_di(struct oce_dev *dev);
313 
314 #ifdef __cplusplus
315 }
316 #endif
317 
318 #endif /* _OCE_IMPL_H_ */
319