Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) 2008-2009 Cisco Systems, Inc.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (c) 2009 Intel Corporation.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Maintained at www.Open-FCoE.org
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <net/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <scsi/fc/fc_els.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <scsi/fc/fc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <scsi/fc/fc_fip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <scsi/fc/fc_encaps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <scsi/fc/fc_fcoe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <scsi/fc/fc_fcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <scsi/libfc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <scsi/libfcoe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include "libfcoe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define	FCOE_CTLR_MIN_FKA	500		/* min keep alive (mS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define	FCOE_CTLR_DEF_FKA	FIP_DEF_FKA	/* default keep alive (mS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) static void fcoe_ctlr_timeout(struct timer_list *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) static void fcoe_ctlr_timer_work(struct work_struct *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) static void fcoe_ctlr_recv_work(struct work_struct *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) static void fcoe_ctlr_vn_start(struct fcoe_ctlr *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) static int fcoe_ctlr_vn_lookup(struct fcoe_ctlr *, u32, u8 *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) static int fcoe_ctlr_vlan_recv(struct fcoe_ctlr *, struct sk_buff *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) static u8 fcoe_all_enode[ETH_ALEN] = FIP_ALL_ENODE_MACS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) static u8 fcoe_all_vn2vn[ETH_ALEN] = FIP_ALL_VN2VN_MACS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) static u8 fcoe_all_p2p[ETH_ALEN] = FIP_ALL_P2P_MACS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) static const char * const fcoe_ctlr_states[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	[FIP_ST_DISABLED] =	"DISABLED",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	[FIP_ST_LINK_WAIT] =	"LINK_WAIT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	[FIP_ST_AUTO] =		"AUTO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	[FIP_ST_NON_FIP] =	"NON_FIP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	[FIP_ST_ENABLED] =	"ENABLED",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	[FIP_ST_VNMP_START] =	"VNMP_START",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	[FIP_ST_VNMP_PROBE1] =	"VNMP_PROBE1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	[FIP_ST_VNMP_PROBE2] =	"VNMP_PROBE2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	[FIP_ST_VNMP_CLAIM] =	"VNMP_CLAIM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	[FIP_ST_VNMP_UP] =	"VNMP_UP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) static const char *fcoe_ctlr_state(enum fip_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	const char *cp = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	if (state < ARRAY_SIZE(fcoe_ctlr_states))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 		cp = fcoe_ctlr_states[state];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	if (!cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 		cp = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	return cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  * fcoe_ctlr_set_state() - Set and do debug printing for the new FIP state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * @state: The new state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) static void fcoe_ctlr_set_state(struct fcoe_ctlr *fip, enum fip_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	if (state == fip->state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	if (fip->lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		LIBFCOE_FIP_DBG(fip, "state %s -> %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 			fcoe_ctlr_state(fip->state), fcoe_ctlr_state(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	fip->state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97)  * fcoe_ctlr_mtu_valid() - Check if a FCF's MTU is valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)  * @fcf: The FCF to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  * Return non-zero if FCF fcoe_size has been validated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	return (fcf->flags & FIP_FL_SOL) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  * fcoe_ctlr_fcf_usable() - Check if a FCF is usable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)  * @fcf: The FCF to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111)  * Return non-zero if the FCF is usable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	u16 flags = FIP_FL_SOL | FIP_FL_AVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	return (fcf->flags & flags) == flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  * fcoe_ctlr_map_dest() - Set flag and OUI for mapping destination addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) static void fcoe_ctlr_map_dest(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	if (fip->mode == FIP_MODE_VN2VN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 		hton24(fip->dest_addr, FIP_VN_FC_MAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		hton24(fip->dest_addr, FIP_DEF_FC_MAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	hton24(fip->dest_addr + 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	fip->map_dest = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135)  * fcoe_ctlr_init() - Initialize the FCoE Controller instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136)  * @fip: The FCoE controller to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137)  * @mode: FIP mode to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	fcoe_ctlr_set_state(fip, FIP_ST_LINK_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	fip->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	fip->fip_resp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	INIT_LIST_HEAD(&fip->fcfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	mutex_init(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	spin_lock_init(&fip->ctlr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	fip->flogi_oxid = FC_XID_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	timer_setup(&fip->timer, fcoe_ctlr_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	INIT_WORK(&fip->recv_work, fcoe_ctlr_recv_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	skb_queue_head_init(&fip->fip_recv_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) EXPORT_SYMBOL(fcoe_ctlr_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  * fcoe_sysfs_fcf_add() - Add a fcoe_fcf{,_device} to a fcoe_ctlr{,_device}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  * @new: The newly discovered FCF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)  * Called with fip->ctlr_mutex held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	struct fcoe_ctlr *fip = new->fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	struct fcoe_ctlr_device *ctlr_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	struct fcoe_fcf_device *temp, *fcf_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	int rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 			new->fabric_name, new->fcf_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	temp = kzalloc(sizeof(*temp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	if (!temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	temp->fabric_name = new->fabric_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	temp->switch_name = new->switch_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	temp->fc_map = new->fc_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	temp->vfid = new->vfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	memcpy(temp->mac, new->fcf_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	temp->priority = new->pri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	temp->fka_period = new->fka_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	temp->selected = 0; /* default to unselected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	 * If ctlr_dev doesn't exist then it means we're a libfcoe user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	 * who doesn't use fcoe_syfs and didn't allocate a fcoe_ctlr_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	 * fnic would be an example of a driver with this behavior. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	 * case we want to add the fcoe_fcf to the fcoe_ctlr list, but we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	 * don't want to make sysfs changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	if (ctlr_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		mutex_lock(&ctlr_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		fcf_dev = fcoe_fcf_device_add(ctlr_dev, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		if (unlikely(!fcf_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 			rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 			mutex_unlock(&ctlr_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		 * The fcoe_sysfs layer can return a CONNECTED fcf that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 		 * has a priv (fcf was never deleted) or a CONNECTED fcf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		 * that doesn't have a priv (fcf was deleted). However,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		 * libfcoe will always delete FCFs before trying to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		 * them. This is ensured because both recv_adv and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		 * age_fcfs are protected by the the fcoe_ctlr's mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		 * This means that we should never get a FCF with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		 * non-NULL priv pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		BUG_ON(fcf_dev->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		fcf_dev->priv = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		new->fcf_dev = fcf_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		mutex_unlock(&ctlr_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	list_add(&new->list, &fip->fcfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	fip->fcf_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	kfree(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229)  * fcoe_sysfs_fcf_del() - Remove a fcoe_fcf{,_device} to a fcoe_ctlr{,_device}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230)  * @new: The FCF to be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232)  * Called with fip->ctlr_mutex held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	struct fcoe_ctlr *fip = new->fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	struct fcoe_ctlr_device *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	struct fcoe_fcf_device *fcf_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	list_del(&new->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	fip->fcf_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	 * If ctlr_dev doesn't exist then it means we're a libfcoe user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	 * who doesn't use fcoe_syfs and didn't allocate a fcoe_ctlr_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	 * or a fcoe_fcf_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	 * fnic would be an example of a driver with this behavior. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	 * case we want to remove the fcoe_fcf from the fcoe_ctlr list (above),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	 * but we don't want to make sysfs changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	cdev = fcoe_ctlr_to_ctlr_dev(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	if (cdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		mutex_lock(&cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		fcf_dev = fcoe_fcf_to_fcf_dev(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		WARN_ON(!fcf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		new->fcf_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		fcoe_fcf_device_delete(fcf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		mutex_unlock(&cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266)  * @fip: The FCoE controller whose FCFs are to be reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)  * Called with &fcoe_ctlr lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	struct fcoe_fcf *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	fip->sel_fcf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		fcoe_sysfs_fcf_del(fcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	WARN_ON(fip->fcf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	fip->sel_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285)  * fcoe_ctlr_destroy() - Disable and tear down a FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286)  * @fip: The FCoE controller to tear down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288)  * This is called by FCoE drivers before freeing the &fcoe_ctlr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290)  * The receive handler will have been deleted before this to guarantee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291)  * that no more recv_work will be scheduled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293)  * The timer routine will simply return once we set FIP_ST_DISABLED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)  * This guarantees that no further timeouts or work will be scheduled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	cancel_work_sync(&fip->recv_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	skb_queue_purge(&fip->fip_recv_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	fcoe_ctlr_set_state(fip, FIP_ST_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	fcoe_ctlr_reset_fcfs(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	del_timer_sync(&fip->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	cancel_work_sync(&fip->timer_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) EXPORT_SYMBOL(fcoe_ctlr_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311)  * fcoe_ctlr_announce() - announce new FCF selection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314)  * Also sets the destination MAC for FCoE and control packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)  * Called with neither ctlr_mutex nor ctlr_lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	struct fcoe_fcf *sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	spin_lock_bh(&fip->ctlr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	kfree_skb(fip->flogi_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	fip->flogi_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	list_for_each_entry(fcf, &fip->fcfs, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		fcf->flogi_sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	spin_unlock_bh(&fip->ctlr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	sel = fip->sel_fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	if (sel && ether_addr_equal(sel->fcf_mac, fip->dest_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	if (!is_zero_ether_addr(fip->dest_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		printk(KERN_NOTICE "libfcoe: host%d: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		       "FIP Fibre-Channel Forwarder MAC %pM deselected\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		       fip->lp->host->host_no, fip->dest_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		eth_zero_addr(fip->dest_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	if (sel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		printk(KERN_INFO "libfcoe: host%d: FIP selected "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		       "Fibre-Channel Forwarder MAC %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		       fip->lp->host->host_no, sel->fcf_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		memcpy(fip->dest_addr, sel->fcoe_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		fip->map_dest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354)  * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355)  * @fip: The FCoE controller to get the maximum FCoE size from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357)  * Returns the maximum packet size including the FCoE header and trailer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358)  * but not including any Ethernet or VLAN headers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) static inline u32 fcoe_ctlr_fcoe_size(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	 * Determine the max FCoE frame size allowed, including
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	 * FCoE header and trailer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	 * Note:  lp->mfs is currently the payload size, not the frame size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	return fip->lp->mfs + sizeof(struct fc_frame_header) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		sizeof(struct fcoe_hdr) + sizeof(struct fcoe_crc_eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) }
^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)  * fcoe_ctlr_solicit() - Send a FIP solicitation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373)  * @fip: The FCoE controller to send the solicitation on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374)  * @fcf: The destination FCF (if NULL, a multicast solicitation is sent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	struct fip_sol {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		struct ethhdr eth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		struct fip_header fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 			struct fip_mac_desc mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 			struct fip_wwn_desc wwnn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 			struct fip_size_desc size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		} __packed desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	}  __packed * sol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	u32 fcoe_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	skb = dev_alloc_skb(sizeof(*sol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	sol = (struct fip_sol *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	memset(sol, 0, sizeof(*sol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	memcpy(sol->eth.h_dest, fcf ? fcf->fcf_mac : fcoe_all_fcfs, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	memcpy(sol->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	sol->eth.h_proto = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	sol->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	sol->fip.fip_op = htons(FIP_OP_DISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	sol->fip.fip_subcode = FIP_SC_SOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	sol->fip.fip_flags = htons(FIP_FL_FPMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	if (fip->spma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		sol->fip.fip_flags |= htons(FIP_FL_SPMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	memcpy(sol->desc.mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	sol->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	sol->desc.wwnn.fd_desc.fip_dlen = sizeof(sol->desc.wwnn) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	put_unaligned_be64(fip->lp->wwnn, &sol->desc.wwnn.fd_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	fcoe_size = fcoe_ctlr_fcoe_size(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	sol->desc.size.fd_desc.fip_dtype = FIP_DT_FCOE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	sol->desc.size.fd_desc.fip_dlen = sizeof(sol->desc.size) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	sol->desc.size.fd_size = htons(fcoe_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	skb_put(skb, sizeof(*sol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	skb->protocol = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	skb->priority = fip->priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	fip->send(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	if (!fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		fip->sol_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434)  * fcoe_ctlr_link_up() - Start FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435)  * @fip: The FCoE controller to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437)  * Called from the LLD when the network link is ready.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) void fcoe_ctlr_link_up(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	if (fip->state == FIP_ST_NON_FIP || fip->state == FIP_ST_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		fc_linkup(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	} else if (fip->state == FIP_ST_LINK_WAIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		if (fip->mode == FIP_MODE_NON_FIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 			fcoe_ctlr_set_state(fip, FIP_ST_NON_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 			fcoe_ctlr_set_state(fip, FIP_ST_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		switch (fip->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			LIBFCOE_FIP_DBG(fip, "invalid mode %d\n", fip->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		case FIP_MODE_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 			LIBFCOE_FIP_DBG(fip, "%s", "setting AUTO mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		case FIP_MODE_FABRIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		case FIP_MODE_NON_FIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 			mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 			fc_linkup(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 			fcoe_ctlr_solicit(fip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		case FIP_MODE_VN2VN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			fcoe_ctlr_vn_start(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 			fc_linkup(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) EXPORT_SYMBOL(fcoe_ctlr_link_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)  * fcoe_ctlr_reset() - Reset a FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)  * @fip:       The FCoE controller to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) static void fcoe_ctlr_reset(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	fcoe_ctlr_reset_fcfs(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	del_timer(&fip->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	fip->ctlr_ka_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	fip->port_ka_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	fip->sol_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	fip->flogi_oxid = FC_XID_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	fcoe_ctlr_map_dest(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  * fcoe_ctlr_link_down() - Stop a FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  * @fip: The FCoE controller to be stopped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493)  * Returns non-zero if the link was up and now isn't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495)  * Called from the LLD when the network link is not ready.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496)  * There may be multiple calls while the link is down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) int fcoe_ctlr_link_down(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	int link_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	LIBFCOE_FIP_DBG(fip, "link down.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	fcoe_ctlr_reset(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	link_dropped = fip->state != FIP_ST_LINK_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	fcoe_ctlr_set_state(fip, FIP_ST_LINK_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	if (link_dropped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		fc_linkdown(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	return link_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) EXPORT_SYMBOL(fcoe_ctlr_link_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516)  * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517)  * @fip:   The FCoE controller to send the FKA on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518)  * @lport: libfc fc_lport to send from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519)  * @ports: 0 for controller keep-alive, 1 for port keep-alive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520)  * @sa:	   The source MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522)  * A controller keep-alive is sent every fka_period (typically 8 seconds).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523)  * The source MAC is the native MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525)  * A port keep-alive is sent every 90 seconds while logged in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526)  * The source MAC is the assigned mapped source address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527)  * The destination is the FCF's F-port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 				      struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 				      int ports, u8 *sa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	struct fip_kal {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		struct ethhdr eth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		struct fip_header fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		struct fip_mac_desc mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	} __packed * kal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	struct fip_vn_desc *vn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	struct fc_lport *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	fcf = fip->sel_fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	lp = fip->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	if (!fcf || (ports && !lp->port_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	len = sizeof(*kal) + ports * sizeof(*vn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	skb = dev_alloc_skb(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	kal = (struct fip_kal *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	memset(kal, 0, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	memcpy(kal->eth.h_dest, fcf->fcf_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	memcpy(kal->eth.h_source, sa, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	kal->eth.h_proto = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	kal->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	kal->fip.fip_op = htons(FIP_OP_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	kal->fip.fip_subcode = FIP_SC_KEEP_ALIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 				     ports * sizeof(*vn)) / FIP_BPW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	kal->fip.fip_flags = htons(FIP_FL_FPMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	if (fip->spma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		kal->fip.fip_flags |= htons(FIP_FL_SPMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	if (ports) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		vn = (struct fip_vn_desc *)(kal + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		vn->fd_desc.fip_dtype = FIP_DT_VN_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		memcpy(vn->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		hton24(vn->fd_fc_id, lport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		put_unaligned_be64(lport->wwpn, &vn->fd_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	skb_put(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	skb->protocol = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	skb->priority = fip->priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	fip->send(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589)  * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590)  * @fip:   The FCoE controller for the ELS frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591)  * @lport: The local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592)  * @dtype: The FIP descriptor type for the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593)  * @skb:   The FCoE ELS frame including FC header but no FCoE headers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594)  * @d_id:  The destination port ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596)  * Returns non-zero error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598)  * The caller must check that the length is a multiple of 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600)  * The @skb must have enough headroom (28 bytes) and tailroom (8 bytes).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601)  * Headroom includes the FIP encapsulation description, FIP header, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602)  * Ethernet header.  The tailroom is for the FIP MAC descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 			    u8 dtype, struct sk_buff *skb, u32 d_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	struct fip_encaps_head {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		struct ethhdr eth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		struct fip_header fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		struct fip_encaps encaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	} __packed * cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	struct fip_mac_desc *mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	size_t dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	u16 fip_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	u8 op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	fh = (struct fc_frame_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	op = *(u8 *)(fh + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	dlen = sizeof(struct fip_encaps) + skb->len;	/* len before push */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	cap = skb_push(skb, sizeof(*cap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	memset(cap, 0, sizeof(*cap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	if (lport->point_to_multipoint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		if (fcoe_ctlr_vn_lookup(fip, d_id, cap->eth.h_dest))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		fip_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		fcf = fip->sel_fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		if (!fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		fip_flags = fcf->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		fip_flags &= fip->spma ? FIP_FL_SPMA | FIP_FL_FPMA :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 					 FIP_FL_FPMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		if (!fip_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		memcpy(cap->eth.h_dest, fcf->fcf_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	memcpy(cap->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	cap->eth.h_proto = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	cap->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	cap->fip.fip_op = htons(FIP_OP_LS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	if (op == ELS_LS_ACC || op == ELS_LS_RJT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		cap->fip.fip_subcode = FIP_SC_REP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		cap->fip.fip_subcode = FIP_SC_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	cap->fip.fip_flags = htons(fip_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	cap->encaps.fd_desc.fip_dtype = dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	if (op != ELS_LS_RJT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		dlen += sizeof(*mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		mac = skb_put_zero(skb, sizeof(*mac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		mac->fd_desc.fip_dtype = FIP_DT_MAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 			memcpy(mac->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		} else if (fip->mode == FIP_MODE_VN2VN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			hton24(mac->fd_mac, FIP_VN_FC_MAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 			hton24(mac->fd_mac + 3, fip->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		} else if (fip_flags & FIP_FL_SPMA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 			LIBFCOE_FIP_DBG(fip, "FLOGI/FDISC sent with SPMA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 			LIBFCOE_FIP_DBG(fip, "FLOGI/FDISC sent with FPMA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			/* FPMA only FLOGI.  Must leave the MAC desc zeroed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	cap->fip.fip_dl_len = htons(dlen / FIP_BPW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	skb->protocol = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	skb->priority = fip->priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682)  * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683)  * @fip:	FCoE controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684)  * @lport:	libfc fc_lport to send from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685)  * @skb:	FCoE ELS frame including FC header but no FCoE headers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687)  * Returns a non-zero error code if the frame should not be sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688)  * Returns zero if the caller should send the frame with FCoE encapsulation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690)  * The caller must check that the length is a multiple of 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691)  * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692)  * The the skb must also be an fc_frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694)  * This is called from the lower-level driver with spinlocks held,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695)  * so we must not take a mutex here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		       struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	struct fc_frame *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	u16 old_xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	u8 op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	u8 mac[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	fp = container_of(skb, struct fc_frame, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	fh = (struct fc_frame_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	op = *(u8 *)(fh + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	if (op == ELS_FLOGI && fip->mode != FIP_MODE_VN2VN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		old_xid = fip->flogi_oxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		fip->flogi_oxid = ntohs(fh->fh_ox_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		if (fip->state == FIP_ST_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			if (old_xid == FC_XID_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 				fip->flogi_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 			fip->flogi_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 			if (fip->flogi_count < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			fcoe_ctlr_map_dest(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		if (fip->state == FIP_ST_NON_FIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			fcoe_ctlr_map_dest(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	if (fip->state == FIP_ST_NON_FIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	if (!fip->sel_fcf && fip->mode != FIP_MODE_VN2VN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	case ELS_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		op = FIP_DT_FLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		if (fip->mode == FIP_MODE_VN2VN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		spin_lock_bh(&fip->ctlr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		kfree_skb(fip->flogi_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		fip->flogi_req = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		fip->flogi_req_send = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		spin_unlock_bh(&fip->ctlr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		schedule_work(&fip->timer_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		return -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	case ELS_FDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		if (ntoh24(fh->fh_s_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		op = FIP_DT_FDISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	case ELS_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		if (fip->mode == FIP_MODE_VN2VN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			if (fip->state != FIP_ST_VNMP_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			if (ntoh24(fh->fh_d_id) == FC_FID_FLOGI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			if (fip->state != FIP_ST_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 			if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		op = FIP_DT_LOGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	case ELS_LS_ACC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		 * If non-FIP, we may have gotten an SID by accepting an FLOGI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		 * from a point-to-point connection.  Switch to using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		 * the source mac based on the SID.  The destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		 * MAC in this case would have been set by receiving the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		 * FLOGI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		if (fip->state == FIP_ST_NON_FIP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			if (fip->flogi_oxid == FC_XID_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 			fip->flogi_oxid = FC_XID_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			fc_fcoe_set_mac(mac, fh->fh_d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			fip->update_mac(lport, mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	case ELS_LS_RJT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		op = fr_encaps(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		if (op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		if (fip->state != FIP_ST_ENABLED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		    fip->state != FIP_ST_VNMP_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	LIBFCOE_FIP_DBG(fip, "els_send op %u d_id %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			op, ntoh24(fh->fh_d_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	if (fcoe_ctlr_encaps(fip, lport, op, skb, ntoh24(fh->fh_d_id)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	fip->send(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	return -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	LIBFCOE_FIP_DBG(fip, "drop els_send op %u d_id %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			op, ntoh24(fh->fh_d_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) EXPORT_SYMBOL(fcoe_ctlr_els_send);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803)  * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804)  * @fip: The FCoE controller to free FCFs on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806)  * Called with lock held and preemption disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808)  * An FCF is considered old if we have missed two advertisements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809)  * That is, there have been no valid advertisement from it for 2.5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810)  * times its keep-alive period.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812)  * In addition, determine the time when an FCF selection can occur.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814)  * Also, increment the MissDiscAdvCount when no advertisement is received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815)  * for the corresponding FCF for 1.5 * FKA_ADV_PERIOD (FC-BB-5 LESB).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817)  * Returns the time in jiffies for the next call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	struct fcoe_fcf *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	unsigned long deadline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	unsigned long sel_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	struct list_head del_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	struct fc_stats *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	INIT_LIST_HEAD(&del_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	stats = per_cpu_ptr(fip->lp->stats, get_cpu());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		deadline = fcf->time + fcf->fka_period + fcf->fka_period / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		if (fip->sel_fcf == fcf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 			if (time_after(jiffies, deadline)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 				stats->MissDiscAdvCount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 				printk(KERN_INFO "libfcoe: host%d: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 				       "Missing Discovery Advertisement "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 				       "for fab %16.16llx count %lld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 				       fip->lp->host->host_no, fcf->fabric_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 				       stats->MissDiscAdvCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			} else if (time_after(next_timer, deadline))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 				next_timer = deadline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		deadline += fcf->fka_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		if (time_after_eq(jiffies, deadline)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			if (fip->sel_fcf == fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 				fip->sel_fcf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 			 * Move to delete list so we can call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 			 * fcoe_sysfs_fcf_del (which can sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			 * after the put_cpu().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			list_del(&fcf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			list_add(&fcf->list, &del_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 			stats->VLinkFailureCount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			if (time_after(next_timer, deadline))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 				next_timer = deadline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			if (fcoe_ctlr_mtu_valid(fcf) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			    (!sel_time || time_before(sel_time, fcf->time)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 				sel_time = fcf->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	list_for_each_entry_safe(fcf, next, &del_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		/* Removes fcf from current list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		fcoe_sysfs_fcf_del(fcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	if (sel_time && !fip->sel_fcf && !fip->sel_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		fip->sel_time = sel_time;
^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) 	return next_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883)  * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884)  * @fip: The FCoE controller receiving the advertisement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885)  * @skb: The received FIP advertisement frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886)  * @fcf: The resulting FCF entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888)  * Returns zero on a valid parsed advertisement,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889)  * otherwise returns non zero value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			       struct sk_buff *skb, struct fcoe_fcf *fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	struct fip_header *fiph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	struct fip_desc *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	struct fip_wwn_desc *wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	struct fip_fab_desc *fab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	struct fip_fka_desc *fka;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	unsigned long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	size_t rlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	size_t dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	u32 desc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	memset(fcf, 0, sizeof(*fcf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	fcf->fka_period = msecs_to_jiffies(FCOE_CTLR_DEF_FKA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	fiph = (struct fip_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	fcf->flags = ntohs(fiph->fip_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	 * mask of required descriptors. validating each one clears its bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	desc_mask = BIT(FIP_DT_PRI) | BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 			BIT(FIP_DT_FAB) | BIT(FIP_DT_FKA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	rlen = ntohs(fiph->fip_dl_len) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	if (rlen + sizeof(*fiph) > skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	desc = (struct fip_desc *)(fiph + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	while (rlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		dlen = desc->fip_dlen * FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		if (dlen < sizeof(*desc) || dlen > rlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		/* Drop Adv if there are duplicate critical descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		if ((desc->fip_dtype < 32) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		    !(desc_mask & 1U << desc->fip_dtype)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			LIBFCOE_FIP_DBG(fip, "Duplicate Critical "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 					"Descriptors in FIP adv\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		switch (desc->fip_dtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		case FIP_DT_PRI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 			if (dlen != sizeof(struct fip_pri_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			fcf->pri = ((struct fip_pri_desc *)desc)->fd_pri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 			desc_mask &= ~BIT(FIP_DT_PRI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		case FIP_DT_MAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			if (dlen != sizeof(struct fip_mac_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 			memcpy(fcf->fcf_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 			       ((struct fip_mac_desc *)desc)->fd_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 			       ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 			memcpy(fcf->fcoe_mac, fcf->fcf_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 			if (!is_valid_ether_addr(fcf->fcf_mac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 				LIBFCOE_FIP_DBG(fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 					"Invalid MAC addr %pM in FIP adv\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 					fcf->fcf_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 			desc_mask &= ~BIT(FIP_DT_MAC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		case FIP_DT_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 			if (dlen != sizeof(struct fip_wwn_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 			wwn = (struct fip_wwn_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 			fcf->switch_name = get_unaligned_be64(&wwn->fd_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 			desc_mask &= ~BIT(FIP_DT_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		case FIP_DT_FAB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 			if (dlen != sizeof(struct fip_fab_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 			fab = (struct fip_fab_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 			fcf->fabric_name = get_unaligned_be64(&fab->fd_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 			fcf->vfid = ntohs(fab->fd_vfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			fcf->fc_map = ntoh24(fab->fd_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 			desc_mask &= ~BIT(FIP_DT_FAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		case FIP_DT_FKA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 			if (dlen != sizeof(struct fip_fka_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 			fka = (struct fip_fka_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 			if (fka->fd_flags & FIP_FKA_ADV_D)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 				fcf->fd_flags = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 			t = ntohl(fka->fd_fka_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 			if (t >= FCOE_CTLR_MIN_FKA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 				fcf->fka_period = msecs_to_jiffies(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 			desc_mask &= ~BIT(FIP_DT_FKA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		case FIP_DT_MAP_OUI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		case FIP_DT_FCOE_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		case FIP_DT_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		case FIP_DT_FDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		case FIP_DT_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		case FIP_DT_ELP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 			LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 					"in FIP adv\n", desc->fip_dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 			/* standard says ignore unknown descriptors >= 128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 			if (desc->fip_dtype < FIP_DT_NON_CRITICAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		desc = (struct fip_desc *)((char *)desc + dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		rlen -= dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	if (!fcf->fc_map || (fcf->fc_map & 0x10000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	if (!fcf->switch_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	if (desc_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		LIBFCOE_FIP_DBG(fip, "adv missing descriptors mask %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 				desc_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) len_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 			desc->fip_dtype, dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)  * fcoe_ctlr_recv_adv() - Handle an incoming advertisement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)  * @fip: The FCoE controller receiving the advertisement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)  * @skb: The received FIP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	struct fcoe_fcf new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	unsigned long sol_tov = msecs_to_jiffies(FCOE_CTLR_SOL_TOV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	int first = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	int mtu_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	if (fcoe_ctlr_parse_adv(fip, skb, &new))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	first = list_empty(&fip->fcfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	list_for_each_entry(fcf, &fip->fcfs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		if (fcf->switch_name == new.switch_name &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		    fcf->fabric_name == new.fabric_name &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		    fcf->fc_map == new.fc_map &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		    ether_addr_equal(fcf->fcf_mac, new.fcf_mac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		if (fip->fcf_count >= FCOE_CTLR_FCF_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		fcf = kmalloc(sizeof(*fcf), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		if (!fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		memcpy(fcf, &new, sizeof(new));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		fcf->fip = fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		rc = fcoe_sysfs_fcf_add(fcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			printk(KERN_ERR "Failed to allocate sysfs instance "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			       "for FCF, fab %16.16llx mac %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 			       new.fabric_name, new.fcf_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			kfree(fcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		 * Update the FCF's keep-alive descriptor flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		 * Other flag changes from new advertisements are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		 * ignored after a solicited advertisement is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		 * received and the FCF is selectable (usable).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		fcf->fd_flags = new.fd_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		if (!fcoe_ctlr_fcf_usable(fcf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			fcf->flags = new.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		if (fcf == fip->sel_fcf && !fcf->fd_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			fip->ctlr_ka_time -= fcf->fka_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			fip->ctlr_ka_time += new.fka_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			if (time_before(fip->ctlr_ka_time, fip->timer.expires))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 				mod_timer(&fip->timer, fip->ctlr_ka_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		fcf->fka_period = new.fka_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	mtu_valid = fcoe_ctlr_mtu_valid(fcf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	fcf->time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 				fcf->fabric_name, fcf->fcf_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	 * If this advertisement is not solicited and our max receive size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	 * hasn't been verified, send a solicited advertisement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	if (!mtu_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		fcoe_ctlr_solicit(fip, fcf);
^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) 	 * If its been a while since we did a solicit, and this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	 * the first advertisement we've received, do a multicast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	 * solicitation to gather as many advertisements as we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	 * before selection occurs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	if (first && time_after(jiffies, fip->sol_time + sol_tov))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		fcoe_ctlr_solicit(fip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	 * Put this FCF at the head of the list for priority among equals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	 * This helps in the case of an NPV switch which insists we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	 * the FCF that answers multicast solicitations, not the others that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	 * are sending periodic multicast advertisements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	if (mtu_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		list_move(&fcf->list, &fip->fcfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	 * If this is the first validated FCF, note the time and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	 * set a timer to trigger selection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	if (mtu_valid && !fip->sel_fcf && !fip->sel_time &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	    fcoe_ctlr_fcf_usable(fcf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		fip->sel_time = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			msecs_to_jiffies(FCOE_CTLR_START_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		if (!timer_pending(&fip->timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		    time_before(fip->sel_time, fip->timer.expires))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			mod_timer(&fip->timer, fip->sel_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)  * fcoe_ctlr_recv_els() - Handle an incoming FIP encapsulated ELS frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)  * @fip: The FCoE controller which received the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)  * @skb: The received FIP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	struct fc_lport *lport = fip->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	struct fip_header *fiph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	struct fc_frame *fp = (struct fc_frame *)skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	struct fc_frame_header *fh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	struct fip_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	struct fip_encaps *els;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	struct fcoe_fcf *sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	struct fc_stats *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	enum fip_desc_type els_dtype = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	u8 els_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	u8 sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	u8 granted_mac[ETH_ALEN] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	size_t els_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	size_t rlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	size_t dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	u32 desc_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	u32 desc_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	fiph = (struct fip_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	sub = fiph->fip_subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	if (sub != FIP_SC_REQ && sub != FIP_SC_REP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	rlen = ntohs(fiph->fip_dl_len) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	if (rlen + sizeof(*fiph) > skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	desc = (struct fip_desc *)(fiph + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	while (rlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		desc_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		dlen = desc->fip_dlen * FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		if (dlen < sizeof(*desc) || dlen > rlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 			goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		/* Drop ELS if there are duplicate critical descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		if (desc->fip_dtype < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 			if ((desc->fip_dtype != FIP_DT_MAC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 			    (desc_mask & 1U << desc->fip_dtype)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 				LIBFCOE_FIP_DBG(fip, "Duplicate Critical "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 						"Descriptors in FIP ELS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 			desc_mask |= (1 << desc->fip_dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		switch (desc->fip_dtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		case FIP_DT_MAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 			sel = fip->sel_fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 			if (desc_cnt == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 				LIBFCOE_FIP_DBG(fip, "FIP descriptors "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 						"received out of order\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 			 * Some switch implementations send two MAC descriptors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 			 * with first MAC(granted_mac) being the FPMA, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 			 * second one(fcoe_mac) is used as destination address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 			 * for sending/receiving FCoE packets. FIP traffic is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			 * sent using fip_mac. For regular switches, both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 			 * fip_mac and fcoe_mac would be the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 			if (desc_cnt == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 				memcpy(granted_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 				       ((struct fip_mac_desc *)desc)->fd_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 				       ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 			if (dlen != sizeof(struct fip_mac_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 			if ((desc_cnt == 3) && (sel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 				memcpy(sel->fcoe_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 				       ((struct fip_mac_desc *)desc)->fd_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 				       ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		case FIP_DT_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		case FIP_DT_FDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		case FIP_DT_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		case FIP_DT_ELP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 			if (desc_cnt != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 				LIBFCOE_FIP_DBG(fip, "FIP descriptors "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 						"received out of order\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 			if (fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 			if (dlen < sizeof(*els) + sizeof(*fh) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 			els_len = dlen - sizeof(*els);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 			els = (struct fip_encaps *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 			fh = (struct fc_frame_header *)(els + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			els_dtype = desc->fip_dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 			LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 					"in FIP adv\n", desc->fip_dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 			/* standard says ignore unknown descriptors >= 128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			if (desc->fip_dtype < FIP_DT_NON_CRITICAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			if (desc_cnt <= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 				LIBFCOE_FIP_DBG(fip, "FIP descriptors "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 						"received out of order\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		desc = (struct fip_desc *)((char *)desc + dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		rlen -= dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	if (!fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	els_op = *(u8 *)(fh + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	    sub == FIP_SC_REP && fip->mode != FIP_MODE_VN2VN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		if (els_op == ELS_LS_ACC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 			if (!is_valid_ether_addr(granted_mac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 				LIBFCOE_FIP_DBG(fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 					"Invalid MAC address %pM in FIP ELS\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 					granted_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 				goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 			memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 			if (fip->flogi_oxid == ntohs(fh->fh_ox_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 				fip->flogi_oxid = FC_XID_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 				if (els_dtype == FIP_DT_FLOGI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 					fcoe_ctlr_announce(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 		} else if (els_dtype == FIP_DT_FLOGI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 			   !fcoe_ctlr_flogi_retry(fip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 			goto drop;	/* retrying FLOGI so drop reject */
^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) 	if ((desc_cnt == 0) || ((els_op != ELS_LS_RJT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	    (!(1U << FIP_DT_MAC & desc_mask)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 		LIBFCOE_FIP_DBG(fip, "Missing critical descriptors "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 				"in FIP ELS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	 * Convert skb into an fc_frame containing only the ELS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	skb_pull(skb, (u8 *)fh - skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	skb_trim(skb, els_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	fp = (struct fc_frame *)skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	fc_frame_init(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	fr_sof(fp) = FC_SOF_I3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	fr_eof(fp) = FC_EOF_T;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	fr_dev(fp) = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	fr_encaps(fp) = els_dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	stats = per_cpu_ptr(lport->stats, get_cpu());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	stats->RxFrames++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	stats->RxWords += skb->len / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	fc_exch_recv(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) len_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 			desc->fip_dtype, dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	kfree_skb(skb);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)  * fcoe_ctlr_recv_els() - Handle an incoming link reset frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)  * @fip: The FCoE controller that received the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)  * @skb: The received FIP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)  * There may be multiple VN_Port descriptors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)  * The overall length has already been checked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 				     struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	struct fip_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	struct fip_mac_desc *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	struct fip_wwn_desc *wp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	struct fip_vn_desc *vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	size_t rlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	size_t dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	struct fcoe_fcf *fcf = fip->sel_fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	struct fc_lport *lport = fip->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	struct fc_lport *vn_port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	u32 desc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	int num_vlink_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	int reset_phys_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	struct fip_vn_desc **vlink_desc_arr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	struct fip_header *fh = (struct fip_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	struct ethhdr *eh = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	if (!fcf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		 * We are yet to select best FCF, but we got CVL in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		 * meantime. reset the ctlr and let it rediscover the FCF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		LIBFCOE_FIP_DBG(fip, "Resetting fcoe_ctlr as FCF has not been "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		    "selected yet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 		mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		fcoe_ctlr_reset(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	 * If we've selected an FCF check that the CVL is from there to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	 * processing CVLs from an unexpected source.  If it is from an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	 * unexpected source drop it on the floor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	if (!ether_addr_equal(eh->h_source, fcf->fcf_mac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		LIBFCOE_FIP_DBG(fip, "Dropping CVL due to source address "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 		    "mismatch with FCF src=%pM\n", eh->h_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	 * If we haven't logged into the fabric but receive a CVL we should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	 * reset everything and go back to solicitation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	if (!lport->port_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		LIBFCOE_FIP_DBG(fip, "lport not logged in, resoliciting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		fcoe_ctlr_reset(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		fc_lport_reset(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		fcoe_ctlr_solicit(fip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	 * mask of required descriptors.  Validating each one clears its bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	rlen = ntohs(fh->fip_dl_len) * FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	desc = (struct fip_desc *)(fh + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	 * Actually need to subtract 'sizeof(*mp) - sizeof(*wp)' from 'rlen'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	 * before determining max Vx_Port descriptor but a buggy FCF could have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	 * omitted either or both MAC Address and Name Identifier descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	num_vlink_desc = rlen / sizeof(*vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	if (num_vlink_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		vlink_desc_arr = kmalloc_array(num_vlink_desc, sizeof(vp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 					       GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	if (!vlink_desc_arr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	num_vlink_desc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	while (rlen >= sizeof(*desc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 		dlen = desc->fip_dlen * FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 		if (dlen > rlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		/* Drop CVL if there are duplicate critical descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		if ((desc->fip_dtype < 32) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		    (desc->fip_dtype != FIP_DT_VN_ID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		    !(desc_mask & 1U << desc->fip_dtype)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 			LIBFCOE_FIP_DBG(fip, "Duplicate Critical "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 					"Descriptors in FIP CVL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		switch (desc->fip_dtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 		case FIP_DT_MAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 			mp = (struct fip_mac_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 			if (dlen < sizeof(*mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 				goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 			if (!ether_addr_equal(mp->fd_mac, fcf->fcf_mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 				goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 			desc_mask &= ~BIT(FIP_DT_MAC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 		case FIP_DT_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 			wp = (struct fip_wwn_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 			if (dlen < sizeof(*wp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 				goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 			if (get_unaligned_be64(&wp->fd_wwn) != fcf->switch_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 				goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 			desc_mask &= ~BIT(FIP_DT_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		case FIP_DT_VN_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 			vp = (struct fip_vn_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 			if (dlen < sizeof(*vp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 				goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 			vlink_desc_arr[num_vlink_desc++] = vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 			vn_port = fc_vport_id_lookup(lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 						      ntoh24(vp->fd_fc_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 			if (vn_port && (vn_port == lport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 				mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 				per_cpu_ptr(lport->stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 					    get_cpu())->VLinkFailureCount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 				put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 				fcoe_ctlr_reset(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 				mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 			/* standard says ignore unknown descriptors >= 128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 			if (desc->fip_dtype < FIP_DT_NON_CRITICAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 				goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		desc = (struct fip_desc *)((char *)desc + dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		rlen -= dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	 * reset only if all required descriptors were present and valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	if (desc_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		LIBFCOE_FIP_DBG(fip, "missing descriptors mask %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 				desc_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	else if (!num_vlink_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		LIBFCOE_FIP_DBG(fip, "CVL: no Vx_Port descriptor found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 		 * No Vx_Port description. Clear all NPIV ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		 * followed by physical port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 		mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 		per_cpu_ptr(lport->stats, get_cpu())->VLinkFailureCount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		fcoe_ctlr_reset(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		mutex_lock(&lport->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		list_for_each_entry(vn_port, &lport->vports, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 			fc_lport_reset(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		mutex_unlock(&lport->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		fc_lport_reset(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		fcoe_ctlr_solicit(fip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 		LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		for (i = 0; i < num_vlink_desc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 			vp = vlink_desc_arr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 			vn_port = fc_vport_id_lookup(lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 						     ntoh24(vp->fd_fc_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 			if (!vn_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 			 * 'port_id' is already validated, check MAC address and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 			 * wwpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 			if (!ether_addr_equal(fip->get_src_addr(vn_port),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 					      vp->fd_mac) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 				get_unaligned_be64(&vp->fd_wwpn) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 							vn_port->wwpn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 			if (vn_port == lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 				 * Physical port, defer processing till all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 				 * listed NPIV ports are cleared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 				reset_phys_port = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 			else    /* NPIV port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 				fc_lport_reset(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		if (reset_phys_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 			fc_lport_reset(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 			fcoe_ctlr_solicit(fip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	kfree(vlink_desc_arr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)  * fcoe_ctlr_recv() - Receive a FIP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)  * @fip: The FCoE controller that received the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)  * @skb: The received FIP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)  * This may be called from either NET_RX_SOFTIRQ or IRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	skb = skb_share_check(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	skb_queue_tail(&fip->fip_recv_list, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	schedule_work(&fip->recv_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) EXPORT_SYMBOL(fcoe_ctlr_recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)  * fcoe_ctlr_recv_handler() - Receive a FIP frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)  * @fip: The FCoE controller that received the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)  * @skb: The received FIP frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)  * Returns non-zero if the frame is dropped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	struct fip_header *fiph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	struct ethhdr *eh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	enum fip_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	bool fip_vlan_resp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	u16 op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	u8 sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	if (skb_linearize(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	if (skb->len < sizeof(*fiph))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	eh = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	if (fip->mode == FIP_MODE_VN2VN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 		if (!ether_addr_equal(eh->h_dest, fip->ctl_src_addr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 		    !ether_addr_equal(eh->h_dest, fcoe_all_vn2vn) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		    !ether_addr_equal(eh->h_dest, fcoe_all_p2p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 			goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	} else if (!ether_addr_equal(eh->h_dest, fip->ctl_src_addr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		   !ether_addr_equal(eh->h_dest, fcoe_all_enode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	fiph = (struct fip_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	op = ntohs(fiph->fip_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	sub = fiph->fip_subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	if (FIP_VER_DECAPS(fiph->fip_ver) != FIP_VER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	if (ntohs(fiph->fip_dl_len) * FIP_BPW + sizeof(*fiph) > skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	state = fip->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	if (state == FIP_ST_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		fip->map_dest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		fcoe_ctlr_set_state(fip, FIP_ST_ENABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		state = FIP_ST_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 		LIBFCOE_FIP_DBG(fip, "Using FIP mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	fip_vlan_resp = fip->fip_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	if (fip->mode == FIP_MODE_VN2VN && op == FIP_OP_VN2VN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 		return fcoe_ctlr_vn_recv(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	if (fip_vlan_resp && op == FIP_OP_VLAN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 		LIBFCOE_FIP_DBG(fip, "fip vlan discovery\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		return fcoe_ctlr_vlan_recv(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	if (state != FIP_ST_ENABLED && state != FIP_ST_VNMP_UP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	    state != FIP_ST_VNMP_CLAIM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	if (op == FIP_OP_LS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		fcoe_ctlr_recv_els(fip, skb);	/* consumes skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	if (state != FIP_ST_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	if (op == FIP_OP_DISC && sub == FIP_SC_ADV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		fcoe_ctlr_recv_adv(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	else if (op == FIP_OP_CTRL && sub == FIP_SC_CLR_VLINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		fcoe_ctlr_recv_clr_vlink(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)  * fcoe_ctlr_select() - Select the best FCF (if possible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)  * Returns the selected FCF, or NULL if none are usable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)  * If there are conflicting advertisements, no FCF can be chosen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)  * If there is already a selected FCF, this will choose a better one or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)  * an equivalent one that hasn't already been sent a FLOGI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)  * Called with lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	struct fcoe_fcf *best = fip->sel_fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	list_for_each_entry(fcf, &fip->fcfs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		LIBFCOE_FIP_DBG(fip, "consider FCF fab %16.16llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 				"VFID %d mac %pM map %x val %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 				"sent %u pri %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 				fcf->fabric_name, fcf->vfid, fcf->fcf_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 				fcf->fc_map, fcoe_ctlr_mtu_valid(fcf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 				fcf->flogi_sent, fcf->pri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		if (!fcoe_ctlr_fcf_usable(fcf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 			LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 					"map %x %svalid %savailable\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 					fcf->fabric_name, fcf->fc_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 					(fcf->flags & FIP_FL_SOL) ? "" : "in",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 					(fcf->flags & FIP_FL_AVAIL) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 					"" : "un");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 		if (!best || fcf->pri < best->pri || best->flogi_sent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 			best = fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		if (fcf->fabric_name != best->fabric_name ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		    fcf->vfid != best->vfid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 		    fcf->fc_map != best->fc_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 			LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 					"or FC-MAP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	fip->sel_fcf = best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	if (best) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 		LIBFCOE_FIP_DBG(fip, "using FCF mac %pM\n", best->fcf_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 		fip->port_ka_time = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 			msecs_to_jiffies(FIP_VN_KA_PERIOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 		fip->ctlr_ka_time = jiffies + best->fka_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 		if (time_before(fip->ctlr_ka_time, fip->timer.expires))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 			mod_timer(&fip->timer, fip->ctlr_ka_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	return best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)  * fcoe_ctlr_flogi_send_locked() - send FIP-encapsulated FLOGI to current FCF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)  * Returns non-zero error if it could not be sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)  * Called with ctlr_mutex and ctlr_lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)  * Caller must verify that fip->sel_fcf is not NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	struct sk_buff *skb_orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	skb_orig = fip->flogi_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	if (!skb_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	 * Clone and send the FLOGI request.  If clone fails, use original.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	skb = skb_clone(skb_orig, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 		skb = skb_orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 		fip->flogi_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	fh = (struct fc_frame_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	error = fcoe_ctlr_encaps(fip, fip->lp, FIP_DT_FLOGI, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 				 ntoh24(fh->fh_d_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	fip->send(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	fip->sel_fcf->flogi_sent = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)  * fcoe_ctlr_flogi_retry() - resend FLOGI request to a new FCF if possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)  * Returns non-zero error code if there's no FLOGI request to retry or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)  * no alternate FCF available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	spin_lock_bh(&fip->ctlr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	fcf = fcoe_ctlr_select(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	if (!fcf || fcf->flogi_sent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 		kfree_skb(fip->flogi_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		fip->flogi_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 		error = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 		fcoe_ctlr_solicit(fip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 		error = fcoe_ctlr_flogi_send_locked(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	spin_unlock_bh(&fip->ctlr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) }
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)  * fcoe_ctlr_flogi_send() - Handle sending of FIP FLOGI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)  * @fip: The FCoE controller that timed out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)  * Done here because fcoe_ctlr_els_send() can't get mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)  * Called with ctlr_mutex held.  The caller must not hold ctlr_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	spin_lock_bh(&fip->ctlr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	fcf = fip->sel_fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	if (!fcf || !fip->flogi_req_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	LIBFCOE_FIP_DBG(fip, "sending FLOGI\n");
^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) 	 * If this FLOGI is being sent due to a timeout retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	 * to the same FCF as before, select a different FCF if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	if (fcf->flogi_sent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 		LIBFCOE_FIP_DBG(fip, "sending FLOGI - reselect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 		fcf = fcoe_ctlr_select(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 		if (!fcf || fcf->flogi_sent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 			LIBFCOE_FIP_DBG(fip, "sending FLOGI - clearing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 			list_for_each_entry(fcf, &fip->fcfs, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 				fcf->flogi_sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 			fcf = fcoe_ctlr_select(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	if (fcf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 		fcoe_ctlr_flogi_send_locked(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		fip->flogi_req_send = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	} else /* XXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 		LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	spin_unlock_bh(&fip->ctlr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)  * fcoe_ctlr_timeout() - FIP timeout handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)  * @t: Timer context use to obtain the controller reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) static void fcoe_ctlr_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	struct fcoe_ctlr *fip = from_timer(fip, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	schedule_work(&fip->timer_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)  * fcoe_ctlr_timer_work() - Worker thread function for timer work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)  * @work: Handle to a FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)  * Ages FCFs.  Triggers FCF selection if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)  * Sends keep-alives and resets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) static void fcoe_ctlr_timer_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	struct fcoe_ctlr *fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	struct fc_lport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	u8 *mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	u8 reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	u8 send_ctlr_ka = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	u8 send_port_ka = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	struct fcoe_fcf *sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	unsigned long next_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	fip = container_of(work, struct fcoe_ctlr, timer_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	if (fip->mode == FIP_MODE_VN2VN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 		return fcoe_ctlr_vn_timeout(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	if (fip->state == FIP_ST_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	fcf = fip->sel_fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	next_timer = fcoe_ctlr_age_fcfs(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	sel = fip->sel_fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	if (!sel && fip->sel_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 		if (time_after_eq(jiffies, fip->sel_time)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 			sel = fcoe_ctlr_select(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 			fip->sel_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 		} else if (time_after(next_timer, fip->sel_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 			next_timer = fip->sel_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	if (sel && fip->flogi_req_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 		fcoe_ctlr_flogi_send(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	else if (!sel && fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 		reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	if (sel && !sel->fd_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 		if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 			fip->ctlr_ka_time = jiffies + sel->fka_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 			send_ctlr_ka = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 		if (time_after(next_timer, fip->ctlr_ka_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 			next_timer = fip->ctlr_ka_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 		if (time_after_eq(jiffies, fip->port_ka_time)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 			fip->port_ka_time = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 				msecs_to_jiffies(FIP_VN_KA_PERIOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 			send_port_ka = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 		if (time_after(next_timer, fip->port_ka_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 			next_timer = fip->port_ka_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	if (!list_empty(&fip->fcfs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 		mod_timer(&fip->timer, next_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	if (reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 		fc_lport_reset(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 		/* restart things with a solicitation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 		fcoe_ctlr_solicit(fip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	if (send_ctlr_ka)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 		fcoe_ctlr_send_keep_alive(fip, NULL, 0, fip->ctl_src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	if (send_port_ka) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 		mutex_lock(&fip->lp->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		mac = fip->get_src_addr(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 		fcoe_ctlr_send_keep_alive(fip, fip->lp, 1, mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 		list_for_each_entry(vport, &fip->lp->vports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 			mac = fip->get_src_addr(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 			fcoe_ctlr_send_keep_alive(fip, vport, 1, mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 		mutex_unlock(&fip->lp->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)  * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)  * @recv_work: Handle to a FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	struct fcoe_ctlr *fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	fip = container_of(recv_work, struct fcoe_ctlr, recv_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	while ((skb = skb_dequeue(&fip->fip_recv_list)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 		fcoe_ctlr_recv_handler(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)  * fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)  * @lport: The local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)  * @fp:	 The FC frame to snoop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)  * Snoop potential response to FLOGI or even incoming FLOGI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)  * The caller has checked that we are waiting for login as indicated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)  * by fip->flogi_oxid != FC_XID_UNKNOWN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)  * The caller is responsible for freeing the frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)  * Fill in the granted_mac address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)  * Return non-zero if the frame should not be delivered to libfc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 			 struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	u8 op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	u8 *sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	sa = eth_hdr(&fp->skb)->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	fh = fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	if (fh->fh_type != FC_TYPE_ELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	op = fc_frame_payload_op(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	if (op == ELS_LS_ACC && fh->fh_r_ctl == FC_RCTL_ELS_REP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	    fip->flogi_oxid == ntohs(fh->fh_ox_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 		mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 		if (fip->state != FIP_ST_AUTO && fip->state != FIP_ST_NON_FIP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 			mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 		fcoe_ctlr_set_state(fip, FIP_ST_NON_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 		LIBFCOE_FIP_DBG(fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 				"received FLOGI LS_ACC using non-FIP mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 		 * FLOGI accepted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		 * If the src mac addr is FC_OUI-based, then we mark the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 		 * address_mode flag to use FC_OUI-based Ethernet DA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 		 * Otherwise we use the FCoE gateway addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 		if (ether_addr_equal(sa, (u8[6])FC_FCOE_FLOGI_MAC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 			fcoe_ctlr_map_dest(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 			memcpy(fip->dest_addr, sa, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 			fip->map_dest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 		fip->flogi_oxid = FC_XID_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 		mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 		fc_fcoe_set_mac(fr_cb(fp)->granted_mac, fh->fh_d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	} else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 		 * Save source MAC for point-to-point responses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 		mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 		if (fip->state == FIP_ST_AUTO || fip->state == FIP_ST_NON_FIP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 			memcpy(fip->dest_addr, sa, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 			fip->map_dest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 			if (fip->state == FIP_ST_AUTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 				LIBFCOE_FIP_DBG(fip, "received non-FIP FLOGI. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 						"Setting non-FIP mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 			fcoe_ctlr_set_state(fip, FIP_ST_NON_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 		mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) EXPORT_SYMBOL(fcoe_ctlr_recv_flogi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)  * fcoe_wwn_from_mac() - Converts a 48-bit IEEE MAC address to a 64-bit FC WWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)  * @mac:    The MAC address to convert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)  * @scheme: The scheme to use when converting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)  * @port:   The port indicator for converting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)  * Returns: u64 fc world wide name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 		      unsigned int scheme, unsigned int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	u64 wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	u64 host_mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	/* The MAC is in NO, so flip only the low 48 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	host_mac = ((u64) mac[0] << 40) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 		((u64) mac[1] << 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 		((u64) mac[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 		((u64) mac[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 		((u64) mac[4] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 		(u64) mac[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	WARN_ON(host_mac >= (1ULL << 48));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	wwn = host_mac | ((u64) scheme << 60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	switch (scheme) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 		WARN_ON(port != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 		WARN_ON(port >= 0xfff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 		wwn |= (u64) port << 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	return wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)  * fcoe_ctlr_rport() - return the fcoe_rport for a given fc_rport_priv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)  * @rdata: libfc remote port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	return container_of(rdata, struct fcoe_rport, rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)  * fcoe_ctlr_vn_send() - Send a FIP VN2VN Probe Request or Reply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)  * @sub: sub-opcode for probe request, reply, or advertisement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)  * @dest: The destination Ethernet MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)  * @min_len: minimum size of the Ethernet payload to be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) static void fcoe_ctlr_vn_send(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 			      enum fip_vn2vn_subcode sub,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 			      const u8 *dest, size_t min_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	struct fip_vn2vn_probe_frame {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 		struct ethhdr eth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		struct fip_header fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 		struct fip_mac_desc mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 		struct fip_wwn_desc wwnn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 		struct fip_vn_desc vn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	} __packed * frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	struct fip_fc4_feat *ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	struct fip_size_desc *size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	u32 fcp_feat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	size_t dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	len = sizeof(*frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	dlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	if (sub == FIP_SC_VN_CLAIM_NOTIFY || sub == FIP_SC_VN_CLAIM_REP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 		dlen = sizeof(struct fip_fc4_feat) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		       sizeof(struct fip_size_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 		len += dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 	dlen += sizeof(frame->mac) + sizeof(frame->wwnn) + sizeof(frame->vn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	len = max(len, min_len + sizeof(struct ethhdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	skb = dev_alloc_skb(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	frame = (struct fip_vn2vn_probe_frame *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	memset(frame, 0, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	memcpy(frame->eth.h_dest, dest, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	if (sub == FIP_SC_VN_BEACON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 		hton24(frame->eth.h_source, FIP_VN_FC_MAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 		hton24(frame->eth.h_source + 3, fip->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 		memcpy(frame->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	frame->eth.h_proto = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	frame->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	frame->fip.fip_op = htons(FIP_OP_VN2VN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	frame->fip.fip_subcode = sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	frame->fip.fip_dl_len = htons(dlen / FIP_BPW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	frame->mac.fd_desc.fip_dtype = FIP_DT_MAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	frame->mac.fd_desc.fip_dlen = sizeof(frame->mac) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	memcpy(frame->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	frame->wwnn.fd_desc.fip_dtype = FIP_DT_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	frame->wwnn.fd_desc.fip_dlen = sizeof(frame->wwnn) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	put_unaligned_be64(fip->lp->wwnn, &frame->wwnn.fd_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	frame->vn.fd_desc.fip_dtype = FIP_DT_VN_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	frame->vn.fd_desc.fip_dlen = sizeof(frame->vn) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	hton24(frame->vn.fd_mac, FIP_VN_FC_MAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	hton24(frame->vn.fd_mac + 3, fip->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 	hton24(frame->vn.fd_fc_id, fip->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	put_unaligned_be64(fip->lp->wwpn, &frame->vn.fd_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	 * For claims, add FC-4 features.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	 * TBD: Add interface to get fc-4 types and features from libfc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	if (sub == FIP_SC_VN_CLAIM_NOTIFY || sub == FIP_SC_VN_CLAIM_REP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 		ff = (struct fip_fc4_feat *)(frame + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 		ff->fd_desc.fip_dtype = FIP_DT_FC4F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 		ff->fd_desc.fip_dlen = sizeof(*ff) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		ff->fd_fts = fip->lp->fcts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 		fcp_feat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 		if (fip->lp->service_params & FCP_SPPF_INIT_FCN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 			fcp_feat |= FCP_FEAT_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 		if (fip->lp->service_params & FCP_SPPF_TARG_FCN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 			fcp_feat |= FCP_FEAT_TARG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		fcp_feat <<= (FC_TYPE_FCP * 4) % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 		ff->fd_ff.fd_feat[FC_TYPE_FCP * 4 / 32] = htonl(fcp_feat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 		size = (struct fip_size_desc *)(ff + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 		size->fd_desc.fip_dtype = FIP_DT_FCOE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		size->fd_desc.fip_dlen = sizeof(*size) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 		size->fd_size = htons(fcoe_ctlr_fcoe_size(fip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	skb_put(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	skb->protocol = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 	skb->priority = fip->priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	fip->send(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)  * fcoe_ctlr_vn_rport_callback - Event handler for rport events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120)  * @lport: The lport which is receiving the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)  * @rdata: remote port private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)  * @event: The event that occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124)  * Locking Note:  The rport lock must not be held when calling this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) static void fcoe_ctlr_vn_rport_callback(struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 					struct fc_rport_priv *rdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 					enum fc_rport_event event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	struct fcoe_ctlr *fip = lport->disc.priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	struct fcoe_rport *frport = fcoe_ctlr_rport(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	LIBFCOE_FIP_DBG(fip, "vn_rport_callback %x event %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 			rdata->ids.port_id, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	case RPORT_EV_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		frport->login_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	case RPORT_EV_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	case RPORT_EV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 	case RPORT_EV_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 		frport->login_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 		if (frport->login_count > FCOE_CTLR_VN2VN_LOGIN_LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 			LIBFCOE_FIP_DBG(fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 					"rport FLOGI limited port_id %6.6x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 					rdata->ids.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 			fc_rport_logoff(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) static struct fc_rport_operations fcoe_ctlr_vn_rport_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	.event_callback = fcoe_ctlr_vn_rport_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)  * fcoe_ctlr_disc_stop_locked() - stop discovery in VN2VN mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)  * @lport: The local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) static void fcoe_ctlr_disc_stop_locked(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	struct fc_rport_priv *rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	mutex_lock(&lport->disc.disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	list_for_each_entry_rcu(rdata, &lport->disc.rports, peers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 		if (kref_get_unless_zero(&rdata->kref)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 			fc_rport_logoff(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 			kref_put(&rdata->kref, fc_rport_destroy);
^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) 	lport->disc.disc_callback = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	mutex_unlock(&lport->disc.disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) }
^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)  * fcoe_ctlr_disc_stop() - stop discovery in VN2VN mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)  * @lport: The local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)  * Called through the local port template for discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)  * Called without the ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) static void fcoe_ctlr_disc_stop(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	struct fcoe_ctlr *fip = lport->disc.priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	fcoe_ctlr_disc_stop_locked(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200)  * fcoe_ctlr_disc_stop_final() - stop discovery for shutdown in VN2VN mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)  * @lport: The local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)  * Called through the local port template for discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)  * Called without the ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) static void fcoe_ctlr_disc_stop_final(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	fcoe_ctlr_disc_stop(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	fc_rport_flush_queue();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214)  * fcoe_ctlr_vn_restart() - VN2VN probe restart with new port_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)  * Called with fcoe_ctlr lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	unsigned long wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	u32 port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	fcoe_ctlr_disc_stop_locked(fip->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	 * Get proposed port ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	 * If this is the first try after link up, use any previous port_id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	 * If there was none, use the low bits of the port_name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	 * On subsequent tries, get the next random one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	 * Don't use reserved IDs, use another non-zero value, just as random.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	port_id = fip->port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	if (fip->probe_tries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 		port_id = prandom_u32_state(&fip->rnd_state) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	else if (!port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 		port_id = fip->lp->wwpn & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	if (!port_id || port_id == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 		port_id = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	fip->port_id = port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	if (fip->probe_tries < FIP_VN_RLIM_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		fip->probe_tries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		wait = prandom_u32() % FIP_VN_PROBE_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		wait = FIP_VN_RLIM_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	mod_timer(&fip->timer, jiffies + msecs_to_jiffies(wait));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	fcoe_ctlr_set_state(fip, FIP_ST_VNMP_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)  * fcoe_ctlr_vn_start() - Start in VN2VN mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)  * Called with fcoe_ctlr lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	fip->probe_tries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	prandom_seed_state(&fip->rnd_state, fip->lp->wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	fcoe_ctlr_vn_restart(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)  * fcoe_ctlr_vn_parse - parse probe request or response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)  * @skb: incoming packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)  * @frport: parsed FCoE rport from the probe request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)  * Returns non-zero error number on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)  * Does not consume the packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 			      struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 			      struct fcoe_rport *frport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	struct fip_header *fiph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	struct fip_desc *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	struct fip_mac_desc *macd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 	struct fip_wwn_desc *wwn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	struct fip_vn_desc *vn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	struct fip_size_desc *size = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	size_t rlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	size_t dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	u32 desc_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	u32 dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	u8 sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	fiph = (struct fip_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	frport->flags = ntohs(fiph->fip_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	sub = fiph->fip_subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	switch (sub) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	case FIP_SC_VN_PROBE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	case FIP_SC_VN_PROBE_REP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	case FIP_SC_VN_BEACON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 		desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 			    BIT(FIP_DT_VN_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	case FIP_SC_VN_CLAIM_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	case FIP_SC_VN_CLAIM_REP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 		desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 			    BIT(FIP_DT_VN_ID) | BIT(FIP_DT_FC4F) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 			    BIT(FIP_DT_FCOE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 		LIBFCOE_FIP_DBG(fip, "vn_parse unknown subcode %u\n", sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 		return -EINVAL;
^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) 	rlen = ntohs(fiph->fip_dl_len) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	if (rlen + sizeof(*fiph) > skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	desc = (struct fip_desc *)(fiph + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	while (rlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 		dlen = desc->fip_dlen * FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 		if (dlen < sizeof(*desc) || dlen > rlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 		dtype = desc->fip_dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 		if (dtype < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 			if (!(desc_mask & BIT(dtype))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 				LIBFCOE_FIP_DBG(fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 						"unexpected or duplicated desc "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 						"desc type %u in "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 						"FIP VN2VN subtype %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 						dtype, sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 			desc_mask &= ~BIT(dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		switch (dtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 		case FIP_DT_MAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 			if (dlen != sizeof(struct fip_mac_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 			macd = (struct fip_mac_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 			if (!is_valid_ether_addr(macd->fd_mac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 				LIBFCOE_FIP_DBG(fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 					"Invalid MAC addr %pM in FIP VN2VN\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 					 macd->fd_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 			memcpy(frport->enode_mac, macd->fd_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 		case FIP_DT_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 			if (dlen != sizeof(struct fip_wwn_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 			wwn = (struct fip_wwn_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 			frport->rdata.ids.node_name =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 				get_unaligned_be64(&wwn->fd_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 		case FIP_DT_VN_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 			if (dlen != sizeof(struct fip_vn_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 			vn = (struct fip_vn_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 			memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 			frport->rdata.ids.port_id = ntoh24(vn->fd_fc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 			frport->rdata.ids.port_name =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 				get_unaligned_be64(&vn->fd_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 		case FIP_DT_FC4F:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 			if (dlen != sizeof(struct fip_fc4_feat))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 		case FIP_DT_FCOE_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 			if (dlen != sizeof(struct fip_size_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 			size = (struct fip_size_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 			frport->fcoe_len = ntohs(size->fd_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 			LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 					"in FIP probe\n", dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 			/* standard says ignore unknown descriptors >= 128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 			if (dtype < FIP_DT_NON_CRITICAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		desc = (struct fip_desc *)((char *)desc + dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		rlen -= dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) len_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 	LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 			dtype, dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	return -EINVAL;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393)  * fcoe_ctlr_vn_send_claim() - send multicast FIP VN2VN Claim Notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) static void fcoe_ctlr_vn_send_claim(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 	fcoe_ctlr_vn_send(fip, FIP_SC_VN_CLAIM_NOTIFY, fcoe_all_vn2vn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	fip->sol_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)  * fcoe_ctlr_vn_probe_req() - handle incoming VN2VN probe request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)  * @frport: parsed FCoE rport from the probe request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) static void fcoe_ctlr_vn_probe_req(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 				   struct fcoe_rport *frport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	if (frport->rdata.ids.port_id != fip->port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 	switch (fip->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	case FIP_ST_VNMP_CLAIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	case FIP_ST_VNMP_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 		LIBFCOE_FIP_DBG(fip, "vn_probe_req: send reply, state %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 				fip->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 				  frport->enode_mac, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	case FIP_ST_VNMP_PROBE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	case FIP_ST_VNMP_PROBE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		 * Decide whether to reply to the Probe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		 * Our selected address is never a "recorded" one, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 		 * only reply if our WWPN is greater and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 		 * Probe's REC bit is not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 		 * If we don't reply, we will change our address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 		if (fip->lp->wwpn > frport->rdata.ids.port_name &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 		    !(frport->flags & FIP_FL_REC_OR_P2P)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 			LIBFCOE_FIP_DBG(fip, "vn_probe_req: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 					"port_id collision\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 			fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 					  frport->enode_mac, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	case FIP_ST_VNMP_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 		LIBFCOE_FIP_DBG(fip, "vn_probe_req: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 				"restart VN2VN negotiation\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 		fcoe_ctlr_vn_restart(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 		LIBFCOE_FIP_DBG(fip, "vn_probe_req: ignore state %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 				fip->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)  * fcoe_ctlr_vn_probe_reply() - handle incoming VN2VN probe reply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458)  * @frport: parsed FCoE rport from the probe request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) static void fcoe_ctlr_vn_probe_reply(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 				     struct fcoe_rport *frport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	if (frport->rdata.ids.port_id != fip->port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	switch (fip->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 	case FIP_ST_VNMP_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	case FIP_ST_VNMP_PROBE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	case FIP_ST_VNMP_PROBE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	case FIP_ST_VNMP_CLAIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 		LIBFCOE_FIP_DBG(fip, "vn_probe_reply: restart state %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 				fip->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 		fcoe_ctlr_vn_restart(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	case FIP_ST_VNMP_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 		LIBFCOE_FIP_DBG(fip, "vn_probe_reply: send claim notify\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 		fcoe_ctlr_vn_send_claim(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486)  * fcoe_ctlr_vn_add() - Add a VN2VN entry to the list, based on a claim reply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)  * @new: newly-parsed FCoE rport as a template for new rdata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) static void fcoe_ctlr_vn_add(struct fcoe_ctlr *fip, struct fcoe_rport *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	struct fc_lport *lport = fip->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	struct fc_rport_priv *rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	struct fc_rport_identifiers *ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 	struct fcoe_rport *frport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	u32 port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	port_id = new->rdata.ids.port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	if (port_id == fip->port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	mutex_lock(&lport->disc.disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	rdata = fc_rport_create(lport, port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	if (!rdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 		mutex_unlock(&lport->disc.disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	mutex_lock(&rdata->rp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	mutex_unlock(&lport->disc.disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	rdata->ops = &fcoe_ctlr_vn_rport_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 	rdata->disc_id = lport->disc.disc_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	ids = &rdata->ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	if ((ids->port_name != -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 	     ids->port_name != new->rdata.ids.port_name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	    (ids->node_name != -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	     ids->node_name != new->rdata.ids.node_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 		mutex_unlock(&rdata->rp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 		LIBFCOE_FIP_DBG(fip, "vn_add rport logoff %6.6x\n", port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 		fc_rport_logoff(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 		mutex_lock(&rdata->rp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	ids->port_name = new->rdata.ids.port_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	ids->node_name = new->rdata.ids.node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	mutex_unlock(&rdata->rp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	frport = fcoe_ctlr_rport(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	LIBFCOE_FIP_DBG(fip, "vn_add rport %6.6x %s state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 			port_id, frport->fcoe_len ? "old" : "new",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 			rdata->rp_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	frport->fcoe_len = new->fcoe_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	frport->flags = new->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	frport->login_count = new->login_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	memcpy(frport->enode_mac, new->enode_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	memcpy(frport->vn_mac, new->vn_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	frport->time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)  * fcoe_ctlr_vn_lookup() - Find VN remote port's MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545)  * @port_id:  The port_id of the remote VN_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)  * @mac: buffer which will hold the VN_NODE destination MAC address, if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)  * Returns non-zero error if no remote port found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) static int fcoe_ctlr_vn_lookup(struct fcoe_ctlr *fip, u32 port_id, u8 *mac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	struct fc_lport *lport = fip->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	struct fc_rport_priv *rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	struct fcoe_rport *frport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	rdata = fc_rport_lookup(lport, port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	if (rdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 		frport = fcoe_ctlr_rport(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 		memcpy(mac, frport->enode_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 		kref_put(&rdata->kref, fc_rport_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568)  * fcoe_ctlr_vn_claim_notify() - handle received FIP VN2VN Claim Notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570)  * @new: newly-parsed FCoE rport as a template for new rdata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) static void fcoe_ctlr_vn_claim_notify(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 				      struct fcoe_rport *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	if (new->flags & FIP_FL_REC_OR_P2P) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 		LIBFCOE_FIP_DBG(fip, "send probe req for P2P/REC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 		fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REQ, fcoe_all_vn2vn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	switch (fip->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	case FIP_ST_VNMP_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	case FIP_ST_VNMP_PROBE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	case FIP_ST_VNMP_PROBE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 		if (new->rdata.ids.port_id == fip->port_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 			LIBFCOE_FIP_DBG(fip, "vn_claim_notify: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 					"restart, state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 					fip->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 			fcoe_ctlr_vn_restart(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	case FIP_ST_VNMP_CLAIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	case FIP_ST_VNMP_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 		if (new->rdata.ids.port_id == fip->port_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 			if (new->rdata.ids.port_name > fip->lp->wwpn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 				LIBFCOE_FIP_DBG(fip, "vn_claim_notify: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 						"restart, port_id collision\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 				fcoe_ctlr_vn_restart(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 			LIBFCOE_FIP_DBG(fip, "vn_claim_notify: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 					"send claim notify\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 			fcoe_ctlr_vn_send_claim(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 		LIBFCOE_FIP_DBG(fip, "vn_claim_notify: send reply to %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 				new->rdata.ids.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		fcoe_ctlr_vn_send(fip, FIP_SC_VN_CLAIM_REP, new->enode_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 				  min((u32)new->fcoe_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 				      fcoe_ctlr_fcoe_size(fip)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 		fcoe_ctlr_vn_add(fip, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 		LIBFCOE_FIP_DBG(fip, "vn_claim_notify: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 				"ignoring claim from %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 				new->rdata.ids.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)  * fcoe_ctlr_vn_claim_resp() - handle received Claim Response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)  * @fip: The FCoE controller that received the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)  * @new: newly-parsed FCoE rport from the Claim Response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) static void fcoe_ctlr_vn_claim_resp(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 				    struct fcoe_rport *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	LIBFCOE_FIP_DBG(fip, "claim resp from from rport %x - state %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 			new->rdata.ids.port_id, fcoe_ctlr_state(fip->state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	if (fip->state == FIP_ST_VNMP_UP || fip->state == FIP_ST_VNMP_CLAIM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 		fcoe_ctlr_vn_add(fip, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639)  * fcoe_ctlr_vn_beacon() - handle received beacon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640)  * @fip: The FCoE controller that received the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641)  * @new: newly-parsed FCoE rport from the Beacon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) static void fcoe_ctlr_vn_beacon(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 				struct fcoe_rport *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	struct fc_lport *lport = fip->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	struct fc_rport_priv *rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 	struct fcoe_rport *frport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	if (new->flags & FIP_FL_REC_OR_P2P) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		LIBFCOE_FIP_DBG(fip, "p2p beacon while in vn2vn mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 		fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REQ, fcoe_all_vn2vn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	rdata = fc_rport_lookup(lport, new->rdata.ids.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	if (rdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		if (rdata->ids.node_name == new->rdata.ids.node_name &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 		    rdata->ids.port_name == new->rdata.ids.port_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 			frport = fcoe_ctlr_rport(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 			LIBFCOE_FIP_DBG(fip, "beacon from rport %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 					rdata->ids.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 			if (!frport->time && fip->state == FIP_ST_VNMP_UP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 				LIBFCOE_FIP_DBG(fip, "beacon expired "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 						"for rport %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 						rdata->ids.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 				fc_rport_login(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 			frport->time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 		kref_put(&rdata->kref, fc_rport_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	if (fip->state != FIP_ST_VNMP_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 	 * Beacon from a new neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	 * Send a claim notify if one hasn't been sent recently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	 * Don't add the neighbor yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 	LIBFCOE_FIP_DBG(fip, "beacon from new rport %x. sending claim notify\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 			new->rdata.ids.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	if (time_after(jiffies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 		       fip->sol_time + msecs_to_jiffies(FIP_VN_ANN_WAIT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 		fcoe_ctlr_vn_send_claim(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)  * fcoe_ctlr_vn_age() - Check for VN_ports without recent beacons
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696)  * Called only in state FIP_ST_VNMP_UP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697)  * Returns the soonest time for next age-out or a time far in the future.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) static unsigned long fcoe_ctlr_vn_age(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 	struct fc_lport *lport = fip->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	struct fc_rport_priv *rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 	struct fcoe_rport *frport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	unsigned long next_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	unsigned long deadline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	next_time = jiffies + msecs_to_jiffies(FIP_VN_BEACON_INT * 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 	mutex_lock(&lport->disc.disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 	list_for_each_entry_rcu(rdata, &lport->disc.rports, peers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 		if (!kref_get_unless_zero(&rdata->kref))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 		frport = fcoe_ctlr_rport(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 		if (!frport->time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 			kref_put(&rdata->kref, fc_rport_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 		deadline = frport->time +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 			   msecs_to_jiffies(FIP_VN_BEACON_INT * 25 / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 		if (time_after_eq(jiffies, deadline)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 			frport->time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 			LIBFCOE_FIP_DBG(fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 				"port %16.16llx fc_id %6.6x beacon expired\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 				rdata->ids.port_name, rdata->ids.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 			fc_rport_logoff(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 		} else if (time_before(deadline, next_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 			next_time = deadline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 		kref_put(&rdata->kref, fc_rport_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	mutex_unlock(&lport->disc.disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	return next_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)  * fcoe_ctlr_vn_recv() - Receive a FIP frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735)  * @fip: The FCoE controller that received the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)  * @skb: The received FIP frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)  * Returns non-zero if the frame is dropped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)  * Always consumes the frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 	struct fip_header *fiph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 	enum fip_vn2vn_subcode sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	struct fcoe_rport frport = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 	int rc, vlan_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	fiph = (struct fip_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 	sub = fiph->fip_subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	if (fip->lp->vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 		vlan_id = skb_vlan_tag_get_id(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 	if (vlan_id && vlan_id != fip->lp->vlan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 		LIBFCOE_FIP_DBG(fip, "vn_recv drop frame sub %x vlan %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 				sub, vlan_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 		rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	rc = fcoe_ctlr_vn_parse(fip, skb, &frport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 		LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	switch (sub) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	case FIP_SC_VN_PROBE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 		fcoe_ctlr_vn_probe_req(fip, &frport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 	case FIP_SC_VN_PROBE_REP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 		fcoe_ctlr_vn_probe_reply(fip, &frport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 	case FIP_SC_VN_CLAIM_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 		fcoe_ctlr_vn_claim_notify(fip, &frport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 	case FIP_SC_VN_CLAIM_REP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 		fcoe_ctlr_vn_claim_resp(fip, &frport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	case FIP_SC_VN_BEACON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 		fcoe_ctlr_vn_beacon(fip, &frport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 		LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796)  * fcoe_ctlr_vlan_parse - parse vlan discovery request or response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)  * @skb: incoming packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)  * @frport: parsed FCoE rport from the probe request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)  * Returns non-zero error number on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802)  * Does not consume the packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 			      struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 			      struct fcoe_rport *frport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	struct fip_header *fiph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 	struct fip_desc *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	struct fip_mac_desc *macd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 	struct fip_wwn_desc *wwn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	size_t rlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	size_t dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	u32 desc_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 	u32 dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	u8 sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 	fiph = (struct fip_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	frport->flags = ntohs(fiph->fip_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	sub = fiph->fip_subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	switch (sub) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	case FIP_SC_VL_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 		desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 		LIBFCOE_FIP_DBG(fip, "vn_parse unknown subcode %u\n", sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 	rlen = ntohs(fiph->fip_dl_len) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	if (rlen + sizeof(*fiph) > skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	desc = (struct fip_desc *)(fiph + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 	while (rlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 		dlen = desc->fip_dlen * FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 		if (dlen < sizeof(*desc) || dlen > rlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 		dtype = desc->fip_dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 		if (dtype < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 			if (!(desc_mask & BIT(dtype))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 				LIBFCOE_FIP_DBG(fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 						"unexpected or duplicated desc "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 						"desc type %u in "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 						"FIP VN2VN subtype %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 						dtype, sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 			desc_mask &= ~BIT(dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 		switch (dtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		case FIP_DT_MAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 			if (dlen != sizeof(struct fip_mac_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 			macd = (struct fip_mac_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 			if (!is_valid_ether_addr(macd->fd_mac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 				LIBFCOE_FIP_DBG(fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 					"Invalid MAC addr %pM in FIP VN2VN\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 					 macd->fd_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 			memcpy(frport->enode_mac, macd->fd_mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 		case FIP_DT_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 			if (dlen != sizeof(struct fip_wwn_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 				goto len_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 			wwn = (struct fip_wwn_desc *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 			frport->rdata.ids.node_name =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 				get_unaligned_be64(&wwn->fd_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 			LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 					"in FIP probe\n", dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 			/* standard says ignore unknown descriptors >= 128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 			if (dtype < FIP_DT_NON_CRITICAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 		desc = (struct fip_desc *)((char *)desc + dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 		rlen -= dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) len_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 			dtype, dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)  * fcoe_ctlr_vlan_send() - Send a FIP VLAN Notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896)  * @sub: sub-opcode for vlan notification or vn2vn vlan notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897)  * @dest: The destination Ethernet MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) static void fcoe_ctlr_vlan_send(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 			      enum fip_vlan_subcode sub,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 			      const u8 *dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	struct fip_vlan_notify_frame {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 		struct ethhdr eth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 		struct fip_header fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 		struct fip_mac_desc mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 		struct fip_vlan_desc vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	} __packed * frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	size_t dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 	len = sizeof(*frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	dlen = sizeof(frame->mac) + sizeof(frame->vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 	len = max(len, sizeof(struct ethhdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 	skb = dev_alloc_skb(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	LIBFCOE_FIP_DBG(fip, "fip %s vlan notification, vlan %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 			fip->mode == FIP_MODE_VN2VN ? "vn2vn" : "fcf",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 			fip->lp->vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	frame = (struct fip_vlan_notify_frame *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	memset(frame, 0, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 	memcpy(frame->eth.h_dest, dest, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 	memcpy(frame->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	frame->eth.h_proto = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	frame->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	frame->fip.fip_op = htons(FIP_OP_VLAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	frame->fip.fip_subcode = sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	frame->fip.fip_dl_len = htons(dlen / FIP_BPW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 	frame->mac.fd_desc.fip_dtype = FIP_DT_MAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	frame->mac.fd_desc.fip_dlen = sizeof(frame->mac) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 	memcpy(frame->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 	frame->vlan.fd_desc.fip_dtype = FIP_DT_VLAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	frame->vlan.fd_desc.fip_dlen = sizeof(frame->vlan) / FIP_BPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	put_unaligned_be16(fip->lp->vlan, &frame->vlan.fd_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 	skb_put(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	skb->protocol = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 	skb->priority = fip->priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 	skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 	skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	fip->send(fip, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955)  * fcoe_ctlr_vlan_disk_reply() - send FIP VLAN Discovery Notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)  * @frport: The newly-parsed FCoE rport from the Discovery Request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959)  * Called with ctlr_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) static void fcoe_ctlr_vlan_disc_reply(struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 				      struct fcoe_rport *frport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	enum fip_vlan_subcode sub = FIP_SC_VL_NOTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	if (fip->mode == FIP_MODE_VN2VN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 		sub = FIP_SC_VL_VN2VN_NOTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	fcoe_ctlr_vlan_send(fip, sub, frport->enode_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973)  * fcoe_ctlr_vlan_recv - vlan request receive handler for VN2VN mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)  * @skb: The received FIP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) static int fcoe_ctlr_vlan_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 	struct fip_header *fiph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	enum fip_vlan_subcode sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 	struct fcoe_rport frport = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	fiph = (struct fip_header *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 	sub = fiph->fip_subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	rc = fcoe_ctlr_vlan_parse(fip, skb, &frport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 		LIBFCOE_FIP_DBG(fip, "vlan_recv vlan_parse error %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	if (sub == FIP_SC_VL_REQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 		fcoe_ctlr_vlan_disc_reply(fip, &frport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)  * fcoe_ctlr_disc_recv - discovery receive handler for VN2VN mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)  * @lport: The local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004)  * @fp: The received frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006)  * This should never be called since we don't see RSCNs or other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007)  * fabric-generated ELSes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) static void fcoe_ctlr_disc_recv(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 	struct fc_seq_els_data rjt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	rjt_data.reason = ELS_RJT_UNSUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 	rjt_data.explan = ELS_EXPL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	fc_seq_els_rsp_send(fp, ELS_LS_RJT, &rjt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	fc_frame_free(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020)  * fcoe_ctlr_disc_start - start discovery for VN2VN mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)  * This sets a flag indicating that remote ports should be created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023)  * and started for the peers we discover.  We use the disc_callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)  * pointer as that flag.  Peers already discovered are created here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026)  * The lport lock is held during this call. The callback must be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027)  * later, without holding either the lport or discovery locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028)  * The fcoe_ctlr lock may also be held during this call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) static void fcoe_ctlr_disc_start(void (*callback)(struct fc_lport *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 						  enum fc_disc_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 				 struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 	struct fc_disc *disc = &lport->disc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	struct fcoe_ctlr *fip = disc->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 	mutex_lock(&disc->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 	disc->disc_callback = callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 	disc->disc_id = (disc->disc_id + 2) | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 	disc->pending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 	schedule_work(&fip->timer_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 	mutex_unlock(&disc->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046)  * fcoe_ctlr_vn_disc() - report FIP VN_port discovery results after claim state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049)  * Starts the FLOGI and PLOGI login process to each discovered rport for which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050)  * we've received at least one beacon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051)  * Performs the discovery complete callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) static void fcoe_ctlr_vn_disc(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 	struct fc_lport *lport = fip->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 	struct fc_disc *disc = &lport->disc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 	struct fc_rport_priv *rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	struct fcoe_rport *frport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	void (*callback)(struct fc_lport *, enum fc_disc_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 	mutex_lock(&disc->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	callback = disc->pending ? disc->disc_callback : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	disc->pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 	list_for_each_entry_rcu(rdata, &disc->rports, peers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		if (!kref_get_unless_zero(&rdata->kref))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 		frport = fcoe_ctlr_rport(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		if (frport->time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 			fc_rport_login(rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 		kref_put(&rdata->kref, fc_rport_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 	mutex_unlock(&disc->disc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 	if (callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 		callback(lport, DISC_EV_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078)  * fcoe_ctlr_vn_timeout - timer work function for VN2VN mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079)  * @fip: The FCoE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 	unsigned long next_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 	u8 mac[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 	u32 new_port_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 	switch (fip->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 	case FIP_ST_VNMP_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 		fcoe_ctlr_set_state(fip, FIP_ST_VNMP_PROBE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 		LIBFCOE_FIP_DBG(fip, "vn_timeout: send 1st probe request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 		fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REQ, fcoe_all_vn2vn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 		next_time = jiffies + msecs_to_jiffies(FIP_VN_PROBE_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	case FIP_ST_VNMP_PROBE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 		fcoe_ctlr_set_state(fip, FIP_ST_VNMP_PROBE2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 		LIBFCOE_FIP_DBG(fip, "vn_timeout: send 2nd probe request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 		fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REQ, fcoe_all_vn2vn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 		next_time = jiffies + msecs_to_jiffies(FIP_VN_ANN_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	case FIP_ST_VNMP_PROBE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 		fcoe_ctlr_set_state(fip, FIP_ST_VNMP_CLAIM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 		new_port_id = fip->port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 		hton24(mac, FIP_VN_FC_MAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 		hton24(mac + 3, new_port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 		fcoe_ctlr_map_dest(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 		fip->update_mac(fip->lp, mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 		LIBFCOE_FIP_DBG(fip, "vn_timeout: send claim notify\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 		fcoe_ctlr_vn_send_claim(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 		next_time = jiffies + msecs_to_jiffies(FIP_VN_ANN_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	case FIP_ST_VNMP_CLAIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 		 * This may be invoked either by starting discovery so don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 		 * go to the next state unless it's been long enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 		next_time = fip->sol_time + msecs_to_jiffies(FIP_VN_ANN_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 		if (time_after_eq(jiffies, next_time)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 			fcoe_ctlr_set_state(fip, FIP_ST_VNMP_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 			LIBFCOE_FIP_DBG(fip, "vn_timeout: send vn2vn beacon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 			fcoe_ctlr_vn_send(fip, FIP_SC_VN_BEACON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 					  fcoe_all_vn2vn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 			next_time = jiffies + msecs_to_jiffies(FIP_VN_ANN_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 			fip->port_ka_time = next_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 		fcoe_ctlr_vn_disc(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 	case FIP_ST_VNMP_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 		next_time = fcoe_ctlr_vn_age(fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 		if (time_after_eq(jiffies, fip->port_ka_time)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 			LIBFCOE_FIP_DBG(fip, "vn_timeout: send vn2vn beacon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 			fcoe_ctlr_vn_send(fip, FIP_SC_VN_BEACON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 					  fcoe_all_vn2vn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 			fip->port_ka_time = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 				 msecs_to_jiffies(FIP_VN_BEACON_INT +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 					(prandom_u32() % FIP_VN_BEACON_FUZZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 		if (time_before(fip->port_ka_time, next_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 			next_time = fip->port_ka_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 	case FIP_ST_LINK_WAIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 		WARN(1, "unexpected state %d\n", fip->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	mod_timer(&fip->timer, next_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	/* If port ID is new, notify local port after dropping ctlr_mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 	if (new_port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 		fc_lport_set_local_id(fip->lp, new_port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157)  * fcoe_ctlr_mode_set() - Set or reset the ctlr's mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158)  * @lport: The local port to be (re)configured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159)  * @fip:   The FCoE controller whose mode is changing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160)  * @fip_mode: The new fip mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162)  * Note that the we shouldn't be changing the libfc discovery settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163)  * (fc_disc_config) while an lport is going through the libfc state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164)  * machine. The mode can only be changed when a fcoe_ctlr device is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165)  * disabled, so that should ensure that this routine is only called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166)  * when nothing is happening.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) static void fcoe_ctlr_mode_set(struct fc_lport *lport, struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 			       enum fip_mode fip_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 	void *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 	WARN_ON(lport->state != LPORT_ST_RESET &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 		lport->state != LPORT_ST_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 	if (fip_mode == FIP_MODE_VN2VN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 		lport->rport_priv_size = sizeof(struct fcoe_rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 		lport->point_to_multipoint = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 		lport->tt.disc_recv_req = fcoe_ctlr_disc_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 		lport->tt.disc_start = fcoe_ctlr_disc_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 		lport->tt.disc_stop = fcoe_ctlr_disc_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 		lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 		priv = fip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 		lport->rport_priv_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 		lport->point_to_multipoint = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 		lport->tt.disc_recv_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 		lport->tt.disc_start = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 		lport->tt.disc_stop = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 		lport->tt.disc_stop_final = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 		priv = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 	fc_disc_config(lport, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198)  * fcoe_libfc_config() - Sets up libfc related properties for local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199)  * @lport:    The local port to configure libfc for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200)  * @fip:      The FCoE controller in use by the local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201)  * @tt:       The libfc function template
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202)  * @init_fcp: If non-zero, the FCP portion of libfc should be initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204)  * Returns : 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 		      const struct libfc_function_template *tt, int init_fcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 	/* Set the function pointers set by the LLDD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 	memcpy(&lport->tt, tt, sizeof(*tt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	if (init_fcp && fc_fcp_init(lport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 	fc_exch_init(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	fc_elsct_init(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	fc_lport_init(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	fc_disc_init(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 	fcoe_ctlr_mode_set(lport, fip, fip->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) EXPORT_SYMBOL_GPL(fcoe_libfc_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 	struct fcoe_ctlr_device *ctlr_dev = fcoe_fcf_dev_to_ctlr_dev(fcf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 	struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 	struct fcoe_fcf *fcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 	mutex_lock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 	mutex_lock(&ctlr_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 	fcf = fcoe_fcf_device_priv(fcf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 	if (fcf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 		fcf_dev->selected = (fcf == fip->sel_fcf) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 		fcf_dev->selected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 	mutex_unlock(&ctlr_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 	mutex_unlock(&fip->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) EXPORT_SYMBOL(fcoe_fcf_get_selected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 	struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 	struct fc_lport *lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 	mutex_lock(&ctlr->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 	switch (ctlr_dev->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 	case FIP_CONN_TYPE_VN2VN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 		ctlr->mode = FIP_MODE_VN2VN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 	case FIP_CONN_TYPE_FABRIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 		ctlr->mode = FIP_MODE_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 	mutex_unlock(&ctlr->ctlr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 	fcoe_ctlr_mode_set(lport, ctlr, ctlr->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode);