From 38eccabd1067b93af0fedbf447ab846e7df1ca66 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Tue, 17 Mar 2009 11:41:30 -0700 Subject: [SCSI] fcoe: Initialize all possilbe skb_queue(s) when module is loaded Currently the skb_queue is initialized every time the associated CPU goes online. This patch has libfcoe initializing the skb_queue for all possible CPUs when the module is loaded. This patch also re-orders some declarations in the fcoe_rcv() function so the structure declarations are grouped before the primitive declarations. Lastly, this patch converts all CPU indicies to use unsigned int since CPU indicies should not be negative. Signed-off-by: Robert Love Signed-off-by: James Bottomley --- include/scsi/libfcoe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/scsi/libfcoe.h') diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index c41f7d0c6efc..124dc5bd9f87 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -29,7 +29,7 @@ * this percpu struct for fcoe */ struct fcoe_percpu_s { - int cpu; + unsigned int cpu; struct task_struct *thread; struct sk_buff_head fcoe_rx_list; struct page *crc_eof_page; -- cgit v1.2.2 From 5e5e92df49d4dfbef9ba981297c7f76d189376ac Mon Sep 17 00:00:00 2001 From: Robert Love Date: Tue, 17 Mar 2009 11:41:35 -0700 Subject: [SCSI] fcoe: Use percpu kernel funcs for struct fcoe_percpu_s Convert fcoe_percpu array to use the per-cpu variables that the kernel provides. Use the kernel's functions to access this structure. The cpu member of the fcoe_percpu_s is no longer needed, so this patch removes it too. Signed-off-by: Yi Zou Signed-off-by: Robert Love Signed-off-by: James Bottomley --- include/scsi/libfcoe.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/scsi/libfcoe.h') diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index 124dc5bd9f87..1ad4f93d5548 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -29,7 +29,6 @@ * this percpu struct for fcoe */ struct fcoe_percpu_s { - unsigned int cpu; struct task_struct *thread; struct sk_buff_head fcoe_rx_list; struct page *crc_eof_page; -- cgit v1.2.2 From 5919a59503577c2dc6eaa8bfba0f7bde3f9924ba Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Fri, 27 Mar 2009 09:03:29 -0700 Subject: [SCSI] fcoe: prep work to completely remove fc_transport_fcoe code The fcoe transport code was added for generic FCoE transport infrastructure to allow additional offload related module loading on demand, this is not required anymore after recently added different offload approach by having offload related func ops in netdev. This patch removes fcoe transport related code use, calls functions directly between existing libfcoe.c and fcoe_sw.c for now, for example fcoe_sw_destroy and fcoe_sw_create calling. The fcoe_sw.c and libfcoe.c code will be further consolidated in later patches and then also the default fcoe sw transport code file fcoe_sw.c will be completely removed. The fcoe transport code files are completely removed in next patch to keep this patch simple for reviewing. [This patch is an update to a previous patch. This update resolves a build error as well as fixes a defect related to not calling fc_release_transport().] Signed-off-by: Vasu Dev Signed-off-by: Robert Love Signed-off-by: James Bottomley --- include/scsi/libfcoe.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/scsi/libfcoe.h') diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index 1ad4f93d5548..dc64405b5814 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -149,4 +149,6 @@ int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); /* fcoe sw hba */ int __init fcoe_sw_init(void); int __exit fcoe_sw_exit(void); +int fcoe_sw_create(struct net_device *); +int fcoe_sw_destroy(struct net_device *); #endif /* _LIBFCOE_H */ -- cgit v1.2.2 From 7f3491429553cbff20367851fb897c449d028393 Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Fri, 27 Mar 2009 09:06:31 -0700 Subject: [SCSI] fcoe: removes default sw transport code file fcoe_sw.c Moves only required code from fcoe_sw.c to libfcoe.c towards having just one source file for fcoe module, this gets rid off default sw transport code in a separate fcoe_sw.c file. Very minor renaming along this move, dropped _sw_ or _SW_ use in names and replaced them by _if_ as a auxiliary interface functions. Now some of these funcs can be removed or merged with other func after fcoe transport is gone, but that should be in another patch to keep this patch simple. Now the libfcoe.c file name for fcoe module doesn't go along well, so the libfcoe.c file renaming to fcoe.c as the only single fcoe module file is done in next patch to keep this patch clean and small for review. Signed-off-by: Vasu Dev Signed-off-by: Robert Love Signed-off-by: James Bottomley --- include/scsi/libfcoe.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/scsi/libfcoe.h') diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index dc64405b5814..e99633cefd37 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -145,10 +145,4 @@ int fcoe_hostlist_remove(const struct fc_lport *); struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int); int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); - -/* fcoe sw hba */ -int __init fcoe_sw_init(void); -int __exit fcoe_sw_exit(void); -int fcoe_sw_create(struct net_device *); -int fcoe_sw_destroy(struct net_device *); #endif /* _LIBFCOE_H */ -- cgit v1.2.2 From fdd78027fd472351783fb6110a72d991c1a07402 Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Tue, 17 Mar 2009 11:42:24 -0700 Subject: [SCSI] fcoe: cleans up libfcoe.h and adds fcoe.h for fcoe module Removes no where used several inline functions prefixed with skb_* and be16_to_cpu. Moves fcoe module specific func prototypes to fcoe.c from libfcoe.h, moved only need for build. Adds fcoe module header file fcoe.h and then moves fcoe module specific fcoe_percpu_s and fcoe_softc to fcoe.h from libfcoe.h. Moves all defines from fcoe.c to fcoe.h since now fcoe module has its own header file fcoe.h. [jejb: removed EXPORT_SYMBOL_GPL(fcoe_fc_crc) which caused a section mismatch] Signed-off-by: Vasu Dev Signed-off-by: Robert Love Signed-off-by: James Bottomley --- include/scsi/libfcoe.h | 120 +------------------------------------------------ 1 file changed, 2 insertions(+), 118 deletions(-) (limited to 'include/scsi/libfcoe.h') diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index e99633cefd37..d07ebe688403 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -25,124 +25,8 @@ #include #include -/* - * this percpu struct for fcoe - */ -struct fcoe_percpu_s { - struct task_struct *thread; - struct sk_buff_head fcoe_rx_list; - struct page *crc_eof_page; - int crc_eof_offset; -}; - -/* - * the fcoe sw transport private data - */ -struct fcoe_softc { - struct list_head list; - struct fc_lport *lp; - struct net_device *real_dev; - struct net_device *phys_dev; /* device with ethtool_ops */ - struct packet_type fcoe_packet_type; - struct sk_buff_head fcoe_pending_queue; - u8 fcoe_pending_queue_active; - - u8 dest_addr[ETH_ALEN]; - u8 ctl_src_addr[ETH_ALEN]; - u8 data_src_addr[ETH_ALEN]; - /* - * fcoe protocol address learning related stuff - */ - u16 flogi_oxid; - u8 flogi_progress; - u8 address_mode; -}; - -static inline struct net_device *fcoe_netdev( - const struct fc_lport *lp) -{ - return ((struct fcoe_softc *)lport_priv(lp))->real_dev; -} - -static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb) -{ - return (struct fcoe_hdr *)skb_network_header(skb); -} - -static inline int skb_fcoe_offset(const struct sk_buff *skb) -{ - return skb_network_offset(skb); -} - -static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb) -{ - return (struct fc_frame_header *)skb_transport_header(skb); -} - -static inline int skb_fc_offset(const struct sk_buff *skb) -{ - return skb_transport_offset(skb); -} - -static inline void skb_reset_fc_header(struct sk_buff *skb) -{ - skb_reset_network_header(skb); - skb_set_transport_header(skb, skb_network_offset(skb) + - sizeof(struct fcoe_hdr)); -} - -static inline bool skb_fc_is_data(const struct sk_buff *skb) -{ - return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA; -} - -static inline bool skb_fc_is_cmd(const struct sk_buff *skb) -{ - return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD; -} - -static inline bool skb_fc_has_exthdr(const struct sk_buff *skb) -{ - return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) || - (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) || - (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH); -} - -static inline bool skb_fc_is_roff(const struct sk_buff *skb) -{ - return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF; -} - -static inline u16 skb_fc_oxid(const struct sk_buff *skb) -{ - return be16_to_cpu(skb_fc_header(skb)->fh_ox_id); -} - -static inline u16 skb_fc_rxid(const struct sk_buff *skb) -{ - return be16_to_cpu(skb_fc_header(skb)->fh_rx_id); -} - /* libfcoe funcs */ -int fcoe_reset(struct Scsi_Host *shost); -u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], - unsigned int scheme, unsigned int port); - -u32 fcoe_fc_crc(struct fc_frame *fp); -int fcoe_xmit(struct fc_lport *, struct fc_frame *); -int fcoe_rcv(struct sk_buff *, struct net_device *, - struct packet_type *, struct net_device *); - -int fcoe_percpu_receive_thread(void *arg); -void fcoe_clean_pending_queue(struct fc_lport *lp); -void fcoe_percpu_clean(struct fc_lport *lp); -void fcoe_watchdog(ulong vp); -int fcoe_link_ok(struct fc_lport *lp); - -struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); -int fcoe_hostlist_add(const struct fc_lport *); -int fcoe_hostlist_remove(const struct fc_lport *); - -struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int); +u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); + #endif /* _LIBFCOE_H */ -- cgit v1.2.2 From 97c8389d54b9665c38105ea72a428a44b97ff2f6 Mon Sep 17 00:00:00 2001 From: Joe Eykholt Date: Tue, 17 Mar 2009 11:42:40 -0700 Subject: [SCSI] fcoe, libfcoe: Add support for FIP. FCoE discovery and keep-alive. FIP is the new standard way to discover Fibre-Channel Forwarders (FCFs) by sending solicitations and listening for advertisements from FCFs. It also provides for keep-alives and period advertisements so that both parties know they have connectivity. If the FCF loses connectivity to the storage fabric, it can send a Link Reset to inform the E_node. This version is also compatible with pre-FIP implementations, so no configured selection between FIP mode and non-FIP mode is required. We wait a couple seconds after sending the initial solicitation and then send an old-style FLOGI. If we receive any FIP frames, we use FIP only mode. If the old FLOGI receives a response, we disable FIP mode. After every reset or link up, this determination is repeated. Signed-off-by: Joe Eykholt Signed-off-by: Vasu Dev Signed-off-by: Robert Love Signed-off-by: James Bottomley --- include/scsi/libfcoe.h | 134 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) (limited to 'include/scsi/libfcoe.h') diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index d07ebe688403..666cc131732e 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -1,5 +1,6 @@ /* - * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. + * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2007-2008 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, @@ -20,11 +21,142 @@ #ifndef _LIBFCOE_H #define _LIBFCOE_H +#include +#include #include #include +#include #include #include +/* + * FIP tunable parameters. + */ +#define FCOE_CTLR_START_DELAY 2000 /* mS after first adv. to choose FCF */ +#define FCOE_CTRL_SOL_TOV 2000 /* min. solicitation interval (mS) */ +#define FCOE_CTLR_FCF_LIMIT 20 /* max. number of FCF entries */ + +/** + * enum fip_state - internal state of FCoE controller. + * @FIP_ST_DISABLED: controller has been disabled or not yet enabled. + * @FIP_ST_LINK_WAIT: the physical link is down or unusable. + * @FIP_ST_AUTO: determining whether to use FIP or non-FIP mode. + * @FIP_ST_NON_FIP: non-FIP mode selected. + * @FIP_ST_ENABLED: FIP mode selected. + */ +enum fip_state { + FIP_ST_DISABLED, + FIP_ST_LINK_WAIT, + FIP_ST_AUTO, + FIP_ST_NON_FIP, + FIP_ST_ENABLED, +}; + +/** + * struct fcoe_ctlr - FCoE Controller and FIP state. + * @state: internal FIP state for network link and FIP or non-FIP mode. + * @lp: &fc_lport: libfc local port. + * @sel_fcf: currently selected FCF, or NULL. + * @fcfs: list of discovered FCFs. + * @fcf_count: number of discovered FCF entries. + * @sol_time: time when a multicast solicitation was last sent. + * @sel_time: time after which to select an FCF. + * @port_ka_time: time of next port keep-alive. + * @ctlr_ka_time: time of next controller keep-alive. + * @timer: timer struct used for all delayed events. + * @link_work: &work_struct for doing FCF selection. + * @recv_work: &work_struct for receiving FIP frames. + * @fip_recv_list: list of received FIP frames. + * @user_mfs: configured maximum FC frame size, including FC header. + * @flogi_oxid: exchange ID of most recent fabric login. + * @flogi_count: number of FLOGI attempts in AUTO mode. + * @link: current link status for libfc. + * @last_link: last link state reported to libfc. + * @map_dest: use the FC_MAP mode for destination MAC addresses. + * @dest_addr: MAC address of the selected FC forwarder. + * @ctl_src_addr: the native MAC address of our local port. + * @data_src_addr: the assigned MAC address for the local port after FLOGI. + * @send: LLD-supplied function to handle sending of FIP Ethernet frames. + * @update_mac: LLD-supplied function to handle changes to MAC addresses. + * @lock: lock protecting this structure. + * + * This structure is used by all FCoE drivers. It contains information + * needed by all FCoE low-level drivers (LLDs) as well as internal state + * for FIP, and fields shared with the LLDS. + */ +struct fcoe_ctlr { + enum fip_state state; + struct fc_lport *lp; + struct fcoe_fcf *sel_fcf; + struct list_head fcfs; + u16 fcf_count; + unsigned long sol_time; + unsigned long sel_time; + unsigned long port_ka_time; + unsigned long ctlr_ka_time; + struct timer_list timer; + struct work_struct link_work; + struct work_struct recv_work; + struct sk_buff_head fip_recv_list; + u16 user_mfs; + u16 flogi_oxid; + u8 flogi_count; + u8 link; + u8 last_link; + u8 map_dest; + u8 dest_addr[ETH_ALEN]; + u8 ctl_src_addr[ETH_ALEN]; + u8 data_src_addr[ETH_ALEN]; + + void (*send)(struct fcoe_ctlr *, struct sk_buff *); + void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new); + spinlock_t lock; +}; + +/* + * struct fcoe_fcf - Fibre-Channel Forwarder. + * @list: list linkage. + * @time: system time (jiffies) when an advertisement was last received. + * @switch_name: WWN of switch from advertisement. + * @fabric_name: WWN of fabric from advertisement. + * @fc_map: FC_MAP value from advertisement. + * @fcf_mac: Ethernet address of the FCF. + * @vfid: virtual fabric ID. + * @pri: seletion priority, smaller values are better. + * @flags: flags received from advertisement. + * @fka_period: keep-alive period, in jiffies. + * + * A Fibre-Channel Forwarder (FCF) is the entity on the Ethernet that + * passes FCoE frames on to an FC fabric. This structure represents + * one FCF from which advertisements have been received. + * + * When looking up an FCF, @switch_name, @fabric_name, @fc_map, @vfid, and + * @fcf_mac together form the lookup key. + */ +struct fcoe_fcf { + struct list_head list; + unsigned long time; + + u64 switch_name; + u64 fabric_name; + u32 fc_map; + u16 vfid; + u8 fcf_mac[ETH_ALEN]; + + u8 pri; + u16 flags; + u32 fka_period; +}; + +/* FIP API functions */ +void fcoe_ctlr_init(struct fcoe_ctlr *); +void fcoe_ctlr_destroy(struct fcoe_ctlr *); +void fcoe_ctlr_link_up(struct fcoe_ctlr *); +int fcoe_ctlr_link_down(struct fcoe_ctlr *); +int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *); +void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *); +int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa); + /* libfcoe funcs */ u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); -- cgit v1.2.2