diff options
Diffstat (limited to 'include/scsi/libfcoe.h')
-rw-r--r-- | include/scsi/libfcoe.h | 227 |
1 files changed, 119 insertions, 108 deletions
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index c41f7d0c6ef..666cc131732 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,134 +21,144 @@ #ifndef _LIBFCOE_H #define _LIBFCOE_H +#include <linux/etherdevice.h> +#include <linux/if_ether.h> #include <linux/netdevice.h> #include <linux/skbuff.h> +#include <linux/workqueue.h> #include <scsi/fc/fc_fcoe.h> #include <scsi/libfc.h> /* - * this percpu struct for fcoe + * FIP tunable parameters. */ -struct fcoe_percpu_s { - int cpu; - struct task_struct *thread; - struct sk_buff_head fcoe_rx_list; - struct page *crc_eof_page; - int crc_eof_offset; +#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, }; -/* - * the fcoe sw transport private data +/** + * 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_softc { - struct list_head list; +struct fcoe_ctlr { + enum fip_state state; 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; - + 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]; - /* - * 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; -} + void (*send)(struct fcoe_ctlr *, struct sk_buff *); + void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new); + spinlock_t lock; +}; -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); -} +/* + * 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; -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; -} + u64 switch_name; + u64 fabric_name; + u32 fc_map; + u16 vfid; + u8 fcf_mac[ETH_ALEN]; -static inline u16 skb_fc_oxid(const struct sk_buff *skb) -{ - return be16_to_cpu(skb_fc_header(skb)->fh_ox_id); -} + u8 pri; + u16 flags; + u32 fka_period; +}; -static inline u16 skb_fc_rxid(const struct sk_buff *skb) -{ - return be16_to_cpu(skb_fc_header(skb)->fh_rx_id); -} +/* 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 */ -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 *); -/* fcoe sw hba */ -int __init fcoe_sw_init(void); -int __exit fcoe_sw_exit(void); #endif /* _LIBFCOE_H */ |