[SCSI] Merge tag 'fcoe-02-19-13' into for-linus
authorJames Bottomley <JBottomley@Parallels.com>
Fri, 1 Mar 2013 09:09:51 +0000 (09:09 +0000)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 1 Mar 2013 09:10:08 +0000 (09:10 +0000)
FCoE Updates for 3.9

Signed-off-by: James Bottomley <JBottomley@Parallels.com>
23 files changed:
Documentation/ABI/testing/sysfs-bus-fcoe
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/fcoe/fcoe.c
drivers/scsi/fcoe/fcoe.h
drivers/scsi/fcoe/fcoe_ctlr.c
drivers/scsi/fcoe/fcoe_sysfs.c
drivers/scsi/fcoe/fcoe_transport.c
drivers/scsi/fcoe/libfcoe.h
drivers/scsi/libfc/fc_fcp.c
drivers/scsi/libfc/fc_libfc.h
drivers/scsi/libfc/fc_rport.c
include/scsi/fc/Kbuild
include/scsi/fc/fc_els.h [deleted file]
include/scsi/fc/fc_fs.h [deleted file]
include/scsi/fc/fc_gs.h [deleted file]
include/scsi/fc/fc_ns.h [deleted file]
include/scsi/fcoe_sysfs.h
include/scsi/libfcoe.h
include/uapi/scsi/fc/Kbuild
include/uapi/scsi/fc/fc_els.h [new file with mode: 0644]
include/uapi/scsi/fc/fc_fs.h [new file with mode: 0644]
include/uapi/scsi/fc/fc_gs.h [new file with mode: 0644]
include/uapi/scsi/fc/fc_ns.h [new file with mode: 0644]

index 50e2a80..21640ea 100644 (file)
@@ -1,14 +1,53 @@
-What:          /sys/bus/fcoe/ctlr_X
+What:          /sys/bus/fcoe/
+Date:          August 2012
+KernelVersion: TBD
+Contact:       Robert Love <robert.w.love@intel.com>, devel@open-fcoe.org
+Description:   The FCoE bus. Attributes in this directory are control interfaces.
+Attributes:
+
+       ctlr_create: 'FCoE Controller' instance creation interface. Writing an
+                    <ifname> to this file will allocate and populate sysfs with a
+                    fcoe_ctlr_device (ctlr_X). The user can then configure any
+                    per-port settings and finally write to the fcoe_ctlr_device's
+                    'start' attribute to begin the kernel's discovery and login
+                    process.
+
+       ctlr_destroy: 'FCoE Controller' instance removal interface. Writing a
+                      fcoe_ctlr_device's sysfs name to this file will log the
+                      fcoe_ctlr_device out of the fabric or otherwise connected
+                      FCoE devices. It will also free all kernel memory allocated
+                      for this fcoe_ctlr_device and any structures associated
+                      with it, this includes the scsi_host.
+
+What:          /sys/bus/fcoe/devices/ctlr_X
 Date:          March 2012
 KernelVersion: TBD
 Contact:       Robert Love <robert.w.love@intel.com>, devel@open-fcoe.org
-Description:   'FCoE Controller' instances on the fcoe bus
+Description:   'FCoE Controller' instances on the fcoe bus.
+               The FCoE Controller now has a three stage creation process.
+               1) Write interface name to ctlr_create 2) Configure the FCoE
+               Controller (ctlr_X) 3) Enable the FCoE Controller to begin
+               discovery and login. The FCoE Controller is destroyed by
+               writing it's name, i.e. ctlr_X to the ctlr_delete file.
+
 Attributes:
 
        fcf_dev_loss_tmo: Device loss timeout peroid (see below). Changing
                          this value will change the dev_loss_tmo for all
                          FCFs discovered by this controller.
 
+       mode:             Display or change the FCoE Controller's mode. Possible
+                         modes are 'Fabric' and 'VN2VN'. If a FCoE Controller
+                         is started in 'Fabric' mode then FIP FCF discovery is
+                         initiated and ultimately a fabric login is attempted.
+                         If a FCoE Controller is started in 'VN2VN' mode then
+                         FIP VN2VN discovery and login is performed. A FCoE
+                         Controller only supports one mode at a time.
+
+       enabled:          Whether an FCoE controller is enabled or disabled.
+                         0 if disabled, 1 if enabled. Writing either 0 or 1
+                         to this file will enable or disable the FCoE controller.
+
        lesb/link_fail:   Link Error Status Block (LESB) link failure count.
 
        lesb/vlink_fail:  Link Error Status Block (LESB) virtual link
@@ -26,7 +65,7 @@ Attributes:
 
 Notes: ctlr_X (global increment starting at 0)
 
-What:          /sys/bus/fcoe/fcf_X
+What:          /sys/bus/fcoe/devices/fcf_X
 Date:          March 2012
 KernelVersion: TBD
 Contact:       Robert Love <robert.w.love@intel.com>, devel@open-fcoe.org
index 6401db4..2daf4b0 100644 (file)
@@ -62,6 +62,10 @@ static int bnx2fc_destroy(struct net_device *net_device);
 static int bnx2fc_enable(struct net_device *netdev);
 static int bnx2fc_disable(struct net_device *netdev);
 
+/* fcoe_syfs control interface handlers */
+static int bnx2fc_ctlr_alloc(struct net_device *netdev);
+static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev);
+
 static void bnx2fc_recv_frame(struct sk_buff *skb);
 
 static void bnx2fc_start_disc(struct bnx2fc_interface *interface);
@@ -89,7 +93,6 @@ static void bnx2fc_port_shutdown(struct fc_lport *lport);
 static void bnx2fc_stop(struct bnx2fc_interface *interface);
 static int __init bnx2fc_mod_init(void);
 static void __exit bnx2fc_mod_exit(void);
-static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev);
 
 unsigned int bnx2fc_debug_level;
 module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR);
@@ -107,44 +110,6 @@ static inline struct net_device *bnx2fc_netdev(const struct fc_lport *lport)
                ((struct fcoe_port *)lport_priv(lport))->priv)->netdev;
 }
 
-/**
- * bnx2fc_get_lesb() - Fill the FCoE Link Error Status Block
- * @lport: the local port
- * @fc_lesb: the link error status block
- */
-static void bnx2fc_get_lesb(struct fc_lport *lport,
-                           struct fc_els_lesb *fc_lesb)
-{
-       struct net_device *netdev = bnx2fc_netdev(lport);
-
-       __fcoe_get_lesb(lport, fc_lesb, netdev);
-}
-
-static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
-{
-       struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
-       struct net_device *netdev = bnx2fc_netdev(fip->lp);
-       struct fcoe_fc_els_lesb *fcoe_lesb;
-       struct fc_els_lesb fc_lesb;
-
-       __fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
-       fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
-
-       ctlr_dev->lesb.lesb_link_fail =
-               ntohl(fcoe_lesb->lesb_link_fail);
-       ctlr_dev->lesb.lesb_vlink_fail =
-               ntohl(fcoe_lesb->lesb_vlink_fail);
-       ctlr_dev->lesb.lesb_miss_fka =
-               ntohl(fcoe_lesb->lesb_miss_fka);
-       ctlr_dev->lesb.lesb_symb_err =
-               ntohl(fcoe_lesb->lesb_symb_err);
-       ctlr_dev->lesb.lesb_err_block =
-               ntohl(fcoe_lesb->lesb_err_block);
-       ctlr_dev->lesb.lesb_fcs_error =
-               ntohl(fcoe_lesb->lesb_fcs_error);
-}
-EXPORT_SYMBOL(bnx2fc_ctlr_get_lesb);
-
 static void bnx2fc_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
 {
        struct fcoe_ctlr_device *ctlr_dev =
@@ -741,35 +706,6 @@ static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev)
        return 0;
 }
 
-static void bnx2fc_link_speed_update(struct fc_lport *lport)
-{
-       struct fcoe_port *port = lport_priv(lport);
-       struct bnx2fc_interface *interface = port->priv;
-       struct net_device *netdev = interface->netdev;
-       struct ethtool_cmd ecmd;
-
-       if (!__ethtool_get_settings(netdev, &ecmd)) {
-               lport->link_supported_speeds &=
-                       ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
-               if (ecmd.supported & (SUPPORTED_1000baseT_Half |
-                                     SUPPORTED_1000baseT_Full))
-                       lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
-               if (ecmd.supported & SUPPORTED_10000baseT_Full)
-                       lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
-
-               switch (ethtool_cmd_speed(&ecmd)) {
-               case SPEED_1000:
-                       lport->link_speed = FC_PORTSPEED_1GBIT;
-                       break;
-               case SPEED_2500:
-                       lport->link_speed = FC_PORTSPEED_2GBIT;
-                       break;
-               case SPEED_10000:
-                       lport->link_speed = FC_PORTSPEED_10GBIT;
-                       break;
-               }
-       }
-}
 static int bnx2fc_link_ok(struct fc_lport *lport)
 {
        struct fcoe_port *port = lport_priv(lport);
@@ -827,7 +763,7 @@ static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev)
        port->fcoe_pending_queue_active = 0;
        setup_timer(&port->timer, fcoe_queue_timer, (unsigned long) lport);
 
-       bnx2fc_link_speed_update(lport);
+       fcoe_link_speed_update(lport);
 
        if (!lport->vport) {
                if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN))
@@ -871,6 +807,7 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
                                     u16 vlan_id)
 {
        struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context;
+       struct fcoe_ctlr_device *cdev;
        struct fc_lport *lport;
        struct fc_lport *vport;
        struct bnx2fc_interface *interface, *tmp;
@@ -930,30 +867,47 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
                BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n",
                                interface->netdev->name, event);
 
-               bnx2fc_link_speed_update(lport);
+               fcoe_link_speed_update(lport);
+
+               cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
 
                if (link_possible && !bnx2fc_link_ok(lport)) {
-                       /* Reset max recv frame size to default */
-                       fc_set_mfs(lport, BNX2FC_MFS);
-                       /*
-                        * ctlr link up will only be handled during
-                        * enable to avoid sending discovery solicitation
-                        * on a stale vlan
-                        */
-                       if (interface->enabled)
-                               fcoe_ctlr_link_up(ctlr);
+                       switch (cdev->enabled) {
+                       case FCOE_CTLR_DISABLED:
+                               pr_info("Link up while interface is disabled.\n");
+                               break;
+                       case FCOE_CTLR_ENABLED:
+                       case FCOE_CTLR_UNUSED:
+                               /* Reset max recv frame size to default */
+                               fc_set_mfs(lport, BNX2FC_MFS);
+                               /*
+                                * ctlr link up will only be handled during
+                                * enable to avoid sending discovery
+                                * solicitation on a stale vlan
+                                */
+                               if (interface->enabled)
+                                       fcoe_ctlr_link_up(ctlr);
+                       };
                } else if (fcoe_ctlr_link_down(ctlr)) {
-                       mutex_lock(&lport->lp_mutex);
-                       list_for_each_entry(vport, &lport->vports, list)
-                               fc_host_port_type(vport->host) =
-                                                       FC_PORTTYPE_UNKNOWN;
-                       mutex_unlock(&lport->lp_mutex);
-                       fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN;
-                       per_cpu_ptr(lport->stats,
-                                   get_cpu())->LinkFailureCount++;
-                       put_cpu();
-                       fcoe_clean_pending_queue(lport);
-                       wait_for_upload = 1;
+                       switch (cdev->enabled) {
+                       case FCOE_CTLR_DISABLED:
+                               pr_info("Link down while interface is disabled.\n");
+                               break;
+                       case FCOE_CTLR_ENABLED:
+                       case FCOE_CTLR_UNUSED:
+                               mutex_lock(&lport->lp_mutex);
+                               list_for_each_entry(vport, &lport->vports, list)
+                                       fc_host_port_type(vport->host) =
+                                       FC_PORTTYPE_UNKNOWN;
+                               mutex_unlock(&lport->lp_mutex);
+                               fc_host_port_type(lport->host) =
+                                       FC_PORTTYPE_UNKNOWN;
+                               per_cpu_ptr(lport->stats,
+                                           get_cpu())->LinkFailureCount++;
+                               put_cpu();
+                               fcoe_clean_pending_queue(lport);
+                               wait_for_upload = 1;
+                       };
                }
        }
        mutex_unlock(&bnx2fc_dev_lock);
@@ -1484,6 +1438,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface,
        port = lport_priv(lport);
        port->lport = lport;
        port->priv = interface;
+       port->get_netdev = bnx2fc_netdev;
        INIT_WORK(&port->destroy_work, bnx2fc_destroy_work);
 
        /* Configure fcoe_port */
@@ -2003,7 +1958,9 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev)
                set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic);
 }
 
-
+/**
+ * Deperecated: Use bnx2fc_enabled()
+ */
 static int bnx2fc_disable(struct net_device *netdev)
 {
        struct bnx2fc_interface *interface;
@@ -2029,7 +1986,9 @@ static int bnx2fc_disable(struct net_device *netdev)
        return rc;
 }
 
-
+/**
+ * Deprecated: Use bnx2fc_enabled()
+ */
 static int bnx2fc_enable(struct net_device *netdev)
 {
        struct bnx2fc_interface *interface;
@@ -2055,17 +2014,57 @@ static int bnx2fc_enable(struct net_device *netdev)
 }
 
 /**
- * bnx2fc_create - Create bnx2fc FCoE interface
+ * bnx2fc_ctlr_enabled() - Enable or disable an FCoE Controller
+ * @cdev: The FCoE Controller that is being enabled or disabled
+ *
+ * fcoe_sysfs will ensure that the state of 'enabled' has
+ * changed, so no checking is necessary here. This routine simply
+ * calls fcoe_enable or fcoe_disable, both of which are deprecated.
+ * When those routines are removed the functionality can be merged
+ * here.
+ */
+static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev)
+{
+       struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev);
+       struct fc_lport *lport = ctlr->lp;
+       struct net_device *netdev = bnx2fc_netdev(lport);
+
+       switch (cdev->enabled) {
+       case FCOE_CTLR_ENABLED:
+               return bnx2fc_enable(netdev);
+       case FCOE_CTLR_DISABLED:
+               return bnx2fc_disable(netdev);
+       case FCOE_CTLR_UNUSED:
+       default:
+               return -ENOTSUPP;
+       };
+}
+
+enum bnx2fc_create_link_state {
+       BNX2FC_CREATE_LINK_DOWN,
+       BNX2FC_CREATE_LINK_UP,
+};
+
+/**
+ * _bnx2fc_create() - Create bnx2fc FCoE interface
+ * @netdev  :   The net_device object the Ethernet interface to create on
+ * @fip_mode:   The FIP mode for this creation
+ * @link_state: The ctlr link state on creation
  *
- * @buffer: The name of Ethernet interface to create on
- * @kp:     The associated kernel param
+ * Called from either the libfcoe 'create' module parameter
+ * via fcoe_create or from fcoe_syfs's ctlr_create file.
  *
- * Called from sysfs.
+ * libfcoe's 'create' module parameter is deprecated so some
+ * consolidation of code can be done when that interface is
+ * removed.
  *
  * Returns: 0 for success
  */
-static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
+static int _bnx2fc_create(struct net_device *netdev,
+                         enum fip_state fip_mode,
+                         enum bnx2fc_create_link_state link_state)
 {
+       struct fcoe_ctlr_device *cdev;
        struct fcoe_ctlr *ctlr;
        struct bnx2fc_interface *interface;
        struct bnx2fc_hba *hba;
@@ -2160,7 +2159,15 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
        /* Make this master N_port */
        ctlr->lp = lport;
 
-       if (!bnx2fc_link_ok(lport)) {
+       cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
+
+       if (link_state == BNX2FC_CREATE_LINK_UP)
+               cdev->enabled = FCOE_CTLR_ENABLED;
+       else
+               cdev->enabled = FCOE_CTLR_DISABLED;
+
+       if (link_state == BNX2FC_CREATE_LINK_UP &&
+           !bnx2fc_link_ok(lport)) {
                fcoe_ctlr_link_up(ctlr);
                fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
                set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state);
@@ -2168,7 +2175,10 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
 
        BNX2FC_HBA_DBG(lport, "create: START DISC\n");
        bnx2fc_start_disc(interface);
-       interface->enabled = true;
+
+       if (link_state == BNX2FC_CREATE_LINK_UP)
+               interface->enabled = true;
+
        /*
         * Release from kref_init in bnx2fc_interface_setup, on success
         * lport should be holding a reference taken in bnx2fc_if_create
@@ -2193,6 +2203,37 @@ mod_err:
        return rc;
 }
 
+/**
+ * bnx2fc_create() - Create a bnx2fc interface
+ * @netdev  : The net_device object the Ethernet interface to create on
+ * @fip_mode: The FIP mode for this creation
+ *
+ * Called from fcoe transport
+ *
+ * Returns: 0 for success
+ */
+static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
+{
+       return _bnx2fc_create(netdev, fip_mode, BNX2FC_CREATE_LINK_UP);
+}
+
+/**
+ * bnx2fc_ctlr_alloc() - Allocate a bnx2fc interface from fcoe_sysfs
+ * @netdev: The net_device to be used by the allocated FCoE Controller
+ *
+ * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr
+ * in a link_down state. The allows the user an opportunity to configure
+ * the FCoE Controller from sysfs before enabling the FCoE Controller.
+ *
+ * Creating in with this routine starts the FCoE Controller in Fabric
+ * mode. The user can change to VN2VN or another mode before enabling.
+ */
+static int bnx2fc_ctlr_alloc(struct net_device *netdev)
+{
+       return _bnx2fc_create(netdev, FIP_MODE_FABRIC,
+                             BNX2FC_CREATE_LINK_DOWN);
+}
+
 /**
  * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc hba instance
  *
@@ -2318,6 +2359,7 @@ static struct fcoe_transport bnx2fc_transport = {
        .name = {"bnx2fc"},
        .attached = false,
        .list = LIST_HEAD_INIT(bnx2fc_transport.list),
+       .alloc = bnx2fc_ctlr_alloc,
        .match = bnx2fc_match,
        .create = bnx2fc_create,
        .destroy = bnx2fc_destroy,
@@ -2562,13 +2604,13 @@ module_init(bnx2fc_mod_init);
 module_exit(bnx2fc_mod_exit);
 
 static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = {
-       .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode,
-       .get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb,
-       .get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb,
-       .get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb,
-       .get_fcoe_ctlr_symb_err = bnx2fc_ctlr_get_lesb,
-       .get_fcoe_ctlr_err_block = bnx2fc_ctlr_get_lesb,
-       .get_fcoe_ctlr_fcs_error = bnx2fc_ctlr_get_lesb,
+       .set_fcoe_ctlr_enabled = bnx2fc_ctlr_enabled,
+       .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
+       .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
+       .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
+       .get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb,
+       .get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb,
+       .get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb,
 
        .get_fcoe_fcf_selected = fcoe_fcf_get_selected,
        .get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id,
@@ -2675,7 +2717,7 @@ static struct libfc_function_template bnx2fc_libfc_fcn_templ = {
        .elsct_send             = bnx2fc_elsct_send,
        .fcp_abort_io           = bnx2fc_abort_io,
        .fcp_cleanup            = bnx2fc_cleanup,
-       .get_lesb               = bnx2fc_get_lesb,
+       .get_lesb               = fcoe_get_lesb,
        .rport_event_callback   = bnx2fc_rport_event_handler,
 };
 
index 666b7ac..b5d92fc 100644 (file)
@@ -82,11 +82,11 @@ static int fcoe_rcv(struct sk_buff *, struct net_device *,
                    struct packet_type *, struct net_device *);
 static int fcoe_percpu_receive_thread(void *);
 static void fcoe_percpu_clean(struct fc_lport *);
-static int fcoe_link_speed_update(struct fc_lport *);
 static int fcoe_link_ok(struct fc_lport *);
 
 static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
 static int fcoe_hostlist_add(const struct fc_lport *);
+static void fcoe_hostlist_del(const struct fc_lport *);
 
 static int fcoe_device_notification(struct notifier_block *, ulong, void *);
 static void fcoe_dev_setup(void);
@@ -117,6 +117,11 @@ static int fcoe_destroy(struct net_device *netdev);
 static int fcoe_enable(struct net_device *netdev);
 static int fcoe_disable(struct net_device *netdev);
 
+/* fcoe_syfs control interface handlers */
+static int fcoe_ctlr_alloc(struct net_device *netdev);
+static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev);
+
+
 static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
                                      u32 did, struct fc_frame *,
                                      unsigned int op,
@@ -126,8 +131,6 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
                                      void *, u32 timeout);
 static void fcoe_recv_frame(struct sk_buff *skb);
 
-static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
-
 /* notification function for packets from net device */
 static struct notifier_block fcoe_notifier = {
        .notifier_call = fcoe_device_notification,
@@ -151,11 +154,11 @@ static int fcoe_vport_create(struct fc_vport *, bool disabled);
 static int fcoe_vport_disable(struct fc_vport *, bool disable);
 static void fcoe_set_vport_symbolic_name(struct fc_vport *);
 static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
-static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *);
 static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);
 
 static struct fcoe_sysfs_function_template fcoe_sysfs_templ = {
-       .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode,
+       .set_fcoe_ctlr_mode = fcoe_ctlr_set_fip_mode,
+       .set_fcoe_ctlr_enabled = fcoe_ctlr_enabled,
        .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
        .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
        .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
@@ -1112,10 +1115,17 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
        port = lport_priv(lport);
        port->lport = lport;
        port->priv = fcoe;
+       port->get_netdev = fcoe_netdev;
        port->max_queue_depth = FCOE_MAX_QUEUE_DEPTH;
        port->min_queue_depth = FCOE_MIN_QUEUE_DEPTH;
        INIT_WORK(&port->destroy_work, fcoe_destroy_work);
 
+       /*
+        * Need to add the lport to the hostlist
+        * so we catch NETDEV_CHANGE events.
+        */
+       fcoe_hostlist_add(lport);
+
        /* configure a fc_lport including the exchange manager */
        rc = fcoe_lport_config(lport);
        if (rc) {
@@ -1187,6 +1197,7 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
 out_lp_destroy:
        fc_exch_mgr_free(lport);
 out_host_put:
+       fcoe_hostlist_del(lport);
        scsi_host_put(lport->host);
 out:
        return ERR_PTR(rc);
@@ -1964,6 +1975,7 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
 static int fcoe_device_notification(struct notifier_block *notifier,
                                    ulong event, void *ptr)
 {
+       struct fcoe_ctlr_device *cdev;
        struct fc_lport *lport = NULL;
        struct net_device *netdev = ptr;
        struct fcoe_ctlr *ctlr;
@@ -2020,13 +2032,29 @@ static int fcoe_device_notification(struct notifier_block *notifier,
 
        fcoe_link_speed_update(lport);
 
-       if (link_possible && !fcoe_link_ok(lport))
-               fcoe_ctlr_link_up(ctlr);
-       else if (fcoe_ctlr_link_down(ctlr)) {
-               stats = per_cpu_ptr(lport->stats, get_cpu());
-               stats->LinkFailureCount++;
-               put_cpu();
-               fcoe_clean_pending_queue(lport);
+       cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
+
+       if (link_possible && !fcoe_link_ok(lport)) {
+               switch (cdev->enabled) {
+               case FCOE_CTLR_DISABLED:
+                       pr_info("Link up while interface is disabled.\n");
+                       break;
+               case FCOE_CTLR_ENABLED:
+               case FCOE_CTLR_UNUSED:
+                       fcoe_ctlr_link_up(ctlr);
+               };
+       } else if (fcoe_ctlr_link_down(ctlr)) {
+               switch (cdev->enabled) {
+               case FCOE_CTLR_DISABLED:
+                       pr_info("Link down while interface is disabled.\n");
+                       break;
+               case FCOE_CTLR_ENABLED:
+               case FCOE_CTLR_UNUSED:
+                       stats = per_cpu_ptr(lport->stats, get_cpu());
+                       stats->LinkFailureCount++;
+                       put_cpu();
+                       fcoe_clean_pending_queue(lport);
+               };
        }
 out:
        return rc;
@@ -2039,6 +2067,8 @@ out:
  * Called from fcoe transport.
  *
  * Returns: 0 for success
+ *
+ * Deprecated: use fcoe_ctlr_enabled()
  */
 static int fcoe_disable(struct net_device *netdev)
 {
@@ -2097,6 +2127,33 @@ out:
        return rc;
 }
 
+/**
+ * fcoe_ctlr_enabled() - Enable or disable an FCoE Controller
+ * @cdev: The FCoE Controller that is being enabled or disabled
+ *
+ * fcoe_sysfs will ensure that the state of 'enabled' has
+ * changed, so no checking is necessary here. This routine simply
+ * calls fcoe_enable or fcoe_disable, both of which are deprecated.
+ * When those routines are removed the functionality can be merged
+ * here.
+ */
+static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev)
+{
+       struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev);
+       struct fc_lport *lport = ctlr->lp;
+       struct net_device *netdev = fcoe_netdev(lport);
+
+       switch (cdev->enabled) {
+       case FCOE_CTLR_ENABLED:
+               return fcoe_enable(netdev);
+       case FCOE_CTLR_DISABLED:
+               return fcoe_disable(netdev);
+       case FCOE_CTLR_UNUSED:
+       default:
+               return -ENOTSUPP;
+       };
+}
+
 /**
  * fcoe_destroy() - Destroy a FCoE interface
  * @netdev  : The net_device object the Ethernet interface to create on
@@ -2139,8 +2196,31 @@ static void fcoe_destroy_work(struct work_struct *work)
 {
        struct fcoe_port *port;
        struct fcoe_interface *fcoe;
+       struct Scsi_Host *shost;
+       struct fc_host_attrs *fc_host;
+       unsigned long flags;
+       struct fc_vport *vport;
+       struct fc_vport *next_vport;
 
        port = container_of(work, struct fcoe_port, destroy_work);
+       shost = port->lport->host;
+       fc_host = shost_to_fc_host(shost);
+
+       /* Loop through all the vports and mark them for deletion */
+       spin_lock_irqsave(shost->host_lock, flags);
+       list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) {
+               if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
+                       continue;
+               } else {
+                       vport->flags |= FC_VPORT_DELETING;
+                       queue_work(fc_host_work_q(shost),
+                                  &vport->vport_delete_work);
+               }
+       }
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
+       flush_workqueue(fc_host_work_q(shost));
+
        mutex_lock(&fcoe_config_mutex);
 
        fcoe = port->priv;
@@ -2204,16 +2284,26 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
 #endif
 }
 
+enum fcoe_create_link_state {
+       FCOE_CREATE_LINK_DOWN,
+       FCOE_CREATE_LINK_UP,
+};
+
 /**
- * fcoe_create() - Create a fcoe interface
- * @netdev  : The net_device object the Ethernet interface to create on
- * @fip_mode: The FIP mode for this creation
+ * _fcoe_create() - (internal) Create a fcoe interface
+ * @netdev  :   The net_device object the Ethernet interface to create on
+ * @fip_mode:   The FIP mode for this creation
+ * @link_state: The ctlr link state on creation
  *
- * Called from fcoe transport
+ * Called from either the libfcoe 'create' module parameter
+ * via fcoe_create or from fcoe_syfs's ctlr_create file.
  *
- * Returns: 0 for success
+ * libfcoe's 'create' module parameter is deprecated so some
+ * consolidation of code can be done when that interface is
+ * removed.
  */
-static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
+static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode,
+                       enum fcoe_create_link_state link_state)
 {
        int rc = 0;
        struct fcoe_ctlr_device *ctlr_dev;
@@ -2254,13 +2344,29 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
        /* setup DCB priority attributes. */
        fcoe_dcb_create(fcoe);
 
-       /* add to lports list */
-       fcoe_hostlist_add(lport);
-
        /* start FIP Discovery and FLOGI */
        lport->boot_time = jiffies;
        fc_fabric_login(lport);
-       if (!fcoe_link_ok(lport)) {
+
+       /*
+        * If the fcoe_ctlr_device is to be set to DISABLED
+        * it must be done after the lport is added to the
+        * hostlist, but before the rtnl_lock is released.
+        * This is because the rtnl_lock protects the
+        * hostlist that fcoe_device_notification uses. If
+        * the FCoE Controller is intended to be created
+        * DISABLED then 'enabled' needs to be considered
+        * handling link events. 'enabled' must be set
+        * before the lport can be found in the hostlist
+        * when a link up event is received.
+        */
+       if (link_state == FCOE_CREATE_LINK_UP)
+               ctlr_dev->enabled = FCOE_CTLR_ENABLED;
+       else
+               ctlr_dev->enabled = FCOE_CTLR_DISABLED;
+
+       if (link_state == FCOE_CREATE_LINK_UP &&
+           !fcoe_link_ok(lport)) {
                rtnl_unlock();
                fcoe_ctlr_link_up(ctlr);
                mutex_unlock(&fcoe_config_mutex);
@@ -2275,37 +2381,34 @@ out_nortnl:
 }
 
 /**
- * fcoe_link_speed_update() - Update the supported and actual link speeds
- * @lport: The local port to update speeds for
+ * fcoe_create() - Create a fcoe interface
+ * @netdev  : The net_device object the Ethernet interface to create on
+ * @fip_mode: The FIP mode for this creation
+ *
+ * Called from fcoe transport
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
+{
+       return _fcoe_create(netdev, fip_mode, FCOE_CREATE_LINK_UP);
+}
+
+/**
+ * fcoe_ctlr_alloc() - Allocate a fcoe interface from fcoe_sysfs
+ * @netdev: The net_device to be used by the allocated FCoE Controller
  *
- * Returns: 0 if the ethtool query was successful
- *          -1 if the ethtool query failed
+ * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr
+ * in a link_down state. The allows the user an opportunity to configure
+ * the FCoE Controller from sysfs before enabling the FCoE Controller.
+ *
+ * Creating in with this routine starts the FCoE Controller in Fabric
+ * mode. The user can change to VN2VN or another mode before enabling.
  */
-static int fcoe_link_speed_update(struct fc_lport *lport)
+static int fcoe_ctlr_alloc(struct net_device *netdev)
 {
-       struct net_device *netdev = fcoe_netdev(lport);
-       struct ethtool_cmd ecmd;
-
-       if (!__ethtool_get_settings(netdev, &ecmd)) {
-               lport->link_supported_speeds &=
-                       ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
-               if (ecmd.supported & (SUPPORTED_1000baseT_Half |
-                                     SUPPORTED_1000baseT_Full))
-                       lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
-               if (ecmd.supported & SUPPORTED_10000baseT_Full)
-                       lport->link_supported_speeds |=
-                               FC_PORTSPEED_10GBIT;
-               switch (ethtool_cmd_speed(&ecmd)) {
-               case SPEED_1000:
-                       lport->link_speed = FC_PORTSPEED_1GBIT;
-                       break;
-               case SPEED_10000:
-                       lport->link_speed = FC_PORTSPEED_10GBIT;
-                       break;
-               }
-               return 0;
-       }
-       return -1;
+       return _fcoe_create(netdev, FIP_MODE_FABRIC,
+                           FCOE_CREATE_LINK_DOWN);
 }
 
 /**
@@ -2375,10 +2478,13 @@ static int fcoe_reset(struct Scsi_Host *shost)
        struct fcoe_port *port = lport_priv(lport);
        struct fcoe_interface *fcoe = port->priv;
        struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
+       struct fcoe_ctlr_device *cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
 
        fcoe_ctlr_link_down(ctlr);
        fcoe_clean_pending_queue(ctlr->lp);
-       if (!fcoe_link_ok(ctlr->lp))
+
+       if (cdev->enabled != FCOE_CTLR_DISABLED &&
+           !fcoe_link_ok(ctlr->lp))
                fcoe_ctlr_link_up(ctlr);
        return 0;
 }
@@ -2445,12 +2551,31 @@ static int fcoe_hostlist_add(const struct fc_lport *lport)
        return 0;
 }
 
+/**
+ * fcoe_hostlist_del() - Remove the FCoE interface identified by a local
+ *                      port to the hostlist
+ * @lport: The local port that identifies the FCoE interface to be added
+ *
+ * Locking: must be called with the RTNL mutex held
+ *
+ */
+static void fcoe_hostlist_del(const struct fc_lport *lport)
+{
+       struct fcoe_interface *fcoe;
+       struct fcoe_port *port;
+
+       port = lport_priv(lport);
+       fcoe = port->priv;
+       list_del(&fcoe->list);
+       return;
+}
 
 static struct fcoe_transport fcoe_sw_transport = {
        .name = {FCOE_TRANSPORT_DEFAULT},
        .attached = false,
        .list = LIST_HEAD_INIT(fcoe_sw_transport.list),
        .match = fcoe_match,
+       .alloc = fcoe_ctlr_alloc,
        .create = fcoe_create,
        .destroy = fcoe_destroy,
        .enable = fcoe_enable,
@@ -2534,9 +2659,9 @@ static void __exit fcoe_exit(void)
        /* releases the associated fcoe hosts */
        rtnl_lock();
        list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) {
-               list_del(&fcoe->list);
                ctlr = fcoe_to_ctlr(fcoe);
                port = lport_priv(ctlr->lp);
+               fcoe_hostlist_del(port->lport);
                queue_work(fcoe_wq, &port->destroy_work);
        }
        rtnl_unlock();
@@ -2776,43 +2901,6 @@ static void fcoe_set_vport_symbolic_name(struct fc_vport *vport)
                             NULL, NULL, 3 * lport->r_a_tov);
 }
 
-/**
- * fcoe_get_lesb() - Fill the FCoE Link Error Status Block
- * @lport: the local port
- * @fc_lesb: the link error status block
- */
-static void fcoe_get_lesb(struct fc_lport *lport,
-                        struct fc_els_lesb *fc_lesb)
-{
-       struct net_device *netdev = fcoe_netdev(lport);
-
-       __fcoe_get_lesb(lport, fc_lesb, netdev);
-}
-
-static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
-{
-       struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
-       struct net_device *netdev = fcoe_netdev(fip->lp);
-       struct fcoe_fc_els_lesb *fcoe_lesb;
-       struct fc_els_lesb fc_lesb;
-
-       __fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
-       fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
-
-       ctlr_dev->lesb.lesb_link_fail =
-               ntohl(fcoe_lesb->lesb_link_fail);
-       ctlr_dev->lesb.lesb_vlink_fail =
-               ntohl(fcoe_lesb->lesb_vlink_fail);
-       ctlr_dev->lesb.lesb_miss_fka =
-               ntohl(fcoe_lesb->lesb_miss_fka);
-       ctlr_dev->lesb.lesb_symb_err =
-               ntohl(fcoe_lesb->lesb_symb_err);
-       ctlr_dev->lesb.lesb_err_block =
-               ntohl(fcoe_lesb->lesb_err_block);
-       ctlr_dev->lesb.lesb_fcs_error =
-               ntohl(fcoe_lesb->lesb_fcs_error);
-}
-
 static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
 {
        struct fcoe_ctlr_device *ctlr_dev =
index b42dc32..2b53672 100644 (file)
@@ -55,12 +55,12 @@ do {                                                                \
 
 #define FCOE_DBG(fmt, args...)                                         \
        FCOE_CHECK_LOGGING(FCOE_LOGGING,                                \
-                          printk(KERN_INFO "fcoe: " fmt, ##args);)
+                          pr_info("fcoe: " fmt, ##args);)
 
 #define FCOE_NETDEV_DBG(netdev, fmt, args...)                  \
        FCOE_CHECK_LOGGING(FCOE_NETDEV_LOGGING,                 \
-                          printk(KERN_INFO "fcoe: %s: " fmt,   \
-                                 netdev->name, ##args);)
+                          pr_info("fcoe: %s: " fmt,            \
+                                  netdev->name, ##args);)
 
 /**
  * struct fcoe_interface - A FCoE interface
index 4a909d7..08c3bc3 100644 (file)
@@ -1291,8 +1291,16 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
 
        LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n");
 
-       if (!fcf || !lport->port_id)
+       if (!fcf || !lport->port_id) {
+               /*
+                * We are yet to select best FCF, but we got CVL in the
+                * meantime. reset the ctlr and let it rediscover the FCF
+                */
+               mutex_lock(&fip->ctlr_mutex);
+               fcoe_ctlr_reset(fip);
+               mutex_unlock(&fip->ctlr_mutex);
                return;
+       }
 
        /*
         * mask of required descriptors.  Validating each one clears its bit.
@@ -1551,15 +1559,6 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
                                fcf->fabric_name, fcf->vfid, fcf->fcf_mac,
                                fcf->fc_map, fcoe_ctlr_mtu_valid(fcf),
                                fcf->flogi_sent, fcf->pri);
-               if (fcf->fabric_name != first->fabric_name ||
-                   fcf->vfid != first->vfid ||
-                   fcf->fc_map != first->fc_map) {
-                       LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
-                                       "or FC-MAP\n");
-                       return NULL;
-               }
-               if (fcf->flogi_sent)
-                       continue;
                if (!fcoe_ctlr_fcf_usable(fcf)) {
                        LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx "
                                        "map %x %svalid %savailable\n",
@@ -1569,6 +1568,15 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
                                        "" : "un");
                        continue;
                }
+               if (fcf->fabric_name != first->fabric_name ||
+                   fcf->vfid != first->vfid ||
+                   fcf->fc_map != first->fc_map) {
+                       LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
+                                       "or FC-MAP\n");
+                       return NULL;
+               }
+               if (fcf->flogi_sent)
+                       continue;
                if (!best || fcf->pri < best->pri || best->flogi_sent)
                        best = fcf;
        }
@@ -2864,22 +2872,21 @@ void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev)
 }
 EXPORT_SYMBOL(fcoe_fcf_get_selected);
 
-void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *ctlr_dev)
+void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev)
 {
        struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
 
        mutex_lock(&ctlr->ctlr_mutex);
-       switch (ctlr->mode) {
-       case FIP_MODE_FABRIC:
-               ctlr_dev->mode = FIP_CONN_TYPE_FABRIC;
-               break;
-       case FIP_MODE_VN2VN:
-               ctlr_dev->mode = FIP_CONN_TYPE_VN2VN;
+       switch (ctlr_dev->mode) {
+       case FIP_CONN_TYPE_VN2VN:
+               ctlr->mode = FIP_MODE_VN2VN;
                break;
+       case FIP_CONN_TYPE_FABRIC:
        default:
-               ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN;
+               ctlr->mode = FIP_MODE_FABRIC;
                break;
        }
+
        mutex_unlock(&ctlr->ctlr_mutex);
 }
-EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode);
+EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode);
index 5e75168..8c05ae0 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/etherdevice.h>
+#include <linux/ctype.h>
 
 #include <scsi/fcoe_sysfs.h>
+#include <scsi/libfcoe.h>
+
+/*
+ * OK to include local libfcoe.h for debug_logging, but cannot include
+ * <scsi/libfcoe.h> otherwise non-netdev based fcoe solutions would have
+ * have to include more than fcoe_sysfs.h.
+ */
+#include "libfcoe.h"
 
 static atomic_t ctlr_num;
 static atomic_t fcf_num;
@@ -71,6 +80,8 @@ MODULE_PARM_DESC(fcf_dev_loss_tmo,
        ((x)->lesb.lesb_err_block)
 #define fcoe_ctlr_fcs_error(x)                 \
        ((x)->lesb.lesb_fcs_error)
+#define fcoe_ctlr_enabled(x)                   \
+       ((x)->enabled)
 #define fcoe_fcf_state(x)                      \
        ((x)->state)
 #define fcoe_fcf_fabric_name(x)                        \
@@ -210,25 +221,34 @@ static ssize_t show_fcoe_fcf_device_##field(struct device *dev,   \
 #define fcoe_enum_name_search(title, table_type, table)                        \
 static const char *get_fcoe_##title##_name(enum table_type table_key)  \
 {                                                                      \
-       int i;                                                          \
-       char *name = NULL;                                              \
-                                                                       \
-       for (i = 0; i < ARRAY_SIZE(table); i++) {                       \
-               if (table[i].value == table_key) {                      \
-                       name = table[i].name;                           \
-                       break;                                          \
-               }                                                       \
-       }                                                               \
-       return name;                                                    \
+       if (table_key < 0 || table_key >= ARRAY_SIZE(table))            \
+               return NULL;                                            \
+       return table[table_key];                                        \
+}
+
+static char *fip_conn_type_names[] = {
+       [ FIP_CONN_TYPE_UNKNOWN ] = "Unknown",
+       [ FIP_CONN_TYPE_FABRIC ]  = "Fabric",
+       [ FIP_CONN_TYPE_VN2VN ]   = "VN2VN",
+};
+fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
+
+static enum fip_conn_type fcoe_parse_mode(const char *buf)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(fip_conn_type_names); i++) {
+               if (strcasecmp(buf, fip_conn_type_names[i]) == 0)
+                       return i;
+       }
+
+       return FIP_CONN_TYPE_UNKNOWN;
 }
 
-static struct {
-       enum fcf_state value;
-       char           *name;
-} fcf_state_names[] = {
-       { FCOE_FCF_STATE_UNKNOWN,      "Unknown" },
-       { FCOE_FCF_STATE_DISCONNECTED, "Disconnected" },
-       { FCOE_FCF_STATE_CONNECTED,    "Connected" },
+static char *fcf_state_names[] = {
+       [ FCOE_FCF_STATE_UNKNOWN ]      = "Unknown",
+       [ FCOE_FCF_STATE_DISCONNECTED ] = "Disconnected",
+       [ FCOE_FCF_STATE_CONNECTED ]    = "Connected",
 };
 fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names)
 #define FCOE_FCF_STATE_MAX_NAMELEN 50
@@ -246,17 +266,7 @@ static ssize_t show_fcf_state(struct device *dev,
 }
 static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL);
 
-static struct {
-       enum fip_conn_type value;
-       char               *name;
-} fip_conn_type_names[] = {
-       { FIP_CONN_TYPE_UNKNOWN, "Unknown" },
-       { FIP_CONN_TYPE_FABRIC, "Fabric" },
-       { FIP_CONN_TYPE_VN2VN, "VN2VN" },
-};
-fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
-#define FCOE_CTLR_MODE_MAX_NAMELEN 50
-
+#define FCOE_MAX_MODENAME_LEN 20
 static ssize_t show_ctlr_mode(struct device *dev,
                              struct device_attribute *attr,
                              char *buf)
@@ -264,17 +274,116 @@ static ssize_t show_ctlr_mode(struct device *dev,
        struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
        const char *name;
 
-       if (ctlr->f->get_fcoe_ctlr_mode)
-               ctlr->f->get_fcoe_ctlr_mode(ctlr);
-
        name = get_fcoe_ctlr_mode_name(ctlr->mode);
        if (!name)
                return -EINVAL;
-       return snprintf(buf, FCOE_CTLR_MODE_MAX_NAMELEN,
+       return snprintf(buf, FCOE_MAX_MODENAME_LEN,
+                       "%s\n", name);
+}
+
+static ssize_t store_ctlr_mode(struct device *dev,
+                              struct device_attribute *attr,
+                              const char *buf, size_t count)
+{
+       struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
+       char mode[FCOE_MAX_MODENAME_LEN + 1];
+
+       if (count > FCOE_MAX_MODENAME_LEN)
+               return -EINVAL;
+
+       strncpy(mode, buf, count);
+
+       if (mode[count - 1] == '\n')
+               mode[count - 1] = '\0';
+       else
+               mode[count] = '\0';
+
+       switch (ctlr->enabled) {
+       case FCOE_CTLR_ENABLED:
+               LIBFCOE_SYSFS_DBG(ctlr, "Cannot change mode when enabled.");
+               return -EBUSY;
+       case FCOE_CTLR_DISABLED:
+               if (!ctlr->f->set_fcoe_ctlr_mode) {
+                       LIBFCOE_SYSFS_DBG(ctlr,
+                                         "Mode change not supported by LLD.");
+                       return -ENOTSUPP;
+               }
+
+               ctlr->mode = fcoe_parse_mode(mode);
+               if (ctlr->mode == FIP_CONN_TYPE_UNKNOWN) {
+                       LIBFCOE_SYSFS_DBG(ctlr,
+                                         "Unknown mode %s provided.", buf);
+                       return -EINVAL;
+               }
+
+               ctlr->f->set_fcoe_ctlr_mode(ctlr);
+               LIBFCOE_SYSFS_DBG(ctlr, "Mode changed to %s.", buf);
+
+               return count;
+       case FCOE_CTLR_UNUSED:
+       default:
+               LIBFCOE_SYSFS_DBG(ctlr, "Mode change not supported.");
+               return -ENOTSUPP;
+       };
+}
+
+static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO | S_IWUSR,
+                       show_ctlr_mode, store_ctlr_mode);
+
+static ssize_t store_ctlr_enabled(struct device *dev,
+                                 struct device_attribute *attr,
+                                 const char *buf, size_t count)
+{
+       struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
+       int rc;
+
+       switch (ctlr->enabled) {
+       case FCOE_CTLR_ENABLED:
+               if (*buf == '1')
+                       return count;
+               ctlr->enabled = FCOE_CTLR_DISABLED;
+               break;
+       case FCOE_CTLR_DISABLED:
+               if (*buf == '0')
+                       return count;
+               ctlr->enabled = FCOE_CTLR_ENABLED;
+               break;
+       case FCOE_CTLR_UNUSED:
+               return -ENOTSUPP;
+       };
+
+       rc = ctlr->f->set_fcoe_ctlr_enabled(ctlr);
+       if (rc)
+               return rc;
+
+       return count;
+}
+
+static char *ctlr_enabled_state_names[] = {
+       [ FCOE_CTLR_ENABLED ]  = "1",
+       [ FCOE_CTLR_DISABLED ] = "0",
+};
+fcoe_enum_name_search(ctlr_enabled_state, ctlr_enabled_state,
+                     ctlr_enabled_state_names)
+#define FCOE_CTLR_ENABLED_MAX_NAMELEN 50
+
+static ssize_t show_ctlr_enabled_state(struct device *dev,
+                                      struct device_attribute *attr,
+                                      char *buf)
+{
+       struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
+       const char *name;
+
+       name = get_fcoe_ctlr_enabled_state_name(ctlr->enabled);
+       if (!name)
+               return -EINVAL;
+       return snprintf(buf, FCOE_CTLR_ENABLED_MAX_NAMELEN,
                        "%s\n", name);
 }
-static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO,
-                       show_ctlr_mode, NULL);
+
+static FCOE_DEVICE_ATTR(ctlr, enabled, S_IRUGO | S_IWUSR,
+                       show_ctlr_enabled_state,
+                       store_ctlr_enabled);
 
 static ssize_t
 store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev,
@@ -359,6 +468,7 @@ static struct attribute_group fcoe_ctlr_lesb_attr_group = {
 
 static struct attribute *fcoe_ctlr_attrs[] = {
        &device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr,
+       &device_attr_fcoe_ctlr_enabled.attr,
        &device_attr_fcoe_ctlr_mode.attr,
        NULL,
 };
@@ -443,9 +553,16 @@ struct device_type fcoe_fcf_device_type = {
        .release = fcoe_fcf_device_release,
 };
 
+struct bus_attribute fcoe_bus_attr_group[] = {
+       __ATTR(ctlr_create, S_IWUSR, NULL, fcoe_ctlr_create_store),
+       __ATTR(ctlr_destroy, S_IWUSR, NULL, fcoe_ctlr_destroy_store),
+       __ATTR_NULL
+};
+
 struct bus_type fcoe_bus_type = {
        .name = "fcoe",
        .match = &fcoe_bus_match,
+       .bus_attrs = fcoe_bus_attr_group,
 };
 
 /**
@@ -566,6 +683,7 @@ struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent,
 
        ctlr->id = atomic_inc_return(&ctlr_num) - 1;
        ctlr->f = f;
+       ctlr->mode = FIP_CONN_TYPE_FABRIC;
        INIT_LIST_HEAD(&ctlr->fcfs);
        mutex_init(&ctlr->lock);
        ctlr->dev.parent = parent;
index ac76d8a..f3a5a53 100644 (file)
@@ -83,6 +83,50 @@ static struct notifier_block libfcoe_notifier = {
        .notifier_call = libfcoe_device_notification,
 };
 
+/**
+ * fcoe_link_speed_update() - Update the supported and actual link speeds
+ * @lport: The local port to update speeds for
+ *
+ * Returns: 0 if the ethtool query was successful
+ *          -1 if the ethtool query failed
+ */
+int fcoe_link_speed_update(struct fc_lport *lport)
+{
+       struct net_device *netdev = fcoe_get_netdev(lport);
+       struct ethtool_cmd ecmd;
+
+       if (!__ethtool_get_settings(netdev, &ecmd)) {
+               lport->link_supported_speeds &=
+                       ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
+               if (ecmd.supported & (SUPPORTED_1000baseT_Half |
+                                     SUPPORTED_1000baseT_Full))
+                       lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
+               if (ecmd.supported & SUPPORTED_10000baseT_Full)
+                       lport->link_supported_speeds |=
+                               FC_PORTSPEED_10GBIT;
+               switch (ethtool_cmd_speed(&ecmd)) {
+               case SPEED_1000:
+                       lport->link_speed = FC_PORTSPEED_1GBIT;
+                       break;
+               case SPEED_10000:
+                       lport->link_speed = FC_PORTSPEED_10GBIT;
+                       break;
+               }
+               return 0;
+       }
+       return -1;
+}
+EXPORT_SYMBOL_GPL(fcoe_link_speed_update);
+
+/**
+ * __fcoe_get_lesb() - Get the Link Error Status Block (LESB) for a given lport
+ * @lport: The local port to update speeds for
+ * @fc_lesb: Pointer to the LESB to be filled up
+ * @netdev: Pointer to the netdev that is associated with the lport
+ *
+ * Note, the Link Error Status Block (LESB) for FCoE is defined in FC-BB-6
+ * Clause 7.11 in v1.04.
+ */
 void __fcoe_get_lesb(struct fc_lport *lport,
                     struct fc_els_lesb *fc_lesb,
                     struct net_device *netdev)
@@ -112,6 +156,51 @@ void __fcoe_get_lesb(struct fc_lport *lport,
 }
 EXPORT_SYMBOL_GPL(__fcoe_get_lesb);
 
+/**
+ * fcoe_get_lesb() - Fill the FCoE Link Error Status Block
+ * @lport: the local port
+ * @fc_lesb: the link error status block
+ */
+void fcoe_get_lesb(struct fc_lport *lport,
+                        struct fc_els_lesb *fc_lesb)
+{
+       struct net_device *netdev = fcoe_get_netdev(lport);
+
+       __fcoe_get_lesb(lport, fc_lesb, netdev);
+}
+EXPORT_SYMBOL_GPL(fcoe_get_lesb);
+
+/**
+ * fcoe_ctlr_get_lesb() - Get the Link Error Status Block (LESB) for a given
+ * fcoe controller device
+ * @ctlr_dev: The given fcoe controller device
+ *
+ */
+void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
+{
+       struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
+       struct net_device *netdev = fcoe_get_netdev(fip->lp);
+       struct fcoe_fc_els_lesb *fcoe_lesb;
+       struct fc_els_lesb fc_lesb;
+
+       __fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
+       fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
+
+       ctlr_dev->lesb.lesb_link_fail =
+               ntohl(fcoe_lesb->lesb_link_fail);
+       ctlr_dev->lesb.lesb_vlink_fail =
+               ntohl(fcoe_lesb->lesb_vlink_fail);
+       ctlr_dev->lesb.lesb_miss_fka =
+               ntohl(fcoe_lesb->lesb_miss_fka);
+       ctlr_dev->lesb.lesb_symb_err =
+               ntohl(fcoe_lesb->lesb_symb_err);
+       ctlr_dev->lesb.lesb_err_block =
+               ntohl(fcoe_lesb->lesb_err_block);
+       ctlr_dev->lesb.lesb_fcs_error =
+               ntohl(fcoe_lesb->lesb_fcs_error);
+}
+EXPORT_SYMBOL_GPL(fcoe_ctlr_get_lesb);
+
 void fcoe_wwn_to_str(u64 wwn, char *buf, int len)
 {
        u8 wwpn[8];
@@ -627,6 +716,110 @@ static int libfcoe_device_notification(struct notifier_block *notifier,
        return NOTIFY_OK;
 }
 
+ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
+                              const char *buf, size_t count)
+{
+       struct net_device *netdev = NULL;
+       struct fcoe_transport *ft = NULL;
+       struct fcoe_ctlr_device *ctlr_dev = NULL;
+       int rc = 0;
+       int err;
+
+       mutex_lock(&ft_mutex);
+
+       netdev = fcoe_if_to_netdev(buf);
+       if (!netdev) {
+               LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buf);
+               rc = -ENODEV;
+               goto out_nodev;
+       }
+
+       ft = fcoe_netdev_map_lookup(netdev);
+       if (ft) {
+               LIBFCOE_TRANSPORT_DBG("transport %s already has existing "
+                                     "FCoE instance on %s.\n",
+                                     ft->name, netdev->name);
+               rc = -EEXIST;
+               goto out_putdev;
+       }
+
+       ft = fcoe_transport_lookup(netdev);
+       if (!ft) {
+               LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
+                                     netdev->name);
+               rc = -ENODEV;
+               goto out_putdev;
+       }
+
+       /* pass to transport create */
+       err = ft->alloc ? ft->alloc(netdev) : -ENODEV;
+       if (err) {
+               fcoe_del_netdev_mapping(netdev);
+               rc = -ENOMEM;
+               goto out_putdev;
+       }
+
+       err = fcoe_add_netdev_mapping(netdev, ft);
+       if (err) {
+               LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping "
+                                     "for FCoE transport %s for %s.\n",
+                                     ft->name, netdev->name);
+               rc = -ENODEV;
+               goto out_putdev;
+       }
+
+       LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n",
+                             ft->name, (ctlr_dev) ? "succeeded" : "failed",
+                             netdev->name);
+
+out_putdev:
+       dev_put(netdev);
+out_nodev:
+       mutex_unlock(&ft_mutex);
+       if (rc)
+               return rc;
+       return count;
+}
+
+ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus,
+                               const char *buf, size_t count)
+{
+       int rc = -ENODEV;
+       struct net_device *netdev = NULL;
+       struct fcoe_transport *ft = NULL;
+
+       mutex_lock(&ft_mutex);
+
+       netdev = fcoe_if_to_netdev(buf);
+       if (!netdev) {
+               LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buf);
+               goto out_nodev;
+       }
+
+       ft = fcoe_netdev_map_lookup(netdev);
+       if (!ft) {
+               LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
+                                     netdev->name);
+               goto out_putdev;
+       }
+
+       /* pass to transport destroy */
+       rc = ft->destroy(netdev);
+       if (rc)
+               goto out_putdev;
+
+       fcoe_del_netdev_mapping(netdev);
+       LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n",
+                             ft->name, (rc) ? "failed" : "succeeded",
+                             netdev->name);
+       rc = count; /* required for successful return */
+out_putdev:
+       dev_put(netdev);
+out_nodev:
+       mutex_unlock(&ft_mutex);
+       return rc;
+}
+EXPORT_SYMBOL(fcoe_ctlr_destroy_store);
 
 /**
  * fcoe_transport_create() - Create a fcoe interface
@@ -769,11 +962,7 @@ out_putdev:
        dev_put(netdev);
 out_nodev:
        mutex_unlock(&ft_mutex);
-
-       if (rc == -ERESTARTSYS)
-               return restart_syscall();
-       else
-               return rc;
+       return rc;
 }
 
 /**
index 6af5fc3..d3bb16d 100644 (file)
@@ -2,9 +2,10 @@
 #define _FCOE_LIBFCOE_H_
 
 extern unsigned int libfcoe_debug_logging;
-#define LIBFCOE_LOGGING            0x01 /* General logging, not categorized */
-#define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */
-#define LIBFCOE_TRANSPORT_LOGGING      0x04 /* FCoE transport logging */
+#define LIBFCOE_LOGGING                  0x01 /* General logging, not categorized */
+#define LIBFCOE_FIP_LOGGING       0x02 /* FIP logging */
+#define LIBFCOE_TRANSPORT_LOGGING 0x04 /* FCoE transport logging */
+#define LIBFCOE_SYSFS_LOGGING     0x08 /* fcoe_sysfs logging */
 
 #define LIBFCOE_CHECK_LOGGING(LEVEL, CMD)              \
 do {                                                   \
@@ -16,16 +17,19 @@ do {                                                        \
 
 #define LIBFCOE_DBG(fmt, args...)                                      \
        LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING,                          \
-                             printk(KERN_INFO "libfcoe: " fmt, ##args);)
+                             pr_info("libfcoe: " fmt, ##args);)
 
 #define LIBFCOE_FIP_DBG(fip, fmt, args...)                             \
        LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING,                      \
-                             printk(KERN_INFO "host%d: fip: " fmt,     \
-                                    (fip)->lp->host->host_no, ##args);)
+                             pr_info("host%d: fip: " fmt,              \
+                                     (fip)->lp->host->host_no, ##args);)
 
 #define LIBFCOE_TRANSPORT_DBG(fmt, args...)                            \
        LIBFCOE_CHECK_LOGGING(LIBFCOE_TRANSPORT_LOGGING,                \
-                             printk(KERN_INFO "%s: " fmt,              \
-                                    __func__, ##args);)
+                             pr_info("%s: " fmt, __func__, ##args);)
+
+#define LIBFCOE_SYSFS_DBG(cdev, fmt, args...)                          \
+       LIBFCOE_CHECK_LOGGING(LIBFCOE_SYSFS_LOGGING,                    \
+                             pr_info("ctlr_%d: " fmt, cdev->id, ##args);)
 
 #endif /* _FCOE_LIBFCOE_H_ */
index fcb9d0b..09c81b2 100644 (file)
@@ -1381,10 +1381,10 @@ static void fc_fcp_timeout(unsigned long data)
 
        fsp->state |= FC_SRB_FCP_PROCESSING_TMO;
 
-       if (fsp->state & FC_SRB_RCV_STATUS)
-               fc_fcp_complete_locked(fsp);
-       else if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
+       if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
                fc_fcp_rec(fsp);
+       else if (fsp->state & FC_SRB_RCV_STATUS)
+               fc_fcp_complete_locked(fsp);
        else
                fc_fcp_recovery(fsp, FC_TIMED_OUT);
        fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO;
index c2830cc..b74189d 100644 (file)
@@ -41,25 +41,25 @@ extern unsigned int fc_debug_logging;
 
 #define FC_LIBFC_DBG(fmt, args...)                                     \
        FC_CHECK_LOGGING(FC_LIBFC_LOGGING,                              \
-                        printk(KERN_INFO "libfc: " fmt, ##args))
+                        pr_info("libfc: " fmt, ##args))
 
 #define FC_LPORT_DBG(lport, fmt, args...)                              \
        FC_CHECK_LOGGING(FC_LPORT_LOGGING,                              \
-                        printk(KERN_INFO "host%u: lport %6.6x: " fmt,  \
-                               (lport)->host->host_no,                 \
-                               (lport)->port_id, ##args))
+                        pr_info("host%u: lport %6.6x: " fmt,           \
+                                (lport)->host->host_no,                \
+                                (lport)->port_id, ##args))
 
-#define FC_DISC_DBG(disc, fmt, args...)                                \
-       FC_CHECK_LOGGING(FC_DISC_LOGGING,                       \
-                        printk(KERN_INFO "host%u: disc: " fmt, \
-                               fc_disc_lport(disc)->host->host_no,     \
-                               ##args))
+#define FC_DISC_DBG(disc, fmt, args...)                                        \
+       FC_CHECK_LOGGING(FC_DISC_LOGGING,                               \
+                        pr_info("host%u: disc: " fmt,                  \
+                                fc_disc_lport(disc)->host->host_no,    \
+                                ##args))
 
 #define FC_RPORT_ID_DBG(lport, port_id, fmt, args...)                  \
        FC_CHECK_LOGGING(FC_RPORT_LOGGING,                              \
-                        printk(KERN_INFO "host%u: rport %6.6x: " fmt,  \
-                               (lport)->host->host_no,                 \
-                               (port_id), ##args))
+                        pr_info("host%u: rport %6.6x: " fmt,           \
+                                (lport)->host->host_no,                \
+                                (port_id), ##args))
 
 #define FC_RPORT_DBG(rdata, fmt, args...)                              \
        FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args)
@@ -70,13 +70,13 @@ extern unsigned int fc_debug_logging;
                if ((pkt)->seq_ptr) {                                   \
                        struct fc_exch *_ep = NULL;                     \
                        _ep = fc_seq_exch((pkt)->seq_ptr);              \
-                       printk(KERN_INFO "host%u: fcp: %6.6x: "         \
+                       pr_info("host%u: fcp: %6.6x: "                  \
                                "xid %04x-%04x: " fmt,                  \
                                (pkt)->lp->host->host_no,               \
                                (pkt)->rport->port_id,                  \
                                (_ep)->oxid, (_ep)->rxid, ##args);      \
                } else {                                                \
-                       printk(KERN_INFO "host%u: fcp: %6.6x: " fmt,    \
+                       pr_info("host%u: fcp: %6.6x: " fmt,             \
                                (pkt)->lp->host->host_no,               \
                                (pkt)->rport->port_id, ##args);         \
                }                                                       \
@@ -84,14 +84,14 @@ extern unsigned int fc_debug_logging;
 
 #define FC_EXCH_DBG(exch, fmt, args...)                                        \
        FC_CHECK_LOGGING(FC_EXCH_LOGGING,                               \
-                        printk(KERN_INFO "host%u: xid %4x: " fmt,      \
-                               (exch)->lp->host->host_no,              \
-                               exch->xid, ##args))
+                        pr_info("host%u: xid %4x: " fmt,               \
+                                (exch)->lp->host->host_no,             \
+                                exch->xid, ##args))
 
 #define FC_SCSI_DBG(lport, fmt, args...)                               \
        FC_CHECK_LOGGING(FC_SCSI_LOGGING,                               \
-                        printk(KERN_INFO "host%u: scsi: " fmt,         \
-                               (lport)->host->host_no, ##args))
+                        pr_info("host%u: scsi: " fmt,                  \
+                                (lport)->host->host_no, ##args))
 
 /*
  * FC-4 Providers.
index 83aa1ef..d518d17 100644 (file)
@@ -582,7 +582,7 @@ static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp)
 static void fc_rport_error_retry(struct fc_rport_priv *rdata,
                                 struct fc_frame *fp)
 {
-       unsigned long delay = FC_DEF_E_D_TOV;
+       unsigned long delay = msecs_to_jiffies(FC_DEF_E_D_TOV);
 
        /* make sure this isn't an FC_EX_CLOSED error, never retry those */
        if (PTR_ERR(fp) == -FC_EX_CLOSED)
index 5660381..e69de29 100644 (file)
@@ -1,4 +0,0 @@
-header-y += fc_els.h
-header-y += fc_fs.h
-header-y += fc_gs.h
-header-y += fc_ns.h
diff --git a/include/scsi/fc/fc_els.h b/include/scsi/fc/fc_els.h
deleted file mode 100644 (file)
index 481abbd..0000000
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- * Copyright(c) 2007 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained at www.Open-FCoE.org
- */
-
-#ifndef _FC_ELS_H_
-#define        _FC_ELS_H_
-
-#include <linux/types.h>
-
-/*
- * Fibre Channel Switch - Enhanced Link Services definitions.
- * From T11 FC-LS Rev 1.2 June 7, 2005.
- */
-
-/*
- * ELS Command codes - byte 0 of the frame payload
- */
-enum fc_els_cmd {
-       ELS_LS_RJT =    0x01,   /* ESL reject */
-       ELS_LS_ACC =    0x02,   /* ESL Accept */
-       ELS_PLOGI =     0x03,   /* N_Port login */
-       ELS_FLOGI =     0x04,   /* F_Port login */
-       ELS_LOGO =      0x05,   /* Logout */
-       ELS_ABTX =      0x06,   /* Abort exchange - obsolete */
-       ELS_RCS =       0x07,   /* read connection status */
-       ELS_RES =       0x08,   /* read exchange status block */
-       ELS_RSS =       0x09,   /* read sequence status block */
-       ELS_RSI =       0x0a,   /* read sequence initiative */
-       ELS_ESTS =      0x0b,   /* establish streaming */
-       ELS_ESTC =      0x0c,   /* estimate credit */
-       ELS_ADVC =      0x0d,   /* advise credit */
-       ELS_RTV =       0x0e,   /* read timeout value */
-       ELS_RLS =       0x0f,   /* read link error status block */
-       ELS_ECHO =      0x10,   /* echo */
-       ELS_TEST =      0x11,   /* test */
-       ELS_RRQ =       0x12,   /* reinstate recovery qualifier */
-       ELS_REC =       0x13,   /* read exchange concise */
-       ELS_SRR =       0x14,   /* sequence retransmission request */
-       ELS_PRLI =      0x20,   /* process login */
-       ELS_PRLO =      0x21,   /* process logout */
-       ELS_SCN =       0x22,   /* state change notification */
-       ELS_TPLS =      0x23,   /* test process login state */
-       ELS_TPRLO =     0x24,   /* third party process logout */
-       ELS_LCLM =      0x25,   /* login control list mgmt (obs) */
-       ELS_GAID =      0x30,   /* get alias_ID */
-       ELS_FACT =      0x31,   /* fabric activate alias_id */
-       ELS_FDACDT =    0x32,   /* fabric deactivate alias_id */
-       ELS_NACT =      0x33,   /* N-port activate alias_id */
-       ELS_NDACT =     0x34,   /* N-port deactivate alias_id */
-       ELS_QOSR =      0x40,   /* quality of service request */
-       ELS_RVCS =      0x41,   /* read virtual circuit status */
-       ELS_PDISC =     0x50,   /* discover N_port service params */
-       ELS_FDISC =     0x51,   /* discover F_port service params */
-       ELS_ADISC =     0x52,   /* discover address */
-       ELS_RNC =       0x53,   /* report node cap (obs) */
-       ELS_FARP_REQ =  0x54,   /* FC ARP request */
-       ELS_FARP_REPL = 0x55,   /* FC ARP reply */
-       ELS_RPS =       0x56,   /* read port status block */
-       ELS_RPL =       0x57,   /* read port list */
-       ELS_RPBC =      0x58,   /* read port buffer condition */
-       ELS_FAN =       0x60,   /* fabric address notification */
-       ELS_RSCN =      0x61,   /* registered state change notification */
-       ELS_SCR =       0x62,   /* state change registration */
-       ELS_RNFT =      0x63,   /* report node FC-4 types */
-       ELS_CSR =       0x68,   /* clock synch. request */
-       ELS_CSU =       0x69,   /* clock synch. update */
-       ELS_LINIT =     0x70,   /* loop initialize */
-       ELS_LSTS =      0x72,   /* loop status */
-       ELS_RNID =      0x78,   /* request node ID data */
-       ELS_RLIR =      0x79,   /* registered link incident report */
-       ELS_LIRR =      0x7a,   /* link incident record registration */
-       ELS_SRL =       0x7b,   /* scan remote loop */
-       ELS_SBRP =      0x7c,   /* set bit-error reporting params */
-       ELS_RPSC =      0x7d,   /* report speed capabilities */
-       ELS_QSA =       0x7e,   /* query security attributes */
-       ELS_EVFP =      0x7f,   /* exchange virt. fabrics params */
-       ELS_LKA =       0x80,   /* link keep-alive */
-       ELS_AUTH_ELS =  0x90,   /* authentication ELS */
-};
-
-/*
- * Initializer useful for decoding table.
- * Please keep this in sync with the above definitions.
- */
-#define        FC_ELS_CMDS_INIT {                      \
-       [ELS_LS_RJT] =  "LS_RJT",               \
-       [ELS_LS_ACC] =  "LS_ACC",               \
-       [ELS_PLOGI] =   "PLOGI",                \
-       [ELS_FLOGI] =   "FLOGI",                \
-       [ELS_LOGO] =    "LOGO",                 \
-       [ELS_ABTX] =    "ABTX",                 \
-       [ELS_RCS] =     "RCS",                  \
-       [ELS_RES] =     "RES",                  \
-       [ELS_RSS] =     "RSS",                  \
-       [ELS_RSI] =     "RSI",                  \
-       [ELS_ESTS] =    "ESTS",                 \
-       [ELS_ESTC] =    "ESTC",                 \
-       [ELS_ADVC] =    "ADVC",                 \
-       [ELS_RTV] =     "RTV",                  \
-       [ELS_RLS] =     "RLS",                  \
-       [ELS_ECHO] =    "ECHO",                 \
-       [ELS_TEST] =    "TEST",                 \
-       [ELS_RRQ] =     "RRQ",                  \
-       [ELS_REC] =     "REC",                  \
-       [ELS_SRR] =     "SRR",                  \
-       [ELS_PRLI] =    "PRLI",                 \
-       [ELS_PRLO] =    "PRLO",                 \
-       [ELS_SCN] =     "SCN",                  \
-       [ELS_TPLS] =    "TPLS",                 \
-       [ELS_TPRLO] =   "TPRLO",                \
-       [ELS_LCLM] =    "LCLM",                 \
-       [ELS_GAID] =    "GAID",                 \
-       [ELS_FACT] =    "FACT",                 \
-       [ELS_FDACDT] =  "FDACDT",               \
-       [ELS_NACT] =    "NACT",                 \
-       [ELS_NDACT] =   "NDACT",                \
-       [ELS_QOSR] =    "QOSR",                 \
-       [ELS_RVCS] =    "RVCS",                 \
-       [ELS_PDISC] =   "PDISC",                \
-       [ELS_FDISC] =   "FDISC",                \
-       [ELS_ADISC] =   "ADISC",                \
-       [ELS_RNC] =     "RNC",                  \
-       [ELS_FARP_REQ] = "FARP_REQ",            \
-       [ELS_FARP_REPL] =  "FARP_REPL",         \
-       [ELS_RPS] =     "RPS",                  \
-       [ELS_RPL] =     "RPL",                  \
-       [ELS_RPBC] =    "RPBC",                 \
-       [ELS_FAN] =     "FAN",                  \
-       [ELS_RSCN] =    "RSCN",                 \
-       [ELS_SCR] =     "SCR",                  \
-       [ELS_RNFT] =    "RNFT",                 \
-       [ELS_CSR] =     "CSR",                  \
-       [ELS_CSU] =     "CSU",                  \
-       [ELS_LINIT] =   "LINIT",                \
-       [ELS_LSTS] =    "LSTS",                 \
-       [ELS_RNID] =    "RNID",                 \
-       [ELS_RLIR] =    "RLIR",                 \
-       [ELS_LIRR] =    "LIRR",                 \
-       [ELS_SRL] =     "SRL",                  \
-       [ELS_SBRP] =    "SBRP",                 \
-       [ELS_RPSC] =    "RPSC",                 \
-       [ELS_QSA] =     "QSA",                  \
-       [ELS_EVFP] =    "EVFP",                 \
-       [ELS_LKA] =     "LKA",                  \
-       [ELS_AUTH_ELS] = "AUTH_ELS",            \
-}
-
-/*
- * LS_ACC payload.
- */
-struct fc_els_ls_acc {
-       __u8          la_cmd;           /* command code ELS_LS_ACC */
-       __u8          la_resv[3];       /* reserved */
-};
-
-/*
- * ELS reject payload.
- */
-struct fc_els_ls_rjt {
-       __u8    er_cmd;         /* command code ELS_LS_RJT */
-       __u8    er_resv[4];     /* reserved must be zero */
-       __u8    er_reason;      /* reason (enum fc_els_rjt_reason below) */
-       __u8    er_explan;      /* explanation (enum fc_els_rjt_explan below) */
-       __u8    er_vendor;      /* vendor specific code */
-};
-
-/*
- * ELS reject reason codes (er_reason).
- */
-enum fc_els_rjt_reason {
-       ELS_RJT_NONE =          0,      /* no reject - not to be sent */
-       ELS_RJT_INVAL =         0x01,   /* invalid ELS command code */
-       ELS_RJT_LOGIC =         0x03,   /* logical error */
-       ELS_RJT_BUSY =          0x05,   /* logical busy */
-       ELS_RJT_PROT =          0x07,   /* protocol error */
-       ELS_RJT_UNAB =          0x09,   /* unable to perform command request */
-       ELS_RJT_UNSUP =         0x0b,   /* command not supported */
-       ELS_RJT_INPROG =        0x0e,   /* command already in progress */
-       ELS_RJT_FIP =           0x20,   /* FIP error */
-       ELS_RJT_VENDOR =        0xff,   /* vendor specific error */
-};
-
-
-/*
- * reason code explanation (er_explan).
- */
-enum fc_els_rjt_explan {
-       ELS_EXPL_NONE =         0x00,   /* No additional explanation */
-       ELS_EXPL_SPP_OPT_ERR =  0x01,   /* service parameter error - options */
-       ELS_EXPL_SPP_ICTL_ERR = 0x03,   /* service parm error - initiator ctl */
-       ELS_EXPL_AH =           0x11,   /* invalid association header */
-       ELS_EXPL_AH_REQ =       0x13,   /* association_header required */
-       ELS_EXPL_SID =          0x15,   /* invalid originator S_ID */
-       ELS_EXPL_OXID_RXID =    0x17,   /* invalid OX_ID-RX_ID combination */
-       ELS_EXPL_INPROG =       0x19,   /* Request already in progress */
-       ELS_EXPL_PLOGI_REQD =   0x1e,   /* N_Port login required */
-       ELS_EXPL_INSUF_RES =    0x29,   /* insufficient resources */
-       ELS_EXPL_UNAB_DATA =    0x2a,   /* unable to supply requested data */
-       ELS_EXPL_UNSUPR =       0x2c,   /* Request not supported */
-       ELS_EXPL_INV_LEN =      0x2d,   /* Invalid payload length */
-       ELS_EXPL_NOT_NEIGHBOR = 0x62,   /* VN2VN_Port not in neighbor set */
-       /* TBD - above definitions incomplete */
-};
-
-/*
- * Common service parameters (N ports).
- */
-struct fc_els_csp {
-       __u8            sp_hi_ver;      /* highest version supported (obs.) */
-       __u8            sp_lo_ver;      /* highest version supported (obs.) */
-       __be16          sp_bb_cred;     /* buffer-to-buffer credits */
-       __be16          sp_features;    /* common feature flags */
-       __be16          sp_bb_data;     /* b-b state number and data field sz */
-       union {
-               struct {
-                       __be16  _sp_tot_seq; /* total concurrent sequences */
-                       __be16  _sp_rel_off; /* rel. offset by info cat */
-               } sp_plogi;
-               struct {
-                       __be32  _sp_r_a_tov; /* resource alloc. timeout msec */
-               } sp_flogi_acc;
-       } sp_u;
-       __be32          sp_e_d_tov;     /* error detect timeout value */
-};
-#define        sp_tot_seq      sp_u.sp_plogi._sp_tot_seq
-#define        sp_rel_off      sp_u.sp_plogi._sp_rel_off
-#define        sp_r_a_tov      sp_u.sp_flogi_acc._sp_r_a_tov
-
-#define        FC_SP_BB_DATA_MASK 0xfff /* mask for data field size in sp_bb_data */
-
-/*
- * Minimum and maximum values for max data field size in service parameters.
- */
-#define        FC_SP_MIN_MAX_PAYLOAD   FC_MIN_MAX_PAYLOAD
-#define        FC_SP_MAX_MAX_PAYLOAD   FC_MAX_PAYLOAD
-
-/*
- * sp_features
- */
-#define        FC_SP_FT_NPIV   0x8000  /* multiple N_Port_ID support (FLOGI) */
-#define        FC_SP_FT_CIRO   0x8000  /* continuously increasing rel off (PLOGI) */
-#define        FC_SP_FT_CLAD   0x8000  /* clean address (in FLOGI LS_ACC) */
-#define        FC_SP_FT_RAND   0x4000  /* random relative offset */
-#define        FC_SP_FT_VAL    0x2000  /* valid vendor version level */
-#define        FC_SP_FT_NPIV_ACC       0x2000  /* NPIV assignment (FLOGI LS_ACC) */
-#define        FC_SP_FT_FPORT  0x1000  /* F port (1) vs. N port (0) */
-#define        FC_SP_FT_ABB    0x0800  /* alternate BB_credit management */
-#define        FC_SP_FT_EDTR   0x0400  /* E_D_TOV Resolution is nanoseconds */
-#define        FC_SP_FT_MCAST  0x0200  /* multicast */
-#define        FC_SP_FT_BCAST  0x0100  /* broadcast */
-#define        FC_SP_FT_HUNT   0x0080  /* hunt group */
-#define        FC_SP_FT_SIMP   0x0040  /* dedicated simplex */
-#define        FC_SP_FT_SEC    0x0020  /* reserved for security */
-#define        FC_SP_FT_CSYN   0x0010  /* clock synch. supported */
-#define        FC_SP_FT_RTTOV  0x0008  /* R_T_TOV value 100 uS, else 100 mS */
-#define        FC_SP_FT_HALF   0x0004  /* dynamic half duplex */
-#define        FC_SP_FT_SEQC   0x0002  /* SEQ_CNT */
-#define        FC_SP_FT_PAYL   0x0001  /* FLOGI payload length 256, else 116 */
-
-/*
- * Class-specific service parameters.
- */
-struct fc_els_cssp {
-       __be16          cp_class;       /* class flags */
-       __be16          cp_init;        /* initiator flags */
-       __be16          cp_recip;       /* recipient flags */
-       __be16          cp_rdfs;        /* receive data field size */
-       __be16          cp_con_seq;     /* concurrent sequences */
-       __be16          cp_ee_cred;     /* N-port end-to-end credit */
-       __u8            cp_resv1;       /* reserved */
-       __u8            cp_open_seq;    /* open sequences per exchange */
-       __u8            _cp_resv2[2];   /* reserved */
-};
-
-/*
- * cp_class flags.
- */
-#define        FC_CPC_VALID    0x8000          /* class valid */
-#define        FC_CPC_IMIX     0x4000          /* intermix mode */
-#define        FC_CPC_SEQ      0x0800          /* sequential delivery */
-#define        FC_CPC_CAMP     0x0200          /* camp-on */
-#define        FC_CPC_PRI      0x0080          /* priority */
-
-/*
- * cp_init flags.
- * (TBD: not all flags defined here).
- */
-#define        FC_CPI_CSYN     0x0010          /* clock synch. capable */
-
-/*
- * cp_recip flags.
- */
-#define        FC_CPR_CSYN     0x0008          /* clock synch. capable */
-
-/*
- * NFC_ELS_FLOGI: Fabric login request.
- * NFC_ELS_PLOGI: Port login request (same format).
- */
-struct fc_els_flogi {
-       __u8            fl_cmd;         /* command */
-       __u8            _fl_resvd[3];   /* must be zero */
-       struct fc_els_csp fl_csp;       /* common service parameters */
-       __be64          fl_wwpn;        /* port name */
-       __be64          fl_wwnn;        /* node name */
-       struct fc_els_cssp fl_cssp[4];  /* class 1-4 service parameters */
-       __u8            fl_vend[16];    /* vendor version level */
-} __attribute__((__packed__));
-
-/*
- * Process login service parameter page.
- */
-struct fc_els_spp {
-       __u8            spp_type;       /* type code or common service params */
-       __u8            spp_type_ext;   /* type code extension */
-       __u8            spp_flags;
-       __u8            _spp_resvd;
-       __be32          spp_orig_pa;    /* originator process associator */
-       __be32          spp_resp_pa;    /* responder process associator */
-       __be32          spp_params;     /* service parameters */
-};
-
-/*
- * spp_flags.
- */
-#define        FC_SPP_OPA_VAL      0x80        /* originator proc. assoc. valid */
-#define        FC_SPP_RPA_VAL      0x40        /* responder proc. assoc. valid */
-#define        FC_SPP_EST_IMG_PAIR 0x20        /* establish image pair */
-#define        FC_SPP_RESP_MASK    0x0f        /* mask for response code (below) */
-
-/*
- * SPP response code in spp_flags - lower 4 bits.
- */
-enum fc_els_spp_resp {
-       FC_SPP_RESP_ACK =       1,      /* request executed */
-       FC_SPP_RESP_RES =       2,      /* unable due to lack of resources */
-       FC_SPP_RESP_INIT =      3,      /* initialization not complete */
-       FC_SPP_RESP_NO_PA =     4,      /* unknown process associator */
-       FC_SPP_RESP_CONF =      5,      /* configuration precludes image pair */
-       FC_SPP_RESP_COND =      6,      /* request completed conditionally */
-       FC_SPP_RESP_MULT =      7,      /* unable to handle multiple SPPs */
-       FC_SPP_RESP_INVL =      8,      /* SPP is invalid */
-};
-
-/*
- * ELS_RRQ - Reinstate Recovery Qualifier
- */
-struct fc_els_rrq {
-       __u8            rrq_cmd;        /* command (0x12) */
-       __u8            rrq_zero[3];    /* specified as zero - part of cmd */
-       __u8            rrq_resvd;      /* reserved */
-       __u8            rrq_s_id[3];    /* originator FID */
-       __be16          rrq_ox_id;      /* originator exchange ID */
-       __be16          rrq_rx_id;      /* responders exchange ID */
-};
-
-/*
- * ELS_REC - Read exchange concise.
- */
-struct fc_els_rec {
-       __u8            rec_cmd;        /* command (0x13) */
-       __u8            rec_zero[3];    /* specified as zero - part of cmd */
-       __u8            rec_resvd;      /* reserved */
-       __u8            rec_s_id[3];    /* originator FID */
-       __be16          rec_ox_id;      /* originator exchange ID */
-       __be16          rec_rx_id;      /* responders exchange ID */
-};
-
-/*
- * ELS_REC LS_ACC payload.
- */
-struct fc_els_rec_acc {
-       __u8            reca_cmd;       /* accept (0x02) */
-       __u8            reca_zero[3];   /* specified as zero - part of cmd */
-       __be16          reca_ox_id;     /* originator exchange ID */
-       __be16          reca_rx_id;     /* responders exchange ID */
-       __u8            reca_resvd1;    /* reserved */
-       __u8            reca_ofid[3];   /* originator FID */
-       __u8            reca_resvd2;    /* reserved */
-       __u8            reca_rfid[3];   /* responder FID */
-       __be32          reca_fc4value;  /* FC4 value */
-       __be32          reca_e_stat;    /* ESB (exchange status block) status */
-};
-
-/*
- * ELS_PRLI - Process login request and response.
- */
-struct fc_els_prli {
-       __u8            prli_cmd;       /* command */
-       __u8            prli_spp_len;   /* length of each serv. parm. page */
-       __be16          prli_len;       /* length of entire payload */
-       /* service parameter pages follow */
-};
-
-/*
- * ELS_PRLO - Process logout request and response.
- */
-struct fc_els_prlo {
-       __u8            prlo_cmd;       /* command */
-       __u8            prlo_obs;       /* obsolete, but shall be set to 10h */
-       __be16          prlo_len;       /* payload length */
-};
-
-/*
- * ELS_ADISC payload
- */
-struct fc_els_adisc {
-       __u8            adisc_cmd;
-       __u8            adisc_resv[3];
-       __u8            adisc_resv1;
-       __u8            adisc_hard_addr[3];
-       __be64          adisc_wwpn;
-       __be64          adisc_wwnn;
-       __u8            adisc_resv2;
-       __u8            adisc_port_id[3];
-} __attribute__((__packed__));
-
-/*
- * ELS_LOGO - process or fabric logout.
- */
-struct fc_els_logo {
-       __u8            fl_cmd;         /* command code */
-       __u8            fl_zero[3];     /* specified as zero - part of cmd */
-       __u8            fl_resvd;       /* reserved */
-       __u8            fl_n_port_id[3];/* N port ID */
-       __be64          fl_n_port_wwn;  /* port name */
-};
-
-/*
- * ELS_RTV - read timeout value.
- */
-struct fc_els_rtv {
-       __u8            rtv_cmd;        /* command code 0x0e */
-       __u8            rtv_zero[3];    /* specified as zero - part of cmd */
-};
-
-/*
- * LS_ACC for ELS_RTV - read timeout value.
- */
-struct fc_els_rtv_acc {
-       __u8            rtv_cmd;        /* command code 0x02 */
-       __u8            rtv_zero[3];    /* specified as zero - part of cmd */
-       __be32          rtv_r_a_tov;    /* resource allocation timeout value */
-       __be32          rtv_e_d_tov;    /* error detection timeout value */
-       __be32          rtv_toq;        /* timeout qualifier (see below) */
-};
-
-/*
- * rtv_toq bits.
- */
-#define        FC_ELS_RTV_EDRES (1 << 26)      /* E_D_TOV resolution is nS else mS */
-#define        FC_ELS_RTV_RTTOV (1 << 19)      /* R_T_TOV is 100 uS else 100 mS */
-
-/*
- * ELS_SCR - state change registration payload.
- */
-struct fc_els_scr {
-       __u8            scr_cmd;        /* command code */
-       __u8            scr_resv[6];    /* reserved */
-       __u8            scr_reg_func;   /* registration function (see below) */
-};
-
-enum fc_els_scr_func {
-       ELS_SCRF_FAB =  1,      /* fabric-detected registration */
-       ELS_SCRF_NPORT = 2,     /* Nx_Port-detected registration */
-       ELS_SCRF_FULL = 3,      /* full registration */
-       ELS_SCRF_CLEAR = 255,   /* remove any current registrations */
-};
-
-/*
- * ELS_RSCN - registered state change notification payload.
- */
-struct fc_els_rscn {
-       __u8            rscn_cmd;       /* RSCN opcode (0x61) */
-       __u8            rscn_page_len;  /* page length (4) */
-       __be16          rscn_plen;      /* payload length including this word */
-
-       /* followed by 4-byte generic affected Port_ID pages */
-};
-
-struct fc_els_rscn_page {
-       __u8            rscn_page_flags; /* event and address format */
-       __u8            rscn_fid[3];    /* fabric ID */
-};
-
-#define        ELS_RSCN_EV_QUAL_BIT    2       /* shift count for event qualifier */
-#define        ELS_RSCN_EV_QUAL_MASK   0xf     /* mask for event qualifier */
-#define        ELS_RSCN_ADDR_FMT_BIT   0       /* shift count for address format */
-#define        ELS_RSCN_ADDR_FMT_MASK  0x3     /* mask for address format */
-
-enum fc_els_rscn_ev_qual {
-       ELS_EV_QUAL_NONE = 0,           /* unspecified */
-       ELS_EV_QUAL_NS_OBJ = 1,         /* changed name server object */
-       ELS_EV_QUAL_PORT_ATTR = 2,      /* changed port attribute */
-       ELS_EV_QUAL_SERV_OBJ = 3,       /* changed service object */
-       ELS_EV_QUAL_SW_CONFIG = 4,      /* changed switch configuration */
-       ELS_EV_QUAL_REM_OBJ = 5,        /* removed object */
-};
-
-enum fc_els_rscn_addr_fmt {
-       ELS_ADDR_FMT_PORT = 0,  /* rscn_fid is a port address */
-       ELS_ADDR_FMT_AREA = 1,  /* rscn_fid is a area address */
-       ELS_ADDR_FMT_DOM = 2,   /* rscn_fid is a domain address */
-       ELS_ADDR_FMT_FAB = 3,   /* anything on fabric may have changed */
-};
-
-/*
- * ELS_RNID - request Node ID.
- */
-struct fc_els_rnid {
-       __u8            rnid_cmd;       /* RNID opcode (0x78) */
-       __u8            rnid_resv[3];   /* reserved */
-       __u8            rnid_fmt;       /* data format */
-       __u8            rnid_resv2[3];  /* reserved */
-};
-
-/*
- * Node Identification Data formats (rnid_fmt)
- */
-enum fc_els_rnid_fmt {
-       ELS_RNIDF_NONE = 0,             /* no specific identification data */
-       ELS_RNIDF_GEN = 0xdf,           /* general topology discovery format */
-};
-
-/*
- * ELS_RNID response.
- */
-struct fc_els_rnid_resp {
-       __u8            rnid_cmd;       /* response code (LS_ACC) */
-       __u8            rnid_resv[3];   /* reserved */
-       __u8            rnid_fmt;       /* data format */
-       __u8            rnid_cid_len;   /* common ID data length */
-       __u8            rnid_resv2;     /* reserved */
-       __u8            rnid_sid_len;   /* specific ID data length */
-};
-
-struct fc_els_rnid_cid {
-       __be64          rnid_wwpn;      /* N port name */
-       __be64          rnid_wwnn;      /* node name */
-};
-
-struct fc_els_rnid_gen {
-       __u8            rnid_vend_id[16]; /* vendor-unique ID */
-       __be32          rnid_atype;     /* associated type (see below) */
-       __be32          rnid_phys_port; /* physical port number */
-       __be32          rnid_att_nodes; /* number of attached nodes */
-       __u8            rnid_node_mgmt; /* node management (see below) */
-       __u8            rnid_ip_ver;    /* IP version (see below) */
-       __be16          rnid_prot_port; /* UDP / TCP port number */
-       __be32          rnid_ip_addr[4]; /* IP address */
-       __u8            rnid_resvd[2];  /* reserved */
-       __be16          rnid_vend_spec; /* vendor-specific field */
-};
-
-enum fc_els_rnid_atype {
-       ELS_RNIDA_UNK =         0x01,   /* unknown */
-       ELS_RNIDA_OTHER =       0x02,   /* none of the following */
-       ELS_RNIDA_HUB =         0x03,
-       ELS_RNIDA_SWITCH =      0x04,
-       ELS_RNIDA_GATEWAY =     0x05,
-       ELS_RNIDA_CONV =        0x06,   /* Obsolete, do not use this value */
-       ELS_RNIDA_HBA =         0x07,   /* Obsolete, do not use this value */
-       ELS_RNIDA_PROXY =       0x08,   /* Obsolete, do not use this value */
-       ELS_RNIDA_STORAGE =     0x09,
-       ELS_RNIDA_HOST =        0x0a,
-       ELS_RNIDA_SUBSYS =      0x0b,   /* storage subsystem (e.g., RAID) */
-       ELS_RNIDA_ACCESS =      0x0e,   /* access device (e.g. media changer) */
-       ELS_RNIDA_NAS =         0x11,   /* NAS server */
-       ELS_RNIDA_BRIDGE =      0x12,   /* bridge */
-       ELS_RNIDA_VIRT =        0x13,   /* virtualization device */
-       ELS_RNIDA_MF =          0xff,   /* multifunction device (bits below) */
-       ELS_RNIDA_MF_HUB =      1UL << 31,      /* hub */
-       ELS_RNIDA_MF_SW =       1UL << 30,      /* switch */
-       ELS_RNIDA_MF_GW =       1UL << 29,      /* gateway */
-       ELS_RNIDA_MF_ST =       1UL << 28,      /* storage */
-       ELS_RNIDA_MF_HOST =     1UL << 27,      /* host */
-       ELS_RNIDA_MF_SUB =      1UL << 26,      /* storage subsystem */
-       ELS_RNIDA_MF_ACC =      1UL << 25,      /* storage access dev */
-       ELS_RNIDA_MF_WDM =      1UL << 24,      /* wavelength division mux */
-       ELS_RNIDA_MF_NAS =      1UL << 23,      /* NAS server */
-       ELS_RNIDA_MF_BR =       1UL << 22,      /* bridge */
-       ELS_RNIDA_MF_VIRT =     1UL << 21,      /* virtualization device */
-};
-
-enum fc_els_rnid_mgmt {
-       ELS_RNIDM_SNMP =        0,
-       ELS_RNIDM_TELNET =      1,
-       ELS_RNIDM_HTTP =        2,
-       ELS_RNIDM_HTTPS =       3,
-       ELS_RNIDM_XML =         4,      /* HTTP + XML */
-};
-
-enum fc_els_rnid_ipver {
-       ELS_RNIDIP_NONE =       0,      /* no IP support or node mgmt. */
-       ELS_RNIDIP_V4 =         1,      /* IPv4 */
-       ELS_RNIDIP_V6 =         2,      /* IPv6 */
-};
-
-/*
- * ELS RPL - Read Port List.
- */
-struct fc_els_rpl {
-       __u8            rpl_cmd;        /* command */
-       __u8            rpl_resv[5];    /* reserved - must be zero */
-       __be16          rpl_max_size;   /* maximum response size or zero */
-       __u8            rpl_resv1;      /* reserved - must be zero */
-       __u8            rpl_index[3];   /* starting index */
-};
-
-/*
- * Port number block in RPL response.
- */
-struct fc_els_pnb {
-       __be32          pnb_phys_pn;    /* physical port number */
-       __u8            pnb_resv;       /* reserved */
-       __u8            pnb_port_id[3]; /* port ID */
-       __be64          pnb_wwpn;       /* port name */
-};
-
-/*
- * RPL LS_ACC response.
- */
-struct fc_els_rpl_resp {
-       __u8            rpl_cmd;        /* ELS_LS_ACC */
-       __u8            rpl_resv1;      /* reserved - must be zero */
-       __be16          rpl_plen;       /* payload length */
-       __u8            rpl_resv2;      /* reserved - must be zero */
-       __u8            rpl_llen[3];    /* list length */
-       __u8            rpl_resv3;      /* reserved - must be zero */
-       __u8            rpl_index[3];   /* starting index */
-       struct fc_els_pnb rpl_pnb[1];   /* variable number of PNBs */
-};
-
-/*
- * Link Error Status Block.
- */
-struct fc_els_lesb {
-       __be32          lesb_link_fail; /* link failure count */
-       __be32          lesb_sync_loss; /* loss of synchronization count */
-       __be32          lesb_sig_loss;  /* loss of signal count */
-       __be32          lesb_prim_err;  /* primitive sequence error count */
-       __be32          lesb_inv_word;  /* invalid transmission word count */
-       __be32          lesb_inv_crc;   /* invalid CRC count */
-};
-
-/*
- * ELS RPS - Read Port Status Block request.
- */
-struct fc_els_rps {
-       __u8            rps_cmd;        /* command */
-       __u8            rps_resv[2];    /* reserved - must be zero */
-       __u8            rps_flag;       /* flag - see below */
-       __be64          rps_port_spec;  /* port selection */
-};
-
-enum fc_els_rps_flag {
-       FC_ELS_RPS_DID =        0x00,   /* port identified by D_ID of req. */
-       FC_ELS_RPS_PPN =        0x01,   /* port_spec is physical port number */
-       FC_ELS_RPS_WWPN =       0x02,   /* port_spec is port WWN */
-};
-
-/*
- * ELS RPS LS_ACC response.
- */
-struct fc_els_rps_resp {
-       __u8            rps_cmd;        /* command - LS_ACC */
-       __u8            rps_resv[2];    /* reserved - must be zero */
-       __u8            rps_flag;       /* flag - see below */
-       __u8            rps_resv2[2];   /* reserved */
-       __be16          rps_status;     /* port status - see below */
-       struct fc_els_lesb rps_lesb;    /* link error status block */
-};
-
-enum fc_els_rps_resp_flag {
-       FC_ELS_RPS_LPEV =       0x01,   /* L_port extension valid */
-};
-
-enum fc_els_rps_resp_status {
-       FC_ELS_RPS_PTP =        1 << 5, /* point-to-point connection */
-       FC_ELS_RPS_LOOP =       1 << 4, /* loop mode */
-       FC_ELS_RPS_FAB =        1 << 3, /* fabric present */
-       FC_ELS_RPS_NO_SIG =     1 << 2, /* loss of signal */
-       FC_ELS_RPS_NO_SYNC =    1 << 1, /* loss of synchronization */
-       FC_ELS_RPS_RESET =      1 << 0, /* in link reset protocol */
-};
-
-/*
- * ELS LIRR - Link Incident Record Registration request.
- */
-struct fc_els_lirr {
-       __u8            lirr_cmd;       /* command */
-       __u8            lirr_resv[3];   /* reserved - must be zero */
-       __u8            lirr_func;      /* registration function */
-       __u8            lirr_fmt;       /* FC-4 type of RLIR requested */
-       __u8            lirr_resv2[2];  /* reserved - must be zero */
-};
-
-enum fc_els_lirr_func {
-       ELS_LIRR_SET_COND =     0x01,   /* set - conditionally receive */
-       ELS_LIRR_SET_UNCOND =   0x02,   /* set - unconditionally receive */
-       ELS_LIRR_CLEAR =        0xff    /* clear registration */
-};
-
-/*
- * ELS SRL - Scan Remote Loop request.
- */
-struct fc_els_srl {
-       __u8            srl_cmd;        /* command */
-       __u8            srl_resv[3];    /* reserved - must be zero */
-       __u8            srl_flag;       /* flag - see below */
-       __u8            srl_flag_param[3];      /* flag parameter */
-};
-
-enum fc_els_srl_flag {
-       FC_ELS_SRL_ALL =        0x00,   /* scan all FL ports */
-       FC_ELS_SRL_ONE =        0x01,   /* scan specified loop */
-       FC_ELS_SRL_EN_PER =     0x02,   /* enable periodic scanning (param) */
-       FC_ELS_SRL_DIS_PER =    0x03,   /* disable periodic scanning */
-};
-
-/*
- * ELS RLS - Read Link Error Status Block request.
- */
-struct fc_els_rls {
-       __u8            rls_cmd;        /* command */
-       __u8            rls_resv[4];    /* reserved - must be zero */
-       __u8            rls_port_id[3]; /* port ID */
-};
-
-/*
- * ELS RLS LS_ACC Response.
- */
-struct fc_els_rls_resp {
-       __u8            rls_cmd;        /* ELS_LS_ACC */
-       __u8            rls_resv[3];    /* reserved - must be zero */
-       struct fc_els_lesb rls_lesb;    /* link error status block */
-};
-
-/*
- * ELS RLIR - Registered Link Incident Report.
- * This is followed by the CLIR and the CLID, described below.
- */
-struct fc_els_rlir {
-       __u8            rlir_cmd;       /* command */
-       __u8            rlir_resv[3];   /* reserved - must be zero */
-       __u8            rlir_fmt;       /* format (FC4-type if type specific) */
-       __u8            rlir_clr_len;   /* common link incident record length */
-       __u8            rlir_cld_len;   /* common link incident desc. length */
-       __u8            rlir_slr_len;   /* spec. link incident record length */
-};
-
-/*
- * CLIR - Common Link Incident Record Data. - Sent via RLIR.
- */
-struct fc_els_clir {
-       __be64          clir_wwpn;      /* incident port name */
-       __be64          clir_wwnn;      /* incident port node name */
-       __u8            clir_port_type; /* incident port type */
-       __u8            clir_port_id[3];        /* incident port ID */
-
-       __be64          clir_conn_wwpn; /* connected port name */
-       __be64          clir_conn_wwnn; /* connected node name */
-       __be64          clir_fab_name;  /* fabric name */
-       __be32          clir_phys_port; /* physical port number */
-       __be32          clir_trans_id;  /* transaction ID */
-       __u8            clir_resv[3];   /* reserved */
-       __u8            clir_ts_fmt;    /* time stamp format */
-       __be64          clir_timestamp; /* time stamp */
-};
-
-/*
- * CLIR clir_ts_fmt - time stamp format values.
- */
-enum fc_els_clir_ts_fmt {
-       ELS_CLIR_TS_UNKNOWN =   0,      /* time stamp field unknown */
-       ELS_CLIR_TS_SEC_FRAC =  1,      /* time in seconds and fractions */
-       ELS_CLIR_TS_CSU =       2,      /* time in clock synch update format */
-};
-
-/*
- * Common Link Incident Descriptor - sent via RLIR.
- */
-struct fc_els_clid {
-       __u8            clid_iq;        /* incident qualifier flags */
-       __u8            clid_ic;        /* incident code */
-       __be16          clid_epai;      /* domain/area of ISL */
-};
-
-/*
- * CLID incident qualifier flags.
- */
-enum fc_els_clid_iq {
-       ELS_CLID_SWITCH =       0x20,   /* incident port is a switch node */
-       ELS_CLID_E_PORT =       0x10,   /* incident is an ISL (E) port */
-       ELS_CLID_SEV_MASK =     0x0c,   /* severity 2-bit field mask */
-       ELS_CLID_SEV_INFO =     0x00,   /* report is informational */
-       ELS_CLID_SEV_INOP =     0x08,   /* link not operational */
-       ELS_CLID_SEV_DEG =      0x04,   /* link degraded but operational */
-       ELS_CLID_LASER =        0x02,   /* subassembly is a laser */
-       ELS_CLID_FRU =          0x01,   /* format can identify a FRU */
-};
-
-/*
- * CLID incident code.
- */
-enum fc_els_clid_ic {
-       ELS_CLID_IC_IMPL =      1,      /* implicit incident */
-       ELS_CLID_IC_BER =       2,      /* bit-error-rate threshold exceeded */
-       ELS_CLID_IC_LOS =       3,      /* loss of synch or signal */
-       ELS_CLID_IC_NOS =       4,      /* non-operational primitive sequence */
-       ELS_CLID_IC_PST =       5,      /* primitive sequence timeout */
-       ELS_CLID_IC_INVAL =     6,      /* invalid primitive sequence */
-       ELS_CLID_IC_LOOP_TO =   7,      /* loop initialization time out */
-       ELS_CLID_IC_LIP =       8,      /* receiving LIP */
-};
-
-#endif /* _FC_ELS_H_ */
diff --git a/include/scsi/fc/fc_fs.h b/include/scsi/fc/fc_fs.h
deleted file mode 100644 (file)
index 50f28b1..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright(c) 2007 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained at www.Open-FCoE.org
- */
-
-#ifndef _FC_FS_H_
-#define _FC_FS_H_
-
-#include <linux/types.h>
-
-/*
- * Fibre Channel Framing and Signalling definitions.
- * From T11 FC-FS-2 Rev 0.90 - 9 August 2005.
- */
-
-/*
- * Frame header
- */
-struct fc_frame_header {
-       __u8          fh_r_ctl; /* routing control */
-       __u8          fh_d_id[3];       /* Destination ID */
-
-       __u8          fh_cs_ctl;        /* class of service control / pri */
-       __u8          fh_s_id[3];       /* Source ID */
-
-       __u8          fh_type;          /* see enum fc_fh_type below */
-       __u8          fh_f_ctl[3];      /* frame control */
-
-       __u8          fh_seq_id;        /* sequence ID */
-       __u8          fh_df_ctl;        /* data field control */
-       __be16        fh_seq_cnt;       /* sequence count */
-
-       __be16        fh_ox_id;         /* originator exchange ID */
-       __be16        fh_rx_id;         /* responder exchange ID */
-       __be32        fh_parm_offset;   /* parameter or relative offset */
-};
-
-#define FC_FRAME_HEADER_LEN 24 /* expected length of structure */
-
-#define FC_MAX_PAYLOAD  2112U          /* max payload length in bytes */
-#define FC_MIN_MAX_PAYLOAD  256U       /* lower limit on max payload */
-
-#define FC_MAX_FRAME   (FC_MAX_PAYLOAD + FC_FRAME_HEADER_LEN)
-#define FC_MIN_MAX_FRAME (FC_MIN_MAX_PAYLOAD + FC_FRAME_HEADER_LEN)
-
-/*
- * fh_r_ctl - Routing control definitions.
- */
-    /*
-     * FC-4 device_data.
-     */
-enum fc_rctl {
-       FC_RCTL_DD_UNCAT = 0x00,        /* uncategorized information */
-       FC_RCTL_DD_SOL_DATA = 0x01,     /* solicited data */
-       FC_RCTL_DD_UNSOL_CTL = 0x02,    /* unsolicited control */
-       FC_RCTL_DD_SOL_CTL = 0x03,      /* solicited control or reply */
-       FC_RCTL_DD_UNSOL_DATA = 0x04,   /* unsolicited data */
-       FC_RCTL_DD_DATA_DESC = 0x05,    /* data descriptor */
-       FC_RCTL_DD_UNSOL_CMD = 0x06,    /* unsolicited command */
-       FC_RCTL_DD_CMD_STATUS = 0x07,   /* command status */
-
-#define FC_RCTL_ILS_REQ FC_RCTL_DD_UNSOL_CTL   /* ILS request */
-#define FC_RCTL_ILS_REP FC_RCTL_DD_SOL_CTL     /* ILS reply */
-
-       /*
-        * Extended Link_Data
-        */
-       FC_RCTL_ELS_REQ = 0x22, /* extended link services request */
-       FC_RCTL_ELS_REP = 0x23, /* extended link services reply */
-       FC_RCTL_ELS4_REQ = 0x32, /* FC-4 ELS request */
-       FC_RCTL_ELS4_REP = 0x33, /* FC-4 ELS reply */
-       /*
-        * Optional Extended Headers
-        */
-       FC_RCTL_VFTH = 0x50,    /* virtual fabric tagging header */
-       FC_RCTL_IFRH = 0x51,    /* inter-fabric routing header */
-       FC_RCTL_ENCH = 0x52,    /* encapsulation header */
-       /*
-        * Basic Link Services fh_r_ctl values.
-        */
-       FC_RCTL_BA_NOP = 0x80,  /* basic link service NOP */
-       FC_RCTL_BA_ABTS = 0x81, /* basic link service abort */
-       FC_RCTL_BA_RMC = 0x82,  /* remove connection */
-       FC_RCTL_BA_ACC = 0x84,  /* basic accept */
-       FC_RCTL_BA_RJT = 0x85,  /* basic reject */
-       FC_RCTL_BA_PRMT = 0x86, /* dedicated connection preempted */
-       /*
-        * Link Control Information.
-        */
-       FC_RCTL_ACK_1 = 0xc0,   /* acknowledge_1 */
-       FC_RCTL_ACK_0 = 0xc1,   /* acknowledge_0 */
-       FC_RCTL_P_RJT = 0xc2,   /* port reject */
-       FC_RCTL_F_RJT = 0xc3,   /* fabric reject */
-       FC_RCTL_P_BSY = 0xc4,   /* port busy */
-       FC_RCTL_F_BSY = 0xc5,   /* fabric busy to data frame */
-       FC_RCTL_F_BSYL = 0xc6,  /* fabric busy to link control frame */
-       FC_RCTL_LCR = 0xc7,     /* link credit reset */
-       FC_RCTL_END = 0xc9,     /* end */
-};
-                                   /* incomplete list of definitions */
-
-/*
- * R_CTL names initializer.
- * Please keep this matching the above definitions.
- */
-#define FC_RCTL_NAMES_INIT { \
-       [FC_RCTL_DD_UNCAT] =            "uncat",                        \
-       [FC_RCTL_DD_SOL_DATA] =         "sol data",                     \
-       [FC_RCTL_DD_UNSOL_CTL] =        "unsol ctl",                    \
-       [FC_RCTL_DD_SOL_CTL] =          "sol ctl/reply",                \
-       [FC_RCTL_DD_UNSOL_DATA] =       "unsol data",                   \
-       [FC_RCTL_DD_DATA_DESC] =        "data desc",                    \
-       [FC_RCTL_DD_UNSOL_CMD] =        "unsol cmd",                    \
-       [FC_RCTL_DD_CMD_STATUS] =       "cmd status",                   \
-       [FC_RCTL_ELS_REQ] =             "ELS req",                      \
-       [FC_RCTL_ELS_REP] =             "ELS rep",                      \
-       [FC_RCTL_ELS4_REQ] =            "FC-4 ELS req",                 \
-       [FC_RCTL_ELS4_REP] =            "FC-4 ELS rep",                 \
-       [FC_RCTL_BA_NOP] =              "BLS NOP",                      \
-       [FC_RCTL_BA_ABTS] =             "BLS abort",                    \
-       [FC_RCTL_BA_RMC] =              "BLS remove connection",        \
-       [FC_RCTL_BA_ACC] =              "BLS accept",                   \
-       [FC_RCTL_BA_RJT] =              "BLS reject",                   \
-       [FC_RCTL_BA_PRMT] =             "BLS dedicated connection preempted", \
-       [FC_RCTL_ACK_1] =               "LC ACK_1",                     \
-       [FC_RCTL_ACK_0] =               "LC ACK_0",                     \
-       [FC_RCTL_P_RJT] =               "LC port reject",               \
-       [FC_RCTL_F_RJT] =               "LC fabric reject",             \
-       [FC_RCTL_P_BSY] =               "LC port busy",                 \
-       [FC_RCTL_F_BSY] =               "LC fabric busy to data frame", \
-       [FC_RCTL_F_BSYL] =              "LC fabric busy to link control frame",\
-       [FC_RCTL_LCR] =                 "LC link credit reset",         \
-       [FC_RCTL_END] =                 "LC end",                       \
-}
-
-/*
- * Well-known fabric addresses.
- */
-enum fc_well_known_fid {
-       FC_FID_NONE =           0x000000,       /* No destination */
-       FC_FID_BCAST =          0xffffff,       /* broadcast */
-       FC_FID_FLOGI =          0xfffffe,       /* fabric login */
-       FC_FID_FCTRL =          0xfffffd,       /* fabric controller */
-       FC_FID_DIR_SERV =       0xfffffc,       /* directory server */
-       FC_FID_TIME_SERV =      0xfffffb,       /* time server */
-       FC_FID_MGMT_SERV =      0xfffffa,       /* management server */
-       FC_FID_QOS =            0xfffff9,       /* QoS Facilitator */
-       FC_FID_ALIASES =        0xfffff8,       /* alias server (FC-PH2) */
-       FC_FID_SEC_KEY =        0xfffff7,       /* Security key dist. server */
-       FC_FID_CLOCK =          0xfffff6,       /* clock synch server */
-       FC_FID_MCAST_SERV =     0xfffff5,       /* multicast server */
-};
-
-#define        FC_FID_WELL_KNOWN_MAX   0xffffff /* highest well-known fabric ID */
-#define        FC_FID_WELL_KNOWN_BASE  0xfffff5 /* start of well-known fabric ID */
-
-/*
- * Other well-known addresses, outside the above contiguous range.
- */
-#define        FC_FID_DOM_MGR          0xfffc00        /* domain manager base */
-
-/*
- * Fabric ID bytes.
- */
-#define        FC_FID_DOMAIN           0
-#define        FC_FID_PORT             1
-#define        FC_FID_LINK             2
-
-/*
- * fh_type codes
- */
-enum fc_fh_type {
-       FC_TYPE_BLS =   0x00,   /* basic link service */
-       FC_TYPE_ELS =   0x01,   /* extended link service */
-       FC_TYPE_IP =    0x05,   /* IP over FC, RFC 4338 */
-       FC_TYPE_FCP =   0x08,   /* SCSI FCP */
-       FC_TYPE_CT =    0x20,   /* Fibre Channel Services (FC-CT) */
-       FC_TYPE_ILS =   0x22,   /* internal link service */
-};
-
-/*
- * FC_TYPE names initializer.
- * Please keep this matching the above definitions.
- */
-#define FC_TYPE_NAMES_INIT {                           \
-       [FC_TYPE_BLS] =         "BLS",                  \
-       [FC_TYPE_ELS] =         "ELS",                  \
-       [FC_TYPE_IP] =          "IP",                   \
-       [FC_TYPE_FCP] =         "FCP",                  \
-       [FC_TYPE_CT] =          "CT",                   \
-       [FC_TYPE_ILS] =         "ILS",                  \
-}
-
-/*
- * Exchange IDs.
- */
-#define FC_XID_UNKNOWN  0xffff /* unknown exchange ID */
-#define FC_XID_MIN     0x0     /* supported min exchange ID */
-#define FC_XID_MAX     0xfffe  /* supported max exchange ID */
-
-/*
- * fh_f_ctl - Frame control flags.
- */
-#define        FC_FC_EX_CTX    (1 << 23)       /* sent by responder to exchange */
-#define        FC_FC_SEQ_CTX   (1 << 22)       /* sent by responder to sequence */
-#define        FC_FC_FIRST_SEQ (1 << 21)       /* first sequence of this exchange */
-#define        FC_FC_LAST_SEQ  (1 << 20)       /* last sequence of this exchange */
-#define        FC_FC_END_SEQ   (1 << 19)       /* last frame of sequence */
-#define        FC_FC_END_CONN  (1 << 18)       /* end of class 1 connection pending */
-#define        FC_FC_RES_B17   (1 << 17)       /* reserved */
-#define        FC_FC_SEQ_INIT  (1 << 16)       /* transfer of sequence initiative */
-#define        FC_FC_X_ID_REASS (1 << 15)      /* exchange ID has been changed */
-#define        FC_FC_X_ID_INVAL (1 << 14)      /* exchange ID invalidated */
-
-#define        FC_FC_ACK_1     (1 << 12)       /* 13:12 = 1: ACK_1 expected */
-#define        FC_FC_ACK_N     (2 << 12)       /* 13:12 = 2: ACK_N expected */
-#define        FC_FC_ACK_0     (3 << 12)       /* 13:12 = 3: ACK_0 expected */
-
-#define        FC_FC_RES_B11   (1 << 11)       /* reserved */
-#define        FC_FC_RES_B10   (1 << 10)       /* reserved */
-#define        FC_FC_RETX_SEQ  (1 << 9)        /* retransmitted sequence */
-#define        FC_FC_UNI_TX    (1 << 8)        /* unidirectional transmit (class 1) */
-#define        FC_FC_CONT_SEQ(i) ((i) << 6)
-#define        FC_FC_ABT_SEQ(i) ((i) << 4)
-#define        FC_FC_REL_OFF   (1 << 3)        /* parameter is relative offset */
-#define        FC_FC_RES2      (1 << 2)        /* reserved */
-#define        FC_FC_FILL(i)   ((i) & 3)       /* 1:0: bytes of trailing fill */
-
-/*
- * BA_ACC payload.
- */
-struct fc_ba_acc {
-       __u8            ba_seq_id_val;  /* SEQ_ID validity */
-#define FC_BA_SEQ_ID_VAL 0x80
-       __u8            ba_seq_id;      /* SEQ_ID of seq last deliverable */
-       __u8            ba_resvd[2];    /* reserved */
-       __be16          ba_ox_id;       /* OX_ID for aborted seq or exch */
-       __be16          ba_rx_id;       /* RX_ID for aborted seq or exch */
-       __be16          ba_low_seq_cnt; /* low SEQ_CNT of aborted seq */
-       __be16          ba_high_seq_cnt; /* high SEQ_CNT of aborted seq */
-};
-
-/*
- * BA_RJT: Basic Reject payload.
- */
-struct fc_ba_rjt {
-       __u8            br_resvd;       /* reserved */
-       __u8            br_reason;      /* reason code */
-       __u8            br_explan;      /* reason explanation */
-       __u8            br_vendor;      /* vendor unique code */
-};
-
-/*
- * BA_RJT reason codes.
- * From FS-2.
- */
-enum fc_ba_rjt_reason {
-       FC_BA_RJT_NONE =        0,      /* in software this means no reject */
-       FC_BA_RJT_INVL_CMD =    0x01,   /* invalid command code */
-       FC_BA_RJT_LOG_ERR =     0x03,   /* logical error */
-       FC_BA_RJT_LOG_BUSY =    0x05,   /* logical busy */
-       FC_BA_RJT_PROTO_ERR =   0x07,   /* protocol error */
-       FC_BA_RJT_UNABLE =      0x09,   /* unable to perform request */
-       FC_BA_RJT_VENDOR =      0xff,   /* vendor-specific (see br_vendor) */
-};
-
-/*
- * BA_RJT reason code explanations.
- */
-enum fc_ba_rjt_explan {
-       FC_BA_RJT_EXP_NONE =    0x00,   /* no additional expanation */
-       FC_BA_RJT_INV_XID =     0x03,   /* invalid OX_ID-RX_ID combination */
-       FC_BA_RJT_ABT =         0x05,   /* sequence aborted, no seq info */
-};
-
-/*
- * P_RJT or F_RJT: Port Reject or Fabric Reject parameter field.
- */
-struct fc_pf_rjt {
-       __u8            rj_action;      /* reserved */
-       __u8            rj_reason;      /* reason code */
-       __u8            rj_resvd;       /* reserved */
-       __u8            rj_vendor;      /* vendor unique code */
-};
-
-/*
- * P_RJT and F_RJT reject reason codes.
- */
-enum fc_pf_rjt_reason {
-       FC_RJT_NONE =           0,      /* non-reject (reserved by standard) */
-       FC_RJT_INVL_DID =       0x01,   /* invalid destination ID */
-       FC_RJT_INVL_SID =       0x02,   /* invalid source ID */
-       FC_RJT_P_UNAV_T =       0x03,   /* port unavailable, temporary */
-       FC_RJT_P_UNAV =         0x04,   /* port unavailable, permanent */
-       FC_RJT_CLS_UNSUP =      0x05,   /* class not supported */
-       FC_RJT_DEL_USAGE =      0x06,   /* delimiter usage error */
-       FC_RJT_TYPE_UNSUP =     0x07,   /* type not supported */
-       FC_RJT_LINK_CTL =       0x08,   /* invalid link control */
-       FC_RJT_R_CTL =          0x09,   /* invalid R_CTL field */
-       FC_RJT_F_CTL =          0x0a,   /* invalid F_CTL field */
-       FC_RJT_OX_ID =          0x0b,   /* invalid originator exchange ID */
-       FC_RJT_RX_ID =          0x0c,   /* invalid responder exchange ID */
-       FC_RJT_SEQ_ID =         0x0d,   /* invalid sequence ID */
-       FC_RJT_DF_CTL =         0x0e,   /* invalid DF_CTL field */
-       FC_RJT_SEQ_CNT =        0x0f,   /* invalid SEQ_CNT field */
-       FC_RJT_PARAM =          0x10,   /* invalid parameter field */
-       FC_RJT_EXCH_ERR =       0x11,   /* exchange error */
-       FC_RJT_PROTO =          0x12,   /* protocol error */
-       FC_RJT_LEN =            0x13,   /* incorrect length */
-       FC_RJT_UNEXP_ACK =      0x14,   /* unexpected ACK */
-       FC_RJT_FAB_CLASS =      0x15,   /* class unsupported by fabric entity */
-       FC_RJT_LOGI_REQ =       0x16,   /* login required */
-       FC_RJT_SEQ_XS =         0x17,   /* excessive sequences attempted */
-       FC_RJT_EXCH_EST =       0x18,   /* unable to establish exchange */
-       FC_RJT_FAB_UNAV =       0x1a,   /* fabric unavailable */
-       FC_RJT_VC_ID =          0x1b,   /* invalid VC_ID (class 4) */
-       FC_RJT_CS_CTL =         0x1c,   /* invalid CS_CTL field */
-       FC_RJT_INSUF_RES =      0x1d,   /* insuff. resources for VC (Class 4) */
-       FC_RJT_INVL_CLS =       0x1f,   /* invalid class of service */
-       FC_RJT_PREEMT_RJT =     0x20,   /* preemption request rejected */
-       FC_RJT_PREEMT_DIS =     0x21,   /* preemption not enabled */
-       FC_RJT_MCAST_ERR =      0x22,   /* multicast error */
-       FC_RJT_MCAST_ET =       0x23,   /* multicast error terminate */
-       FC_RJT_PRLI_REQ =       0x24,   /* process login required */
-       FC_RJT_INVL_ATT =       0x25,   /* invalid attachment */
-       FC_RJT_VENDOR =         0xff,   /* vendor specific reject */
-};
-
-/* default timeout values */
-
-#define FC_DEF_E_D_TOV 2000UL
-#define FC_DEF_R_A_TOV 10000UL
-
-#endif /* _FC_FS_H_ */
diff --git a/include/scsi/fc/fc_gs.h b/include/scsi/fc/fc_gs.h
deleted file mode 100644 (file)
index a37346d..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright(c) 2007 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained at www.Open-FCoE.org
- */
-
-#ifndef _FC_GS_H_
-#define        _FC_GS_H_
-
-#include <linux/types.h>
-
-/*
- * Fibre Channel Services - Common Transport.
- * From T11.org FC-GS-2 Rev 5.3 November 1998.
- */
-
-struct fc_ct_hdr {
-       __u8            ct_rev;         /* revision */
-       __u8            ct_in_id[3];    /* N_Port ID of original requestor */
-       __u8            ct_fs_type;     /* type of fibre channel service */
-       __u8            ct_fs_subtype;  /* subtype */
-       __u8            ct_options;
-       __u8            _ct_resvd1;
-       __be16          ct_cmd;         /* command / response code */
-       __be16          ct_mr_size;     /* maximum / residual size */
-       __u8            _ct_resvd2;
-       __u8            ct_reason;      /* reject reason */
-       __u8            ct_explan;      /* reason code explanation */
-       __u8            ct_vendor;      /* vendor unique data */
-};
-
-#define        FC_CT_HDR_LEN   16      /* expected sizeof (struct fc_ct_hdr) */
-
-enum fc_ct_rev {
-       FC_CT_REV = 1           /* common transport revision */
-};
-
-/*
- * ct_fs_type values.
- */
-enum fc_ct_fs_type {
-       FC_FST_ALIAS =  0xf8,   /* alias service */
-       FC_FST_MGMT =   0xfa,   /* management service */
-       FC_FST_TIME =   0xfb,   /* time service */
-       FC_FST_DIR =    0xfc,   /* directory service */
-};
-
-/*
- * ct_cmd: Command / response codes
- */
-enum fc_ct_cmd {
-       FC_FS_RJT =     0x8001, /* reject */
-       FC_FS_ACC =     0x8002, /* accept */
-};
-
-/*
- * FS_RJT reason codes.
- */
-enum fc_ct_reason {
-       FC_FS_RJT_CMD =         0x01,   /* invalid command code */
-       FC_FS_RJT_VER =         0x02,   /* invalid version level */
-       FC_FS_RJT_LOG =         0x03,   /* logical error */
-       FC_FS_RJT_IUSIZ =       0x04,   /* invalid IU size */
-       FC_FS_RJT_BSY =         0x05,   /* logical busy */
-       FC_FS_RJT_PROTO =       0x07,   /* protocol error */
-       FC_FS_RJT_UNABL =       0x09,   /* unable to perform command request */
-       FC_FS_RJT_UNSUP =       0x0b,   /* command not supported */
-};
-
-/*
- * FS_RJT reason code explanations.
- */
-enum fc_ct_explan {
-       FC_FS_EXP_NONE =        0x00,   /* no additional explanation */
-       FC_FS_EXP_PID =         0x01,   /* port ID not registered */
-       FC_FS_EXP_PNAM =        0x02,   /* port name not registered */
-       FC_FS_EXP_NNAM =        0x03,   /* node name not registered */
-       FC_FS_EXP_COS =         0x04,   /* class of service not registered */
-       FC_FS_EXP_FTNR =        0x07,   /* FC-4 types not registered */
-       /* definitions not complete */
-};
-
-#endif /* _FC_GS_H_ */
diff --git a/include/scsi/fc/fc_ns.h b/include/scsi/fc/fc_ns.h
deleted file mode 100644 (file)
index f7751d5..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright(c) 2007 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained at www.Open-FCoE.org
- */
-
-#ifndef _FC_NS_H_
-#define        _FC_NS_H_
-
-#include <linux/types.h>
-
-/*
- * Fibre Channel Services - Name Service (dNS)
- * From T11.org FC-GS-2 Rev 5.3 November 1998.
- */
-
-/*
- * Common-transport sub-type for Name Server.
- */
-#define        FC_NS_SUBTYPE       2   /* fs_ct_hdr.ct_fs_subtype */
-
-/*
- * Name server Requests.
- * Note:  this is an incomplete list, some unused requests are omitted.
- */
-enum fc_ns_req {
-       FC_NS_GA_NXT =  0x0100,         /* get all next */
-       FC_NS_GI_A =    0x0101,         /* get identifiers - scope */
-       FC_NS_GPN_ID =  0x0112,         /* get port name by ID */
-       FC_NS_GNN_ID =  0x0113,         /* get node name by ID */
-       FC_NS_GSPN_ID = 0x0118,         /* get symbolic port name */
-       FC_NS_GID_PN =  0x0121,         /* get ID for port name */
-       FC_NS_GID_NN =  0x0131,         /* get IDs for node name */
-       FC_NS_GID_FT =  0x0171,         /* get IDs by FC4 type */
-       FC_NS_GPN_FT =  0x0172,         /* get port names by FC4 type */
-       FC_NS_GID_PT =  0x01a1,         /* get IDs by port type */
-       FC_NS_RPN_ID =  0x0212,         /* reg port name for ID */
-       FC_NS_RNN_ID =  0x0213,         /* reg node name for ID */
-       FC_NS_RFT_ID =  0x0217,         /* reg FC4 type for ID */
-       FC_NS_RSPN_ID = 0x0218,         /* reg symbolic port name */
-       FC_NS_RFF_ID =  0x021f,         /* reg FC4 Features for ID */
-       FC_NS_RSNN_NN = 0x0239,         /* reg symbolic node name */
-};
-
-/*
- * Port type values.
- */
-enum fc_ns_pt {
-       FC_NS_UNID_PORT = 0x00, /* unidentified */
-       FC_NS_N_PORT =  0x01,   /* N port */
-       FC_NS_NL_PORT = 0x02,   /* NL port */
-       FC_NS_FNL_PORT = 0x03,  /* F/NL port */
-       FC_NS_NX_PORT = 0x7f,   /* Nx port */
-       FC_NS_F_PORT =  0x81,   /* F port */
-       FC_NS_FL_PORT = 0x82,   /* FL port */
-       FC_NS_E_PORT =  0x84,   /* E port */
-       FC_NS_B_PORT =  0x85,   /* B port */
-};
-
-/*
- * Port type object.
- */
-struct fc_ns_pt_obj {
-       __u8            pt_type;
-};
-
-/*
- * Port ID object
- */
-struct fc_ns_fid {
-       __u8            fp_flags;       /* flags for responses only */
-       __u8            fp_fid[3];
-};
-
-/*
- * fp_flags in port ID object, for responses only.
- */
-#define        FC_NS_FID_LAST  0x80            /* last object */
-
-/*
- * FC4-types object.
- */
-#define        FC_NS_TYPES     256     /* number of possible FC-4 types */
-#define        FC_NS_BPW       32      /* bits per word in bitmap */
-
-struct fc_ns_fts {
-       __be32  ff_type_map[FC_NS_TYPES / FC_NS_BPW]; /* bitmap of FC-4 types */
-};
-
-/*
- * FC4-features object.
- */
-struct fc_ns_ff        {
-       __be32  fd_feat[FC_NS_TYPES * 4 / FC_NS_BPW]; /* 4-bits per FC-type */
-};
-
-/*
- * GID_PT request.
- */
-struct fc_ns_gid_pt {
-       __u8            fn_pt_type;
-       __u8            fn_domain_id_scope;
-       __u8            fn_area_id_scope;
-       __u8            fn_resvd;
-};
-
-/*
- * GID_FT or GPN_FT request.
- */
-struct fc_ns_gid_ft {
-       __u8            fn_resvd;
-       __u8            fn_domain_id_scope;
-       __u8            fn_area_id_scope;
-       __u8            fn_fc4_type;
-};
-
-/*
- * GPN_FT response.
- */
-struct fc_gpn_ft_resp {
-       __u8            fp_flags;       /* see fp_flags definitions above */
-       __u8            fp_fid[3];      /* port ID */
-       __be32          fp_resvd;
-       __be64          fp_wwpn;        /* port name */
-};
-
-/*
- * GID_PN request
- */
-struct fc_ns_gid_pn {
-       __be64     fn_wwpn;    /* port name */
-};
-
-/*
- * GID_PN response or GSPN_ID request
- */
-struct fc_gid_pn_resp {
-       __u8      fp_resvd;
-       __u8      fp_fid[3];     /* port ID */
-};
-
-/*
- * GSPN_ID response
- */
-struct fc_gspn_resp {
-       __u8    fp_name_len;
-       char    fp_name[];
-};
-
-/*
- * RFT_ID request - register FC-4 types for ID.
- */
-struct fc_ns_rft_id {
-       struct fc_ns_fid fr_fid;        /* port ID object */
-       struct fc_ns_fts fr_fts;        /* FC-4 types object */
-};
-
-/*
- * RPN_ID request - register port name for ID.
- * RNN_ID request - register node name for ID.
- */
-struct fc_ns_rn_id {
-       struct fc_ns_fid fr_fid;        /* port ID object */
-       __be64          fr_wwn;         /* node name or port name */
-} __attribute__((__packed__));
-
-/*
- * RSNN_NN request - register symbolic node name
- */
-struct fc_ns_rsnn {
-       __be64          fr_wwn;         /* node name */
-       __u8            fr_name_len;
-       char            fr_name[];
-} __attribute__((__packed__));
-
-/*
- * RSPN_ID request - register symbolic port name
- */
-struct fc_ns_rspn {
-       struct fc_ns_fid fr_fid;        /* port ID object */
-       __u8            fr_name_len;
-       char            fr_name[];
-} __attribute__((__packed__));
-
-/*
- * RFF_ID request - register FC-4 Features for ID.
- */
-struct fc_ns_rff_id {
-       struct fc_ns_fid fr_fid;        /* port ID object */
-       __u8            fr_resvd[2];
-       __u8            fr_feat;        /* FC-4 Feature bits */
-       __u8            fr_type;        /* FC-4 type */
-} __attribute__((__packed__));
-
-#endif /* _FC_NS_H_ */
index 604cb9b..7e23148 100644 (file)
@@ -34,7 +34,8 @@ struct fcoe_sysfs_function_template {
        void (*get_fcoe_ctlr_symb_err)(struct fcoe_ctlr_device *);
        void (*get_fcoe_ctlr_err_block)(struct fcoe_ctlr_device *);
        void (*get_fcoe_ctlr_fcs_error)(struct fcoe_ctlr_device *);
-       void (*get_fcoe_ctlr_mode)(struct fcoe_ctlr_device *);
+       void (*set_fcoe_ctlr_mode)(struct fcoe_ctlr_device *);
+       int  (*set_fcoe_ctlr_enabled)(struct fcoe_ctlr_device *);
        void (*get_fcoe_fcf_selected)(struct fcoe_fcf_device *);
        void (*get_fcoe_fcf_vlan_id)(struct fcoe_fcf_device *);
 };
@@ -48,6 +49,12 @@ enum fip_conn_type {
        FIP_CONN_TYPE_VN2VN,
 };
 
+enum ctlr_enabled_state {
+       FCOE_CTLR_ENABLED,
+       FCOE_CTLR_DISABLED,
+       FCOE_CTLR_UNUSED,
+};
+
 struct fcoe_ctlr_device {
        u32                             id;
 
@@ -64,6 +71,8 @@ struct fcoe_ctlr_device {
        int                             fcf_dev_loss_tmo;
        enum fip_conn_type              mode;
 
+       enum ctlr_enabled_state         enabled;
+
        /* expected in host order for displaying */
        struct fcoe_fc_els_lesb         lesb;
 };
index 8742d85..4427393 100644 (file)
@@ -260,6 +260,9 @@ void __fcoe_get_lesb(struct fc_lport *lport, struct fc_els_lesb *fc_lesb,
                     struct net_device *netdev);
 void fcoe_wwn_to_str(u64 wwn, char *buf, int len);
 int fcoe_validate_vport_create(struct fc_vport *vport);
+int fcoe_link_speed_update(struct fc_lport *);
+void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
+void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev);
 
 /**
  * is_fip_mode() - returns true if FIP mode selected.
@@ -289,8 +292,11 @@ static inline bool is_fip_mode(struct fcoe_ctlr *fip)
  * @attached:  whether this transport is already attached
  * @list:      list linkage to all attached transports
  * @match:     handler to allow the transport driver to match up a given netdev
+ * @alloc:      handler to allocate per-instance FCoE structures
+ *             (no discovery or login)
  * @create:    handler to sysfs entry of create for FCoE instances
- * @destroy:   handler to sysfs entry of destroy for FCoE instances
+ * @destroy:    handler to delete per-instance FCoE structures
+ *             (frees all memory)
  * @enable:    handler to sysfs entry of enable for FCoE instances
  * @disable:   handler to sysfs entry of disable for FCoE instances
  */
@@ -299,6 +305,7 @@ struct fcoe_transport {
        bool attached;
        struct list_head list;
        bool (*match) (struct net_device *device);
+       int (*alloc) (struct net_device *device);
        int (*create) (struct net_device *device, enum fip_state fip_mode);
        int (*destroy) (struct net_device *device);
        int (*enable) (struct net_device *device);
@@ -347,7 +354,20 @@ struct fcoe_port {
        struct timer_list     timer;
        struct work_struct    destroy_work;
        u8                    data_src_addr[ETH_ALEN];
+       struct net_device * (*get_netdev)(const struct fc_lport *lport);
 };
+
+/**
+ * fcoe_get_netdev() - Return the net device associated with a local port
+ * @lport: The local port to get the net device from
+ */
+static inline struct net_device *fcoe_get_netdev(const struct fc_lport *lport)
+{
+       struct fcoe_port *port = ((struct fcoe_port *)lport_priv(lport));
+
+       return (port->get_netdev) ? port->get_netdev(lport) : NULL;
+}
+
 void fcoe_clean_pending_queue(struct fc_lport *);
 void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb);
 void fcoe_queue_timer(ulong lport);
@@ -356,7 +376,7 @@ int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen,
 
 /* FCoE Sysfs helpers */
 void fcoe_fcf_get_selected(struct fcoe_fcf_device *);
-void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *);
+void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *);
 
 /**
  * struct netdev_list
@@ -372,4 +392,12 @@ struct fcoe_netdev_mapping {
 int fcoe_transport_attach(struct fcoe_transport *ft);
 int fcoe_transport_detach(struct fcoe_transport *ft);
 
+/* sysfs store handler for ctrl_control interface */
+ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
+                              const char *buf, size_t count);
+ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus,
+                               const char *buf, size_t count);
+
 #endif /* _LIBFCOE_H */
+
+
index aafaa5a..5ead9fa 100644 (file)
@@ -1 +1,5 @@
 # UAPI Header export list
+header-y += fc_els.h
+header-y += fc_fs.h
+header-y += fc_gs.h
+header-y += fc_ns.h
diff --git a/include/uapi/scsi/fc/fc_els.h b/include/uapi/scsi/fc/fc_els.h
new file mode 100644 (file)
index 0000000..481abbd
--- /dev/null
@@ -0,0 +1,831 @@
+/*
+ * Copyright(c) 2007 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#ifndef _FC_ELS_H_
+#define        _FC_ELS_H_
+
+#include <linux/types.h>
+
+/*
+ * Fibre Channel Switch - Enhanced Link Services definitions.
+ * From T11 FC-LS Rev 1.2 June 7, 2005.
+ */
+
+/*
+ * ELS Command codes - byte 0 of the frame payload
+ */
+enum fc_els_cmd {
+       ELS_LS_RJT =    0x01,   /* ESL reject */
+       ELS_LS_ACC =    0x02,   /* ESL Accept */
+       ELS_PLOGI =     0x03,   /* N_Port login */
+       ELS_FLOGI =     0x04,   /* F_Port login */
+       ELS_LOGO =      0x05,   /* Logout */
+       ELS_ABTX =      0x06,   /* Abort exchange - obsolete */
+       ELS_RCS =       0x07,   /* read connection status */
+       ELS_RES =       0x08,   /* read exchange status block */
+       ELS_RSS =       0x09,   /* read sequence status block */
+       ELS_RSI =       0x0a,   /* read sequence initiative */
+       ELS_ESTS =      0x0b,   /* establish streaming */
+       ELS_ESTC =      0x0c,   /* estimate credit */
+       ELS_ADVC =      0x0d,   /* advise credit */
+       ELS_RTV =       0x0e,   /* read timeout value */
+       ELS_RLS =       0x0f,   /* read link error status block */
+       ELS_ECHO =      0x10,   /* echo */
+       ELS_TEST =      0x11,   /* test */
+       ELS_RRQ =       0x12,   /* reinstate recovery qualifier */
+       ELS_REC =       0x13,   /* read exchange concise */
+       ELS_SRR =       0x14,   /* sequence retransmission request */
+       ELS_PRLI =      0x20,   /* process login */
+       ELS_PRLO =      0x21,   /* process logout */
+       ELS_SCN =       0x22,   /* state change notification */
+       ELS_TPLS =      0x23,   /* test process login state */
+       ELS_TPRLO =     0x24,   /* third party process logout */
+       ELS_LCLM =      0x25,   /* login control list mgmt (obs) */
+       ELS_GAID =      0x30,   /* get alias_ID */
+       ELS_FACT =      0x31,   /* fabric activate alias_id */
+       ELS_FDACDT =    0x32,   /* fabric deactivate alias_id */
+       ELS_NACT =      0x33,   /* N-port activate alias_id */
+       ELS_NDACT =     0x34,   /* N-port deactivate alias_id */
+       ELS_QOSR =      0x40,   /* quality of service request */
+       ELS_RVCS =      0x41,   /* read virtual circuit status */
+       ELS_PDISC =     0x50,   /* discover N_port service params */
+       ELS_FDISC =     0x51,   /* discover F_port service params */
+       ELS_ADISC =     0x52,   /* discover address */
+       ELS_RNC =       0x53,   /* report node cap (obs) */
+       ELS_FARP_REQ =  0x54,   /* FC ARP request */
+       ELS_FARP_REPL = 0x55,   /* FC ARP reply */
+       ELS_RPS =       0x56,   /* read port status block */
+       ELS_RPL =       0x57,   /* read port list */
+       ELS_RPBC =      0x58,   /* read port buffer condition */
+       ELS_FAN =       0x60,   /* fabric address notification */
+       ELS_RSCN =      0x61,   /* registered state change notification */
+       ELS_SCR =       0x62,   /* state change registration */
+       ELS_RNFT =      0x63,   /* report node FC-4 types */
+       ELS_CSR =       0x68,   /* clock synch. request */
+       ELS_CSU =       0x69,   /* clock synch. update */
+       ELS_LINIT =     0x70,   /* loop initialize */
+       ELS_LSTS =      0x72,   /* loop status */
+       ELS_RNID =      0x78,   /* request node ID data */
+       ELS_RLIR =      0x79,   /* registered link incident report */
+       ELS_LIRR =      0x7a,   /* link incident record registration */
+       ELS_SRL =       0x7b,   /* scan remote loop */
+       ELS_SBRP =      0x7c,   /* set bit-error reporting params */
+       ELS_RPSC =      0x7d,   /* report speed capabilities */
+       ELS_QSA =       0x7e,   /* query security attributes */
+       ELS_EVFP =      0x7f,   /* exchange virt. fabrics params */
+       ELS_LKA =       0x80,   /* link keep-alive */
+       ELS_AUTH_ELS =  0x90,   /* authentication ELS */
+};
+
+/*
+ * Initializer useful for decoding table.
+ * Please keep this in sync with the above definitions.
+ */
+#define        FC_ELS_CMDS_INIT {                      \
+       [ELS_LS_RJT] =  "LS_RJT",               \
+       [ELS_LS_ACC] =  "LS_ACC",               \
+       [ELS_PLOGI] =   "PLOGI",                \
+       [ELS_FLOGI] =   "FLOGI",                \
+       [ELS_LOGO] =    "LOGO",                 \
+       [ELS_ABTX] =    "ABTX",                 \
+       [ELS_RCS] =     "RCS",                  \
+       [ELS_RES] =     "RES",                  \
+       [ELS_RSS] =     "RSS",                  \
+       [ELS_RSI] =     "RSI",                  \
+       [ELS_ESTS] =    "ESTS",                 \
+       [ELS_ESTC] =    "ESTC",                 \
+       [ELS_ADVC] =    "ADVC",                 \
+       [ELS_RTV] =     "RTV",                  \
+       [ELS_RLS] =     "RLS",                  \
+       [ELS_ECHO] =    "ECHO",                 \
+       [ELS_TEST] =    "TEST",                 \
+       [ELS_RRQ] =     "RRQ",                  \
+       [ELS_REC] =     "REC",                  \
+       [ELS_SRR] =     "SRR",                  \
+       [ELS_PRLI] =    "PRLI",                 \
+       [ELS_PRLO] =    "PRLO",                 \
+       [ELS_SCN] =     "SCN",                  \
+       [ELS_TPLS] =    "TPLS",                 \
+       [ELS_TPRLO] =   "TPRLO",                \
+       [ELS_LCLM] =    "LCLM",                 \
+       [ELS_GAID] =    "GAID",                 \
+       [ELS_FACT] =    "FACT",                 \
+       [ELS_FDACDT] =  "FDACDT",               \
+       [ELS_NACT] =    "NACT",                 \
+       [ELS_NDACT] =   "NDACT",                \
+       [ELS_QOSR] =    "QOSR",                 \
+       [ELS_RVCS] =    "RVCS",                 \
+       [ELS_PDISC] =   "PDISC",                \
+       [ELS_FDISC] =   "FDISC",                \
+       [ELS_ADISC] =   "ADISC",                \
+       [ELS_RNC] =     "RNC",                  \
+       [ELS_FARP_REQ] = "FARP_REQ",            \
+       [ELS_FARP_REPL] =  "FARP_REPL",         \
+       [ELS_RPS] =     "RPS",                  \
+       [ELS_RPL] =     "RPL",                  \
+       [ELS_RPBC] =    "RPBC",                 \
+       [ELS_FAN] =     "FAN",                  \
+       [ELS_RSCN] =    "RSCN",                 \
+       [ELS_SCR] =     "SCR",                  \
+       [ELS_RNFT] =    "RNFT",                 \
+       [ELS_CSR] =     "CSR",                  \
+       [ELS_CSU] =     "CSU",                  \
+       [ELS_LINIT] =   "LINIT",                \
+       [ELS_LSTS] =    "LSTS",                 \
+       [ELS_RNID] =    "RNID",                 \
+       [ELS_RLIR] =    "RLIR",                 \
+       [ELS_LIRR] =    "LIRR",                 \
+       [ELS_SRL] =     "SRL",                  \
+       [ELS_SBRP] =    "SBRP",                 \
+       [ELS_RPSC] =    "RPSC",                 \
+       [ELS_QSA] =     "QSA",                  \
+       [ELS_EVFP] =    "EVFP",                 \
+       [ELS_LKA] =     "LKA",                  \
+       [ELS_AUTH_ELS] = "AUTH_ELS",            \
+}
+
+/*
+ * LS_ACC payload.
+ */
+struct fc_els_ls_acc {
+       __u8          la_cmd;           /* command code ELS_LS_ACC */
+       __u8          la_resv[3];       /* reserved */
+};
+
+/*
+ * ELS reject payload.
+ */
+struct fc_els_ls_rjt {
+       __u8    er_cmd;         /* command code ELS_LS_RJT */
+       __u8    er_resv[4];     /* reserved must be zero */
+       __u8    er_reason;      /* reason (enum fc_els_rjt_reason below) */
+       __u8    er_explan;      /* explanation (enum fc_els_rjt_explan below) */
+       __u8    er_vendor;      /* vendor specific code */
+};
+
+/*
+ * ELS reject reason codes (er_reason).
+ */
+enum fc_els_rjt_reason {
+       ELS_RJT_NONE =          0,      /* no reject - not to be sent */
+       ELS_RJT_INVAL =         0x01,   /* invalid ELS command code */
+       ELS_RJT_LOGIC =         0x03,   /* logical error */
+       ELS_RJT_BUSY =          0x05,   /* logical busy */
+       ELS_RJT_PROT =          0x07,   /* protocol error */
+       ELS_RJT_UNAB =          0x09,   /* unable to perform command request */
+       ELS_RJT_UNSUP =         0x0b,   /* command not supported */
+       ELS_RJT_INPROG =        0x0e,   /* command already in progress */
+       ELS_RJT_FIP =           0x20,   /* FIP error */
+       ELS_RJT_VENDOR =        0xff,   /* vendor specific error */
+};
+
+
+/*
+ * reason code explanation (er_explan).
+ */
+enum fc_els_rjt_explan {
+       ELS_EXPL_NONE =         0x00,   /* No additional explanation */
+       ELS_EXPL_SPP_OPT_ERR =  0x01,   /* service parameter error - options */
+       ELS_EXPL_SPP_ICTL_ERR = 0x03,   /* service parm error - initiator ctl */
+       ELS_EXPL_AH =           0x11,   /* invalid association header */
+       ELS_EXPL_AH_REQ =       0x13,   /* association_header required */
+       ELS_EXPL_SID =          0x15,   /* invalid originator S_ID */
+       ELS_EXPL_OXID_RXID =    0x17,   /* invalid OX_ID-RX_ID combination */
+       ELS_EXPL_INPROG =       0x19,   /* Request already in progress */
+       ELS_EXPL_PLOGI_REQD =   0x1e,   /* N_Port login required */
+       ELS_EXPL_INSUF_RES =    0x29,   /* insufficient resources */
+       ELS_EXPL_UNAB_DATA =    0x2a,   /* unable to supply requested data */
+       ELS_EXPL_UNSUPR =       0x2c,   /* Request not supported */
+       ELS_EXPL_INV_LEN =      0x2d,   /* Invalid payload length */
+       ELS_EXPL_NOT_NEIGHBOR = 0x62,   /* VN2VN_Port not in neighbor set */
+       /* TBD - above definitions incomplete */
+};
+
+/*
+ * Common service parameters (N ports).
+ */
+struct fc_els_csp {
+       __u8            sp_hi_ver;      /* highest version supported (obs.) */
+       __u8            sp_lo_ver;      /* highest version supported (obs.) */
+       __be16          sp_bb_cred;     /* buffer-to-buffer credits */
+       __be16          sp_features;    /* common feature flags */
+       __be16          sp_bb_data;     /* b-b state number and data field sz */
+       union {
+               struct {
+                       __be16  _sp_tot_seq; /* total concurrent sequences */
+                       __be16  _sp_rel_off; /* rel. offset by info cat */
+               } sp_plogi;
+               struct {
+                       __be32  _sp_r_a_tov; /* resource alloc. timeout msec */
+               } sp_flogi_acc;
+       } sp_u;
+       __be32          sp_e_d_tov;     /* error detect timeout value */
+};
+#define        sp_tot_seq      sp_u.sp_plogi._sp_tot_seq
+#define        sp_rel_off      sp_u.sp_plogi._sp_rel_off
+#define        sp_r_a_tov      sp_u.sp_flogi_acc._sp_r_a_tov
+
+#define        FC_SP_BB_DATA_MASK 0xfff /* mask for data field size in sp_bb_data */
+
+/*
+ * Minimum and maximum values for max data field size in service parameters.
+ */
+#define        FC_SP_MIN_MAX_PAYLOAD   FC_MIN_MAX_PAYLOAD
+#define        FC_SP_MAX_MAX_PAYLOAD   FC_MAX_PAYLOAD
+
+/*
+ * sp_features
+ */
+#define        FC_SP_FT_NPIV   0x8000  /* multiple N_Port_ID support (FLOGI) */
+#define        FC_SP_FT_CIRO   0x8000  /* continuously increasing rel off (PLOGI) */
+#define        FC_SP_FT_CLAD   0x8000  /* clean address (in FLOGI LS_ACC) */
+#define        FC_SP_FT_RAND   0x4000  /* random relative offset */
+#define        FC_SP_FT_VAL    0x2000  /* valid vendor version level */
+#define        FC_SP_FT_NPIV_ACC       0x2000  /* NPIV assignment (FLOGI LS_ACC) */
+#define        FC_SP_FT_FPORT  0x1000  /* F port (1) vs. N port (0) */
+#define        FC_SP_FT_ABB    0x0800  /* alternate BB_credit management */
+#define        FC_SP_FT_EDTR   0x0400  /* E_D_TOV Resolution is nanoseconds */
+#define        FC_SP_FT_MCAST  0x0200  /* multicast */
+#define        FC_SP_FT_BCAST  0x0100  /* broadcast */
+#define        FC_SP_FT_HUNT   0x0080  /* hunt group */
+#define        FC_SP_FT_SIMP   0x0040  /* dedicated simplex */
+#define        FC_SP_FT_SEC    0x0020  /* reserved for security */
+#define        FC_SP_FT_CSYN   0x0010  /* clock synch. supported */
+#define        FC_SP_FT_RTTOV  0x0008  /* R_T_TOV value 100 uS, else 100 mS */
+#define        FC_SP_FT_HALF   0x0004  /* dynamic half duplex */
+#define        FC_SP_FT_SEQC   0x0002  /* SEQ_CNT */
+#define        FC_SP_FT_PAYL   0x0001  /* FLOGI payload length 256, else 116 */
+
+/*
+ * Class-specific service parameters.
+ */
+struct fc_els_cssp {
+       __be16          cp_class;       /* class flags */
+       __be16          cp_init;        /* initiator flags */
+       __be16          cp_recip;       /* recipient flags */
+       __be16          cp_rdfs;        /* receive data field size */
+       __be16          cp_con_seq;     /* concurrent sequences */
+       __be16          cp_ee_cred;     /* N-port end-to-end credit */
+       __u8            cp_resv1;       /* reserved */
+       __u8            cp_open_seq;    /* open sequences per exchange */
+       __u8            _cp_resv2[2];   /* reserved */
+};
+
+/*
+ * cp_class flags.
+ */
+#define        FC_CPC_VALID    0x8000          /* class valid */
+#define        FC_CPC_IMIX     0x4000          /* intermix mode */
+#define        FC_CPC_SEQ      0x0800          /* sequential delivery */
+#define        FC_CPC_CAMP     0x0200          /* camp-on */
+#define        FC_CPC_PRI      0x0080          /* priority */
+
+/*
+ * cp_init flags.
+ * (TBD: not all flags defined here).
+ */
+#define        FC_CPI_CSYN     0x0010          /* clock synch. capable */
+
+/*
+ * cp_recip flags.
+ */
+#define        FC_CPR_CSYN     0x0008          /* clock synch. capable */
+
+/*
+ * NFC_ELS_FLOGI: Fabric login request.
+ * NFC_ELS_PLOGI: Port login request (same format).
+ */
+struct fc_els_flogi {
+       __u8            fl_cmd;         /* command */
+       __u8            _fl_resvd[3];   /* must be zero */
+       struct fc_els_csp fl_csp;       /* common service parameters */
+       __be64          fl_wwpn;        /* port name */
+       __be64          fl_wwnn;        /* node name */
+       struct fc_els_cssp fl_cssp[4];  /* class 1-4 service parameters */
+       __u8            fl_vend[16];    /* vendor version level */
+} __attribute__((__packed__));
+
+/*
+ * Process login service parameter page.
+ */
+struct fc_els_spp {
+       __u8            spp_type;       /* type code or common service params */
+       __u8            spp_type_ext;   /* type code extension */
+       __u8            spp_flags;
+       __u8            _spp_resvd;
+       __be32          spp_orig_pa;    /* originator process associator */
+       __be32          spp_resp_pa;    /* responder process associator */
+       __be32          spp_params;     /* service parameters */
+};
+
+/*
+ * spp_flags.
+ */
+#define        FC_SPP_OPA_VAL      0x80        /* originator proc. assoc. valid */
+#define        FC_SPP_RPA_VAL      0x40        /* responder proc. assoc. valid */
+#define        FC_SPP_EST_IMG_PAIR 0x20        /* establish image pair */
+#define        FC_SPP_RESP_MASK    0x0f        /* mask for response code (below) */
+
+/*
+ * SPP response code in spp_flags - lower 4 bits.
+ */
+enum fc_els_spp_resp {
+       FC_SPP_RESP_ACK =       1,      /* request executed */
+       FC_SPP_RESP_RES =       2,      /* unable due to lack of resources */
+       FC_SPP_RESP_INIT =      3,      /* initialization not complete */
+       FC_SPP_RESP_NO_PA =     4,      /* unknown process associator */
+       FC_SPP_RESP_CONF =      5,      /* configuration precludes image pair */
+       FC_SPP_RESP_COND =      6,      /* request completed conditionally */
+       FC_SPP_RESP_MULT =      7,      /* unable to handle multiple SPPs */
+       FC_SPP_RESP_INVL =      8,      /* SPP is invalid */
+};
+
+/*
+ * ELS_RRQ - Reinstate Recovery Qualifier
+ */
+struct fc_els_rrq {
+       __u8            rrq_cmd;        /* command (0x12) */
+       __u8            rrq_zero[3];    /* specified as zero - part of cmd */
+       __u8            rrq_resvd;      /* reserved */
+       __u8            rrq_s_id[3];    /* originator FID */
+       __be16          rrq_ox_id;      /* originator exchange ID */
+       __be16          rrq_rx_id;      /* responders exchange ID */
+};
+
+/*
+ * ELS_REC - Read exchange concise.
+ */
+struct fc_els_rec {
+       __u8            rec_cmd;        /* command (0x13) */
+       __u8            rec_zero[3];    /* specified as zero - part of cmd */
+       __u8            rec_resvd;      /* reserved */
+       __u8            rec_s_id[3];    /* originator FID */
+       __be16          rec_ox_id;      /* originator exchange ID */
+       __be16          rec_rx_id;      /* responders exchange ID */
+};
+
+/*
+ * ELS_REC LS_ACC payload.
+ */
+struct fc_els_rec_acc {
+       __u8            reca_cmd;       /* accept (0x02) */
+       __u8            reca_zero[3];   /* specified as zero - part of cmd */
+       __be16          reca_ox_id;     /* originator exchange ID */
+       __be16          reca_rx_id;     /* responders exchange ID */
+       __u8            reca_resvd1;    /* reserved */
+       __u8            reca_ofid[3];   /* originator FID */
+       __u8            reca_resvd2;    /* reserved */
+       __u8            reca_rfid[3];   /* responder FID */
+       __be32          reca_fc4value;  /* FC4 value */
+       __be32          reca_e_stat;    /* ESB (exchange status block) status */
+};
+
+/*
+ * ELS_PRLI - Process login request and response.
+ */
+struct fc_els_prli {
+       __u8            prli_cmd;       /* command */
+       __u8            prli_spp_len;   /* length of each serv. parm. page */
+       __be16          prli_len;       /* length of entire payload */
+       /* service parameter pages follow */
+};
+
+/*
+ * ELS_PRLO - Process logout request and response.
+ */
+struct fc_els_prlo {
+       __u8            prlo_cmd;       /* command */
+       __u8            prlo_obs;       /* obsolete, but shall be set to 10h */
+       __be16          prlo_len;       /* payload length */
+};
+
+/*
+ * ELS_ADISC payload
+ */
+struct fc_els_adisc {
+       __u8            adisc_cmd;
+       __u8            adisc_resv[3];
+       __u8            adisc_resv1;
+       __u8            adisc_hard_addr[3];
+       __be64          adisc_wwpn;
+       __be64          adisc_wwnn;
+       __u8            adisc_resv2;
+       __u8            adisc_port_id[3];
+} __attribute__((__packed__));
+
+/*
+ * ELS_LOGO - process or fabric logout.
+ */
+struct fc_els_logo {
+       __u8            fl_cmd;         /* command code */
+       __u8            fl_zero[3];     /* specified as zero - part of cmd */
+       __u8            fl_resvd;       /* reserved */
+       __u8            fl_n_port_id[3];/* N port ID */
+       __be64          fl_n_port_wwn;  /* port name */
+};
+
+/*
+ * ELS_RTV - read timeout value.
+ */
+struct fc_els_rtv {
+       __u8            rtv_cmd;        /* command code 0x0e */
+       __u8            rtv_zero[3];    /* specified as zero - part of cmd */
+};
+
+/*
+ * LS_ACC for ELS_RTV - read timeout value.
+ */
+struct fc_els_rtv_acc {
+       __u8            rtv_cmd;        /* command code 0x02 */
+       __u8            rtv_zero[3];    /* specified as zero - part of cmd */
+       __be32          rtv_r_a_tov;    /* resource allocation timeout value */
+       __be32          rtv_e_d_tov;    /* error detection timeout value */
+       __be32          rtv_toq;        /* timeout qualifier (see below) */
+};
+
+/*
+ * rtv_toq bits.
+ */
+#define        FC_ELS_RTV_EDRES (1 << 26)      /* E_D_TOV resolution is nS else mS */
+#define        FC_ELS_RTV_RTTOV (1 << 19)      /* R_T_TOV is 100 uS else 100 mS */
+
+/*
+ * ELS_SCR - state change registration payload.
+ */
+struct fc_els_scr {
+       __u8            scr_cmd;        /* command code */
+       __u8            scr_resv[6];    /* reserved */
+       __u8            scr_reg_func;   /* registration function (see below) */
+};
+
+enum fc_els_scr_func {
+       ELS_SCRF_FAB =  1,      /* fabric-detected registration */
+       ELS_SCRF_NPORT = 2,     /* Nx_Port-detected registration */
+       ELS_SCRF_FULL = 3,      /* full registration */
+       ELS_SCRF_CLEAR = 255,   /* remove any current registrations */
+};
+
+/*
+ * ELS_RSCN - registered state change notification payload.
+ */
+struct fc_els_rscn {
+       __u8            rscn_cmd;       /* RSCN opcode (0x61) */
+       __u8            rscn_page_len;  /* page length (4) */
+       __be16          rscn_plen;      /* payload length including this word */
+
+       /* followed by 4-byte generic affected Port_ID pages */
+};
+
+struct fc_els_rscn_page {
+       __u8            rscn_page_flags; /* event and address format */
+       __u8            rscn_fid[3];    /* fabric ID */
+};
+
+#define        ELS_RSCN_EV_QUAL_BIT    2       /* shift count for event qualifier */
+#define        ELS_RSCN_EV_QUAL_MASK   0xf     /* mask for event qualifier */
+#define        ELS_RSCN_ADDR_FMT_BIT   0       /* shift count for address format */
+#define        ELS_RSCN_ADDR_FMT_MASK  0x3     /* mask for address format */
+
+enum fc_els_rscn_ev_qual {
+       ELS_EV_QUAL_NONE = 0,           /* unspecified */
+       ELS_EV_QUAL_NS_OBJ = 1,         /* changed name server object */
+       ELS_EV_QUAL_PORT_ATTR = 2,      /* changed port attribute */
+       ELS_EV_QUAL_SERV_OBJ = 3,       /* changed service object */
+       ELS_EV_QUAL_SW_CONFIG = 4,      /* changed switch configuration */
+       ELS_EV_QUAL_REM_OBJ = 5,        /* removed object */
+};
+
+enum fc_els_rscn_addr_fmt {
+       ELS_ADDR_FMT_PORT = 0,  /* rscn_fid is a port address */
+       ELS_ADDR_FMT_AREA = 1,  /* rscn_fid is a area address */
+       ELS_ADDR_FMT_DOM = 2,   /* rscn_fid is a domain address */
+       ELS_ADDR_FMT_FAB = 3,   /* anything on fabric may have changed */
+};
+
+/*
+ * ELS_RNID - request Node ID.
+ */
+struct fc_els_rnid {
+       __u8            rnid_cmd;       /* RNID opcode (0x78) */
+       __u8            rnid_resv[3];   /* reserved */
+       __u8            rnid_fmt;       /* data format */
+       __u8            rnid_resv2[3];  /* reserved */
+};
+
+/*
+ * Node Identification Data formats (rnid_fmt)
+ */
+enum fc_els_rnid_fmt {
+       ELS_RNIDF_NONE = 0,             /* no specific identification data */
+       ELS_RNIDF_GEN = 0xdf,           /* general topology discovery format */
+};
+
+/*
+ * ELS_RNID response.
+ */
+struct fc_els_rnid_resp {
+       __u8            rnid_cmd;       /* response code (LS_ACC) */
+       __u8            rnid_resv[3];   /* reserved */
+       __u8            rnid_fmt;       /* data format */
+       __u8            rnid_cid_len;   /* common ID data length */
+       __u8            rnid_resv2;     /* reserved */
+       __u8            rnid_sid_len;   /* specific ID data length */
+};
+
+struct fc_els_rnid_cid {
+       __be64          rnid_wwpn;      /* N port name */
+       __be64          rnid_wwnn;      /* node name */
+};
+
+struct fc_els_rnid_gen {
+       __u8            rnid_vend_id[16]; /* vendor-unique ID */
+       __be32          rnid_atype;     /* associated type (see below) */
+       __be32          rnid_phys_port; /* physical port number */
+       __be32          rnid_att_nodes; /* number of attached nodes */
+       __u8            rnid_node_mgmt; /* node management (see below) */
+       __u8            rnid_ip_ver;    /* IP version (see below) */
+       __be16          rnid_prot_port; /* UDP / TCP port number */
+       __be32          rnid_ip_addr[4]; /* IP address */
+       __u8            rnid_resvd[2];  /* reserved */
+       __be16          rnid_vend_spec; /* vendor-specific field */
+};
+
+enum fc_els_rnid_atype {
+       ELS_RNIDA_UNK =         0x01,   /* unknown */
+       ELS_RNIDA_OTHER =       0x02,   /* none of the following */
+       ELS_RNIDA_HUB =         0x03,
+       ELS_RNIDA_SWITCH =      0x04,
+       ELS_RNIDA_GATEWAY =     0x05,
+       ELS_RNIDA_CONV =        0x06,   /* Obsolete, do not use this value */
+       ELS_RNIDA_HBA =         0x07,   /* Obsolete, do not use this value */
+       ELS_RNIDA_PROXY =       0x08,   /* Obsolete, do not use this value */
+       ELS_RNIDA_STORAGE =     0x09,
+       ELS_RNIDA_HOST =        0x0a,
+       ELS_RNIDA_SUBSYS =      0x0b,   /* storage subsystem (e.g., RAID) */
+       ELS_RNIDA_ACCESS =      0x0e,   /* access device (e.g. media changer) */
+       ELS_RNIDA_NAS =         0x11,   /* NAS server */
+       ELS_RNIDA_BRIDGE =      0x12,   /* bridge */
+       ELS_RNIDA_VIRT =        0x13,   /* virtualization device */
+       ELS_RNIDA_MF =          0xff,   /* multifunction device (bits below) */
+       ELS_RNIDA_MF_HUB =      1UL << 31,      /* hub */
+       ELS_RNIDA_MF_SW =       1UL << 30,      /* switch */
+       ELS_RNIDA_MF_GW =       1UL << 29,      /* gateway */
+       ELS_RNIDA_MF_ST =       1UL << 28,      /* storage */
+       ELS_RNIDA_MF_HOST =     1UL << 27,      /* host */
+       ELS_RNIDA_MF_SUB =      1UL << 26,      /* storage subsystem */
+       ELS_RNIDA_MF_ACC =      1UL << 25,      /* storage access dev */
+       ELS_RNIDA_MF_WDM =      1UL << 24,      /* wavelength division mux */
+       ELS_RNIDA_MF_NAS =      1UL << 23,      /* NAS server */
+       ELS_RNIDA_MF_BR =       1UL << 22,      /* bridge */
+       ELS_RNIDA_MF_VIRT =     1UL << 21,      /* virtualization device */
+};
+
+enum fc_els_rnid_mgmt {
+       ELS_RNIDM_SNMP =        0,
+       ELS_RNIDM_TELNET =      1,
+       ELS_RNIDM_HTTP =        2,
+       ELS_RNIDM_HTTPS =       3,
+       ELS_RNIDM_XML =         4,      /* HTTP + XML */
+};
+
+enum fc_els_rnid_ipver {
+       ELS_RNIDIP_NONE =       0,      /* no IP support or node mgmt. */
+       ELS_RNIDIP_V4 =         1,      /* IPv4 */
+       ELS_RNIDIP_V6 =         2,      /* IPv6 */
+};
+
+/*
+ * ELS RPL - Read Port List.
+ */
+struct fc_els_rpl {
+       __u8            rpl_cmd;        /* command */
+       __u8            rpl_resv[5];    /* reserved - must be zero */
+       __be16          rpl_max_size;   /* maximum response size or zero */
+       __u8            rpl_resv1;      /* reserved - must be zero */
+       __u8            rpl_index[3];   /* starting index */
+};
+
+/*
+ * Port number block in RPL response.
+ */
+struct fc_els_pnb {
+       __be32          pnb_phys_pn;    /* physical port number */
+       __u8            pnb_resv;       /* reserved */
+       __u8            pnb_port_id[3]; /* port ID */
+       __be64          pnb_wwpn;       /* port name */
+};
+
+/*
+ * RPL LS_ACC response.
+ */
+struct fc_els_rpl_resp {
+       __u8            rpl_cmd;        /* ELS_LS_ACC */
+       __u8            rpl_resv1;      /* reserved - must be zero */
+       __be16          rpl_plen;       /* payload length */
+       __u8            rpl_resv2;      /* reserved - must be zero */
+       __u8            rpl_llen[3];    /* list length */
+       __u8            rpl_resv3;      /* reserved - must be zero */
+       __u8            rpl_index[3];   /* starting index */
+       struct fc_els_pnb rpl_pnb[1];   /* variable number of PNBs */
+};
+
+/*
+ * Link Error Status Block.
+ */
+struct fc_els_lesb {
+       __be32          lesb_link_fail; /* link failure count */
+       __be32          lesb_sync_loss; /* loss of synchronization count */
+       __be32          lesb_sig_loss;  /* loss of signal count */
+       __be32          lesb_prim_err;  /* primitive sequence error count */
+       __be32          lesb_inv_word;  /* invalid transmission word count */
+       __be32          lesb_inv_crc;   /* invalid CRC count */
+};
+
+/*
+ * ELS RPS - Read Port Status Block request.
+ */
+struct fc_els_rps {
+       __u8            rps_cmd;        /* command */
+       __u8            rps_resv[2];    /* reserved - must be zero */
+       __u8            rps_flag;       /* flag - see below */
+       __be64          rps_port_spec;  /* port selection */
+};
+
+enum fc_els_rps_flag {
+       FC_ELS_RPS_DID =        0x00,   /* port identified by D_ID of req. */
+       FC_ELS_RPS_PPN =        0x01,   /* port_spec is physical port number */
+       FC_ELS_RPS_WWPN =       0x02,   /* port_spec is port WWN */
+};
+
+/*
+ * ELS RPS LS_ACC response.
+ */
+struct fc_els_rps_resp {
+       __u8            rps_cmd;        /* command - LS_ACC */
+       __u8            rps_resv[2];    /* reserved - must be zero */
+       __u8            rps_flag;       /* flag - see below */
+       __u8            rps_resv2[2];   /* reserved */
+       __be16          rps_status;     /* port status - see below */
+       struct fc_els_lesb rps_lesb;    /* link error status block */
+};
+
+enum fc_els_rps_resp_flag {
+       FC_ELS_RPS_LPEV =       0x01,   /* L_port extension valid */
+};
+
+enum fc_els_rps_resp_status {
+       FC_ELS_RPS_PTP =        1 << 5, /* point-to-point connection */
+       FC_ELS_RPS_LOOP =       1 << 4, /* loop mode */
+       FC_ELS_RPS_FAB =        1 << 3, /* fabric present */
+       FC_ELS_RPS_NO_SIG =     1 << 2, /* loss of signal */
+       FC_ELS_RPS_NO_SYNC =    1 << 1, /* loss of synchronization */
+       FC_ELS_RPS_RESET =      1 << 0, /* in link reset protocol */
+};
+
+/*
+ * ELS LIRR - Link Incident Record Registration request.
+ */
+struct fc_els_lirr {
+       __u8            lirr_cmd;       /* command */
+       __u8            lirr_resv[3];   /* reserved - must be zero */
+       __u8            lirr_func;      /* registration function */
+       __u8            lirr_fmt;       /* FC-4 type of RLIR requested */
+       __u8            lirr_resv2[2];  /* reserved - must be zero */
+};
+
+enum fc_els_lirr_func {
+       ELS_LIRR_SET_COND =     0x01,   /* set - conditionally receive */
+       ELS_LIRR_SET_UNCOND =   0x02,   /* set - unconditionally receive */
+       ELS_LIRR_CLEAR =        0xff    /* clear registration */
+};
+
+/*
+ * ELS SRL - Scan Remote Loop request.
+ */
+struct fc_els_srl {
+       __u8            srl_cmd;        /* command */
+       __u8            srl_resv[3];    /* reserved - must be zero */
+       __u8            srl_flag;       /* flag - see below */
+       __u8            srl_flag_param[3];      /* flag parameter */
+};
+
+enum fc_els_srl_flag {
+       FC_ELS_SRL_ALL =        0x00,   /* scan all FL ports */
+       FC_ELS_SRL_ONE =        0x01,   /* scan specified loop */
+       FC_ELS_SRL_EN_PER =     0x02,   /* enable periodic scanning (param) */
+       FC_ELS_SRL_DIS_PER =    0x03,   /* disable periodic scanning */
+};
+
+/*
+ * ELS RLS - Read Link Error Status Block request.
+ */
+struct fc_els_rls {
+       __u8            rls_cmd;        /* command */
+       __u8            rls_resv[4];    /* reserved - must be zero */
+       __u8            rls_port_id[3]; /* port ID */
+};
+
+/*
+ * ELS RLS LS_ACC Response.
+ */
+struct fc_els_rls_resp {
+       __u8            rls_cmd;        /* ELS_LS_ACC */
+       __u8            rls_resv[3];    /* reserved - must be zero */
+       struct fc_els_lesb rls_lesb;    /* link error status block */
+};
+
+/*
+ * ELS RLIR - Registered Link Incident Report.
+ * This is followed by the CLIR and the CLID, described below.
+ */
+struct fc_els_rlir {
+       __u8            rlir_cmd;       /* command */
+       __u8            rlir_resv[3];   /* reserved - must be zero */
+       __u8            rlir_fmt;       /* format (FC4-type if type specific) */
+       __u8            rlir_clr_len;   /* common link incident record length */
+       __u8            rlir_cld_len;   /* common link incident desc. length */
+       __u8            rlir_slr_len;   /* spec. link incident record length */
+};
+
+/*
+ * CLIR - Common Link Incident Record Data. - Sent via RLIR.
+ */
+struct fc_els_clir {
+       __be64          clir_wwpn;      /* incident port name */
+       __be64          clir_wwnn;      /* incident port node name */
+       __u8            clir_port_type; /* incident port type */
+       __u8            clir_port_id[3];        /* incident port ID */
+
+       __be64          clir_conn_wwpn; /* connected port name */
+       __be64          clir_conn_wwnn; /* connected node name */
+       __be64          clir_fab_name;  /* fabric name */
+       __be32          clir_phys_port; /* physical port number */
+       __be32          clir_trans_id;  /* transaction ID */
+       __u8            clir_resv[3];   /* reserved */
+       __u8            clir_ts_fmt;    /* time stamp format */
+       __be64          clir_timestamp; /* time stamp */
+};
+
+/*
+ * CLIR clir_ts_fmt - time stamp format values.
+ */
+enum fc_els_clir_ts_fmt {
+       ELS_CLIR_TS_UNKNOWN =   0,      /* time stamp field unknown */
+       ELS_CLIR_TS_SEC_FRAC =  1,      /* time in seconds and fractions */
+       ELS_CLIR_TS_CSU =       2,      /* time in clock synch update format */
+};
+
+/*
+ * Common Link Incident Descriptor - sent via RLIR.
+ */
+struct fc_els_clid {
+       __u8            clid_iq;        /* incident qualifier flags */
+       __u8            clid_ic;        /* incident code */
+       __be16          clid_epai;      /* domain/area of ISL */
+};
+
+/*
+ * CLID incident qualifier flags.
+ */
+enum fc_els_clid_iq {
+       ELS_CLID_SWITCH =       0x20,   /* incident port is a switch node */
+       ELS_CLID_E_PORT =       0x10,   /* incident is an ISL (E) port */
+       ELS_CLID_SEV_MASK =     0x0c,   /* severity 2-bit field mask */
+       ELS_CLID_SEV_INFO =     0x00,   /* report is informational */
+       ELS_CLID_SEV_INOP =     0x08,   /* link not operational */
+       ELS_CLID_SEV_DEG =      0x04,   /* link degraded but operational */
+       ELS_CLID_LASER =        0x02,   /* subassembly is a laser */
+       ELS_CLID_FRU =          0x01,   /* format can identify a FRU */
+};
+
+/*
+ * CLID incident code.
+ */
+enum fc_els_clid_ic {
+       ELS_CLID_IC_IMPL =      1,      /* implicit incident */
+       ELS_CLID_IC_BER =       2,      /* bit-error-rate threshold exceeded */
+       ELS_CLID_IC_LOS =       3,      /* loss of synch or signal */
+       ELS_CLID_IC_NOS =       4,      /* non-operational primitive sequence */
+       ELS_CLID_IC_PST =       5,      /* primitive sequence timeout */
+       ELS_CLID_IC_INVAL =     6,      /* invalid primitive sequence */
+       ELS_CLID_IC_LOOP_TO =   7,      /* loop initialization time out */
+       ELS_CLID_IC_LIP =       8,      /* receiving LIP */
+};
+
+#endif /* _FC_ELS_H_ */
diff --git a/include/uapi/scsi/fc/fc_fs.h b/include/uapi/scsi/fc/fc_fs.h
new file mode 100644 (file)
index 0000000..50f28b1
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * Copyright(c) 2007 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#ifndef _FC_FS_H_
+#define _FC_FS_H_
+
+#include <linux/types.h>
+
+/*
+ * Fibre Channel Framing and Signalling definitions.
+ * From T11 FC-FS-2 Rev 0.90 - 9 August 2005.
+ */
+
+/*
+ * Frame header
+ */
+struct fc_frame_header {
+       __u8          fh_r_ctl; /* routing control */
+       __u8          fh_d_id[3];       /* Destination ID */
+
+       __u8          fh_cs_ctl;        /* class of service control / pri */
+       __u8          fh_s_id[3];       /* Source ID */
+
+       __u8          fh_type;          /* see enum fc_fh_type below */
+       __u8          fh_f_ctl[3];      /* frame control */
+
+       __u8          fh_seq_id;        /* sequence ID */
+       __u8          fh_df_ctl;        /* data field control */
+       __be16        fh_seq_cnt;       /* sequence count */
+
+       __be16        fh_ox_id;         /* originator exchange ID */
+       __be16        fh_rx_id;         /* responder exchange ID */
+       __be32        fh_parm_offset;   /* parameter or relative offset */
+};
+
+#define FC_FRAME_HEADER_LEN 24 /* expected length of structure */
+
+#define FC_MAX_PAYLOAD  2112U          /* max payload length in bytes */
+#define FC_MIN_MAX_PAYLOAD  256U       /* lower limit on max payload */
+
+#define FC_MAX_FRAME   (FC_MAX_PAYLOAD + FC_FRAME_HEADER_LEN)
+#define FC_MIN_MAX_FRAME (FC_MIN_MAX_PAYLOAD + FC_FRAME_HEADER_LEN)
+
+/*
+ * fh_r_ctl - Routing control definitions.
+ */
+    /*
+     * FC-4 device_data.
+     */
+enum fc_rctl {
+       FC_RCTL_DD_UNCAT = 0x00,        /* uncategorized information */
+       FC_RCTL_DD_SOL_DATA = 0x01,     /* solicited data */
+       FC_RCTL_DD_UNSOL_CTL = 0x02,    /* unsolicited control */
+       FC_RCTL_DD_SOL_CTL = 0x03,      /* solicited control or reply */
+       FC_RCTL_DD_UNSOL_DATA = 0x04,   /* unsolicited data */
+       FC_RCTL_DD_DATA_DESC = 0x05,    /* data descriptor */
+       FC_RCTL_DD_UNSOL_CMD = 0x06,    /* unsolicited command */
+       FC_RCTL_DD_CMD_STATUS = 0x07,   /* command status */
+
+#define FC_RCTL_ILS_REQ FC_RCTL_DD_UNSOL_CTL   /* ILS request */
+#define FC_RCTL_ILS_REP FC_RCTL_DD_SOL_CTL     /* ILS reply */
+
+       /*
+        * Extended Link_Data
+        */
+       FC_RCTL_ELS_REQ = 0x22, /* extended link services request */
+       FC_RCTL_ELS_REP = 0x23, /* extended link services reply */
+       FC_RCTL_ELS4_REQ = 0x32, /* FC-4 ELS request */
+       FC_RCTL_ELS4_REP = 0x33, /* FC-4 ELS reply */
+       /*
+        * Optional Extended Headers
+        */
+       FC_RCTL_VFTH = 0x50,    /* virtual fabric tagging header */
+       FC_RCTL_IFRH = 0x51,    /* inter-fabric routing header */
+       FC_RCTL_ENCH = 0x52,    /* encapsulation header */
+       /*
+        * Basic Link Services fh_r_ctl values.
+        */
+       FC_RCTL_BA_NOP = 0x80,  /* basic link service NOP */
+       FC_RCTL_BA_ABTS = 0x81, /* basic link service abort */
+       FC_RCTL_BA_RMC = 0x82,  /* remove connection */
+       FC_RCTL_BA_ACC = 0x84,  /* basic accept */
+       FC_RCTL_BA_RJT = 0x85,  /* basic reject */
+       FC_RCTL_BA_PRMT = 0x86, /* dedicated connection preempted */
+       /*
+        * Link Control Information.
+        */
+       FC_RCTL_ACK_1 = 0xc0,   /* acknowledge_1 */
+       FC_RCTL_ACK_0 = 0xc1,   /* acknowledge_0 */
+       FC_RCTL_P_RJT = 0xc2,   /* port reject */
+       FC_RCTL_F_RJT = 0xc3,   /* fabric reject */
+       FC_RCTL_P_BSY = 0xc4,   /* port busy */
+       FC_RCTL_F_BSY = 0xc5,   /* fabric busy to data frame */
+       FC_RCTL_F_BSYL = 0xc6,  /* fabric busy to link control frame */
+       FC_RCTL_LCR = 0xc7,     /* link credit reset */
+       FC_RCTL_END = 0xc9,     /* end */
+};
+                                   /* incomplete list of definitions */
+
+/*
+ * R_CTL names initializer.
+ * Please keep this matching the above definitions.
+ */
+#define FC_RCTL_NAMES_INIT { \
+       [FC_RCTL_DD_UNCAT] =            "uncat",                        \
+       [FC_RCTL_DD_SOL_DATA] =         "sol data",                     \
+       [FC_RCTL_DD_UNSOL_CTL] =        "unsol ctl",                    \
+       [FC_RCTL_DD_SOL_CTL] =          "sol ctl/reply",                \
+       [FC_RCTL_DD_UNSOL_DATA] =       "unsol data",                   \
+       [FC_RCTL_DD_DATA_DESC] =        "data desc",                    \
+       [FC_RCTL_DD_UNSOL_CMD] =        "unsol cmd",                    \
+       [FC_RCTL_DD_CMD_STATUS] =       "cmd status",                   \
+       [FC_RCTL_ELS_REQ] =             "ELS req",                      \
+       [FC_RCTL_ELS_REP] =             "ELS rep",                      \
+       [FC_RCTL_ELS4_REQ] =            "FC-4 ELS req",                 \
+       [FC_RCTL_ELS4_REP] =            "FC-4 ELS rep",                 \
+       [FC_RCTL_BA_NOP] =              "BLS NOP",                      \
+       [FC_RCTL_BA_ABTS] =             "BLS abort",                    \
+       [FC_RCTL_BA_RMC] =              "BLS remove connection",        \
+       [FC_RCTL_BA_ACC] =              "BLS accept",                   \
+       [FC_RCTL_BA_RJT] =              "BLS reject",                   \
+       [FC_RCTL_BA_PRMT] =             "BLS dedicated connection preempted", \
+       [FC_RCTL_ACK_1] =               "LC ACK_1",                     \
+       [FC_RCTL_ACK_0] =               "LC ACK_0",                     \
+       [FC_RCTL_P_RJT] =               "LC port reject",               \
+       [FC_RCTL_F_RJT] =               "LC fabric reject",             \
+       [FC_RCTL_P_BSY] =               "LC port busy",                 \
+       [FC_RCTL_F_BSY] =               "LC fabric busy to data frame", \
+       [FC_RCTL_F_BSYL] =              "LC fabric busy to link control frame",\
+       [FC_RCTL_LCR] =                 "LC link credit reset",         \
+       [FC_RCTL_END] =                 "LC end",                       \
+}
+
+/*
+ * Well-known fabric addresses.
+ */
+enum fc_well_known_fid {
+       FC_FID_NONE =           0x000000,       /* No destination */
+       FC_FID_BCAST =          0xffffff,       /* broadcast */
+       FC_FID_FLOGI =          0xfffffe,       /* fabric login */
+       FC_FID_FCTRL =          0xfffffd,       /* fabric controller */
+       FC_FID_DIR_SERV =       0xfffffc,       /* directory server */
+       FC_FID_TIME_SERV =      0xfffffb,       /* time server */
+       FC_FID_MGMT_SERV =      0xfffffa,       /* management server */
+       FC_FID_QOS =            0xfffff9,       /* QoS Facilitator */
+       FC_FID_ALIASES =        0xfffff8,       /* alias server (FC-PH2) */
+       FC_FID_SEC_KEY =        0xfffff7,       /* Security key dist. server */
+       FC_FID_CLOCK =          0xfffff6,       /* clock synch server */
+       FC_FID_MCAST_SERV =     0xfffff5,       /* multicast server */
+};
+
+#define        FC_FID_WELL_KNOWN_MAX   0xffffff /* highest well-known fabric ID */
+#define        FC_FID_WELL_KNOWN_BASE  0xfffff5 /* start of well-known fabric ID */
+
+/*
+ * Other well-known addresses, outside the above contiguous range.
+ */
+#define        FC_FID_DOM_MGR          0xfffc00        /* domain manager base */
+
+/*
+ * Fabric ID bytes.
+ */
+#define        FC_FID_DOMAIN           0
+#define        FC_FID_PORT             1
+#define        FC_FID_LINK             2
+
+/*
+ * fh_type codes
+ */
+enum fc_fh_type {
+       FC_TYPE_BLS =   0x00,   /* basic link service */
+       FC_TYPE_ELS =   0x01,   /* extended link service */
+       FC_TYPE_IP =    0x05,   /* IP over FC, RFC 4338 */
+       FC_TYPE_FCP =   0x08,   /* SCSI FCP */
+       FC_TYPE_CT =    0x20,   /* Fibre Channel Services (FC-CT) */
+       FC_TYPE_ILS =   0x22,   /* internal link service */
+};
+
+/*
+ * FC_TYPE names initializer.
+ * Please keep this matching the above definitions.
+ */
+#define FC_TYPE_NAMES_INIT {                           \
+       [FC_TYPE_BLS] =         "BLS",                  \
+       [FC_TYPE_ELS] =         "ELS",                  \
+       [FC_TYPE_IP] =          "IP",                   \
+       [FC_TYPE_FCP] =         "FCP",                  \
+       [FC_TYPE_CT] =          "CT",                   \
+       [FC_TYPE_ILS] =         "ILS",                  \
+}
+
+/*
+ * Exchange IDs.
+ */
+#define FC_XID_UNKNOWN  0xffff /* unknown exchange ID */
+#define FC_XID_MIN     0x0     /* supported min exchange ID */
+#define FC_XID_MAX     0xfffe  /* supported max exchange ID */
+
+/*
+ * fh_f_ctl - Frame control flags.
+ */
+#define        FC_FC_EX_CTX    (1 << 23)       /* sent by responder to exchange */
+#define        FC_FC_SEQ_CTX   (1 << 22)       /* sent by responder to sequence */
+#define        FC_FC_FIRST_SEQ (1 << 21)       /* first sequence of this exchange */
+#define        FC_FC_LAST_SEQ  (1 << 20)       /* last sequence of this exchange */
+#define        FC_FC_END_SEQ   (1 << 19)       /* last frame of sequence */
+#define        FC_FC_END_CONN  (1 << 18)       /* end of class 1 connection pending */
+#define        FC_FC_RES_B17   (1 << 17)       /* reserved */
+#define        FC_FC_SEQ_INIT  (1 << 16)       /* transfer of sequence initiative */
+#define        FC_FC_X_ID_REASS (1 << 15)      /* exchange ID has been changed */
+#define        FC_FC_X_ID_INVAL (1 << 14)      /* exchange ID invalidated */
+
+#define        FC_FC_ACK_1     (1 << 12)       /* 13:12 = 1: ACK_1 expected */
+#define        FC_FC_ACK_N     (2 << 12)       /* 13:12 = 2: ACK_N expected */
+#define        FC_FC_ACK_0     (3 << 12)       /* 13:12 = 3: ACK_0 expected */
+
+#define        FC_FC_RES_B11   (1 << 11)       /* reserved */
+#define        FC_FC_RES_B10   (1 << 10)       /* reserved */
+#define        FC_FC_RETX_SEQ  (1 << 9)        /* retransmitted sequence */
+#define        FC_FC_UNI_TX    (1 << 8)        /* unidirectional transmit (class 1) */
+#define        FC_FC_CONT_SEQ(i) ((i) << 6)
+#define        FC_FC_ABT_SEQ(i) ((i) << 4)
+#define        FC_FC_REL_OFF   (1 << 3)        /* parameter is relative offset */
+#define        FC_FC_RES2      (1 << 2)        /* reserved */
+#define        FC_FC_FILL(i)   ((i) & 3)       /* 1:0: bytes of trailing fill */
+
+/*
+ * BA_ACC payload.
+ */
+struct fc_ba_acc {
+       __u8            ba_seq_id_val;  /* SEQ_ID validity */
+#define FC_BA_SEQ_ID_VAL 0x80
+       __u8            ba_seq_id;      /* SEQ_ID of seq last deliverable */
+       __u8            ba_resvd[2];    /* reserved */
+       __be16          ba_ox_id;       /* OX_ID for aborted seq or exch */
+       __be16          ba_rx_id;       /* RX_ID for aborted seq or exch */
+       __be16          ba_low_seq_cnt; /* low SEQ_CNT of aborted seq */
+       __be16          ba_high_seq_cnt; /* high SEQ_CNT of aborted seq */
+};
+
+/*
+ * BA_RJT: Basic Reject payload.
+ */
+struct fc_ba_rjt {
+       __u8            br_resvd;       /* reserved */
+       __u8            br_reason;      /* reason code */
+       __u8            br_explan;      /* reason explanation */
+       __u8            br_vendor;      /* vendor unique code */
+};
+
+/*
+ * BA_RJT reason codes.
+ * From FS-2.
+ */
+enum fc_ba_rjt_reason {
+       FC_BA_RJT_NONE =        0,      /* in software this means no reject */
+       FC_BA_RJT_INVL_CMD =    0x01,   /* invalid command code */
+       FC_BA_RJT_LOG_ERR =     0x03,   /* logical error */
+       FC_BA_RJT_LOG_BUSY =    0x05,   /* logical busy */
+       FC_BA_RJT_PROTO_ERR =   0x07,   /* protocol error */
+       FC_BA_RJT_UNABLE =      0x09,   /* unable to perform request */
+       FC_BA_RJT_VENDOR =      0xff,   /* vendor-specific (see br_vendor) */
+};
+
+/*
+ * BA_RJT reason code explanations.
+ */
+enum fc_ba_rjt_explan {
+       FC_BA_RJT_EXP_NONE =    0x00,   /* no additional expanation */
+       FC_BA_RJT_INV_XID =     0x03,   /* invalid OX_ID-RX_ID combination */
+       FC_BA_RJT_ABT =         0x05,   /* sequence aborted, no seq info */
+};
+
+/*
+ * P_RJT or F_RJT: Port Reject or Fabric Reject parameter field.
+ */
+struct fc_pf_rjt {
+       __u8            rj_action;      /* reserved */
+       __u8            rj_reason;      /* reason code */
+       __u8            rj_resvd;       /* reserved */
+       __u8            rj_vendor;      /* vendor unique code */
+};
+
+/*
+ * P_RJT and F_RJT reject reason codes.
+ */
+enum fc_pf_rjt_reason {
+       FC_RJT_NONE =           0,      /* non-reject (reserved by standard) */
+       FC_RJT_INVL_DID =       0x01,   /* invalid destination ID */
+       FC_RJT_INVL_SID =       0x02,   /* invalid source ID */
+       FC_RJT_P_UNAV_T =       0x03,   /* port unavailable, temporary */
+       FC_RJT_P_UNAV =         0x04,   /* port unavailable, permanent */
+       FC_RJT_CLS_UNSUP =      0x05,   /* class not supported */
+       FC_RJT_DEL_USAGE =      0x06,   /* delimiter usage error */
+       FC_RJT_TYPE_UNSUP =     0x07,   /* type not supported */
+       FC_RJT_LINK_CTL =       0x08,   /* invalid link control */
+       FC_RJT_R_CTL =          0x09,   /* invalid R_CTL field */
+       FC_RJT_F_CTL =          0x0a,   /* invalid F_CTL field */
+       FC_RJT_OX_ID =          0x0b,   /* invalid originator exchange ID */
+       FC_RJT_RX_ID =          0x0c,   /* invalid responder exchange ID */
+       FC_RJT_SEQ_ID =         0x0d,   /* invalid sequence ID */
+       FC_RJT_DF_CTL =         0x0e,   /* invalid DF_CTL field */
+       FC_RJT_SEQ_CNT =        0x0f,   /* invalid SEQ_CNT field */
+       FC_RJT_PARAM =          0x10,   /* invalid parameter field */
+       FC_RJT_EXCH_ERR =       0x11,   /* exchange error */
+       FC_RJT_PROTO =          0x12,   /* protocol error */
+       FC_RJT_LEN =            0x13,   /* incorrect length */
+       FC_RJT_UNEXP_ACK =      0x14,   /* unexpected ACK */
+       FC_RJT_FAB_CLASS =      0x15,   /* class unsupported by fabric entity */
+       FC_RJT_LOGI_REQ =       0x16,   /* login required */
+       FC_RJT_SEQ_XS =         0x17,   /* excessive sequences attempted */
+       FC_RJT_EXCH_EST =       0x18,   /* unable to establish exchange */
+       FC_RJT_FAB_UNAV =       0x1a,   /* fabric unavailable */
+       FC_RJT_VC_ID =          0x1b,   /* invalid VC_ID (class 4) */
+       FC_RJT_CS_CTL =         0x1c,   /* invalid CS_CTL field */
+       FC_RJT_INSUF_RES =      0x1d,   /* insuff. resources for VC (Class 4) */
+       FC_RJT_INVL_CLS =       0x1f,   /* invalid class of service */
+       FC_RJT_PREEMT_RJT =     0x20,   /* preemption request rejected */
+       FC_RJT_PREEMT_DIS =     0x21,   /* preemption not enabled */
+       FC_RJT_MCAST_ERR =      0x22,   /* multicast error */
+       FC_RJT_MCAST_ET =       0x23,   /* multicast error terminate */
+       FC_RJT_PRLI_REQ =       0x24,   /* process login required */
+       FC_RJT_INVL_ATT =       0x25,   /* invalid attachment */
+       FC_RJT_VENDOR =         0xff,   /* vendor specific reject */
+};
+
+/* default timeout values */
+
+#define FC_DEF_E_D_TOV 2000UL
+#define FC_DEF_R_A_TOV 10000UL
+
+#endif /* _FC_FS_H_ */
diff --git a/include/uapi/scsi/fc/fc_gs.h b/include/uapi/scsi/fc/fc_gs.h
new file mode 100644 (file)
index 0000000..a37346d
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright(c) 2007 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#ifndef _FC_GS_H_
+#define        _FC_GS_H_
+
+#include <linux/types.h>
+
+/*
+ * Fibre Channel Services - Common Transport.
+ * From T11.org FC-GS-2 Rev 5.3 November 1998.
+ */
+
+struct fc_ct_hdr {
+       __u8            ct_rev;         /* revision */
+       __u8            ct_in_id[3];    /* N_Port ID of original requestor */
+       __u8            ct_fs_type;     /* type of fibre channel service */
+       __u8            ct_fs_subtype;  /* subtype */
+       __u8            ct_options;
+       __u8            _ct_resvd1;
+       __be16          ct_cmd;         /* command / response code */
+       __be16          ct_mr_size;     /* maximum / residual size */
+       __u8            _ct_resvd2;
+       __u8            ct_reason;      /* reject reason */
+       __u8            ct_explan;      /* reason code explanation */
+       __u8            ct_vendor;      /* vendor unique data */
+};
+
+#define        FC_CT_HDR_LEN   16      /* expected sizeof (struct fc_ct_hdr) */
+
+enum fc_ct_rev {
+       FC_CT_REV = 1           /* common transport revision */
+};
+
+/*
+ * ct_fs_type values.
+ */
+enum fc_ct_fs_type {
+       FC_FST_ALIAS =  0xf8,   /* alias service */
+       FC_FST_MGMT =   0xfa,   /* management service */
+       FC_FST_TIME =   0xfb,   /* time service */
+       FC_FST_DIR =    0xfc,   /* directory service */
+};
+
+/*
+ * ct_cmd: Command / response codes
+ */
+enum fc_ct_cmd {
+       FC_FS_RJT =     0x8001, /* reject */
+       FC_FS_ACC =     0x8002, /* accept */
+};
+
+/*
+ * FS_RJT reason codes.
+ */
+enum fc_ct_reason {
+       FC_FS_RJT_CMD =         0x01,   /* invalid command code */
+       FC_FS_RJT_VER =         0x02,   /* invalid version level */
+       FC_FS_RJT_LOG =         0x03,   /* logical error */
+       FC_FS_RJT_IUSIZ =       0x04,   /* invalid IU size */
+       FC_FS_RJT_BSY =         0x05,   /* logical busy */
+       FC_FS_RJT_PROTO =       0x07,   /* protocol error */
+       FC_FS_RJT_UNABL =       0x09,   /* unable to perform command request */
+       FC_FS_RJT_UNSUP =       0x0b,   /* command not supported */
+};
+
+/*
+ * FS_RJT reason code explanations.
+ */
+enum fc_ct_explan {
+       FC_FS_EXP_NONE =        0x00,   /* no additional explanation */
+       FC_FS_EXP_PID =         0x01,   /* port ID not registered */
+       FC_FS_EXP_PNAM =        0x02,   /* port name not registered */
+       FC_FS_EXP_NNAM =        0x03,   /* node name not registered */
+       FC_FS_EXP_COS =         0x04,   /* class of service not registered */
+       FC_FS_EXP_FTNR =        0x07,   /* FC-4 types not registered */
+       /* definitions not complete */
+};
+
+#endif /* _FC_GS_H_ */
diff --git a/include/uapi/scsi/fc/fc_ns.h b/include/uapi/scsi/fc/fc_ns.h
new file mode 100644 (file)
index 0000000..f7751d5
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright(c) 2007 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#ifndef _FC_NS_H_
+#define        _FC_NS_H_
+
+#include <linux/types.h>
+
+/*
+ * Fibre Channel Services - Name Service (dNS)
+ * From T11.org FC-GS-2 Rev 5.3 November 1998.
+ */
+
+/*
+ * Common-transport sub-type for Name Server.
+ */
+#define        FC_NS_SUBTYPE       2   /* fs_ct_hdr.ct_fs_subtype */
+
+/*
+ * Name server Requests.
+ * Note:  this is an incomplete list, some unused requests are omitted.
+ */
+enum fc_ns_req {
+       FC_NS_GA_NXT =  0x0100,         /* get all next */
+       FC_NS_GI_A =    0x0101,         /* get identifiers - scope */
+       FC_NS_GPN_ID =  0x0112,         /* get port name by ID */
+       FC_NS_GNN_ID =  0x0113,         /* get node name by ID */
+       FC_NS_GSPN_ID = 0x0118,         /* get symbolic port name */
+       FC_NS_GID_PN =  0x0121,         /* get ID for port name */
+       FC_NS_GID_NN =  0x0131,         /* get IDs for node name */
+       FC_NS_GID_FT =  0x0171,         /* get IDs by FC4 type */
+       FC_NS_GPN_FT =  0x0172,         /* get port names by FC4 type */
+       FC_NS_GID_PT =  0x01a1,         /* get IDs by port type */
+       FC_NS_RPN_ID =  0x0212,         /* reg port name for ID */
+       FC_NS_RNN_ID =  0x0213,         /* reg node name for ID */
+       FC_NS_RFT_ID =  0x0217,         /* reg FC4 type for ID */
+       FC_NS_RSPN_ID = 0x0218,         /* reg symbolic port name */
+       FC_NS_RFF_ID =  0x021f,         /* reg FC4 Features for ID */
+       FC_NS_RSNN_NN = 0x0239,         /* reg symbolic node name */
+};
+
+/*
+ * Port type values.
+ */
+enum fc_ns_pt {
+       FC_NS_UNID_PORT = 0x00, /* unidentified */
+       FC_NS_N_PORT =  0x01,   /* N port */
+       FC_NS_NL_PORT = 0x02,   /* NL port */
+       FC_NS_FNL_PORT = 0x03,  /* F/NL port */
+       FC_NS_NX_PORT = 0x7f,   /* Nx port */
+       FC_NS_F_PORT =  0x81,   /* F port */
+       FC_NS_FL_PORT = 0x82,   /* FL port */
+       FC_NS_E_PORT =  0x84,   /* E port */
+       FC_NS_B_PORT =  0x85,   /* B port */
+};
+
+/*
+ * Port type object.
+ */
+struct fc_ns_pt_obj {
+       __u8            pt_type;
+};
+
+/*
+ * Port ID object
+ */
+struct fc_ns_fid {
+       __u8            fp_flags;       /* flags for responses only */
+       __u8            fp_fid[3];
+};
+
+/*
+ * fp_flags in port ID object, for responses only.
+ */
+#define        FC_NS_FID_LAST  0x80            /* last object */
+
+/*
+ * FC4-types object.
+ */
+#define        FC_NS_TYPES     256     /* number of possible FC-4 types */
+#define        FC_NS_BPW       32      /* bits per word in bitmap */
+
+struct fc_ns_fts {
+       __be32  ff_type_map[FC_NS_TYPES / FC_NS_BPW]; /* bitmap of FC-4 types */
+};
+
+/*
+ * FC4-features object.
+ */
+struct fc_ns_ff        {
+       __be32  fd_feat[FC_NS_TYPES * 4 / FC_NS_BPW]; /* 4-bits per FC-type */
+};
+
+/*
+ * GID_PT request.
+ */
+struct fc_ns_gid_pt {
+       __u8            fn_pt_type;
+       __u8            fn_domain_id_scope;
+       __u8            fn_area_id_scope;
+       __u8            fn_resvd;
+};
+
+/*
+ * GID_FT or GPN_FT request.
+ */
+struct fc_ns_gid_ft {
+       __u8            fn_resvd;
+       __u8            fn_domain_id_scope;
+       __u8            fn_area_id_scope;
+       __u8            fn_fc4_type;
+};
+
+/*
+ * GPN_FT response.
+ */
+struct fc_gpn_ft_resp {
+       __u8            fp_flags;       /* see fp_flags definitions above */
+       __u8            fp_fid[3];      /* port ID */
+       __be32          fp_resvd;
+       __be64          fp_wwpn;        /* port name */
+};
+
+/*
+ * GID_PN request
+ */
+struct fc_ns_gid_pn {
+       __be64     fn_wwpn;    /* port name */
+};
+
+/*
+ * GID_PN response or GSPN_ID request
+ */
+struct fc_gid_pn_resp {
+       __u8      fp_resvd;
+       __u8      fp_fid[3];     /* port ID */
+};
+
+/*
+ * GSPN_ID response
+ */
+struct fc_gspn_resp {
+       __u8    fp_name_len;
+       char    fp_name[];
+};
+
+/*
+ * RFT_ID request - register FC-4 types for ID.
+ */
+struct fc_ns_rft_id {
+       struct fc_ns_fid fr_fid;        /* port ID object */
+       struct fc_ns_fts fr_fts;        /* FC-4 types object */
+};
+
+/*
+ * RPN_ID request - register port name for ID.
+ * RNN_ID request - register node name for ID.
+ */
+struct fc_ns_rn_id {
+       struct fc_ns_fid fr_fid;        /* port ID object */
+       __be64          fr_wwn;         /* node name or port name */
+} __attribute__((__packed__));
+
+/*
+ * RSNN_NN request - register symbolic node name
+ */
+struct fc_ns_rsnn {
+       __be64          fr_wwn;         /* node name */
+       __u8            fr_name_len;
+       char            fr_name[];
+} __attribute__((__packed__));
+
+/*
+ * RSPN_ID request - register symbolic port name
+ */
+struct fc_ns_rspn {
+       struct fc_ns_fid fr_fid;        /* port ID object */
+       __u8            fr_name_len;
+       char            fr_name[];
+} __attribute__((__packed__));
+
+/*
+ * RFF_ID request - register FC-4 Features for ID.
+ */
+struct fc_ns_rff_id {
+       struct fc_ns_fid fr_fid;        /* port ID object */
+       __u8            fr_resvd[2];
+       __u8            fr_feat;        /* FC-4 Feature bits */
+       __u8            fr_type;        /* FC-4 type */
+} __attribute__((__packed__));
+
+#endif /* _FC_NS_H_ */