1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
14 */
15
16 #ifndef _AOE_H_
17 #define _AOE_H_
18
19 #include <sys/param.h>
20 #include <sys/types.h>
21 #include <sys/ethernet.h>
22
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26
27 /*
28 * IOCTL supporting stuff
29 */
30 #define AOE_IOCTL_FLAG_MASK 0xFF
31 #define AOE_IOCTL_FLAG_IDLE 0x00
32 #define AOE_IOCTL_FLAG_OPEN 0x01
33 #define AOE_IOCTL_FLAG_EXCL 0x02
34 #define AOE_IOCTL_FLAG_EXCL_BUSY 0x04
35
36 /*
37 * IOCTL cmd definitions
38 */
39 #define AOEIO_CMD ('G'<< 8 | 2009)
40 #define AOEIO_SUB_CMD ('X' << 8)
41
42 /*
43 * IOCTL sub-command
44 */
45 #define AOEIO_CREATE_PORT (AOEIO_SUB_CMD + 0x01)
46 #define AOEIO_DELETE_PORT (AOEIO_SUB_CMD + 0x02)
47 #define AOEIO_GET_PORT_LIST (AOEIO_SUB_CMD + 0x03)
48
49 /*
50 * aoeio_xfer definitions
51 */
52 #define AOEIO_XFER_NONE 0x00
53 #define AOEIO_XFER_READ 0x01
54 #define AOEIO_XFER_WRITE 0x02
55 #define AOEIO_XFER_RW (AOEIO_XFER_READ | AOEIO_XFER_WRITE)
56
57 /*
58 * aoeio_errno definitions
59 */
60 typedef enum {
61 AOEIOE_INVAL_ARG = 5,
62 AOEIOE_BUSY,
63 AOEIOE_ALREADY,
64 AOEIOE_CREATE_MAC,
65 AOEIOE_OPEN_MAC,
66 AOEIOE_CREATE_PORT,
67 AOEIOE_MAC_NOT_FOUND,
68 AOEIOE_OFFLINE_FAILURE,
69 AOEIOE_MORE_DATA
70 } aoeio_stat_t;
71
72 /* Biggest buffer length, can hold up to 1024 port instances */
73 #define AOEIO_MAX_BUF_LEN 0x10000
74 #define AOE_MAX_MACOBJ 16 /* MAX # of ethernet interfaces per port */
75 #define AOE_MAX_UNIT 256 /* MAX # of LU per target/port */
76
77 typedef struct aoeio {
78 uint16_t aoeio_xfer; /* direction */
79 uint16_t aoeio_cmd; /* sub command */
80 uint16_t aoeio_flags; /* flags */
81 uint16_t aoeio_cmd_flags; /* command specific flags */
82 uint32_t aoeio_ilen; /* Input buffer length */
83 uint32_t aoeio_olen; /* Output buffer length */
84 uint32_t aoeio_alen; /* Auxillary buffer length */
85 aoeio_stat_t aoeio_status; /* AoE internal error status */
86 uint64_t aoeio_ibuf; /* Input buffer */
87 uint64_t aoeio_obuf; /* Output buffer */
88 uint64_t aoeio_abuf; /* Auxillary buffer */
89 } aoeio_t;
90
91 /*
92 * Client port type
93 */
94 typedef enum {
95 AOE_CLIENT_INITIATOR = 0,
96 AOE_CLIENT_TARGET
97 } aoe_cli_type_t;
98
99 /*
100 * Client port policy
101 */
102 typedef enum {
103 AOE_POLICY_NONE = 0,
104 AOE_POLICY_FAILOVER,
105 AOE_POLICY_ROUNDROBIN,
106 AOE_POLICY_LOADBALANCE
107 } aoe_cli_policy_t;
108
109 #define AOE_ACP_MODLEN MAXNAMELEN
110
111 /*
112 * AOE port commands
113 */
114 typedef struct aoeio_create_port_param {
115 uint32_t acp_port_id;
116 uint32_t acp_force_promisc;
117 aoe_cli_type_t acp_port_type;
118 aoe_cli_policy_t acp_port_policy;
119 datalink_id_t acp_mac_linkid[AOE_MAX_MACOBJ];
120 uint32_t acp_rsvd0;
121 char acp_module[AOE_ACP_MODLEN];
122 } aoeio_create_port_param_t;
123
124 typedef struct aoeio_delete_port_param {
125 uint32_t adp_port_id;
126 uint32_t adp_rsvd0;
127 } aoeio_delete_port_param_t;
128
129 /*
130 * AOE MAC instance
131 */
132 typedef struct aoe_mac_instance {
133 datalink_id_t ami_mac_linkid;
134 uint32_t ami_rsvd0;
135 ether_addr_t ami_mac_factory_addr;
136 uint16_t ami_mac_promisc;
137 ether_addr_t ami_mac_current_addr;
138 uint16_t ami_rsvd1;
139 uint32_t ami_mtu_size;
140 uint32_t ami_mac_link_state;
141 uint64_t ami_mac_rx_frames;
142 uint64_t ami_mac_tx_frames;
143 } aoe_mac_instance_t;
144
145 /*
146 * AOE port instance
147 */
148 typedef struct aoe_port_instance {
149 uint32_t api_port_id;
150 uint32_t api_mac_cnt;
151 uint32_t api_port_state;
152 uint32_t api_maxxfer;
153 aoe_cli_type_t api_port_type;
154 aoe_cli_policy_t api_port_policy;
155 aoe_mac_instance_t api_mac[AOE_MAX_MACOBJ];
156 } aoe_port_instance_t;
157
158 /*
159 * AOE port instance list
160 */
161 typedef struct aoe_port_list {
162 uint64_t num_ports;
163 aoe_port_instance_t ports[1];
164 } aoe_port_list_t;
165
166 #define AOE_PORT_STATE_OFFLINE 0x00
167 #define AOE_PORT_STATE_ONLINE 0x01
168
169 #define AOE_MAC_LINK_STATE_DOWN 0x00
170 #define AOE_MAC_LINK_STATE_UP 0x01
171
172 #ifdef _KERNEL
173
174 #define AOET_DRIVER_NAME "aoet"
175 #define AOEI_DRIVER_NAME "aoeblk"
176
177 #define AOECMD_ATA 0 /* Issue ATA Command */
178 #define AOECMD_CFG 1 /* Query Config Information */
179 #define AOECMD_MML 2 /* Mac Mask List */
180 #define AOECMD_RSV 3 /* Reserve / Release */
181
182 #define AOEFL_RSP (1<<3)
183 #define AOEFL_ERR (1<<2)
184
185 #define AOEAFL_EXT (1<<6)
186 #define AOEAFL_DEV (1<<4)
187 #define AOEAFL_ASYNC (1<<1)
188 #define AOEAFL_WRITE (1<<0)
189
190 #define AOE_HVER 0x10
191
192 #define ETHERTYPE_AOE 0x88A2 /* ATA over Ethernet */
193
194 #define MINPERMAJ 10
195 #define AOEMAJOR(unit) ((unit) / MINPERMAJ)
196 #define AOEMINOR(unit) ((unit) % MINPERMAJ)
197 #define AOEUNIT(maj, min) ((maj) * MINPERMAJ + (min))
198
199 typedef struct aoe_hdr {
200 ether_addr_t aoeh_dst;
201 ether_addr_t aoeh_src;
202 uint16_t aoeh_type;
203 uint8_t aoeh_verfl;
204 uint8_t aoeh_err;
205 uint16_t aoeh_major;
206 uint8_t aoeh_minor;
207 uint8_t aoeh_cmd;
208 uint32_t aoeh_tag;
209 } aoe_hdr_t;
210
211 typedef struct aoe_atahdr {
212 uint8_t aa_aflags;
213 uint8_t aa_errfeat;
214 uint8_t aa_scnt;
215 uint8_t aa_cmdstat;
216 uint8_t aa_lba0;
217 uint8_t aa_lba1;
218 uint8_t aa_lba2;
219 uint8_t aa_lba3;
220 uint8_t aa_lba4;
221 uint8_t aa_lba5;
222 uint8_t aa_res[2];
223 } aoe_atahdr_t;
224
225 /* ATA commands */
226 #define ATA_READ 0x20 /* read */
227 #define ATA_READ48 0x24 /* read 48bit LBA */
228 #define ATA_WRITE 0x30 /* write */
229 #define ATA_WRITE48 0x34 /* write 48bit LBA */
230 #define ATA_FLUSHCACHE 0xe7 /* flush cache to disk */
231 #define ATA_FLUSHCACHE48 0xea /* flush cache to disk */
232 #define ATA_SETFEATURES 0xef /* features command */
233 #define ATA_SF_ENAB_WCACHE 0x02 /* enable write cache */
234 #define ATA_SF_DIS_WCACHE 0x82 /* disable write cache */
235 #define ATA_ATA_IDENTIFY 0xec /* get ATA params */
236 #define ATA_CHECK_POWER_MODE 0xe5 /* Check power mode */
237
238 typedef struct aoe_cfghdr {
239 uint16_t ac_bufcnt; /* Buffer Count */
240 uint16_t ac_fwver; /* Firmware Version */
241 uint8_t ac_scnt; /* Sector Count */
242 uint8_t ac_aoeccmd; /* AoE Ver + CCmd */
243 uint8_t ac_cslen[2]; /* Config String Length */
244 } aoe_cfghdr_t;
245
246 #define AOEHDRSZ (sizeof (aoe_hdr_t) + sizeof (aoe_atahdr_t))
247 #define FREETAG -1 /* tag magic; denotes free frame */
248 #define INPROCTAG -2 /* tag magic; denotes frame in processing */
249
250 /* Definitions of CCmd of Query Config Information */
251 #define AOE_CFGCMD_READ 0
252 #define AOE_CFGCMD_TEST_EXACT 1
253 #define AOE_CFGCMD_TEST_PREFIX 2
254 #define AOE_CFGCMD_SET 3
255 #define AOE_CFGCMD_FORCE_SET 4
256
257 typedef struct aoe_rsvhdr {
258 uint8_t al_rcmd;
259 uint8_t al_nmacs;
260 ether_addr_t al_addr[];
261 } aoe_rsvhdr_t;
262
263 #define AOE_RCMD_READ_LIST 0
264 #define AOE_RCMD_SET_LIST 1
265 #define AOE_RCMD_FORCE_SET_LIST 2
266
267 /*
268 * aoe_frame_t - structure which encapsulates one or more mblk_t. To add
269 * mblk HBA driver could use eport_alloc_netb() or manually
270 * via f->frm_netb field
271 */
272 struct aoe_eport;
273 typedef struct aoe_frame {
274 void *af_netb; /* Pointer to the mblk_t */
275 struct aoe_eport *af_eport; /* Port object */
276 void *af_mac; /* Library's private MAC object */
277 uint8_t *af_data; /* Typically netb->b_rptr */
278 ether_addr_t af_addr; /* Destination address */
279 uint16_t af_rsvd0;
280 } aoe_frame_t;
281
282 #define FRM2MBLK(x_frm) ((mblk_t *)(x_frm)->af_netb)
283 #define FRM2PRIV(x_frm) ((void *)(((aoe_frame_t *)(x_frm))+1))
284 #define PRIV2FRM(x_frm) ((void *)(((aoe_frame_t *)(x_frm))-1))
285
286 /*
287 * aoe_eport_t - main interface for HBA driver
288 *
289 * eport_maxxfer: calculated based on MTU sizes as a minimal size in group
290 * eport_mac: array of MAC objects of all MAC interfaces in the group
291 * eport_mac_cnt: number of active MAC interfaces in the group
292 *
293 * eport_tx_fram(): Tansmit frame to the wire
294 * eport_alloc_frame(): Allocate new frame out of Library kmem cache.
295 * Typically mac and netb can be set to NULL
296 * eport_release_frame(): release used frame (both solicited and unsolicited)
297 * eport_alloc_netb(): Allocate extra buffer and link with frame
298 * eport_free_netb(): Free f->frm_netb
299 * eport_deregister_client() Unregister HBA driver
300 * eport_ctl(): Used to send notifications on port ONLINE/OFFLINE
301 * eport_report_unit(): Used to report new unit
302 * eport_get_mac_addr(): Used to get MAC object etherent address
303 * eport_get_mac_link_state(): Used to get MAC object link state
304 * eport_allow_port_detach():Returns nonzero if detaching port is not allowed
305 */
306 typedef struct aoe_eport {
307 void *eport_aoe_private; /* Library internal */
308 void *eport_client_private; /* HBA internal */
309 uint32_t eport_maxxfer; /* Calculate max xfer size */
310 void **eport_mac; /* Array of MAC objects */
311 uint32_t eport_mac_cnt; /* Number of MAC objects */
312 uint32_t cache_unit_size;
313
314 void (*eport_tx_frame)(aoe_frame_t *frame);
315 aoe_frame_t *(*eport_alloc_frame)(struct aoe_eport *eport,
316 int unit_id, void *mac, int kmflag);
317 void (*eport_release_frame)(aoe_frame_t *frame);
318 void *(*eport_alloc_netb)(aoe_frame_t *frame,
319 uint32_t buf_size, caddr_t buf, int kmflag);
320 void (*eport_free_netb)(void *netb);
321 void (*eport_deregister_client)(struct aoe_eport *eport);
322 int (*eport_ctl)(struct aoe_eport *eport, void *mac,
323 int cmd, void *arg);
324 int (*eport_report_unit)(struct aoe_eport *eport, void *mac,
325 unsigned long unit, char *);
326 uint8_t *(*eport_get_mac_addr)(void *mac);
327 int (*eport_get_mac_link_state)(void *mac);
328 uint32_t (*eport_allow_port_detach)(struct aoe_eport *eport);
329 } aoe_eport_t;
330
331 /*
332 * aoe_client_t - passed to Library via aoe_register_client()
333 *
334 * ect_eport_flags: EPORT_FLAG_TGT_MODE | EPORT_FLAG_INI_MODE
335 * ect_private_frame_struct_size: private HBA driver per-frame
336 * ect_channelid: set to port_id via NDI property to distinguish HBA ports
337 * ect_client_port_struct: pointer to HBA private
338 *
339 * ect_rx_frame(): Callback on MAC receive event. Frame will be allocated
340 * and ready to be released by HBA. HBA needs to call
341 * eport_release_frame(). To get ETHERNET source HBA
342 * needs to copy it from frm_hdr like this
343 * bcopy(h->ah_src, d->ad_addr, sizeof (ether_addr_t)
344 * where h is a pointer to frm_hdr casted to aoe_hdr
345 *
346 * ect_port_event(): Callback for Library events such as
347 * AOE_NOTIFY_EPORT_LINK_UP | AOE_NOTIFY_EPORT_LINK_DOWN
348 */
349 typedef struct aoe_client {
350 uint32_t ect_eport_flags;
351 uint32_t ect_private_frame_struct_size;
352 uint32_t ect_channelid;
353 void *ect_client_port_struct;
354 void (*ect_rx_frame)(aoe_frame_t *frame);
355 void (*ect_port_event)(aoe_eport_t *eport, uint32_t event);
356 } aoe_client_t;
357
358 #define EPORT_FLAG_TGT_MODE 0x01
359 #define EPORT_FLAG_INI_MODE 0x02
360 #define EPORT_FLAG_MAC_IN_USE 0x04
361
362 #define AOE_NOTIFY_EPORT_LINK_UP 0x01
363 #define AOE_NOTIFY_EPORT_LINK_DOWN 0x02
364 #define AOE_NOTIFY_EPORT_ADDR_CHG 0x03
365
366 #define AOE_PORT_CTL_CMDS 0x3000
367 #define AOE_CMD_PORT_ONLINE (AOE_PORT_CTL_CMDS | 0x01)
368 #define AOE_CMD_PORT_OFFLINE (AOE_PORT_CTL_CMDS | 0x02)
369 #define AOE_CMD_PORT_UNIT_ONLINE (AOE_PORT_CTL_CMDS | 0x04)
370 #define AOE_CMD_PORT_UNIT_OFFLINE (AOE_PORT_CTL_CMDS | 0x08)
371 #define AOE_CMD_PORT_UNIT_RETRANSMIT (AOE_PORT_CTL_CMDS | 0x10)
372
373 /*
374 * AOE Target/Initiator will only call this aoe function explicitly, all others
375 * should be called through vectors in struct aoe_eport.
376 * AOE client call this to register one port to AOE, AOE need initialize
377 * and return the corresponding aoe_port.
378 */
379 extern aoe_eport_t *aoe_register_client(aoe_client_t *client);
380
381 #endif /* _KERNEL */
382
383 #ifdef __cplusplus
384 }
385 #endif
386
387 #endif /* _AOE_H_ */