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_ */