^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Maintained at www.Open-FCoE.org
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/dcbnl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/dcbevent.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <scsi/scsicam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <scsi/scsi_transport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <scsi/scsi_transport_fc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <net/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <scsi/fc/fc_encaps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <scsi/fc/fc_fip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <scsi/fc/fc_fcoe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <scsi/libfc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <scsi/fc_frame.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <scsi/libfcoe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "fcoe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) MODULE_AUTHOR("Open-FCoE.org");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) MODULE_DESCRIPTION("FCoE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Performance tuning parameters for fcoe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static unsigned int fcoe_ddp_min = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) module_param_named(ddp_min, fcoe_ddp_min, uint, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) "Direct Data Placement (DDP).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned int fcoe_debug_logging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) module_param_named(debug_logging, fcoe_debug_logging, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static unsigned int fcoe_e_d_tov = 2 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) module_param_named(e_d_tov, fcoe_e_d_tov, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) MODULE_PARM_DESC(e_d_tov, "E_D_TOV in ms, default 2000");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static unsigned int fcoe_r_a_tov = 2 * 2 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) module_param_named(r_a_tov, fcoe_r_a_tov, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) MODULE_PARM_DESC(r_a_tov, "R_A_TOV in ms, default 4000");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static DEFINE_MUTEX(fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static struct workqueue_struct *fcoe_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* fcoe host list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* must only by accessed under the RTNL mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static LIST_HEAD(fcoe_hostlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Function Prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int fcoe_reset(struct Scsi_Host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static int fcoe_xmit(struct fc_lport *, struct fc_frame *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int fcoe_rcv(struct sk_buff *, struct net_device *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct packet_type *, struct net_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static void fcoe_percpu_clean(struct fc_lport *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static int fcoe_link_ok(struct fc_lport *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static int fcoe_hostlist_add(const struct fc_lport *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static void fcoe_hostlist_del(const struct fc_lport *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int fcoe_device_notification(struct notifier_block *, ulong, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static void fcoe_dev_setup(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static void fcoe_dev_cleanup(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static struct fcoe_interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *fcoe_hostlist_lookup_port(const struct net_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static int fcoe_fip_recv(struct sk_buff *, struct net_device *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct packet_type *, struct net_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static int fcoe_fip_vlan_recv(struct sk_buff *, struct net_device *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct packet_type *, struct net_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static void fcoe_fip_send(struct fcoe_ctlr *, struct sk_buff *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void fcoe_update_src_mac(struct fc_lport *, u8 *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static u8 *fcoe_get_src_mac(struct fc_lport *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void fcoe_destroy_work(struct work_struct *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int fcoe_ddp_setup(struct fc_lport *, u16, struct scatterlist *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int fcoe_ddp_done(struct fc_lport *, u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int fcoe_ddp_target(struct fc_lport *, u16, struct scatterlist *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int fcoe_dcb_app_notification(struct notifier_block *notifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ulong event, void *ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static bool fcoe_match(struct net_device *netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int fcoe_create(struct net_device *netdev, enum fip_mode fip_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static int fcoe_destroy(struct net_device *netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int fcoe_enable(struct net_device *netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int fcoe_disable(struct net_device *netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* fcoe_syfs control interface handlers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int fcoe_ctlr_alloc(struct net_device *netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static void fcoe_ctlr_mode(struct fcoe_ctlr_device *ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u32 did, struct fc_frame *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned int op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) void (*resp)(struct fc_seq *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct fc_frame *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) void *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void *, u32 timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void fcoe_recv_frame(struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* notification function for packets from net device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static struct notifier_block fcoe_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .notifier_call = fcoe_device_notification,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* notification function for DCB events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static struct notifier_block dcb_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .notifier_call = fcoe_dcb_app_notification,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static struct scsi_transport_template *fcoe_nport_scsi_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static struct scsi_transport_template *fcoe_vport_scsi_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int fcoe_vport_destroy(struct fc_vport *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int fcoe_vport_create(struct fc_vport *, bool disabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int fcoe_vport_disable(struct fc_vport *, bool disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static void fcoe_set_vport_symbolic_name(struct fc_vport *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static void fcoe_vport_remove(struct fc_lport *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static struct fcoe_sysfs_function_template fcoe_sysfs_templ = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .set_fcoe_ctlr_mode = fcoe_ctlr_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .set_fcoe_ctlr_enabled = fcoe_ctlr_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .get_fcoe_fcf_selected = fcoe_fcf_get_selected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .get_fcoe_fcf_vlan_id = fcoe_fcf_get_vlan_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static struct libfc_function_template fcoe_libfc_fcn_templ = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .frame_send = fcoe_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .ddp_setup = fcoe_ddp_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .ddp_done = fcoe_ddp_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .ddp_target = fcoe_ddp_target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .elsct_send = fcoe_elsct_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .get_lesb = fcoe_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .lport_set_port_id = fcoe_set_port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static struct fc_function_template fcoe_nport_fc_functions = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .show_host_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .show_host_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .show_host_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .show_host_supported_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .show_host_active_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .show_host_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .show_host_serial_number = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .show_host_manufacturer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .show_host_model = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .show_host_model_description = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .show_host_hardware_version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .show_host_driver_version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .show_host_firmware_version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .show_host_optionrom_version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .show_host_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .show_host_supported_speeds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .get_host_speed = fc_get_host_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .show_host_speed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .show_host_port_type = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .get_host_port_state = fc_get_host_port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .show_host_port_state = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .show_host_symbolic_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .show_rport_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .show_rport_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .show_host_fabric_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .show_starget_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .show_starget_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .show_starget_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .show_rport_dev_loss_tmo = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .get_fc_host_stats = fc_get_host_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .issue_fc_host_lip = fcoe_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .terminate_rport_io = fc_rport_terminate_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .vport_create = fcoe_vport_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .vport_delete = fcoe_vport_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .vport_disable = fcoe_vport_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .set_vport_symbolic_name = fcoe_set_vport_symbolic_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .bsg_request = fc_lport_bsg_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static struct fc_function_template fcoe_vport_fc_functions = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .show_host_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .show_host_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .show_host_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .show_host_supported_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .show_host_active_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .show_host_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .show_host_serial_number = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .show_host_manufacturer = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .show_host_model = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .show_host_model_description = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .show_host_hardware_version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .show_host_driver_version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .show_host_firmware_version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .show_host_optionrom_version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .show_host_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .show_host_supported_speeds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .get_host_speed = fc_get_host_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .show_host_speed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .show_host_port_type = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .get_host_port_state = fc_get_host_port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .show_host_port_state = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .show_host_symbolic_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .show_rport_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .show_rport_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .show_host_fabric_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .show_starget_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .show_starget_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .show_starget_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .show_rport_dev_loss_tmo = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .get_fc_host_stats = fc_get_host_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .issue_fc_host_lip = fcoe_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .terminate_rport_io = fc_rport_terminate_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .bsg_request = fc_lport_bsg_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static struct scsi_host_template fcoe_shost_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .name = "FCoE Driver",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .proc_name = FCOE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .queuecommand = fc_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .eh_timed_out = fc_eh_timed_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .eh_abort_handler = fc_eh_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .eh_device_reset_handler = fc_eh_device_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .eh_host_reset_handler = fc_eh_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .slave_alloc = fc_slave_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .change_queue_depth = scsi_change_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .this_id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .cmd_per_lun = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .sg_tablesize = SG_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .max_sectors = 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .track_queue_depth = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * fcoe_interface_setup() - Setup a FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * @fcoe: The new FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * @netdev: The net device that the fcoe interface is on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * Returns : 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * Locking: must be called with the RTNL mutex held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int fcoe_interface_setup(struct fcoe_interface *fcoe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct net_device *real_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) u8 flogi_maddr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) const struct net_device_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) fcoe->netdev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* Let LLD initialize for FCoE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ops = netdev->netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (ops->ndo_fcoe_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (ops->ndo_fcoe_enable(netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) FCOE_NETDEV_DBG(netdev, "Failed to enable FCoE"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) " specific feature for LLD.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* Do not support for bonding device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (netdev->priv_flags & IFF_BONDING && netdev->flags & IFF_MASTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) FCOE_NETDEV_DBG(netdev, "Bonded interfaces not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* look for SAN MAC address, if multiple SAN MACs exist, only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * use the first one for SPMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) real_dev = is_vlan_dev(netdev) ? vlan_dev_real_dev(netdev) : netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) fcoe->realdev = real_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) for_each_dev_addr(real_dev, ha) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) (is_valid_ether_addr(ha->addr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) memcpy(fip->ctl_src_addr, ha->addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) fip->spma = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* setup Source Mac Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!fip->spma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) memcpy(fip->ctl_src_addr, netdev->dev_addr, netdev->addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Add FCoE MAC address as second unicast MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * or enter promiscuous mode if not capable of listening
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * for multiple unicast MACs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) dev_uc_add(netdev, flogi_maddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (fip->spma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) dev_uc_add(netdev, fip->ctl_src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (fip->mode == FIP_MODE_VN2VN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dev_mc_add(netdev, FIP_ALL_VN2VN_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev_mc_add(netdev, FIP_ALL_P2P_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) dev_mc_add(netdev, FIP_ALL_ENODE_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * setup the receive function from ethernet driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * on the ethertype for the given device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) fcoe->fcoe_packet_type.func = fcoe_rcv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) fcoe->fcoe_packet_type.type = htons(ETH_P_FCOE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) fcoe->fcoe_packet_type.dev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) dev_add_pack(&fcoe->fcoe_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) fcoe->fip_packet_type.func = fcoe_fip_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) fcoe->fip_packet_type.type = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) fcoe->fip_packet_type.dev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) dev_add_pack(&fcoe->fip_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (netdev != real_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) fcoe->fip_vlan_packet_type.func = fcoe_fip_vlan_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) fcoe->fip_vlan_packet_type.type = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) fcoe->fip_vlan_packet_type.dev = real_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) dev_add_pack(&fcoe->fip_vlan_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * fcoe_interface_create() - Create a FCoE interface on a net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * @netdev: The net device to create the FCoE interface on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * @fip_mode: The mode to use for FIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Returns: pointer to a struct fcoe_interface or NULL on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) enum fip_mode fip_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct fcoe_ctlr_device *ctlr_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!try_module_get(THIS_MODULE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) FCOE_NETDEV_DBG(netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) "Could not get a reference to the module\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) fcoe = ERR_PTR(-EBUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &fcoe_sysfs_templ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (!ctlr_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) FCOE_DBG("Failed to add fcoe_ctlr_device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) fcoe = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) goto out_putmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ctlr = fcoe_ctlr_device_priv(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ctlr->cdev = ctlr_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) fcoe = fcoe_ctlr_priv(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev_hold(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * Initialize FIP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) fcoe_ctlr_init(ctlr, fip_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ctlr->send = fcoe_fip_send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ctlr->update_mac = fcoe_update_src_mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ctlr->get_src_addr = fcoe_get_src_mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) err = fcoe_interface_setup(fcoe, netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) fcoe_ctlr_destroy(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) fcoe_ctlr_device_delete(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dev_put(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) fcoe = ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto out_putmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) out_putmod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * fcoe_interface_remove() - remove FCoE interface from netdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * @fcoe: The FCoE interface to be cleaned up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * Caller must be holding the RTNL mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static void fcoe_interface_remove(struct fcoe_interface *fcoe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct net_device *netdev = fcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) u8 flogi_maddr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) const struct net_device_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * Don't listen for Ethernet packets anymore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * synchronize_net() ensures that the packet handlers are not running
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * on another CPU. dev_remove_pack() would do that, this calls the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * unsyncronized version __dev_remove_pack() to avoid multiple delays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) __dev_remove_pack(&fcoe->fcoe_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) __dev_remove_pack(&fcoe->fip_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (netdev != fcoe->realdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) __dev_remove_pack(&fcoe->fip_vlan_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* Delete secondary MAC addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) dev_uc_del(netdev, flogi_maddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (fip->spma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dev_uc_del(netdev, fip->ctl_src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (fip->mode == FIP_MODE_VN2VN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) dev_mc_del(netdev, FIP_ALL_VN2VN_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dev_mc_del(netdev, FIP_ALL_P2P_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) dev_mc_del(netdev, FIP_ALL_ENODE_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* Tell the LLD we are done w/ FCoE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ops = netdev->netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (ops->ndo_fcoe_disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (ops->ndo_fcoe_disable(netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) " specific feature for LLD.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) fcoe->removed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * fcoe_interface_cleanup() - Clean up a FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * @fcoe: The FCoE interface to be cleaned up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct net_device *netdev = fcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Release the self-reference taken during fcoe_interface_create() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* tear-down the FCoE controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) fcoe_ctlr_destroy(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) scsi_host_put(fip->lp->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dev_put(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * fcoe_fip_recv() - Handler for received FIP frames
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * @skb: The receive skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * @netdev: The associated net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * @ptype: The packet_type structure which was used to register this handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * @orig_dev: The original net_device the skb was received on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * (in case dev is a bond)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct packet_type *ptype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct net_device *orig_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) fcoe = container_of(ptype, struct fcoe_interface, fip_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) fcoe_ctlr_recv(ctlr, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * fcoe_fip_vlan_recv() - Handler for received FIP VLAN discovery frames
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * @skb: The receive skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * @netdev: The associated net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * @ptype: The packet_type structure which was used to register this handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * @orig_dev: The original net_device the skb was received on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * (in case dev is a bond)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static int fcoe_fip_vlan_recv(struct sk_buff *skb, struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct packet_type *ptype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct net_device *orig_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) fcoe = container_of(ptype, struct fcoe_interface, fip_vlan_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) fcoe_ctlr_recv(ctlr, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * fcoe_port_send() - Send an Ethernet-encapsulated FIP/FCoE frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * @port: The FCoE port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * @skb: The FIP/FCoE packet to be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static void fcoe_port_send(struct fcoe_port *port, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (port->fcoe_pending_queue.qlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) fcoe_check_wait_queue(port->lport, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) else if (fcoe_start_io(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) fcoe_check_wait_queue(port->lport, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * fcoe_fip_send() - Send an Ethernet-encapsulated FIP frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * @skb: The FIP packet to be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct fcoe_interface *fcoe = fcoe_from_ctlr(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct fip_frame {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct ethhdr eth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct fip_header fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) } __packed *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * Use default VLAN for FIP VLAN discovery protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) frame = (struct fip_frame *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (ntohs(frame->eth.h_proto) == ETH_P_FIP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) ntohs(frame->fip.fip_op) == FIP_OP_VLAN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) fcoe->realdev != fcoe->netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) skb->dev = fcoe->realdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) skb->dev = fcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) fcoe_port_send(lport_priv(fip->lp), skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * fcoe_update_src_mac() - Update the Ethernet MAC filters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * @lport: The local port to update the source MAC on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * @addr: Unicast MAC address to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * Remove any previously-set unicast MAC filter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * Add secondary FCoE MAC address filter for our OUI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct fcoe_interface *fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (!is_zero_ether_addr(port->data_src_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dev_uc_del(fcoe->netdev, port->data_src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (!is_zero_ether_addr(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) dev_uc_add(fcoe->netdev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) memcpy(port->data_src_addr, addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * fcoe_get_src_mac() - return the Ethernet source address for an lport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * @lport: libfc lport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static u8 *fcoe_get_src_mac(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return port->data_src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * fcoe_lport_config() - Set up a local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * @lport: The local port to be setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int fcoe_lport_config(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) lport->link_up = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) lport->qfull = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) lport->max_retry_count = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) lport->max_rport_retry_count = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) lport->e_d_tov = fcoe_e_d_tov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) lport->r_a_tov = fcoe_r_a_tov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) lport->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) lport->does_npiv = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) fc_lport_init_stats(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* lport fc_lport related configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) fc_lport_config(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* offload related configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) lport->crc_offload = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) lport->seq_offload = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) lport->lro_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) lport->lro_xid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) lport->lso_max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * fcoe_netdev_features_change - Updates the lport's offload flags based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * on the LLD netdev's FCoE feature flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static void fcoe_netdev_features_change(struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) mutex_lock(&lport->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (netdev->features & NETIF_F_SG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) lport->sg_supp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) lport->sg_supp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (netdev->features & NETIF_F_FCOE_CRC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) lport->crc_offload = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) lport->crc_offload = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (netdev->features & NETIF_F_FSO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) lport->seq_offload = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) lport->lso_max = netdev->gso_max_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) lport->lso_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) lport->seq_offload = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) lport->lso_max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (netdev->fcoe_ddp_xid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) lport->lro_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) lport->lro_xid = netdev->fcoe_ddp_xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) lport->lro_xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) lport->lro_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) lport->lro_xid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) mutex_unlock(&lport->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * fcoe_netdev_config() - Set up net devive for SW FCoE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * @lport: The local port that is associated with the net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * @netdev: The associated net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * Must be called after fcoe_lport_config() as it will use local port mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) u32 mfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) u64 wwnn, wwpn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /* Setup lport private data to point to fcoe softc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* Figure out the VLAN ID, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (is_vlan_dev(netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) lport->vlan = vlan_dev_vlan_id(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) lport->vlan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * Determine max frame size based on underlying device and optional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * user-configured limit. If the MFS is too low, fcoe_link_ok()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * will return 0, so do this first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) mfs = netdev->mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (netdev->features & NETIF_F_FCOE_MTU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) mfs = FCOE_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) FCOE_NETDEV_DBG(netdev, "Supports FCOE_MTU of %d bytes\n", mfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) mfs -= (sizeof(struct fcoe_hdr) + sizeof(struct fcoe_crc_eof));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (fc_set_mfs(lport, mfs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* offload features support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) fcoe_netdev_features_change(lport, netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) skb_queue_head_init(&port->fcoe_pending_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) port->fcoe_pending_queue_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) timer_setup(&port->timer, fcoe_queue_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) fcoe_link_speed_update(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (!lport->vport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) fc_set_wwnn(lport, wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) fc_set_wwpn(lport, wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * fcoe_shost_config() - Set up the SCSI host associated with a local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * @lport: The local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * @dev: The device associated with the SCSI host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * Must be called after fcoe_lport_config() and fcoe_netdev_config()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static int fcoe_shost_config(struct fc_lport *lport, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /* lport scsi host config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) lport->host->max_lun = FCOE_MAX_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) lport->host->max_id = FCOE_MAX_FCP_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) lport->host->max_channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) lport->host->max_cmd_len = FCOE_MAX_CMD_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (lport->vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) lport->host->transportt = fcoe_vport_scsi_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) lport->host->transportt = fcoe_nport_scsi_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* add the new host to the SCSI-ml */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) rc = scsi_add_host(lport->host, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) FCOE_NETDEV_DBG(fcoe_netdev(lport), "fcoe_shost_config: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) "error on scsi_add_host\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!lport->vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) fc_host_max_npiv_vports(lport->host) = USHRT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) "%s v%s over %s", FCOE_NAME, FCOE_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) fcoe_netdev(lport)->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * fcoe_fdmi_info() - Get FDMI related info from net devive for SW FCoE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * @lport: The local port that is associated with the net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * @netdev: The associated net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * Must be called after fcoe_shost_config() as it will use local port mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct net_device *realdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) realdev = fcoe->realdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /* No FDMI state m/c for NPIV ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (lport->vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (realdev->netdev_ops->ndo_fcoe_get_hbainfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct netdev_fcoe_hbainfo *fdmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) fdmi = kzalloc(sizeof(*fdmi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (!fdmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) rc = realdev->netdev_ops->ndo_fcoe_get_hbainfo(realdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) fdmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) printk(KERN_INFO "fcoe: Failed to retrieve FDMI "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) "information from netdev.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) snprintf(fc_host_serial_number(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) FC_SERIAL_NUMBER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) fdmi->serial_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) snprintf(fc_host_manufacturer(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) FC_SERIAL_NUMBER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) fdmi->manufacturer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) snprintf(fc_host_model(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) FC_SYMBOLIC_NAME_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) fdmi->model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) snprintf(fc_host_model_description(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) FC_SYMBOLIC_NAME_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) fdmi->model_description);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) snprintf(fc_host_hardware_version(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) FC_VERSION_STRING_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) fdmi->hardware_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) snprintf(fc_host_driver_version(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) FC_VERSION_STRING_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) fdmi->driver_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) snprintf(fc_host_optionrom_version(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) FC_VERSION_STRING_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) fdmi->optionrom_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) snprintf(fc_host_firmware_version(lport->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) FC_VERSION_STRING_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) fdmi->firmware_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* Enable FDMI lport states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) lport->fdmi_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) kfree(fdmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) lport->fdmi_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) printk(KERN_INFO "fcoe: No FDMI support.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * fcoe_oem_match() - The match routine for the offloaded exchange manager
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * @fp: The I/O frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) * This routine will be associated with an exchange manager (EM). When
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * the libfc exchange handling code is looking for an EM to use it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * call this routine and pass it the frame that it wishes to send. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) * routine will return True if the associated EM is to be used and False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * if the echange code should continue looking for an EM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * The offload EM that this routine is associated with will handle any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * packets that are for SCSI read requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * This has been enhanced to work when FCoE stack is operating in target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * Returns: True for read types I/O, otherwise returns false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static bool fcoe_oem_match(struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct fc_frame_header *fh = fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct fcp_cmnd *fcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (fc_fcp_is_read(fr_fsp(fp)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) (fr_fsp(fp)->data_len > fcoe_ddp_min))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) else if ((fr_fsp(fp) == NULL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) (fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) (ntohs(fh->fh_rx_id) == FC_XID_UNKNOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) fcp = fc_frame_payload_get(fp, sizeof(*fcp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if ((fcp->fc_flags & FCP_CFL_WRDATA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) (ntohl(fcp->fc_dl) > fcoe_ddp_min))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * fcoe_em_config() - Allocate and configure an exchange manager
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * @lport: The local port that the new EM will be associated with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * Returns: 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) static inline int fcoe_em_config(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct fcoe_interface *fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) struct fcoe_interface *oldfcoe = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) struct net_device *old_real_dev, *cur_real_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) u16 min_xid = FCOE_MIN_XID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) u16 max_xid = FCOE_MAX_XID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * Check if need to allocate an em instance for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * offload exchange ids to be shared across all VN_PORTs/lport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (!lport->lro_enabled || !lport->lro_xid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) (lport->lro_xid >= max_xid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) lport->lro_xid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) goto skip_oem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) * Reuse existing offload em instance in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) * it is already allocated on real eth device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (is_vlan_dev(fcoe->netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) cur_real_dev = vlan_dev_real_dev(fcoe->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) cur_real_dev = fcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) list_for_each_entry(oldfcoe, &fcoe_hostlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (is_vlan_dev(oldfcoe->netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) old_real_dev = vlan_dev_real_dev(oldfcoe->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) old_real_dev = oldfcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (cur_real_dev == old_real_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) fcoe->oem = oldfcoe->oem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (fcoe->oem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (!fc_exch_mgr_add(lport, fcoe->oem, fcoe_oem_match)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) printk(KERN_ERR "fcoe_em_config: failed to add "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) "offload em:%p on interface:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) fcoe->oem, fcoe->netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) fcoe->oem = fc_exch_mgr_alloc(lport, FC_CLASS_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) FCOE_MIN_XID, lport->lro_xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) fcoe_oem_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (!fcoe->oem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) printk(KERN_ERR "fcoe_em_config: failed to allocate "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) "em for offload exches on interface:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) fcoe->netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * Exclude offload EM xid range from next EM xid range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) min_xid += lport->lro_xid + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) skip_oem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (!fc_exch_mgr_alloc(lport, FC_CLASS_3, min_xid, max_xid, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) printk(KERN_ERR "fcoe_em_config: failed to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) "allocate em on interface %s\n", fcoe->netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * fcoe_if_destroy() - Tear down a SW FCoE instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * @lport: The local port to be destroyed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * Locking: Must be called with the RTNL mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static void fcoe_if_destroy(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct fcoe_interface *fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) struct net_device *netdev = fcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* Logout of the fabric */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) fc_fabric_logoff(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) /* Cleanup the fc_lport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) fc_lport_destroy(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* Stop the transmit retry timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) del_timer_sync(&port->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* Free existing transmit skbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) fcoe_clean_pending_queue(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (!is_zero_ether_addr(port->data_src_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) dev_uc_del(netdev, port->data_src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (lport->vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) fcoe_interface_remove(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /* Free queued packets for the per-CPU receive threads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) fcoe_percpu_clean(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /* Detach from the scsi-ml */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) fc_remove_host(lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) scsi_remove_host(lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* Destroy lport scsi_priv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) fc_fcp_destroy(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* There are no more rports or I/O, free the EM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) fc_exch_mgr_free(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* Free memory used by statistical counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) fc_lport_free_stats(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * Release the Scsi_Host for vport but hold on to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * master lport until it fcoe interface fully cleaned-up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (lport->vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) scsi_host_put(lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * fcoe_ddp_setup() - Call a LLD's ddp_setup through the net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * @lport: The local port to setup DDP for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) * @xid: The exchange ID for this DDP transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) * @sgl: The scatterlist describing this transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * @sgc: The number of sg items
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * Returns: 0 if the DDP context was not configured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static int fcoe_ddp_setup(struct fc_lport *lport, u16 xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct scatterlist *sgl, unsigned int sgc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct net_device *netdev = fcoe_netdev(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (netdev->netdev_ops->ndo_fcoe_ddp_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return netdev->netdev_ops->ndo_fcoe_ddp_setup(netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) xid, sgl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) sgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * fcoe_ddp_target() - Call a LLD's ddp_target through the net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * @lport: The local port to setup DDP for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) * @xid: The exchange ID for this DDP transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * @sgl: The scatterlist describing this transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * @sgc: The number of sg items
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * Returns: 0 if the DDP context was not configured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) static int fcoe_ddp_target(struct fc_lport *lport, u16 xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) struct scatterlist *sgl, unsigned int sgc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct net_device *netdev = fcoe_netdev(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (netdev->netdev_ops->ndo_fcoe_ddp_target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return netdev->netdev_ops->ndo_fcoe_ddp_target(netdev, xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) sgl, sgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * fcoe_ddp_done() - Call a LLD's ddp_done through the net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * @lport: The local port to complete DDP on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * @xid: The exchange ID for this DDP transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * Returns: the length of data that have been completed by DDP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) static int fcoe_ddp_done(struct fc_lport *lport, u16 xid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct net_device *netdev = fcoe_netdev(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (netdev->netdev_ops->ndo_fcoe_ddp_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return netdev->netdev_ops->ndo_fcoe_ddp_done(netdev, xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * fcoe_if_create() - Create a FCoE instance on an interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) * @fcoe: The FCoE interface to create a local port on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * @parent: The device pointer to be the parent in sysfs for the SCSI host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * @npiv: Indicates if the port is a vport or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) * Creates a fc_lport instance and a Scsi_Host instance and configure them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * Returns: The allocated fc_lport or an error pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) struct device *parent, int npiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) struct net_device *netdev = fcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) struct fc_lport *lport, *n_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * parent is only a vport if npiv is 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * but we'll only use vport in that case so go ahead and set it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct fc_vport *vport = dev_to_vport(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) FCOE_NETDEV_DBG(netdev, "Create Interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (!npiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) lport = libfc_host_alloc(&fcoe_shost_template, sizeof(*port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) lport = libfc_vport_create(vport, sizeof(*port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (!lport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) port->lport = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) port->priv = fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) port->get_netdev = fcoe_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) port->max_queue_depth = FCOE_MAX_QUEUE_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) port->min_queue_depth = FCOE_MIN_QUEUE_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) INIT_WORK(&port->destroy_work, fcoe_destroy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) * Need to add the lport to the hostlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) * so we catch NETDEV_CHANGE events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) fcoe_hostlist_add(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* configure a fc_lport including the exchange manager */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) rc = fcoe_lport_config(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) FCOE_NETDEV_DBG(netdev, "Could not configure lport for the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) "interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) goto out_host_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (npiv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) FCOE_NETDEV_DBG(netdev, "Setting vport names, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) "%16.16llx %16.16llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) vport->node_name, vport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) fc_set_wwnn(lport, vport->node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) fc_set_wwpn(lport, vport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /* configure lport network properties */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) rc = fcoe_netdev_config(lport, netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) FCOE_NETDEV_DBG(netdev, "Could not configure netdev for the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) "interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) goto out_lp_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /* configure lport scsi host properties */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) rc = fcoe_shost_config(lport, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) FCOE_NETDEV_DBG(netdev, "Could not configure shost for the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) "interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) goto out_lp_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /* Initialize the library */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) rc = fcoe_libfc_config(lport, ctlr, &fcoe_libfc_fcn_templ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) "interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) goto out_lp_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /* Initialized FDMI information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) fcoe_fdmi_info(lport, netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * fcoe_em_alloc() and fcoe_hostlist_add() both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) * need to be atomic with respect to other changes to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) * hostlist since fcoe_em_alloc() looks for an existing EM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * instance on host list updated by fcoe_hostlist_add().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * This is currently handled through the fcoe_config_mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) * begin held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (!npiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /* lport exch manager allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) rc = fcoe_em_config(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) shost = vport_to_shost(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) n_port = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) rc = fc_exch_mgr_list_clone(n_port, lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) FCOE_NETDEV_DBG(netdev, "Could not configure the EM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) goto out_lp_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) out_lp_destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) fc_exch_mgr_free(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) out_host_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) fcoe_hostlist_del(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) scsi_host_put(lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) * fcoe_if_init() - Initialization routine for fcoe.ko
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * Attaches the SW FCoE transport to the FC transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) * Returns: 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static int __init fcoe_if_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) /* attach to scsi transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) fcoe_nport_scsi_transport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) fc_attach_transport(&fcoe_nport_fc_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (!fcoe_nport_scsi_transport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) fcoe_vport_scsi_transport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) fc_attach_transport(&fcoe_vport_fc_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (!fcoe_vport_scsi_transport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) goto err_vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) err_vport:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) fc_release_transport(fcoe_nport_scsi_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) printk(KERN_ERR "fcoe: Failed to attach to the FC transport\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) * fcoe_if_exit() - Tear down fcoe.ko
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) * Detaches the SW FCoE transport from the FC transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) * Returns: 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) static int __exit fcoe_if_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) fc_release_transport(fcoe_nport_scsi_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) fc_release_transport(fcoe_vport_scsi_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) fcoe_nport_scsi_transport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) fcoe_vport_scsi_transport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) static void fcoe_thread_cleanup_local(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) struct page *crc_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct fcoe_percpu_s *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) p = per_cpu_ptr(&fcoe_percpu, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) spin_lock_bh(&p->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) crc_eof = p->crc_eof_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) p->crc_eof_page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) p->crc_eof_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) spin_unlock_bh(&p->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (crc_eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) put_page(crc_eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) flush_work(&p->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) * fcoe_select_cpu() - Selects CPU to handle post-processing of incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) * command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) * This routine selects next CPU based on cpumask to distribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) * incoming requests in round robin.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) * Returns: int CPU number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) static inline unsigned int fcoe_select_cpu(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) static unsigned int selected_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) selected_cpu = cpumask_next(selected_cpu, cpu_online_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (selected_cpu >= nr_cpu_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) selected_cpu = cpumask_first(cpu_online_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return selected_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * fcoe_rcv() - Receive packets from a net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * @skb: The received packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * @netdev: The net device that the packet was received on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * @ptype: The packet type context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * @olddev: The last device net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) * This routine is called by NET_RX_SOFTIRQ. It receives a packet, builds a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) * FC frame and passes the frame to libfc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) struct packet_type *ptype, struct net_device *olddev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) struct fcoe_rcv_info *fr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) struct fcoe_percpu_s *fps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) struct ethhdr *eh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) unsigned int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (unlikely(!lport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) FCOE_NETDEV_DBG(netdev, "Cannot find hba structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (!lport->link_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) FCOE_NETDEV_DBG(netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) "skb_info: len:%d data_len:%d head:%p data:%p tail:%p end:%p sum:%d dev:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) skb->len, skb->data_len, skb->head, skb->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) skb_tail_pointer(skb), skb_end_pointer(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) skb->csum, skb->dev ? skb->dev->name : "<NULL>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) skb = skb_share_check(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) eh = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (is_fip_mode(ctlr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) !ether_addr_equal(eh->h_source, ctlr->dest_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) FCOE_NETDEV_DBG(netdev, "wrong source mac address:%pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) eh->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) * Check for minimum frame length, and make sure required FCoE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * and FC headers are pulled into the linear data area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (unlikely((skb->len < FCOE_MIN_FRAME) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) !pskb_may_pull(skb, FCOE_HEADER_LEN)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) fh = (struct fc_frame_header *) skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (ntoh24(&eh->h_dest[3]) != ntoh24(fh->fh_d_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) FCOE_NETDEV_DBG(netdev, "FC frame d_id mismatch with MAC:%pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) eh->h_dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) fr = fcoe_dev_from_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) fr->fr_dev = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) * In case the incoming frame's exchange is originated from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) * the initiator, then received frame's exchange id is ANDed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * with fc_cpu_mask bits to get the same cpu on which exchange
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) * was originated, otherwise select cpu using rx exchange id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * or fcoe_select_cpu().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (ntoh24(fh->fh_f_ctl) & FC_FC_EX_CTX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) cpu = ntohs(fh->fh_ox_id) & fc_cpu_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (ntohs(fh->fh_rx_id) == FC_XID_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) cpu = fcoe_select_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) cpu = ntohs(fh->fh_rx_id) & fc_cpu_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (cpu >= nr_cpu_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) fps = &per_cpu(fcoe_percpu, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) spin_lock(&fps->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) * We now have a valid CPU that we're targeting for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) * this skb. We also have this receive thread locked,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) * so we're free to queue skbs into it's queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * Note: We used to have a set of conditions under which we would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) * call fcoe_recv_frame directly, rather than queuing to the rx list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) * as it could save a few cycles, but doing so is prohibited, as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) * fcoe_recv_frame has several paths that may sleep, which is forbidden
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) * in softirq context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) __skb_queue_tail(&fps->fcoe_rx_list, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) schedule_work_on(cpu, &fps->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) spin_unlock(&fps->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) per_cpu_ptr(lport->stats, get_cpu())->ErrorFrames++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) * fcoe_alloc_paged_crc_eof() - Allocate a page to be used for the trailer CRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) * @skb: The packet to be transmitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * @tlen: The total length of the trailer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) static int fcoe_alloc_paged_crc_eof(struct sk_buff *skb, int tlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) struct fcoe_percpu_s *fps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) fps = &get_cpu_var(fcoe_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) rc = fcoe_get_paged_crc_eof(skb, tlen, fps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) put_cpu_var(fcoe_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) * fcoe_xmit() - Transmit a FCoE frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * @lport: The local port that the frame is to be transmitted for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * @fp: The frame to be transmitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) * Return: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) int wlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) struct ethhdr *eh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) struct fcoe_crc_eof *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct fc_stats *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) unsigned int hlen; /* header length implies the version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) unsigned int tlen; /* trailer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) unsigned int elen; /* eth header, may include vlan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) struct fcoe_interface *fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) u8 sof, eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) struct fcoe_hdr *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) fh = fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) skb = fp_skb(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) wlen = skb->len / FCOE_WORD_TO_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (!lport->link_up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (unlikely(fh->fh_type == FC_TYPE_ELS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) fcoe_ctlr_els_send(ctlr, lport, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) sof = fr_sof(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) eof = fr_eof(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) elen = sizeof(struct ethhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) hlen = sizeof(struct fcoe_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) tlen = sizeof(struct fcoe_crc_eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) /* crc offload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (likely(lport->crc_offload)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) skb->ip_summed = CHECKSUM_PARTIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) skb->csum_start = skb_headroom(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) skb->csum_offset = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) crc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) skb->ip_summed = CHECKSUM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) crc = fcoe_fc_crc(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) /* copy port crc and eof to the skb buff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (skb_is_nonlinear(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) skb_frag_t *frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) if (fcoe_alloc_paged_crc_eof(skb, tlen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) cp = kmap_atomic(skb_frag_page(frag)) + skb_frag_off(frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) cp = skb_put(skb, tlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) memset(cp, 0, sizeof(*cp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) cp->fcoe_eof = eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) cp->fcoe_crc32 = cpu_to_le32(~crc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) if (skb_is_nonlinear(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) kunmap_atomic(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) cp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) /* adjust skb network/transport offsets to match mac/fcoe/port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) skb_push(skb, elen + hlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) skb->mac_len = elen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) skb->protocol = htons(ETH_P_FCOE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) skb->priority = fcoe->priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (is_vlan_dev(fcoe->netdev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) fcoe->realdev->features & NETIF_F_HW_VLAN_CTAG_TX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) /* must set skb->dev before calling vlan_put_tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) skb->dev = fcoe->realdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) vlan_dev_vlan_id(fcoe->netdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) skb->dev = fcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) /* fill up mac and fcoe headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) eh = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) eh->h_proto = htons(ETH_P_FCOE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (ctlr->map_dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) memcpy(eh->h_dest + 3, fh->fh_d_id, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) memcpy(eh->h_source, port->data_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) hp = (struct fcoe_hdr *)(eh + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) memset(hp, 0, sizeof(*hp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (FC_FCOE_VER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) hp->fcoe_sof = sof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) /* fcoe lso, mss is in max_payload which is non-zero for FCP data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) if (lport->seq_offload && fr_max_payload(fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) skb_shinfo(skb)->gso_size = fr_max_payload(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) skb_shinfo(skb)->gso_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) skb_shinfo(skb)->gso_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) /* update tx stats: regardless if LLD fails */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) stats = per_cpu_ptr(lport->stats, get_cpu());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) stats->TxFrames++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) stats->TxWords += wlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) /* send down to lld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) fr_dev(fp) = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) fcoe_port_send(port, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) * fcoe_filter_frames() - filter out bad fcoe frames, i.e. bad CRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) * @lport: The local port the frame was received on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) * @fp: The received frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) * Return: 0 on passing filtering checks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) static inline int fcoe_filter_frames(struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) struct sk_buff *skb = (struct sk_buff *)fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) struct fc_stats *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) * We only check CRC if no offload is available and if it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) * it's solicited data, in which case, the FCP layer would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) * check it during the copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (lport->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) fh = fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && fh->fh_type == FC_TYPE_FCP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) fcoe = ((struct fcoe_port *)lport_priv(lport))->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (is_fip_mode(ctlr) && fc_frame_payload_op(fp) == ELS_LOGO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) ntoh24(fh->fh_s_id) == FC_FID_FLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) if (!(fr_flags(fp) & FCPHF_CRC_UNCHECKED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) le32_to_cpu(fr_crc(fp)) == ~crc32(~0, skb->data, skb->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) stats = per_cpu_ptr(lport->stats, get_cpu());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) stats->InvalidCRCCount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) if (stats->InvalidCRCCount < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) printk(KERN_WARNING "fcoe: dropping frame with CRC error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) * fcoe_recv_frame() - process a single received frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) * @skb: frame to process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) static void fcoe_recv_frame(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) u32 fr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) struct fcoe_rcv_info *fr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) struct fc_stats *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) struct fcoe_crc_eof crc_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) struct fc_frame *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) struct fcoe_hdr *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) fr = fcoe_dev_from_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) lport = fr->fr_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) if (unlikely(!lport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) FCOE_NETDEV_DBG(skb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) "skb_info: len:%d data_len:%d head:%p data:%p tail:%p end:%p sum:%d dev:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) skb->len, skb->data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) skb->head, skb->data, skb_tail_pointer(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) skb_end_pointer(skb), skb->csum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) skb->dev ? skb->dev->name : "<NULL>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) skb_linearize(skb); /* check for skb_is_nonlinear is within skb_linearize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) * Frame length checks and setting up the header pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) * was done in fcoe_rcv already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) hp = (struct fcoe_hdr *) skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) stats = per_cpu_ptr(lport->stats, get_cpu());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) if (stats->ErrorFrames < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) printk(KERN_WARNING "fcoe: FCoE version "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) "mismatch: The frame has "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) "version %x, but the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) "initiator supports version "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) "%x\n", FC_FCOE_DECAPS_VER(hp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) FC_FCOE_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) skb_pull(skb, sizeof(struct fcoe_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) fr_len = skb->len - sizeof(struct fcoe_crc_eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) stats->RxFrames++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) fp = (struct fc_frame *)skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) fc_frame_init(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) fr_dev(fp) = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) fr_sof(fp) = hp->fcoe_sof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) /* Copy out the CRC and EOF trailer for access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) fr_eof(fp) = crc_eof.fcoe_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) fr_crc(fp) = crc_eof.fcoe_crc32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) if (pskb_trim(skb, fr_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (!fcoe_filter_frames(lport, fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) fc_exch_recv(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) stats->ErrorFrames++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) * fcoe_receive_work() - The per-CPU worker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) * @work: The work struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) static void fcoe_receive_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) struct fcoe_percpu_s *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) struct sk_buff_head tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) p = container_of(work, struct fcoe_percpu_s, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) skb_queue_head_init(&tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) spin_lock_bh(&p->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) skb_queue_splice_init(&p->fcoe_rx_list, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) spin_unlock_bh(&p->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) if (!skb_queue_len(&tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) while ((skb = __skb_dequeue(&tmp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) fcoe_recv_frame(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) * fcoe_dev_setup() - Setup the link change notification interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) static void fcoe_dev_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) register_dcbevent_notifier(&dcb_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) register_netdevice_notifier(&fcoe_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) * fcoe_dev_cleanup() - Cleanup the link change notification interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) static void fcoe_dev_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) unregister_dcbevent_notifier(&dcb_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) unregister_netdevice_notifier(&fcoe_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) static struct fcoe_interface *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) fcoe_hostlist_lookup_realdev_port(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) struct net_device *real_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) list_for_each_entry(fcoe, &fcoe_hostlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) if (is_vlan_dev(fcoe->netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) real_dev = vlan_dev_real_dev(fcoe->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) real_dev = fcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (netdev == real_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) return fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) static int fcoe_dcb_app_notification(struct notifier_block *notifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) ulong event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) struct dcb_app_type *entry = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) int prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) if (entry->app.selector != DCB_APP_IDTYPE_ETHTYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) netdev = dev_get_by_index(&init_net, entry->ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (!netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) fcoe = fcoe_hostlist_lookup_realdev_port(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) dev_put(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (!fcoe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) if (entry->dcbx & DCB_CAP_DCBX_VER_CEE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) prio = ffs(entry->app.priority) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) prio = entry->app.priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if (prio < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if (entry->app.protocol == ETH_P_FIP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) entry->app.protocol == ETH_P_FCOE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) ctlr->priority = prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) if (entry->app.protocol == ETH_P_FCOE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) fcoe->priority = prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) * fcoe_device_notification() - Handler for net device events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) * @notifier: The context of the notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) * @event: The type of event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) * @ptr: The net device that the event was on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * This function is called by the Ethernet driver in case of link change event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) static int fcoe_device_notification(struct notifier_block *notifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) ulong event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) struct fcoe_ctlr_device *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) struct fc_lport *lport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) struct fc_stats *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) u32 link_possible = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) u32 mfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) int rc = NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) list_for_each_entry(fcoe, &fcoe_hostlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) if (fcoe->netdev == netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (!lport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) rc = NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) case NETDEV_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) case NETDEV_GOING_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) link_possible = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) case NETDEV_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) case NETDEV_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) case NETDEV_CHANGEMTU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) if (netdev->features & NETIF_F_FCOE_MTU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) mfs = netdev->mtu - (sizeof(struct fcoe_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) sizeof(struct fcoe_crc_eof));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) if (mfs >= FC_MIN_MAX_FRAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) fc_set_mfs(lport, mfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) case NETDEV_REGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) case NETDEV_UNREGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) list_del(&fcoe->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) fcoe_vport_remove(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) fcoe_if_destroy(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if (!fcoe->removed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) fcoe_interface_remove(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) fcoe_interface_cleanup(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) fcoe_ctlr_device_delete(fcoe_ctlr_to_ctlr_dev(ctlr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) case NETDEV_FEAT_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) fcoe_netdev_features_change(lport, netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) FCOE_NETDEV_DBG(netdev, "Unknown event %ld "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) "from netdev netlink\n", event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) fcoe_link_speed_update(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (link_possible && !fcoe_link_ok(lport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) switch (cdev->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) case FCOE_CTLR_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) pr_info("Link up while interface is disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) case FCOE_CTLR_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) case FCOE_CTLR_UNUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) fcoe_ctlr_link_up(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) } else if (fcoe_ctlr_link_down(ctlr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) switch (cdev->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) case FCOE_CTLR_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) pr_info("Link down while interface is disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) case FCOE_CTLR_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) case FCOE_CTLR_UNUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) stats = per_cpu_ptr(lport->stats, get_cpu());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) stats->LinkFailureCount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) fcoe_clean_pending_queue(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) * fcoe_disable() - Disables a FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) * @netdev : The net_device object the Ethernet interface to create on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) * Called from fcoe transport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) * Deprecated: use fcoe_ctlr_enabled()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) static int fcoe_disable(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) fcoe = fcoe_hostlist_lookup_port(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) if (fcoe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) fcoe_ctlr_link_down(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) fcoe_clean_pending_queue(ctlr->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) * fcoe_enable() - Enables a FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) * @netdev : The net_device object the Ethernet interface to create on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) * Called from fcoe transport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) static int fcoe_enable(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) fcoe = fcoe_hostlist_lookup_port(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) if (!fcoe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (!fcoe_link_ok(ctlr->lp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) fcoe_ctlr_link_up(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) * fcoe_ctlr_enabled() - Enable or disable an FCoE Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) * @cdev: The FCoE Controller that is being enabled or disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) * fcoe_sysfs will ensure that the state of 'enabled' has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) * changed, so no checking is necessary here. This routine simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) * calls fcoe_enable or fcoe_disable, both of which are deprecated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) * When those routines are removed the functionality can be merged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) struct fc_lport *lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) struct net_device *netdev = fcoe_netdev(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) switch (cdev->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) case FCOE_CTLR_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) return fcoe_enable(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) case FCOE_CTLR_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return fcoe_disable(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) case FCOE_CTLR_UNUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) * fcoe_ctlr_mode() - Switch FIP mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) * @ctlr_dev: The FCoE Controller that is being modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) * When the FIP mode has been changed we need to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) * the multicast addresses to ensure we get the correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) * frames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) static void fcoe_ctlr_mode(struct fcoe_ctlr_device *ctlr_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) struct fcoe_interface *fcoe = fcoe_ctlr_priv(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) if (ctlr_dev->mode == FIP_CONN_TYPE_VN2VN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) ctlr->mode != FIP_MODE_VN2VN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) dev_mc_del(fcoe->netdev, FIP_ALL_ENODE_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) dev_mc_add(fcoe->netdev, FIP_ALL_VN2VN_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) dev_mc_add(fcoe->netdev, FIP_ALL_P2P_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) } else if (ctlr->mode != FIP_MODE_FABRIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) dev_mc_del(fcoe->netdev, FIP_ALL_VN2VN_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) dev_mc_del(fcoe->netdev, FIP_ALL_P2P_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) dev_mc_add(fcoe->netdev, FIP_ALL_ENODE_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) fcoe_ctlr_set_fip_mode(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * fcoe_destroy() - Destroy a FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) * @netdev : The net_device object the Ethernet interface to create on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * Called from fcoe transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) static int fcoe_destroy(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) fcoe = fcoe_hostlist_lookup_port(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) if (!fcoe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) goto out_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) list_del(&fcoe->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) queue_work(fcoe_wq, &port->destroy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) out_nodev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) * fcoe_destroy_work() - Destroy a FCoE port in a deferred work context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) * @work: Handle to the FCoE port to be destroyed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) static void fcoe_destroy_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) struct fcoe_ctlr_device *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) port = container_of(work, struct fcoe_port, destroy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) fcoe_vport_remove(port->lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) fcoe_if_destroy(port->lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) if (!fcoe->removed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) fcoe_interface_remove(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) fcoe_interface_cleanup(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) fcoe_ctlr_device_delete(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) * fcoe_match() - Check if the FCoE is supported on the given netdevice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) * @netdev : The net_device object the Ethernet interface to create on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) * Called from fcoe transport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) * Returns: always returns true as this is the default FCoE transport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) * i.e., support all netdevs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) static bool fcoe_match(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) * fcoe_dcb_create() - Initialize DCB attributes and hooks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) * @fcoe: The new FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) static void fcoe_dcb_create(struct fcoe_interface *fcoe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) int ctlr_prio = TC_PRIO_BESTEFFORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) int fcoe_prio = TC_PRIO_INTERACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) #ifdef CONFIG_DCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) int dcbx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) u8 fup, up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) struct net_device *netdev = fcoe->realdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) struct dcb_app app = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) .priority = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) .protocol = ETH_P_FCOE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) /* setup DCB priority attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) if (netdev && netdev->dcbnl_ops && netdev->dcbnl_ops->getdcbx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) dcbx = netdev->dcbnl_ops->getdcbx(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) if (dcbx & DCB_CAP_DCBX_VER_IEEE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) app.selector = IEEE_8021QAZ_APP_SEL_ETHERTYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) up = dcb_ieee_getapp_mask(netdev, &app);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) app.protocol = ETH_P_FIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) fup = dcb_ieee_getapp_mask(netdev, &app);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) app.selector = DCB_APP_IDTYPE_ETHTYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) up = dcb_getapp(netdev, &app);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) app.protocol = ETH_P_FIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) fup = dcb_getapp(netdev, &app);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) fcoe_prio = ffs(up) ? ffs(up) - 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) ctlr_prio = ffs(fup) ? ffs(fup) - 1 : fcoe_prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) fcoe->priority = fcoe_prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) ctlr->priority = ctlr_prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) enum fcoe_create_link_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) FCOE_CREATE_LINK_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) FCOE_CREATE_LINK_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) * _fcoe_create() - (internal) Create a fcoe interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) * @netdev : The net_device object the Ethernet interface to create on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) * @fip_mode: The FIP mode for this creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) * @link_state: The ctlr link state on creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) * Called from either the libfcoe 'create' module parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) * via fcoe_create or from fcoe_syfs's ctlr_create file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) * libfcoe's 'create' module parameter is deprecated so some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) * consolidation of code can be done when that interface is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) * removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) static int _fcoe_create(struct net_device *netdev, enum fip_mode fip_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) enum fcoe_create_link_state link_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) struct fcoe_ctlr_device *ctlr_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) /* look for existing lport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (fcoe_hostlist_lookup(netdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) rc = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) goto out_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) fcoe = fcoe_interface_create(netdev, fip_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) if (IS_ERR(fcoe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) rc = PTR_ERR(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) goto out_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) lport = fcoe_if_create(fcoe, &ctlr_dev->dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) if (IS_ERR(lport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) if (!fcoe->removed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) fcoe_interface_remove(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) fcoe_interface_cleanup(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) fcoe_ctlr_device_delete(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) /* Make this the "master" N_Port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) ctlr->lp = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) /* setup DCB priority attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) fcoe_dcb_create(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) /* start FIP Discovery and FLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) lport->boot_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) fc_fabric_login(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) * If the fcoe_ctlr_device is to be set to DISABLED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) * it must be done after the lport is added to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) * hostlist, but before the rtnl_lock is released.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) * This is because the rtnl_lock protects the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) * hostlist that fcoe_device_notification uses. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) * the FCoE Controller is intended to be created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) * DISABLED then 'enabled' needs to be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) * handling link events. 'enabled' must be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) * before the lport can be found in the hostlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) * when a link up event is received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) if (link_state == FCOE_CREATE_LINK_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) ctlr_dev->enabled = FCOE_CTLR_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) ctlr_dev->enabled = FCOE_CTLR_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) if (link_state == FCOE_CREATE_LINK_UP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) !fcoe_link_ok(lport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) fcoe_ctlr_link_up(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) out_nodev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) * fcoe_create() - Create a fcoe interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) * @netdev : The net_device object the Ethernet interface to create on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) * @fip_mode: The FIP mode for this creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) * Called from fcoe transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) static int fcoe_create(struct net_device *netdev, enum fip_mode fip_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) return _fcoe_create(netdev, fip_mode, FCOE_CREATE_LINK_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) * fcoe_ctlr_alloc() - Allocate a fcoe interface from fcoe_sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) * @netdev: The net_device to be used by the allocated FCoE Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) * in a link_down state. The allows the user an opportunity to configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) * the FCoE Controller from sysfs before enabling the FCoE Controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) * Creating in with this routine starts the FCoE Controller in Fabric
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) * mode. The user can change to VN2VN or another mode before enabling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) static int fcoe_ctlr_alloc(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) return _fcoe_create(netdev, FIP_MODE_FABRIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) FCOE_CREATE_LINK_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) * fcoe_link_ok() - Check if the link is OK for a local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) * @lport: The local port to check link on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) * Returns: 0 if link is UP and OK, -1 if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) static int fcoe_link_ok(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) struct net_device *netdev = fcoe_netdev(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) if (netif_oper_up(netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) * fcoe_percpu_clean() - Clear all pending skbs for an local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) * @lport: The local port whose skbs are to be cleared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) * Must be called with fcoe_create_mutex held to single-thread completion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) * This flushes the pending skbs by flush the work item for each CPU. The work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) * item on each possible CPU is flushed because we may have used the per-CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) * struct of an offline CPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) static void fcoe_percpu_clean(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) struct fcoe_percpu_s *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) unsigned int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) pp = &per_cpu(fcoe_percpu, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) flush_work(&pp->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) * fcoe_reset() - Reset a local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) * @shost: The SCSI host associated with the local port to be reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) * Returns: Always 0 (return value required by FC transport template)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) static int fcoe_reset(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) struct fc_lport *lport = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) struct fcoe_interface *fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) struct fcoe_ctlr_device *cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) fcoe_ctlr_link_down(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) fcoe_clean_pending_queue(ctlr->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) if (cdev->enabled != FCOE_CTLR_DISABLED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) !fcoe_link_ok(ctlr->lp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) fcoe_ctlr_link_up(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) * fcoe_hostlist_lookup_port() - Find the FCoE interface associated with a net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) * @netdev: The net device used as a key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) * Locking: Must be called with the RNL mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) * Returns: NULL or the FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) static struct fcoe_interface *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) fcoe_hostlist_lookup_port(const struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) list_for_each_entry(fcoe, &fcoe_hostlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) if (fcoe->netdev == netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) return fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) * fcoe_hostlist_lookup() - Find the local port associated with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) * given net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) * @netdev: The netdevice used as a key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) * Locking: Must be called with the RTNL mutex held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) * Returns: NULL or the local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) fcoe = fcoe_hostlist_lookup_port(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) return (fcoe) ? ctlr->lp : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) * fcoe_hostlist_add() - Add the FCoE interface identified by a local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) * port to the hostlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) * @lport: The local port that identifies the FCoE interface to be added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) * Locking: must be called with the RTNL mutex held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) static int fcoe_hostlist_add(const struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) if (!fcoe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) list_add_tail(&fcoe->list, &fcoe_hostlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) * fcoe_hostlist_del() - Remove the FCoE interface identified by a local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) * port to the hostlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) * @lport: The local port that identifies the FCoE interface to be added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) * Locking: must be called with the RTNL mutex held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) static void fcoe_hostlist_del(const struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) struct fcoe_interface *fcoe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) list_del(&fcoe->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) static struct fcoe_transport fcoe_sw_transport = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) .name = {FCOE_TRANSPORT_DEFAULT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) .attached = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) .list = LIST_HEAD_INIT(fcoe_sw_transport.list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) .match = fcoe_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) .alloc = fcoe_ctlr_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) .create = fcoe_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) .destroy = fcoe_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) .enable = fcoe_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) .disable = fcoe_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) * fcoe_init() - Initialize fcoe.ko
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) * Returns: 0 on success, or a negative value on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) static int __init fcoe_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) struct fcoe_percpu_s *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) unsigned int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) fcoe_wq = alloc_workqueue("fcoe", 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) if (!fcoe_wq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) /* register as a fcoe transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) rc = fcoe_transport_attach(&fcoe_sw_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) printk(KERN_ERR "failed to register an fcoe transport, check "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) "if libfcoe is loaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) goto out_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) p = per_cpu_ptr(&fcoe_percpu, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) INIT_WORK(&p->work, fcoe_receive_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) skb_queue_head_init(&p->fcoe_rx_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) /* Setup link change notification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) fcoe_dev_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) rc = fcoe_if_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) out_destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) destroy_workqueue(fcoe_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) module_init(fcoe_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) * fcoe_exit() - Clean up fcoe.ko
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) * Returns: 0 on success or a negative value on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) static void __exit fcoe_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) struct fcoe_interface *fcoe, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) unsigned int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) fcoe_dev_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) /* releases the associated fcoe hosts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) port = lport_priv(ctlr->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) fcoe_hostlist_del(port->lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) queue_work(fcoe_wq, &port->destroy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) for_each_possible_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) fcoe_thread_cleanup_local(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) * destroy_work's may be chained but destroy_workqueue()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) * can take care of them. Just kill the fcoe_wq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) destroy_workqueue(fcoe_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) * Detaching from the scsi transport must happen after all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) * destroys are done on the fcoe_wq. destroy_workqueue will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) * enusre the fcoe_wq is flushed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) fcoe_if_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) /* detach from fcoe transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) fcoe_transport_detach(&fcoe_sw_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) module_exit(fcoe_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) * fcoe_flogi_resp() - FCoE specific FLOGI and FDISC response handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) * @seq: active sequence in the FLOGI or FDISC exchange
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) * @fp: response frame, or error encoded in a pointer (timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) * @arg: pointer to the fcoe_ctlr structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) * This handles MAC address management for FCoE, then passes control on to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) * the libfc FLOGI response handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) struct fcoe_ctlr *fip = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) struct fc_exch *exch = fc_seq_exch(seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) struct fc_lport *lport = exch->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) u8 *mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) if (IS_ERR(fp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) mac = fr_cb(fp)->granted_mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) /* pre-FIP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) if (is_zero_ether_addr(mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) fcoe_ctlr_recv_flogi(fip, lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) if (!is_zero_ether_addr(mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) fcoe_update_src_mac(lport, mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) fc_lport_flogi_resp(seq, fp, lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) * fcoe_logo_resp() - FCoE specific LOGO response handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) * @seq: active sequence in the LOGO exchange
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) * @fp: response frame, or error encoded in a pointer (timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) * @arg: pointer to the fcoe_ctlr structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) * This handles MAC address management for FCoE, then passes control on to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) * the libfc LOGO response handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) struct fc_lport *lport = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) static u8 zero_mac[ETH_ALEN] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) if (!IS_ERR(fp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) fcoe_update_src_mac(lport, zero_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) fc_lport_logo_resp(seq, fp, lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) * fcoe_elsct_send - FCoE specific ELS handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) * This does special case handling of FIP encapsualted ELS exchanges for FCoE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) * using FCoE specific response handlers and passing the FIP controller as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) * the argument (the lport is still available from the exchange).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) * Most of the work here is just handed off to the libfc routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) struct fc_frame *fp, unsigned int op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) void (*resp)(struct fc_seq *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) struct fc_frame *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) void *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) void *arg, u32 timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) struct fcoe_interface *fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) struct fc_frame_header *fh = fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) case ELS_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) case ELS_FDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) if (lport->point_to_multipoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) return fc_elsct_send(lport, did, fp, op, fcoe_flogi_resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) fip, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) case ELS_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) /* only hook onto fabric logouts, not port logouts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) lport, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) return fc_elsct_send(lport, did, fp, op, resp, arg, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) * fcoe_vport_create() - create an fc_host/scsi_host for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) * @vport: fc_vport object to create a new fc_host for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) * @disabled: start the new fc_host in a disabled state by default?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) static int fcoe_vport_create(struct fc_vport *vport, bool disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) struct Scsi_Host *shost = vport_to_shost(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) struct fc_lport *n_port = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) struct fcoe_port *port = lport_priv(n_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) struct fcoe_interface *fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) struct net_device *netdev = fcoe->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) struct fc_lport *vn_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) char buf[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) rc = fcoe_validate_vport_create(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) printk(KERN_ERR "fcoe: Failed to create vport, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) "WWPN (0x%s) already exists\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) vn_port = fcoe_if_create(fcoe, &vport->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) if (IS_ERR(vn_port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) printk(KERN_ERR "fcoe: fcoe_vport_create(%s) failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) if (disabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) fc_vport_set_state(vport, FC_VPORT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) vn_port->boot_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) fc_fabric_login(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) fc_vport_setlink(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) * fcoe_vport_destroy() - destroy the fc_host/scsi_host for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) * @vport: fc_vport object that is being destroyed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) static int fcoe_vport_destroy(struct fc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) struct Scsi_Host *shost = vport_to_shost(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) struct fc_lport *n_port = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) struct fc_lport *vn_port = vport->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) mutex_lock(&n_port->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) list_del(&vn_port->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) mutex_unlock(&n_port->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) mutex_lock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) fcoe_if_destroy(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) mutex_unlock(&fcoe_config_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) * fcoe_vport_remove() - remove attached vports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) * @lport: lport for which the vports should be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) static void fcoe_vport_remove(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) struct fc_host_attrs *fc_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) struct fc_vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) struct fc_vport *next_vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) shost = lport->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) fc_host = shost_to_fc_host(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) /* Loop through all the vports and mark them for deletion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) spin_lock_irqsave(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) vport->flags |= FC_VPORT_DELETING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) queue_work(fc_host_work_q(shost),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) &vport->vport_delete_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) spin_unlock_irqrestore(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) flush_workqueue(fc_host_work_q(shost));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) * fcoe_vport_disable() - change vport state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) * @vport: vport to bring online/offline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) * @disable: should the vport be disabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) static int fcoe_vport_disable(struct fc_vport *vport, bool disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) struct fc_lport *lport = vport->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) if (disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) fc_vport_set_state(vport, FC_VPORT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) fc_fabric_logoff(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) lport->boot_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) fc_fabric_login(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) fc_vport_setlink(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) * fcoe_vport_set_symbolic_name() - append vport string to symbolic name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) * @vport: fc_vport with a new symbolic name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) * After generating a new symbolic name string, a new RSPN_ID request is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) * sent to the name server. There is no response handler, so if it fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) * for some reason it will not be retried.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) static void fcoe_set_vport_symbolic_name(struct fc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) struct fc_lport *lport = vport->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) struct fc_frame *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) "%s v%s over %s : %s", FCOE_NAME, FCOE_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) fcoe_netdev(lport)->name, vport->symbolic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) if (lport->state != LPORT_ST_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) len = strnlen(fc_host_symbolic_name(lport->host), 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) fp = fc_frame_alloc(lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) sizeof(struct fc_ct_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) sizeof(struct fc_ns_rspn) + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) if (!fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RSPN_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) NULL, NULL, 3 * lport->r_a_tov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) struct fcoe_ctlr_device *ctlr_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) fcoe_fcf_dev_to_ctlr_dev(fcf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) struct fcoe_interface *fcoe = fcoe_ctlr_priv(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) fcf_dev->vlan_id = vlan_dev_vlan_id(fcoe->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) * fcoe_set_port_id() - Callback from libfc when Port_ID is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) * @lport: the local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) * @port_id: the port ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) * @fp: the received frame, if any, that caused the port_id to be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) * This routine handles the case where we received a FLOGI and are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) * entering point-to-point mode. We need to call fcoe_ctlr_recv_flogi()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) * so it can set the non-mapped mode and gateway address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) * The FLOGI LS_ACC is handled by fcoe_flogi_resp().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) static void fcoe_set_port_id(struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) u32 port_id, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) struct fcoe_interface *fcoe = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) if (fp && fc_frame_payload_op(fp) == ELS_FLOGI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) fcoe_ctlr_recv_flogi(ctlr, lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) }