diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-29 01:44:18 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-29 01:44:18 +0200 |
commit | ec7ae517537ae5c7b0b2cd7f562dfa3e7a05b954 (patch) | |
tree | e6b0c64a51a7c0aa0efd09d4f7a80872e3b1657a /drivers/scsi/fcoe | |
parent | Merge branch 'for-linus' of git://ceph.newdream.net/git/ceph-client (diff) | |
parent | [SCSI] qla4xxx: export address/port of connection (fix udev disk names) (diff) | |
download | linux-ec7ae517537ae5c7b0b2cd7f562dfa3e7a05b954.tar.xz linux-ec7ae517537ae5c7b0b2cd7f562dfa3e7a05b954.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (204 commits)
[SCSI] qla4xxx: export address/port of connection (fix udev disk names)
[SCSI] ipr: Fix BUG on adapter dump timeout
[SCSI] megaraid_sas: Fix instance access in megasas_reset_timer
[SCSI] hpsa: change confusing message to be more clear
[SCSI] iscsi class: fix vlan configuration
[SCSI] qla4xxx: fix data alignment and use nl helpers
[SCSI] iscsi class: fix link local mispelling
[SCSI] iscsi class: Replace iscsi_get_next_target_id with IDA
[SCSI] aacraid: use lower snprintf() limit
[SCSI] lpfc 8.3.27: Change driver version to 8.3.27
[SCSI] lpfc 8.3.27: T10 additions for SLI4
[SCSI] lpfc 8.3.27: Fix queue allocation failure recovery
[SCSI] lpfc 8.3.27: Change algorithm for getting physical port name
[SCSI] lpfc 8.3.27: Changed worst case mailbox timeout
[SCSI] lpfc 8.3.27: Miscellanous logic and interface fixes
[SCSI] megaraid_sas: Changelog and version update
[SCSI] megaraid_sas: Add driver workaround for PERC5/1068 kdump kernel panic
[SCSI] megaraid_sas: Add multiple MSI-X vector/multiple reply queue support
[SCSI] megaraid_sas: Add support for MegaRAID 9360/9380 12GB/s controllers
[SCSI] megaraid_sas: Clear FUSION_IN_RESET before enabling interrupts
...
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 103 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.h | 11 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe_transport.c | 101 |
3 files changed, 116 insertions, 99 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index a1c0ddd53aa9..61384ee4049b 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -51,7 +51,7 @@ MODULE_DESCRIPTION("FCoE"); MODULE_LICENSE("GPL v2"); /* Performance tuning parameters for fcoe */ -static unsigned int fcoe_ddp_min; +static unsigned int fcoe_ddp_min = 4096; module_param_named(ddp_min, fcoe_ddp_min, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \ "Direct Data Placement (DDP)."); @@ -137,7 +137,6 @@ 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 int fcoe_validate_vport_create(struct fc_vport *); static struct libfc_function_template fcoe_libfc_fcn_templ = { .frame_send = fcoe_xmit, @@ -280,6 +279,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, * use the first one for SPMA */ real_dev = (netdev->priv_flags & IFF_802_1Q_VLAN) ? vlan_dev_real_dev(netdev) : netdev; + fcoe->realdev = real_dev; rcu_read_lock(); for_each_dev_addr(real_dev, ha) { if ((ha->type == NETDEV_HW_ADDR_T_SAN) && @@ -580,23 +580,6 @@ static int fcoe_lport_config(struct fc_lport *lport) } /** - * fcoe_get_wwn() - Get the world wide name from LLD if it supports it - * @netdev: the associated net device - * @wwn: the output WWN - * @type: the type of WWN (WWPN or WWNN) - * - * Returns: 0 for success - */ -static int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) -{ - const struct net_device_ops *ops = netdev->netdev_ops; - - if (ops->ndo_fcoe_get_wwn) - return ops->ndo_fcoe_get_wwn(netdev, wwn, type); - return -EINVAL; -} - -/** * fcoe_netdev_features_change - Updates the lport's offload flags based * on the LLD netdev's FCoE feature flags */ @@ -1134,8 +1117,9 @@ static void fcoe_percpu_thread_create(unsigned int cpu) p = &per_cpu(fcoe_percpu, cpu); - thread = kthread_create(fcoe_percpu_receive_thread, - (void *)p, "fcoethread/%d", cpu); + thread = kthread_create_on_node(fcoe_percpu_receive_thread, + (void *)p, cpu_to_node(cpu), + "fcoethread/%d", cpu); if (likely(!IS_ERR(thread))) { kthread_bind(thread, cpu); @@ -1538,7 +1522,13 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) skb_reset_network_header(skb); skb->mac_len = elen; skb->protocol = htons(ETH_P_FCOE); - skb->dev = fcoe->netdev; + if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN && + fcoe->realdev->features & NETIF_F_HW_VLAN_TX) { + skb->vlan_tci = VLAN_TAG_PRESENT | + vlan_dev_vlan_id(fcoe->netdev); + skb->dev = fcoe->realdev; + } else + skb->dev = fcoe->netdev; /* fill up mac and fcoe headers */ eh = eth_hdr(skb); @@ -2446,7 +2436,7 @@ static int fcoe_vport_create(struct fc_vport *vport, bool disabled) rc = fcoe_validate_vport_create(vport); if (rc) { - wwn_to_str(vport->port_name, buf, sizeof(buf)); + fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf)); printk(KERN_ERR "fcoe: Failed to create vport, " "WWPN (0x%s) already exists\n", buf); @@ -2555,28 +2545,9 @@ static void fcoe_set_vport_symbolic_name(struct fc_vport *vport) static void fcoe_get_lesb(struct fc_lport *lport, struct fc_els_lesb *fc_lesb) { - unsigned int cpu; - u32 lfc, vlfc, mdac; - struct fcoe_dev_stats *devst; - struct fcoe_fc_els_lesb *lesb; - struct rtnl_link_stats64 temp; struct net_device *netdev = fcoe_netdev(lport); - lfc = 0; - vlfc = 0; - mdac = 0; - lesb = (struct fcoe_fc_els_lesb *)fc_lesb; - memset(lesb, 0, sizeof(*lesb)); - for_each_possible_cpu(cpu) { - devst = per_cpu_ptr(lport->dev_stats, cpu); - lfc += devst->LinkFailureCount; - vlfc += devst->VLinkFailureCount; - mdac += devst->MissDiscAdvCount; - } - lesb->lesb_link_fail = htonl(lfc); - lesb->lesb_vlink_fail = htonl(vlfc); - lesb->lesb_miss_fka = htonl(mdac); - lesb->lesb_fcs_error = htonl(dev_get_stats(netdev, &temp)->rx_crc_errors); + __fcoe_get_lesb(lport, fc_lesb, netdev); } /** @@ -2600,49 +2571,3 @@ static void fcoe_set_port_id(struct fc_lport *lport, if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); } - -/** - * fcoe_validate_vport_create() - Validate a vport before creating it - * @vport: NPIV port to be created - * - * This routine is meant to add validation for a vport before creating it - * via fcoe_vport_create(). - * Current validations are: - * - WWPN supplied is unique for given lport - * - * -*/ -static int fcoe_validate_vport_create(struct fc_vport *vport) -{ - struct Scsi_Host *shost = vport_to_shost(vport); - struct fc_lport *n_port = shost_priv(shost); - struct fc_lport *vn_port; - int rc = 0; - char buf[32]; - - mutex_lock(&n_port->lp_mutex); - - wwn_to_str(vport->port_name, buf, sizeof(buf)); - /* Check if the wwpn is not same as that of the lport */ - if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) { - FCOE_DBG("vport WWPN 0x%s is same as that of the " - "base port WWPN\n", buf); - rc = -EINVAL; - goto out; - } - - /* Check if there is any existing vport with same wwpn */ - list_for_each_entry(vn_port, &n_port->vports, list) { - if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) { - FCOE_DBG("vport with given WWPN 0x%s already " - "exists\n", buf); - rc = -EINVAL; - break; - } - } - -out: - mutex_unlock(&n_port->lp_mutex); - - return rc; -} diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h index c4a93993c0cf..6c6884bcf840 100644 --- a/drivers/scsi/fcoe/fcoe.h +++ b/drivers/scsi/fcoe/fcoe.h @@ -80,6 +80,7 @@ do { \ struct fcoe_interface { struct list_head list; struct net_device *netdev; + struct net_device *realdev; struct packet_type fcoe_packet_type; struct packet_type fip_packet_type; struct fcoe_ctlr ctlr; @@ -99,14 +100,4 @@ static inline struct net_device *fcoe_netdev(const struct fc_lport *lport) ((struct fcoe_port *)lport_priv(lport))->priv)->netdev; } -static inline void wwn_to_str(u64 wwn, char *buf, int len) -{ - u8 wwpn[8]; - - u64_to_wwn(wwn, wwpn); - snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x", - wwpn[0], wwpn[1], wwpn[2], wwpn[3], - wwpn[4], wwpn[5], wwpn[6], wwpn[7]); -} - #endif /* _FCOE_H_ */ diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index dac8e39a5188..bd97b2273f20 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -83,6 +83,107 @@ static struct notifier_block libfcoe_notifier = { .notifier_call = libfcoe_device_notification, }; +void __fcoe_get_lesb(struct fc_lport *lport, + struct fc_els_lesb *fc_lesb, + struct net_device *netdev) +{ + unsigned int cpu; + u32 lfc, vlfc, mdac; + struct fcoe_dev_stats *devst; + struct fcoe_fc_els_lesb *lesb; + struct rtnl_link_stats64 temp; + + lfc = 0; + vlfc = 0; + mdac = 0; + lesb = (struct fcoe_fc_els_lesb *)fc_lesb; + memset(lesb, 0, sizeof(*lesb)); + for_each_possible_cpu(cpu) { + devst = per_cpu_ptr(lport->dev_stats, cpu); + lfc += devst->LinkFailureCount; + vlfc += devst->VLinkFailureCount; + mdac += devst->MissDiscAdvCount; + } + lesb->lesb_link_fail = htonl(lfc); + lesb->lesb_vlink_fail = htonl(vlfc); + lesb->lesb_miss_fka = htonl(mdac); + lesb->lesb_fcs_error = + htonl(dev_get_stats(netdev, &temp)->rx_crc_errors); +} +EXPORT_SYMBOL_GPL(__fcoe_get_lesb); + +void fcoe_wwn_to_str(u64 wwn, char *buf, int len) +{ + u8 wwpn[8]; + + u64_to_wwn(wwn, wwpn); + snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x", + wwpn[0], wwpn[1], wwpn[2], wwpn[3], + wwpn[4], wwpn[5], wwpn[6], wwpn[7]); +} +EXPORT_SYMBOL_GPL(fcoe_wwn_to_str); + +/** + * fcoe_validate_vport_create() - Validate a vport before creating it + * @vport: NPIV port to be created + * + * This routine is meant to add validation for a vport before creating it + * via fcoe_vport_create(). + * Current validations are: + * - WWPN supplied is unique for given lport + */ +int fcoe_validate_vport_create(struct fc_vport *vport) +{ + struct Scsi_Host *shost = vport_to_shost(vport); + struct fc_lport *n_port = shost_priv(shost); + struct fc_lport *vn_port; + int rc = 0; + char buf[32]; + + mutex_lock(&n_port->lp_mutex); + + fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf)); + /* Check if the wwpn is not same as that of the lport */ + if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) { + LIBFCOE_TRANSPORT_DBG("vport WWPN 0x%s is same as that of the " + "base port WWPN\n", buf); + rc = -EINVAL; + goto out; + } + + /* Check if there is any existing vport with same wwpn */ + list_for_each_entry(vn_port, &n_port->vports, list) { + if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) { + LIBFCOE_TRANSPORT_DBG("vport with given WWPN 0x%s " + "already exists\n", buf); + rc = -EINVAL; + break; + } + } +out: + mutex_unlock(&n_port->lp_mutex); + return rc; +} +EXPORT_SYMBOL_GPL(fcoe_validate_vport_create); + +/** + * fcoe_get_wwn() - Get the world wide name from LLD if it supports it + * @netdev: the associated net device + * @wwn: the output WWN + * @type: the type of WWN (WWPN or WWNN) + * + * Returns: 0 for success + */ +int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) +{ + const struct net_device_ops *ops = netdev->netdev_ops; + + if (ops->ndo_fcoe_get_wwn) + return ops->ndo_fcoe_get_wwn(netdev, wwn, type); + return -EINVAL; +} +EXPORT_SYMBOL_GPL(fcoe_get_wwn); + /** * fcoe_fc_crc() - Calculates the CRC for a given frame * @fp: The frame to be checksumed |