fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SunOS 5.x Multithreaded STREAMS DLPI FCIP Module
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is a pseudo driver module to handle encapsulation of IP and ARP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * datagrams over FibreChannel interfaces. FCIP is a cloneable STREAMS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * driver module which interfaces with IP/ARP using DLPI. This module
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is a Style-2 DLS provider.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The implementation of this module is based on RFC 2625 which gives
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * details on the encapsulation of IP/ARP data over FibreChannel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The fcip module needs to resolve an IP address to a port address before
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sending data to a destination port. A FC device port has 2 addresses
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * associated with it: A 8 byte World Wide unique Port Name and a 3 byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * volatile Port number or Port_ID.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The mapping between a IP address and the World Wide Port Name is handled
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by the ARP layer since the IP over FC draft requires the MAC address to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be the least significant six bytes of the WorldWide Port Names. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip module however needs to identify the destination port uniquely when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the destination FC device has multiple FC ports.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The FC layer mapping between the World Wide Port Name and the Port_ID
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will be handled through the use of a fabric name server or through the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * use of the FARP ELS command as described in the draft. Since the Port_IDs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are volatile, the mapping between the World Wide Port Name and Port_IDs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * must be maintained and validated before use each time a datagram
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * needs to be sent to the destination ports. The FC transport module
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * informs the fcip module of all changes to states of ports on the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fabric through registered callbacks. This enables the fcip module
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to maintain the WW_PN to Port_ID mappings current.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For details on how this module interfaces with the FibreChannel Transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * modules, refer to PSARC/1997/385. Chapter 3 of the FibreChannel Transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Programming guide details the APIs between ULPs and the Transport.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now for some Caveats:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RFC 2625 requires that a FibreChannel Port name (the Port WWN) have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the NAA bits set to '0001' indicating a IEEE 48bit address which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * corresponds to a ULA (Universal LAN MAC address). But with FibreChannel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * adapters containing 2 or more ports, IEEE naming cannot identify the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ports on an adapter uniquely so we will in the first implementation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be operating only on Port 0 of each adapter.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/debug.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/time.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sysmacros.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/systm.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/user.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/stropts.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/stream.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/strlog.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/strsubr.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cpu.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sunddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/stat.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kstat.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/vtrace.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/strsun.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/varargs.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/modctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/thread.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/var.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/proc.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <inet/common.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <netinet/ip6.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <inet/ip.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <inet/arp.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <inet/mi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <inet/nd.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/dlpi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ethernet.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/file.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/syslog.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/disp.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/taskq.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Leadville includes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fibre-channel/fc.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fibre-channel/impl/fc_ulpif.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fibre-channel/ulp/fcip.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * TNF Probe/trace facility include
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if defined(lint) || defined(FCIP_TNF_ENABLED)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/tnf_probe.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_ESBALLOC
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function prototypes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* standard loadable modules entry points */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_attach(dev_info_t *, ddi_attach_cmd_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_detach(dev_info_t *, ddi_detach_cmd_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_dodetach(struct fcipstr *slp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *arg, void **result);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* streams specific */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_setipq(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_wput(queue_t *, mblk_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_wsrv(queue_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_proto(queue_t *, mblk_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_ioctl(queue_t *, mblk_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_open(queue_t *wq, dev_t *devp, int flag,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int sflag, cred_t *credp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_close(queue_t *rq, int flag, int otyp, cred_t *credp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_start(queue_t *wq, mblk_t *mp, struct fcip *fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp, int flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_sendup(struct fcip *fptr, mblk_t *mp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *(*acceptfunc)());
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fcipstr *fcip_accept(struct fcipstr *slp, struct fcip *fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int type, la_wwn_t *dhostp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic mblk_t *fcip_addudind(struct fcip *fptr, mblk_t *mp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcph_network_hdr_t *nhdr, int type);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_setup_mac_addr(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_kstat_init(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_stat_update(kstat_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* dlpi specific */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_spareq(queue_t *wq, mblk_t *mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_pareq(queue_t *wq, mblk_t *mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_ubreq(queue_t *wq, mblk_t *mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_breq(queue_t *wq, mblk_t *mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_dreq(queue_t *wq, mblk_t *mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_areq(queue_t *wq, mblk_t *mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_udreq(queue_t *wq, mblk_t *mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_ireq(queue_t *wq, mblk_t *mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_dl_ioc_hdr_info(queue_t *wq, mblk_t *mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* solaris sundry, DR/CPR etc */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_cache_constructor(void *buf, void *arg, int size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_cache_destructor(void *buf, void *size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_handle_suspend(fcip_port_info_t *fport, fc_detach_cmd_t cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_handle_resume(fcip_port_info_t *fport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_port_info_t *port_info, fc_attach_cmd_t cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fcip_port_info_t *fcip_softstate_free(fcip_port_info_t *fport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_port_attach_handler(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ulp - transport interface function prototypes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_port_attach(opaque_t ulp_handle, fc_ulp_port_info_t *,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_attach_cmd_t cmd, uint32_t sid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_port_detach(opaque_t ulp_handle, fc_ulp_port_info_t *,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_detach_cmd_t cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_port_ioctl(opaque_t ulp_handle, opaque_t port_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, int *rval,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t claimed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_statec_cb(opaque_t ulp_handle, opaque_t phandle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t port_state, uint32_t port_top, fc_portmap_t changelist[],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen, uint32_t sid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_els_cb(opaque_t ulp_handle, opaque_t phandle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_unsol_buf_t *buf, uint32_t claimed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_data_cb(opaque_t ulp_handle, opaque_t phandle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_unsol_buf_t *payload, uint32_t claimed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Routing table specific */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_handle_topology(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_init_port(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct fcip_routing_table *fcip_lookup_rtable(struct fcip *fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *pwwn, int matchflag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_rt_update(struct fcip *fptr, fc_portmap_t *devlist,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_rt_flush(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_rte_remove_deferred(void *arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_do_plogi(struct fcip *fptr, struct fcip_routing_table *frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* dest table specific */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fcip_dest *fcip_get_dest(struct fcip *fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *dlphys);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fcip_dest *fcip_add_dest(struct fcip *fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_dest_add_broadcast_entry(struct fcip *fptr, int new_flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t fcip_get_broadcast_did(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_cleanup_dest(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* helper functions */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fcip_port_info_t *fcip_get_port(opaque_t phandle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_wwn_compare(la_wwn_t *wwn1, la_wwn_t *wwn2, int flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_ether_to_str(struct ether_addr *e, caddr_t s);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_port_get_num_pkts(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_check_port_busy(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_check_remove_minor_node(void);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_set_wwn(la_wwn_t *pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_plogi_in_progress(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_check_port_exists(struct fcip *fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_is_supported_fc_topology(int fc_topology);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* pkt specific */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fcip_pkt_t *fcip_pkt_alloc(struct fcip *fptr, mblk_t *bp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flags, int datalen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_pkt_free(struct fcip_pkt *fcip_pkt, int flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fcip_pkt_t *fcip_ipkt_alloc(struct fcip *fptr, int cmdlen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int resplen, opaque_t pd, int flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_ipkt_free(fcip_pkt_t *fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_ipkt_callback(fc_packet_t *fc_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_free_pkt_dma(fcip_pkt_t *fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_pkt_callback(fc_packet_t *fc_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_init_unicast_pkt(fcip_pkt_t *fcip_pkt, fc_portid_t sid,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portid_t did, void (*comp) ());
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_transport(fcip_pkt_t *fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_pkt_timeout(void *arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_timeout(void *arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_fdestp_enqueue_pkt(struct fcip_dest *fdestp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_fdestp_dequeue_pkt(struct fcip_dest *fdestp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_sendup_constructor(void *buf, void *arg, int flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_sendup_thr(void *arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_sendup_alloc_enque(struct fcip *ftpr, mblk_t *mp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *(*f)());
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zero copy inbound data handling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef FCIP_ESBALLOC
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_ubfree(char *arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* FCIP_ESBALLOC */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(FCIP_ESBALLOC)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void *fcip_allocb(size_t size, uint_t pri);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* FCIP FARP support functions */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fcip_dest *fcip_do_farp(struct fcip *fptr, la_wwn_t *pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *ip_addr, size_t ip_addr_len, int flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_init_broadcast_pkt(fcip_pkt_t *fcip_pkt, void (*comp) (),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int is_els);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_handle_farp_request(struct fcip *fptr, la_els_farp_t *fcmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_handle_farp_response(struct fcip *fptr, la_els_farp_t *fcmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_cache_arp_broadcast(struct fcip *ftpr, fc_unsol_buf_t *buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fcip_port_ns(void *arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/debug.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_DEFAULT 0x1
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_ATTACH 0x2
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_INIT 0x4
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_DETACH 0x8
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_DLPI 0x10
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_ELS 0x20
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_DOWNSTREAM 0x40
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_UPSTREAM 0x80
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_MISC 0x100
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_STARTUP (FCIP_DEBUG_ATTACH|FCIP_DEBUG_INIT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_DATAOUT (FCIP_DEBUG_DLPI|FCIP_DEBUG_DOWNSTREAM)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG_DATAIN (FCIP_DEBUG_ELS|FCIP_DEBUG_UPSTREAM)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_debug = FCIP_DEBUG_DEFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG(level, args) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_debug & (level)) cmn_err args;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else /* DEBUG */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_DEBUG(level, args) /* do nothing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* DEBUG */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define KIOIP KSTAT_INTR_PTR(fcip->fcip_intrstats)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Endian independent ethernet to WWN copy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define ether_to_wwn(E, W) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((void *)(W), sizeof (la_wwn_t)); \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)(E), (void *)&((W)->raw_wwn[2]), ETHERADDRL); \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (W)->raw_wwn[0] |= 0x10
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wwn_to_ether : Endian independent, copies a WWN to struct ether_addr.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The args to the macro are pointers to WWN and ether_addr structures
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define wwn_to_ether(W, E) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&((W)->raw_wwn[2]), (void *)E, ETHERADDRL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The module_info structure contains identification and limit values.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All queues associated with a certain driver share the same module_info
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * structures. This structure defines the characteristics of that driver/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * module's queues. The module name must be unique. The max and min packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sizes limit the no. of characters in M_DATA messages. The Hi and Lo
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * water marks are for flow control when a module has a service procedure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct module_info fcipminfo = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIPIDNUM, /* mi_idnum : Module ID num */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIPNAME, /* mi_idname: Module Name */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIPMINPSZ, /* mi_minpsz: Min packet size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIPMAXPSZ, /* mi_maxpsz: Max packet size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIPHIWAT, /* mi_hiwat : High water mark */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIPLOWAT /* mi_lowat : Low water mark */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The qinit structres contain the module put, service. open and close
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * procedure pointers. All modules and drivers with the same streamtab
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file (i.e same fmodsw or cdevsw entry points) point to the same
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * upstream (read) and downstream (write) qinit structs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct qinit fcip_rinit = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* qi_putp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* qi_srvp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_open, /* qi_qopen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_close, /* qi_qclose */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* qi_qadmin */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fcipminfo, /* qi_minfo */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL /* qi_mstat */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct qinit fcip_winit = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_wput, /* qi_putp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_wsrv, /* qi_srvp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* qi_qopen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* qi_qclose */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* qi_qadmin */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fcipminfo, /* qi_minfo */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL /* qi_mstat */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * streamtab contains pointers to the read and write qinit structures
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct streamtab fcip_info = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fcip_rinit, /* st_rdinit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fcip_winit, /* st_wrinit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* st_muxrinit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* st_muxwrinit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct cb_ops fcip_cb_ops = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* open */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* close */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* strategy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* print */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* dump */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* read */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* write */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* ioctl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* devmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* mmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* segmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nochpoll, /* poll */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_prop_op, /* cb_prop_op */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fcip_info, /* streamtab */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte D_MP | D_HOTPLUG, /* Driver compatibility flag */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CB_REV, /* rev */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* int (*cb_aread)() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev /* int (*cb_awrite)() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * autoconfiguration routines.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct dev_ops fcip_ops = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DEVO_REV, /* devo_rev, */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* refcnt */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_getinfo, /* info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nulldev, /* identify */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nulldev, /* probe */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_attach, /* attach */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_detach, /* detach */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* RESET */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fcip_cb_ops, /* driver operations */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus operations */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_power /* power management */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_VERSION "1.61"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_NAME "SunFC FCIP v" FCIP_VERSION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define PORT_DRIVER "fp"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define GETSTRUCT(struct, number) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((struct *)kmem_zalloc((size_t)(sizeof (struct) * (number)), \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modldrv modldrv = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &mod_driverops, /* Type of module - driver */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_NAME, /* Name of module */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fcip_ops, /* driver ops */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modlinkage modlinkage = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODREV_1, (void *)&modldrv, NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now for some global statics
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t fcip_ub_nbufs = FCIP_UB_NBUFS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t fcip_ub_size = FCIP_UB_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_pkt_ttl_ticks = FCIP_PKT_TTL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_tick_incr = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_wait_cmds = FCIP_WAIT_CMDS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_num_attaching = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_port_attach_pending = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_create_nodes_on_demand = 1; /* keep it similar to fcp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_cache_on_arp_broadcast = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_farp_supported = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_minor_node_created = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Supported FCAs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define QLC_PORT_1_ID_BITS 0x100
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define QLC_PORT_2_ID_BITS 0x101
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define QLC_PORT_NAA 0x2
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define QLC_MODULE_NAME "qlc"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define IS_QLC_PORT(port_dip) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (strcmp(ddi_driver_name(ddi_get_parent((port_dip))),\
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QLC_MODULE_NAME) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip softstate structures head.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void *fcip_softp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * linked list of active (inuse) driver streams
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fcip_num_instances = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic dev_info_t *fcip_module_dip = (dev_info_t *)0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Ethernet broadcast address: Broadcast addressing in IP over fibre
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * channel should be the IEEE ULA (also the low 6 bytes of the Port WWN).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The broadcast addressing varies for differing topologies a node may be in:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - On a private loop the ARP broadcast is a class 3 sequence sent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * using OPNfr (Open Broadcast Replicate primitive) followed by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the ARP frame to D_ID 0xFFFFFF
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - On a public Loop the broadcast sequence is sent to AL_PA 0x00
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (no OPNfr primitive).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - For direct attach and point to point topologies we just send
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the frame to D_ID 0xFFFFFF
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For public loop the handling would probably be different - for now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * I'll just declare this struct - It can be deleted if not necessary.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DL_INFO_ACK template for the fcip module. The dl_info_ack_t structure is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returned as a part of an DL_INFO_ACK message which is a M_PCPROTO message
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returned in response to a DL_INFO_REQ message sent to us from a DLS user
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Let us fake an ether header as much as possible.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dl_addr_length is the Provider's DLSAP addr which is SAP addr +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Physical addr of the provider. We set this to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ushort_t + sizeof (la_wwn_t) for Fibre Channel ports.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dl_mac_type Lets just use DL_ETHER - we can try using DL_IPFC, a new
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dlpi.h define later.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dl_sap_length -2 indicating the SAP address follows the Physical addr
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * component in the DLSAP addr.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dl_service_mode: DLCLDS - connectionless data link service.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic dl_info_ack_t fcip_infoack = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DL_INFO_ACK, /* dl_primitive */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIPMTU, /* dl_max_sdu */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* dl_min_sdu */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIPADDRL, /* dl_addr_length */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DL_ETHER, /* dl_mac_type */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* dl_reserved */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* dl_current_state */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte -2, /* dl_sap_length */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DL_CLDLS, /* dl_service_mode */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* dl_qos_length */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* dl_qos_offset */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* dl_range_length */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* dl_range_offset */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DL_STYLE2, /* dl_provider_style */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (dl_info_ack_t), /* dl_addr_offset */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DL_VERSION_2, /* dl_version */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ETHERADDRL, /* dl_brdcst_addr_length */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (dl_info_ack_t) + FCIPADDRL, /* dl_brdcst_addr_offset */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0 /* dl_growth */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCIP broadcast address definition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct ether_addr fcipnhbroadcastaddr = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RFC2625 requires the broadcast ARP address in the ARP data payload to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be set to 0x00 00 00 00 00 00 for ARP broadcast packets
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct ether_addr fcip_arpbroadcast_addr = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define ether_bcopy(src, dest) bcopy((src), (dest), ETHERADDRL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * global kernel locks
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kcondvar_t fcip_global_cv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kmutex_t fcip_global_mutex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl external defines
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern int fc_ulp_add(fc_ulp_modinfo_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl data structures
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_REV 0x07
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* linked list of port info structures */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fcip_port_info_t *fcip_port_head = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* linked list of fcip structures */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fcipstr *fcipstrup = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic krwlock_t fcipstruplock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Module information structure. This structure gives the FC Transport modules
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information about an ULP that registers with it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fc_ulp_modinfo_t fcip_modinfo = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* for xref checks? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCTL_ULP_MODREV_4, /* FCIP revision */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_TYPE_IS8802_SNAP, /* type 5 for SNAP encapsulated datagrams */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_NAME, /* module name as in the modldrv struct */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x0, /* get all statec callbacks for now */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_attach, /* port attach callback */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_detach, /* port detach callback */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_ioctl, /* port ioctl callback */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_els_cb, /* els callback */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_data_cb, /* data callback */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_statec_cb /* state change callback */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Solaris 9 and up, the /kernel/drv/fp.conf file will have the following entry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ddi-forceattach=1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will ensure that fp is loaded at bootup. No additional checks are needed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_init(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_LOAD();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize the mutexs used by port attach and other callbacks.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The transport can call back into our port_attach_callback
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routine even before _init() completes and bad things can happen.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fcip_global_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&fcip_global_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_init(&fcipstruplock, NULL, RW_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_attach_pending = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now attempt to register fcip with the transport.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If fc_ulp_add fails, fcip module will not be loaded.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fc_ulp_add(&fcip_modinfo);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&fcip_global_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (rval) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_ULP_SAMEMODULE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!fcip: module is already registered with"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " transport"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EEXIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_ULP_SAMETYPE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!fcip: Another module of the same ULP type 0x%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " is already registered with the transport",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_modinfo.ulp_type));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EEXIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_BADULP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!fcip: Current fcip version 0x%x does not match"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " fctl version",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_modinfo.ulp_rev));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENODEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!fcip: fc_ulp_add failed with status 0x%x", rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENODEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_UNLOAD(&modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = ddi_soft_state_init(&fcip_softp, sizeof (struct fcip),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_NUM_INSTANCES)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&fcip_global_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_remove(&fcip_modinfo);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_UNLOAD(&modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = mod_install(&modlinkage)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_UNLOAD(&modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_remove(&fcip_modinfo);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&fcip_global_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_soft_state_fini(&fcip_softp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unload the port driver if this was the only ULP loaded and then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * deregister with the transport.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_fini(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Do not permit the module to be unloaded before a port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * attach callback has happened.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_num_attaching || fcip_port_attach_pending) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = mod_remove(&modlinkage)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unregister with the transport layer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval1 = fc_ulp_remove(&fcip_modinfo);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the ULP was not registered with the transport, init should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have failed. If transport has no knowledge of our existence
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we should simply bail out and succeed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval1 == FC_BADULP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip: ULP was never registered with the transport"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENODEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (rval1 == FC_BADTYPE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip: No ULP of this type 0x%x was registered with "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "transport", fcip_modinfo.ulp_type));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENODEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* DEBUG */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&fcip_global_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_soft_state_fini(&fcip_softp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_UNLOAD(&modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Info about this loadable module
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_info(struct modinfo *modinfop)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (mod_info(&modlinkage, modinfop));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The port attach callback is invoked by the port driver when a FCA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port comes online and binds with the transport layer. The transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then callsback into all ULP modules registered with it. The Port attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * call back will also provide the ULP module with the Port's WWN and S_ID
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_port_attach(opaque_t ulp_handle, fc_ulp_port_info_t *port_info,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_attach_cmd_t cmd, uint32_t sid)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *cur_fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portid_t src_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_ATTACH: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *ww_pn = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It was determined that, as per spec, the lower 48 bits of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the port-WWN will always be unique. This will make the MAC
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * address (i.e the lower 48 bits of the WWN), that IP/ARP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * depend on, unique too. Hence we should be able to remove the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * restriction of attaching to only one of the ports of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * multi port FCAs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Earlier, fcip used to attach only to qlc module and fail
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * silently for attach failures resulting from unknown FCAs or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unsupported FCA ports. Now, we'll do no such checks.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ww_pn = &port_info->port_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_port_attach, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "port id bits",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, nport_id, ww_pn->w.nport_id));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port id bits: 0x%x", ww_pn->w.nport_id));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A port has come online
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_instances++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_attaching++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_port_head == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* OK to sleep here ? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = kmem_zalloc(sizeof (fcip_port_info_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_instances--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_attaching--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_num_attaching >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!fcip(%d): port attach "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "failed: alloc failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(port_info->port_dip));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_head = fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * traverse the port list and also check for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * duplicate port attaches - Nothing wrong in being
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * paranoid Heh Heh.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cur_fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (cur_fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cur_fport->fcipp_handle ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_info->port_handle) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_instances--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_attaching--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_num_attaching >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!fcip(%d): port already "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "attached!!", ddi_get_instance(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_info->port_dip)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cur_fport = cur_fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = kmem_zalloc(sizeof (fcip_port_info_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_instances--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_attaching--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_num_attaching >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!fcip(%d): port attach "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "failed: alloc failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(port_info->port_dip));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_next = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_head = fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * now fill in the details about the port itself
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_linkage = *port_info->port_linkage;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_handle = port_info->port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_dip = port_info->port_dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_topology = port_info->port_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_pstate = port_info->port_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_naa = port_info->port_pwwn.w.naa_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port_info->port_pwwn, &fport->fcipp_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port_info->port_nwwn, &fport->fcipp_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_fca_pkt_size = port_info->port_fca_pkt_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_cmd_dma_attr = *port_info->port_cmd_dma_attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_resp_dma_attr = *port_info->port_resp_dma_attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_fca_acc_attr = *port_info->port_acc_attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_id.port_id = sid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_id.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_sid = src_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocate soft state for this instance
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = ddi_get_instance(fport->fcipp_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_soft_state_zalloc(fcip_softp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!fcip(%d): port attach failed: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "soft state alloc failed", instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto failure;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = ddi_get_soft_state(fcip_softp, instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!fcip(%d): port attach failed: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "failure to get soft state", instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto failure;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * initialize all mutexes and locks required for this module
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fptr->fcip_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fptr->fcip_ub_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fptr->fcip_rt_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fptr->fcip_dest_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fptr->fcip_sendup_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&fptr->fcip_farp_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&fptr->fcip_sendup_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&fptr->fcip_ub_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_dip = fport->fcipp_dip; /* parent's dip */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_instance = instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_upstream = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_PORT_STATE_MASK(port_info->port_state) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_STATE_ONLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_flags & FCIP_LINK_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~FCIP_LINK_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_ATTACHING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_info = fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Extract our MAC addr from our port's WWN. The lower 48
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bits will be our MAC address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wwn_to_ether(&fport->fcipp_nwwn, &fptr->fcip_macaddr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_fcip = fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "fcipdest : 0x%lx, rtable : 0x%lx",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (long)(sizeof (fptr->fcip_dest)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (long)(sizeof (fptr->fcip_rtable))));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(fptr->fcip_dest, sizeof (fptr->fcip_dest));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(fptr->fcip_rtable, sizeof (fptr->fcip_rtable));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * create a taskq to handle sundry jobs for the driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This way we can have jobs run in parallel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_tq = taskq_create("fcip_tasks",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_NUM_THREADS, MINCLSYSPRI, FCIP_MIN_TASKS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_MAX_TASKS, TASKQ_PREPOPULATE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * create a separate thread to handle all unsolicited
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * callback handling. This is because unsolicited_callback
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * can happen from an interrupt context and the upstream
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * modules can put new messages right back in the same
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * thread context. This usually works fine, but sometimes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we may have to block to obtain the dest struct entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for some remote ports.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (thread_create(NULL, DEFAULTSTKSZ,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void (*)())fcip_sendup_thr, (caddr_t)fptr, 0, &p0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte TS_RUN, minclsyspri) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!unable to create fcip sendup thread for "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " instance: 0x%x", instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_thr_initted = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_head = fptr->fcip_sendup_tail = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Let the attach handler do the rest */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_port_attach_handler(fptr) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We have already cleaned up so return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!fcip(%d): port attach failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_CONT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!fcip attach for port instance (0x%x) successful",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_POWER_UP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_RESUME:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport->fcipp_handle == port_info->port_handle) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fcip_handle_resume(fport, port_info, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_port_attach, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "unknown command type",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_uint, cmd, cmd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "unknown cmd type 0x%x in port_attach", cmd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefailure:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_attaching--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_num_attaching >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_softstate_free(fport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_attach_pending = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedone:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_attach_pending = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_port_attach_handler : Completes the port attach operation after
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the ulp_port_attach routine has completed its ground work. The job
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of this function among other things is to obtain and handle topology
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * specifics, initialize a port, setup broadcast address entries in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fcip tables etc. This routine cleans up behind itself on failures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns FC_SUCCESS or FC_FAILURE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_port_attach_handler(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fport != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip module dip: %p instance: %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcip_module_dip, ddi_get_instance(fptr->fcip_dip)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_module_dip == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t fcip_lbolt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_lbolt = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we need to use the fcip devinfo for creating
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the clone device node, but the fcip attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (from its conf file entry claiming to be a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * child of pseudo) may not have happened yet.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait here for 10 seconds and fail port attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the fcip devinfo is not attached yet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_lbolt += drv_usectohz(FCIP_INIT_DELAY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "cv_timedwait lbolt %lx", fcip_lbolt));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) cv_timedwait(&fcip_global_cv, &fcip_global_mutex,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_lbolt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_module_dip == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip attach did not happen"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto port_attach_cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((!fcip_minor_node_created) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_is_supported_fc_topology(fport->fcipp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Checking for same topologies which are considered valid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by fcip_handle_topology(). Dont create a minor node if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nothing is hanging off the FC port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_create_minor_node(fcip_module_dip, "fcip", S_IFCHR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(fptr->fcip_dip), DDI_PSEUDO,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CLONE_DEV) == DDI_FAILURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "failed to create minor node for fcip(%d)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(fptr->fcip_dip)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto port_attach_cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_minor_node_created++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * initialize port for traffic
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_init_port(fptr) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fcip_init_port has already cleaned up its stuff */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fcip_num_instances == 1) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fcip_minor_node_created == 1)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Remove minor node iff this is the last instance */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_remove_minor_node(fcip_module_dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto port_attach_cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~FCIP_ATTACHING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_INITED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_timeout_ticks = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * start the timeout threads
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_timeout_id = timeout(fcip_timeout, fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(1000000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_attaching--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_num_attaching >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteport_attach_cleanup:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_softstate_free(fport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_attaching--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_num_attaching >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handler for DDI_RESUME operations. Port must be ready to restart IP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * traffic on resume
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_handle_resume(fcip_port_info_t *fport, fc_ulp_port_info_t *port_info,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_attach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *tslp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == FC_CMD_POWER_UP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_POWER_DOWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_flags & FCIP_SUSPENDED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmd == FC_CMD_RESUME) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_SUSPENDED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set the current port state and topology
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_topology = port_info->port_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_pstate = port_info->port_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fcipstruplock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (tslp = fcipstrup; tslp; tslp = tslp->sl_nextp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tslp->sl_fcip == fptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No active streams on this port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tslp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fptr->fcip_rtable[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (frp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark the broadcast RTE available again. It
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * was marked SUSPENDED during SUSPEND.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = fcip_get_broadcast_did(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp->fcipr_d_id.port_id == did) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = FCIP_RT_HASH_ELEMS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = frp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_handle_topology will update the port entries in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routing table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_handle_topology also takes care of resetting the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcipr_state field in the routing table structure. The entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * were set to RT_INVALID during suspend.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_handle_topology(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedone:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Restart the timeout thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_timeout_id = timeout(fcip_timeout, fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(1000000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Insert a destination port entry into the routing table for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_rt_update(struct fcip *fptr, fc_portmap_t *devlist, uint32_t listlen)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hash_bucket, i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *pmap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char wwn_buf[20];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_rt_update, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_int, listlen, listlen));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!mutex_owned(&fptr->fcip_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < listlen; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pmap = &(devlist[i]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, &(pmap->map_pwwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_COMPARE_PWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If an entry for a port in the devlist exists in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the per port routing table, make sure the data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is current. We need to do this irrespective of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * underlying port topology.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (pmap->map_type) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_DEVICE_NOCHANGE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_DEVICE_USER_LOGIN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_DEVICE_CHANGED:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_DEVICE_NEW:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto add_new_entry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (frp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto update_entry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_DEVICE_OLD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_DEVICE_USER_LOGOUT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark entry for removal from Routing Table if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one exists. Let the timeout thread actually
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove the entry after we've given up hopes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the port ever showing up.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark the routing table as invalid to bail
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the packets early that are in transit
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = fptr->fcip_broadcast_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp->fcipr_d_id.port_id != did) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = FCIP_RT_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_invalid_timeout =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_timeout_ticks +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_RTE_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "unknown map flags in rt_update"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteadd_new_entry:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(frp == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hash_bucket = FCIP_RT_HASH(pmap->map_pwwn.raw_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(hash_bucket < FCIP_RT_HASH_ELEMS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_rt_update, "cfip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "add new entry",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_int, hashbucket, hash_bucket));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = (struct fcip_routing_table *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(sizeof (struct fcip_routing_table), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* insert at beginning of hash bucket */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_next = fptr->fcip_rtable[hash_bucket];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_rtable[hash_bucket] = frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pmap->map_pwwn, wwn_buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "added entry for pwwn %s and d_id 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wwn_buf, pmap->map_did.port_id));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteupdate_entry:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&pmap->map_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)&frp->fcipr_pwwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&pmap->map_nwwn, (void *)&frp->fcipr_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_d_id = pmap->map_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = pmap->map_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_pd = pmap->map_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there is no pd for a destination port that is not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a broadcast entry, the port is pretty much unusable - so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mark the port for removal so we can try adding back the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * entry again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((frp->fcipr_pd == NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (frp->fcipr_d_id.port_id != fptr->fcip_broadcast_did)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_invalid_timeout = fptr->fcip_timeout_ticks +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FCIP_RTE_TIMEOUT / 2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_fca_dev =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_get_fca_device(fport->fcipp_handle, pmap->map_did);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * login to the remote port. Don't worry about
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * plogi failures for now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pmap->map_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_do_plogi(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (FC_TOP_EXTERNAL(fport->fcipp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&frp->fcipr_pwwn, wwn_buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_MISC, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "logging into pwwn %s, d_id 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wwn_buf, frp->fcipr_d_id.port_id));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_do_plogi(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_BYTE_ARRAY(fcip_rt_update, "fcip io", "detail",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "new wwn in rt", pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &frp->fcipr_pwwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return a matching routing table entry for a given fcip instance
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct fcip_routing_table *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_lookup_rtable(struct fcip *fptr, la_wwn_t *wwn, int matchflag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hash_bucket;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_lookup_rtable, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_BYTE_ARRAY(fcip_lookup_rtable, "fcip io", "detail",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rtable lookup for", wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &wwn->raw_wwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_lookup_rtable, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "match by",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_int, matchflag, matchflag));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&fptr->fcip_rt_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hash_bucket = FCIP_RT_HASH(wwn->raw_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fptr->fcip_rtable[hash_bucket];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (frp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_BYTE_ARRAY(fcip_lookup_rtable, "fcip io", "detail",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rtable entry", nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &(frp->fcipr_nwwn.raw_wwn), sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_wwn_compare(&frp->fcipr_pwwn, wwn, matchflag) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = frp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_lookup_rtable, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "lookup result",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, frp, frp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Attach of fcip under pseudo. The actual setup of the interface
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * actually happens in fcip_port_attach on a callback from the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * transport. The port_attach callback however can proceed only
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * after the devinfo for fcip has been created under pseudo
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch ((int)cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_ATTACH: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_module_dip == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_module_dip = dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this call originates as a result of fcip's conf
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file entry and will result in a fcip instance being
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a child of pseudo. We should ensure here that the port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * driver (fp) has been loaded and initted since we would
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * never get a port attach callback without fp being loaded.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we are unable to succesfully load and initalize fp -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just fail this attach.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "global cv - signaling"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&fcip_global_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ATTACH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "global cv - signaled"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_RESUME:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Resume appears trickier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The detach entry point to permit unloading fcip. We make sure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * there are no active streams before we proceed with the detach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int detached;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_DETACH: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we got here, any active streams should have been
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unplumbed but check anyway
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcipstrup != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_port_head != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check to see if we have unattached/unbound
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ports. If all the ports are unattached/unbound go
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ahead and unregister with the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_DETACHING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_ipq ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags & (FCIP_IN_TIMEOUT |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_IN_CALLBACK | FCIP_ATTACHING |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_SUSPENDED | FCIP_POWER_DOWN |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_REG_INPROGRESS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_detach,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip instance busy"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip instance busy"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check for any outstanding pkts. If yes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fail the detach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_port_get_num_pkts(fptr) > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip instance busy - pkts "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "pending"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_plogi_in_progress(fptr)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip instance busy - plogi in "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "progress"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if fport is non NULL - we have active ports
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove the DETACHING flags on the ports
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_DETACHING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free up all softstate structures
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte detached = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check to see if somebody beat us to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * punch
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte detached = fptr->fcip_flags & FCIP_DETACHED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_DETACHING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_DETACHED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!detached) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_softstate_free(fport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the port was marked as detached
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but it was still in the list, that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * means another thread has marked it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but we got in while it released the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_global_mutex in softstate_free.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Given that, we're still safe to use
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fport->fcipp_next to find out what
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the next port on the list is.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DETACH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "detaching port"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_detach,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip io", /* CSTYLED */, tnf_string,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg, "detaching port"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we haven't removed all the port structures, we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * aren't yet ready to be detached.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_port_head != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_instances = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_module_dip = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_SUSPEND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The port_detach callback is called from the transport when a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC port is being removed from the transport's control. This routine
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * provides fcip with an opportunity to cleanup all activities and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * structures on the port marked for removal.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_port_detach(opaque_t ulp_handle, fc_ulp_port_info_t *port_info,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_detach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *strp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_DETACH: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_port_head == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we are all done but our fini has not been
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called yet!! Let's hope we have no active
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip instances here. - strange secnario but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no harm in having this return a success.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_check_remove_minor_node();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * traverse the port list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport->fcipp_handle ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_info->port_handle) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fail the port detach if there is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * still an attached, bound stream on
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this interface.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fcipstruplock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (strp = fcipstrup; strp != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strp = strp->sl_nextp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strp->sl_fcip == fptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fail port detach if we are in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the middle of a deferred port attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or if the port has outstanding pkts
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_check_port_busy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fptr) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fptr->fcip_flags &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DETACHED)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DETACHED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_softstate_free(fport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_check_remove_minor_node();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fport == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_POWER_DOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_SUSPEND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport->fcipp_handle == port_info->port_handle) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fcip_handle_suspend(fport, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DETACH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "unknown port detach command!!"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if the port is not busy, else returns non zero.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_check_port_busy(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = 0, num_pkts = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&fptr->fcip_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_flags & FCIP_PORT_BUSY ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((num_pkts = fcip_port_get_num_pkts(fptr)) > 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_num_ipkts_pending) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DETACH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "!fcip_check_port_busy: port is busy "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip_flags: 0x%x, num_pkts: 0x%x, ipkts_pending: 0x%lx!",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags, num_pkts, fptr->fcip_num_ipkts_pending));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Helper routine to remove fcip's minor node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There is one minor node per system and it should be removed if there are no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * other fcip instances (which has a 1:1 mapping for fp instances) present
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_check_remove_minor_node(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&fcip_global_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are no more fcip (fp) instances, remove the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * minor node for fcip.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reset fcip_minor_node_created to invalidate it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_num_instances == 0 && (fcip_module_dip != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_remove_minor_node(fcip_module_dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_minor_node_created = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine permits the suspend operation during a CPR/System
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * power management operation. The routine basically quiesces I/Os
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on all active interfaces
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_handle_suspend(fcip_port_info_t *fport, fc_detach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_id_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int tryagain = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *tslp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fail if we are in the middle of a callback. Don't use delay during
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * suspend since clock intrs are not available so busy wait
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (count++ < 15 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fptr->fcip_flags & FCIP_IN_CALLBACK) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fptr->fcip_flags & FCIP_IN_TIMEOUT))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usecwait(1000000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_flags & FCIP_IN_CALLBACK ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags & FCIP_IN_TIMEOUT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == FC_CMD_POWER_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_flags & FCIP_SUSPENDED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto success;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmd == FC_CMD_SUSPEND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_SUSPENDED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If no streams are plumbed - its the easiest case - Just
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bail out without having to do much
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fcipstruplock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (tslp = fcipstrup; tslp; tslp = tslp->sl_nextp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tslp->sl_fcip == fptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No active streams on this port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tslp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto success;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Walk through each Routing table structure and check if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the destination table has any outstanding commands. If yes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait for the commands to drain. Since we go through each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routing table entry in succession, it may be wise to wait
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * only a few seconds for each entry.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (!tryagain) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tryagain = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hash_bucket;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fptr->fcip_rtable[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (frp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark the routing table as SUSPENDED. Even
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mark the broadcast entry SUSPENDED to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * prevent any ARP or other broadcasts. We
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * can reset the state of the broadcast
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RTE when we resume.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = FCIP_RT_SUSPENDED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = &frp->fcipr_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get hold of destination pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hash_bucket = FCIP_DEST_HASH(pwwn->raw_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(hash_bucket < FCIP_DEST_HASH_ELEMS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fptr->fcip_dest[hash_bucket];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fdestp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp->fcipd_rtable) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_wwn_compare(pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fdestp->fcipd_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_COMPARE_PWWN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fdestp->fcipd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = frp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wait for fcip_wait_cmds seconds for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the commands to drain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fdestp->fcipd_ncmds &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count < fcip_wait_cmds) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usecwait(1000000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if we were able to drain all cmds
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * successfully. Else continue with other
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ports and try during the second pass
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp->fcipd_ncmds) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tryagain++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = frp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tryagain == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tryagain) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_SUSPENDED | FCIP_POWER_DOWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesuccess:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tid = fptr->fcip_timeout_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_timeout_id = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the getinfo(9E) entry point
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_INFO_DEVT2DEVINFO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *result = fcip_module_dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*result)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_INFO_DEVT2INSTANCE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *result = (void *)0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called from fcip_attach to initialize kstats for the link
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_kstat_init(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char buf[16];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstat *fcipstatp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&fptr->fcip_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = ddi_get_instance(fptr->fcip_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(buf, "fcip%d", instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef kstat
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_kstatp = kstat_create("fcip", instance, buf, "net",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_TYPE_NAMED,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (sizeof (struct fcipstat)/ sizeof (kstat_named_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_FLAG_PERSISTENT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_kstatp = kstat_create("fcip", instance, buf, "net",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_TYPE_NAMED,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (sizeof (struct fcipstat)/ sizeof (kstat_named_t)), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_kstatp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_WARN, "kstat created failed"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp = (struct fcipstat *)fptr->fcip_kstatp->ks_data;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_ipackets, "ipackets",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_ierrors, "ierrors",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_opackets, "opackets",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_oerrors, "oerrors",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_collisions, "collisions",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_nocanput, "nocanput",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_allocbfail, "allocbfail",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_defer, "defer",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_fram, "fram",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_crc, "crc",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_oflo, "oflo",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_uflo, "uflo",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_missed, "missed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_tlcol, "tlcol",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_trtry, "trtry",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_tnocar, "tnocar",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_inits, "inits",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_notbufs, "notbufs",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_norbufs, "norbufs",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_allocbfail, "allocbfail",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * required by kstat for MIB II objects(RFC 1213)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_rcvbytes, "fcips_rcvbytes",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG); /* # octets received */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* MIB - ifInOctets */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_xmtbytes, "fcips_xmtbytes",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG); /* # octets xmitted */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* MIB - ifOutOctets */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_multircv, "fcips_multircv",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG); /* # multicast packets */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* delivered to upper layer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* MIB - ifInNUcastPkts */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_multixmt, "fcips_multixmt",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG); /* # multicast packets */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* requested to be sent */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* MIB - ifOutNUcastPkts */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_brdcstrcv, "fcips_brdcstrcv",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG); /* # broadcast packets */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* delivered to upper layer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* MIB - ifInNUcastPkts */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_brdcstxmt, "fcips_brdcstxmt",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG); /* # broadcast packets */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* requested to be sent */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* MIB - ifOutNUcastPkts */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_norcvbuf, "fcips_norcvbuf",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG); /* # rcv packets discarded */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* MIB - ifInDiscards */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_named_init(&fcipstatp->fcips_noxmtbuf, "fcips_noxmtbuf",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KSTAT_DATA_ULONG); /* # xmt packets discarded */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_kstatp->ks_update = fcip_stat_update;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_kstatp->ks_private = (void *) fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_install(fptr->fcip_kstatp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the defined kstats for netstat et al to use
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_stat_update(kstat_t *fcip_statp, int val)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstat *fcipstatp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = (struct fcip *)fcip_statp->ks_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp = (struct fcipstat *)fcip_statp->ks_data;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (val == KSTAT_WRITE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ipackets = fcipstatp->fcips_ipackets.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ierrors = fcipstatp->fcips_ierrors.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_opackets = fcipstatp->fcips_opackets.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_oerrors = fcipstatp->fcips_oerrors.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_collisions = fcipstatp->fcips_collisions.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_defer = fcipstatp->fcips_defer.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_fram = fcipstatp->fcips_fram.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_crc = fcipstatp->fcips_crc.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_oflo = fcipstatp->fcips_oflo.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_uflo = fcipstatp->fcips_uflo.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_missed = fcipstatp->fcips_missed.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_tlcol = fcipstatp->fcips_tlcol.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_trtry = fcipstatp->fcips_trtry.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_tnocar = fcipstatp->fcips_tnocar.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_inits = fcipstatp->fcips_inits.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_notbufs = fcipstatp->fcips_notbufs.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_norbufs = fcipstatp->fcips_norbufs.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_nocanput = fcipstatp->fcips_nocanput.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_rcvbytes = fcipstatp->fcips_rcvbytes.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_xmtbytes = fcipstatp->fcips_xmtbytes.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_multircv = fcipstatp->fcips_multircv.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_multixmt = fcipstatp->fcips_multixmt.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_brdcstrcv = fcipstatp->fcips_brdcstrcv.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_norcvbuf = fcipstatp->fcips_norcvbuf.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_noxmtbuf = fcipstatp->fcips_noxmtbuf.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_ipackets.value.ul = fptr->fcip_ipackets;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_ierrors.value.ul = fptr->fcip_ierrors;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_opackets.value.ul = fptr->fcip_opackets;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_oerrors.value.ul = fptr->fcip_oerrors;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_collisions.value.ul = fptr->fcip_collisions;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_nocanput.value.ul = fptr->fcip_nocanput;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_allocbfail.value.ul = fptr->fcip_allocbfail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_defer.value.ul = fptr->fcip_defer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_fram.value.ul = fptr->fcip_fram;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_crc.value.ul = fptr->fcip_crc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_oflo.value.ul = fptr->fcip_oflo;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_uflo.value.ul = fptr->fcip_uflo;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_missed.value.ul = fptr->fcip_missed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_tlcol.value.ul = fptr->fcip_tlcol;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_trtry.value.ul = fptr->fcip_trtry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_tnocar.value.ul = fptr->fcip_tnocar;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_inits.value.ul = fptr->fcip_inits;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_norbufs.value.ul = fptr->fcip_norbufs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_notbufs.value.ul = fptr->fcip_notbufs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_rcvbytes.value.ul = fptr->fcip_rcvbytes;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_xmtbytes.value.ul = fptr->fcip_xmtbytes;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_multircv.value.ul = fptr->fcip_multircv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_multixmt.value.ul = fptr->fcip_multixmt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_brdcstrcv.value.ul = fptr->fcip_brdcstrcv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_brdcstxmt.value.ul = fptr->fcip_brdcstxmt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_norcvbuf.value.ul = fptr->fcip_norcvbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipstatp->fcips_noxmtbuf.value.ul = fptr->fcip_noxmtbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_statec_cb: handles all required state change callback notifications
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it receives from the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_statec_cb(opaque_t ulp_handle, opaque_t phandle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t port_state, uint32_t port_top, fc_portmap_t changelist[],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen, uint32_t sid)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte queue_t *wrq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frtp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_get_port(phandle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = ddi_get_instance(fport->fcipp_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_4((fcip_statec_cb, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "state change callback",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_uint, instance, instance,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_uint, S_ID, sid,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_int, count, listlen));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "fcip%d, state change callback: state:0x%x, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "S_ID:0x%x, count:0x%x", instance, port_state, sid, listlen));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fptr->fcip_flags & (FCIP_DETACHING | FCIP_DETACHED)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fptr->fcip_flags & (FCIP_SUSPENDED | FCIP_POWER_DOWN))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set fcip flags to indicate we are in the middle of a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state change callback so we can wait till the statechange
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is handled before succeeding/failing the SUSPEND/POWER DOWN.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_IN_SC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_pstate = port_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if topology changed. If Yes - Modify the broadcast
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RTE entries to understand the new broadcast D_IDs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport->fcipp_topology != port_top &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port_top != FC_TOP_UNKNOWN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* REMOVE later */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "topology changed: Old topology: 0x%x New topology 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_topology, port_top));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If topology changed - attempt a rediscovery of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices. Helps specially in Fabric/Public loops
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and if on_demand_node_creation is disabled
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_topology = port_top;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_handle_topology(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (FC_PORT_STATE_MASK(port_state)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_ONLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_LIP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_LIP_LBIT_SET:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nothing to do here actually other than if we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * were actually logged onto a port in the devlist
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (which indicates active communication between
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the host port and the port in the changelist).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If however we are in a private loop or point to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * point mode, we need to check for any IP capable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ports and update our routing table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (port_top) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This indicates a fabric port with a NameServer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check the devlist to see if we are in active
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * communication with a port on the devlist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Statec_cb: fabric topology"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, changelist, listlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_NO_NS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No nameserver - so treat it like a Private loop
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or point to point topology and get a map of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices on the link and get IP capable ports to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to update the routing table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "Statec_cb: NO_NS topology"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Statec_cb: Pvt_Loop topology"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PT_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * call get_port_map() and update routing table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, changelist, listlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "Statec_cb: Unknown topology"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We should now enable the Queues and permit I/Os
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to flow through downstream. The update of routing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * table should have flushed out any port entries that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't exist or are not available after the state change
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_flags & FCIP_LINK_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~FCIP_LINK_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Enable write queues
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fcipstruplock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (slp = fcipstrup; slp != NULL; slp = slp->sl_nextp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp && slp->sl_fcip == fptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wrq = WR(slp->sl_rq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (wrq->q_flag & QFULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte qenable(wrq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_OFFLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mark the port_state OFFLINE and wait for it to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * become online. Any new messages in this state will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * simply be queued back up. If the port does not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * come online in a short while, we can begin failing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * messages and flush the routing table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_mark_offline = fptr->fcip_timeout_ticks +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_OFFLINE_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark all Routing table entries as invalid to prevent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * any commands from trickling through to ports that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have disappeared from under us
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = fptr->fcip_rtable[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (frtp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp->fcipr_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = frtp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_RESET_REQUESTED:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Release all Unsolicited buffers back to transport/FCA.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This also means the port state is marked offline - so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we may have to do what OFFLINE state requires us to do.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Care must be taken to wait for any active unsolicited
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * buffer with the other Streams modules - so wait for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a freeb if the unsolicited buffer is passed back all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the way upstream.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef FCIP_ESBALLOC
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fptr->fcip_ub_upstream) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&fptr->fcip_ub_cv, &fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* FCIP_ESBALLOC */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_mark_offline = fptr->fcip_timeout_ticks +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_OFFLINE_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_DEVICE_CHANGE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listlen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, changelist, listlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_RESET:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Not much to do I guess - wait for port to become
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ONLINE. If the port doesn't become online in a short
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * while, the upper layers abort any request themselves.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We can just putback the messages in the streams queues
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the link is offline
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_IN_SC_CB);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Given a port handle, return the fcip_port_info structure corresponding
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to that port handle. The transport allocates and communicates with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ULPs using port handles
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fcip_port_info_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_get_port(opaque_t phandle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(phandle != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport->fcipp_handle == phandle) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* found */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle inbound ELS requests received by the transport. We are only
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * intereseted in FARP/InARP mostly.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_els_cb(opaque_t ulp_handle, opaque_t phandle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_unsol_buf_t *buf, uint32_t claimed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t r_ctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t ls_code;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_farp_t farp_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_farp_t *fcmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_get_port(phandle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_UNCLAIMED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_UNCLAIMED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = ddi_get_instance(fport->fcipp_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fptr->fcip_flags & (FCIP_DETACHING | FCIP_DETACHED)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fptr->fcip_flags & (FCIP_SUSPENDED | FCIP_POWER_DOWN))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_UNCLAIMED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set fcip flags to indicate we are in the middle of a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ELS callback so we can wait till the statechange
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is handled before succeeding/failing the SUSPEND/POWER DOWN.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_IN_ELS_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_els_cb, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "ELS callback",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_uint, instance, instance));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "fcip%d, ELS callback , ", instance));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte r_ctl = buf->ub_frame.r_ctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (r_ctl & R_CTL_ROUTING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_EXTENDED_SVC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (r_ctl == R_CTL_ELS_REQ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code = buf->ub_buffer[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ls_code == LA_ELS_FARP_REQ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Inbound FARP broadcast request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buf->ub_bufsize != sizeof (la_els_farp_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Invalid FARP req buffer size "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "expected 0x%lx, got 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (long)(sizeof (la_els_farp_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_bufsize));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto els_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd = (la_els_farp_t *)buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_wwn_compare(&fcmd->resp_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fport->fcipp_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_COMPARE_NWWN) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto els_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copy the FARP request and release the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unsolicited buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd = &farp_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)buf, (void *)fcmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_farp_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_ubrelease(fport->fcipp_handle, 1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &buf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_farp_supported &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_handle_farp_request(fptr, fcmd) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We successfully sent out a FARP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reply to the requesting port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto els_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto els_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (r_ctl == R_CTL_ELS_RSP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code = buf->ub_buffer[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ls_code == LA_ELS_FARP_REPLY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We received a REPLY to our FARP request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buf->ub_bufsize != sizeof (la_els_farp_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Invalid FARP req buffer size "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "expected 0x%lx, got 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (long)(sizeof (la_els_farp_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_bufsize));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto els_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd = &farp_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)buf, (void *)fcmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_farp_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_ubrelease(fport->fcipp_handle, 1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &buf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_farp_supported &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_handle_farp_response(fptr, fcmd) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Successfully recevied a FARP "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "response"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_farp_rsp_flag = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&fptr->fcip_farp_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto els_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unable to handle a FARP response "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "receive"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto els_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteels_cb_done:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_IN_ELS_CB);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle inbound FARP requests
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_handle_farp_request(struct fcip *fptr, la_els_farp_t *fcmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opaque_t fca_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add an entry for the remote port into our routing and destination
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tables.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_did = fcmd->req_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_hard_addr.hard_addr = fcmd->req_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_type = PORT_DEVICE_NEW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&fcmd->req_pwwn, (void *)&map.map_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&fcmd->req_nwwn, (void *)&map.map_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, &map, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, &fcmd->req_pwwn, FCIP_COMPARE_NWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_add_dest(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = fcip_ipkt_alloc(fptr, sizeof (la_els_farp_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_farp_t), NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto farp_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fill in our port's PWWN and NWWN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->resp_pwwn = fport->fcipp_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->resp_nwwn = fport->fcipp_nwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_init_unicast_pkt(fcip_pkt, fport->fcipp_sid,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->req_id, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_dev =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_get_fca_device(fport->fcipp_handle, fcmd->req_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_RSP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_fca_device = fca_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dest = fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Attempt a PLOGI again
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcmd->resp_flags & FARP_INIT_P_LOGI) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_do_plogi(fptr, frp) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Login to the remote port failed. There is no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * point continuing with the FARP request further
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so bail out here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto farp_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_CP_OUT(fcmd, fc_pkt->pkt_cmd, fc_pkt->pkt_cmd_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_farp_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fc_ulp_issue_els(fport->fcipp_handle, fc_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_handle_farp_request, "fcip io",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CSTYLED */, tnf_string, msg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip_transport of farp reply failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_uint, rval, rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip_transport of farp reply failed 0x%x", rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefarp_done:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle FARP responses to our FARP requests. When we receive a FARP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reply, we need to add the entry for the Port that replied into our
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routing and destination hash tables. It is possible that the remote
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port did not login into us (FARP responses can be received without
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a PLOGI)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_handle_farp_response(struct fcip *fptr, la_els_farp_t *fcmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add an entry for the remote port into our routing and destination
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tables.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_did = fcmd->dest_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_hard_addr.hard_addr = fcmd->dest_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_type = PORT_DEVICE_NEW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&fcmd->resp_pwwn, (void *)&map.map_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&fcmd->resp_nwwn, (void *)&map.map_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, &map, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, &fcmd->resp_pwwn, FCIP_COMPARE_NWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_add_dest(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCIP_HDRS_LENGTH \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fcph_network_hdr_t)+sizeof (llc_snap_hdr_t)+sizeof (ipha_t)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_data_cb is the heart of most IP operations. This routine is called
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by the transport when any unsolicited IP data arrives at a port (which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is almost all IP data). This routine then strips off the Network header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from the payload (after authenticating the received payload ofcourse),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * creates a message blk and sends the data upstream. You will see ugly
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * #defines because of problems with using esballoc() as opposed to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocb to prevent an extra copy of data. We should probably move to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * esballoc entirely when the MTU eventually will be larger than 1500 bytes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * since copies will get more expensive then. At 1500 byte MTUs, there is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no noticable difference between using allocb and esballoc. The other
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * caveat is that the qlc firmware still cannot tell us accurately the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no. of valid bytes in the unsol buffer it DMA'ed so we have to resort
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to looking into the IP header and hoping that the no. of bytes speficified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the header was actually received.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_data_cb(opaque_t ulp_handle, opaque_t phandle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_unsol_buf_t *buf, uint32_t claimed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcph_network_hdr_t *nhdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llc_snap_hdr_t *snaphdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mblk_t *bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t hdrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ushort_t type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ipha_t *iphdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef FCIP_ESBALLOC
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtn_t *free_ubuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_esballoc_arg *fesb_argp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* FCIP_ESBALLOC */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_get_port(phandle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_UNCLAIMED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_UNCLAIMED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fptr->fcip_flags & (FCIP_DETACHING | FCIP_DETACHED)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fptr->fcip_flags & (FCIP_SUSPENDED | FCIP_POWER_DOWN))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto data_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set fcip flags to indicate we are in the middle of a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data callback so we can wait till the statechange
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is handled before succeeding/failing the SUSPEND/POWER DOWN.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_IN_DATA_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_data_cb, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "data callback",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_int, instance, ddi_get_instance(fport->fcipp_dip)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "fcip%d, data callback",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(fport->fcipp_dip)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get to the network and snap headers in the payload
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nhdr = (fcph_network_hdr_t *)buf->ub_buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snaphdr = (llc_snap_hdr_t *)(buf->ub_buffer +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fcph_network_hdr_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdrlen = sizeof (fcph_network_hdr_t) + sizeof (llc_snap_hdr_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get the IP header to obtain the no. of bytes we need to read
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * off from the unsol buffer. This obviously is because not all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data fills up the unsol buffer completely and the firmware
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * doesn't tell us how many valid bytes are in there as well
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iphdr = (ipha_t *)(buf->ub_buffer + hdrlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snaphdr->pid = BE_16(snaphdr->pid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte type = snaphdr->pid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_CONT, "SNAPHDR: dsap %x, ssap %x, ctrl %x\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snaphdr->dsap, snaphdr->ssap, snaphdr->ctrl));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_CONT, "oui[0] 0x%x oui[1] 0x%x oui[2] 0x%x pid 0x%x\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snaphdr->oui[0], snaphdr->oui[1], snaphdr->oui[2], snaphdr->pid));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Authneticate, Authenticate */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (type == ETHERTYPE_IP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = hdrlen + BE_16(iphdr->ipha_length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (type == ETHERTYPE_ARP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = hdrlen + 28;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = buf->ub_bufsize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_CONT, "effective packet length is %d bytes.\n", len));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len < hdrlen || len > FCIP_UB_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "Incorrect buffer size %d bytes", len));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto data_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buf->ub_frame.type != FC_TYPE_IS8802_SNAP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, (CE_NOTE, "Not IP/ARP data"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto data_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, (CE_NOTE, "checking wwn"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fcip_wwn_compare(&nhdr->net_dest_addr, &fport->fcipp_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_COMPARE_NWWN) != 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (!IS_BROADCAST_ADDR(&nhdr->net_dest_addr))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto data_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (fcip_cache_on_arp_broadcast &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte IS_BROADCAST_ADDR(&nhdr->net_dest_addr)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_cache_arp_broadcast(fptr, buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, (CE_NOTE, "Allocate streams block"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Using esballoc instead of allocb should be faster, atleast at
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * larger MTUs than 1500 bytes. Someday we'll get there :)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if defined(FCIP_ESBALLOC)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocate memory for the frtn function arg. The Function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (fcip_ubfree) arg is a struct fcip_esballoc_arg type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which contains pointers to the unsol buffer and the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * opaque port handle for releasing the unsol buffer back to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the FCA for reuse
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fesb_argp = (struct fcip_esballoc_arg *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(sizeof (struct fcip_esballoc_arg), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fesb_argp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "esballoc of mblk failed in data_cb"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto data_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check with KM_NOSLEEP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free_ubuf = (frtn_t *)kmem_zalloc(sizeof (frtn_t), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (free_ubuf == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fesb_argp, sizeof (struct fcip_esballoc_arg));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "esballoc of mblk failed in data_cb"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto data_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fesb_argp->frtnp = free_ubuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fesb_argp->buf = buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fesb_argp->phandle = phandle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free_ubuf->free_func = fcip_ubfree;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free_ubuf->free_arg = (char *)fesb_argp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((bp = (mblk_t *)esballoc((unsigned char *)buf->ub_buffer,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len, BPRI_MED, free_ubuf)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fesb_argp, sizeof (struct fcip_esballoc_arg));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(free_ubuf, sizeof (frtn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "esballoc of mblk failed in data_cb"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto data_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#elif !defined(FCIP_ESBALLOC)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocate streams mblk and copy the contents of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unsolicited buffer into this newly alloc'ed mblk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((bp = (mblk_t *)fcip_allocb((size_t)len, BPRI_LO)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "alloc of mblk failed in data_cb"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_UNCLAIMED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto data_cb_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unsolicited buffers handed up to us from the FCA must be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * endian clean so just bcopy the data into our mblk. Else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we may have to either copy the data byte by byte or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * use the ddi_rep_get* routines to do the copy for us.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(buf->ub_buffer, bp->b_rptr, len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for esballoc'ed mblks - free the UB in the frtn function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * along with the memory allocated for the function arg.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for allocb'ed mblk - release the unsolicited buffer here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_ubrelease(phandle, 1, &buf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* FCIP_ESBALLOC */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_wptr = bp->b_rptr + len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ipackets++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (type == ETHERTYPE_IP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_upstream++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_rptr += hdrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if ipq is valid in the sendup thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_sendup_alloc_enque(fptr, bp, NULL) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We won't get ethernet 802.3 packets in FCIP but we may get
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * types other than ETHERTYPE_IP, such as ETHERTYPE_ARP. Let
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_sendup() do the matching.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_upstream++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_sendup_alloc_enque(fptr, bp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_accept) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unset fcip_flags to indicate we are out of callback and return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedata_cb_done:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_IN_DATA_CB);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(FCIP_ESBALLOC)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate a message block for the inbound data to be sent upstream.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_allocb(size_t size, uint_t pri)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mblk_t *mp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((mp = allocb(size, pri)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This helper routine kmem cache alloc's a sendup element for enquing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * into the sendup list for callbacks upstream from the dedicated sendup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * thread. We enque the msg buf into the sendup list and cv_signal the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sendup thread to finish the callback for us.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_sendup_alloc_enque(struct fcip *fptr, mblk_t *mp, struct fcipstr *(*f)())
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_sendup_elem *msg_elem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_sendup_alloc_enque, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "sendup msg enque"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg_elem = kmem_cache_alloc(fptr->fcip_sendup_cache, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (msg_elem == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* drop pkt to floor - update stats */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto sendup_alloc_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg_elem->fcipsu_mp = mp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg_elem->fcipsu_func = f;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_sendup_head == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_head = fptr->fcip_sendup_tail = msg_elem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_tail->fcipsu_next = msg_elem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_tail = msg_elem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_cnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&fptr->fcip_sendup_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesendup_alloc_done:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * One of the ways of performing the WWN to D_ID mapping required for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * IPFC data is to cache the unsolicited ARP broadcast messages received
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and update the routing table to add entry for the destination port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if we are the intended recipient of the ARP broadcast message. This is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one of the methods recommended in the rfc to obtain the WWN to D_ID mapping
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but is not typically used unless enabled. The driver prefers to use the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nameserver/lilp map to obtain this mapping.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_cache_arp_broadcast(struct fcip *fptr, fc_unsol_buf_t *buf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcph_network_hdr_t *nhdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fport != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nhdr = (fcph_network_hdr_t *)buf->ub_buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, &nhdr->net_src_addr, FCIP_COMPARE_NWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_did.port_id = buf->ub_frame.s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_hard_addr.hard_addr = buf->ub_frame.s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_type = PORT_DEVICE_NEW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&nhdr->net_src_addr, (void *)&map.map_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&nhdr->net_src_addr, (void *)&map.map_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, &map, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, &nhdr->net_src_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_COMPARE_NWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_add_dest(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is a dedicated thread to do callbacks from fcip's data callback
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routines into the modules upstream. The reason for this thread is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the data callback function can be called from an interrupt context and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the upstream modules *can* make calls downstream in the same thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * context. If the call is to a fabric port which is not yet in our
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routing tables, we may have to query the nameserver/fabric for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * MAC addr to Port_ID mapping which may be blocking calls.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_sendup_thr(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = (struct fcip *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_sendup_elem *msg_elem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte queue_t *ip4q = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CALLB_CPR_INIT(&fptr->fcip_cpr_info, &fptr->fcip_sendup_mutex,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte callb_generic_cpr, "fcip_sendup_thr");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (;;) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fptr->fcip_sendup_thr_initted &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_head == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CALLB_CPR_SAFE_BEGIN(&fptr->fcip_cpr_info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&fptr->fcip_sendup_cv,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CALLB_CPR_SAFE_END(&fptr->fcip_cpr_info,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_sendup_thr_initted == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_sendup_thr, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip sendup thr - new msg"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg_elem = fptr->fcip_sendup_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_head = msg_elem->fcipsu_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg_elem->fcipsu_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (msg_elem->fcipsu_func == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Message for ipq. Check to see if the ipq is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is still valid. Since the thread is asynchronous,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * there could have been a close on the stream
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_ipq && canputnext(fptr->fcip_ipq)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ip4q = fptr->fcip_ipq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte putnext(ip4q, msg_elem->fcipsu_mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(msg_elem->fcipsu_mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_sendup(fptr, msg_elem->fcipsu_mp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg_elem->fcipsu_func);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(FCIP_ESBALLOC)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for allocb'ed mblk - decrement upstream count here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr->fcip_ub_upstream > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_upstream--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* FCIP_ESBALLOC */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_free(fptr->fcip_sendup_cache, (void *)msg_elem);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_cnt--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CALLB_CPR_EXIT(&fptr->fcip_cpr_info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* __lock_lint */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Wake up fcip detach thread by the end */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&fptr->fcip_sendup_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte thread_exit();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef FCIP_ESBALLOC
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called from the stream head when it is done using an unsolicited buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We release this buffer then to the FCA for reuse.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_ubfree(char *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_esballoc_arg *fesb_argp = (struct fcip_esballoc_arg *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_unsol_buf_t *ubuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtn_t *frtnp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fcip_get_port(fesb_argp->phandle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fesb_argp != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ubuf = fesb_argp->buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtnp = fesb_argp->frtnp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "freeing ubuf after esballoc in fcip_ubfree"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_ubrelease(fesb_argp->phandle, 1, &ubuf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr->fcip_ub_upstream > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_upstream--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&fptr->fcip_ub_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(frtnp, sizeof (frtn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fesb_argp, sizeof (struct fcip_esballoc_arg));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* FCIP_ESBALLOC */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle data other than that of type ETHERTYPE_IP and send it on its
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * way upstream to the right streams module to handle
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_sendup(struct fcip *fptr, mblk_t *mp, struct fcipstr *(*acceptfunc)())
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp, *nslp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *dhostp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mblk_t *nmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t isgroupaddr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t hdrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcph_network_hdr_t *nhdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llc_snap_hdr_t *snaphdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_sendup, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip sendup"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nhdr = (fcph_network_hdr_t *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snaphdr =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (llc_snap_hdr_t *)(mp->b_rptr + sizeof (fcph_network_hdr_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dhostp = &nhdr->net_dest_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte type = snaphdr->pid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdrlen = sizeof (fcph_network_hdr_t) + sizeof (llc_snap_hdr_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* No group address with fibre channel */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte isgroupaddr = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * While holding a reader lock on the linked list of streams structures,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * attempt to match the address criteria for each stream
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and pass up the raw M_DATA ("fastpath") or a DL_UNITDATA_IND.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fcipstruplock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((slp = (*acceptfunc)(fcipstrup, fptr, type, dhostp)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_sendup, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip sendup - no slp"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Loop on matching open streams until (*acceptfunc)() returns NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; nslp = (*acceptfunc)(slp->sl_nextp, fptr, type, dhostp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = nslp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (canputnext(slp->sl_rq)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nmp = dupmsg(mp)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((slp->sl_flags & FCIP_SLFAST) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !isgroupaddr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nmp->b_rptr += hdrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte putnext(slp->sl_rq, nmp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (slp->sl_flags & FCIP_SLRAW) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* No headers when FCIP_SLRAW is set */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte putnext(slp->sl_rq, nmp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((nmp = fcip_addudind(fptr, nmp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nhdr, type))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte putnext(slp->sl_rq, nmp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Do the last one.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (canputnext(slp->sl_rq)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_flags & FCIP_SLFAST) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mp->b_rptr += hdrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte putnext(slp->sl_rq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (slp->sl_flags & FCIP_SLRAW) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte putnext(slp->sl_rq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((mp = fcip_addudind(fptr, mp, nhdr, type))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte putnext(slp->sl_rq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_sendup, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip sendup done"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Match the stream based on type and wwn if necessary.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Destination wwn dhostp is passed to this routine is reserved
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for future usage. We don't need to use it right now since port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to fcip instance mapping is unique and wwn is already validated when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * packet comes to fcip.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fcipstr *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_accept(struct fcipstr *slp, struct fcip *fptr, int type, la_wwn_t *dhostp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t_uscalar_t sap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_accept, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip accept"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; slp; slp = slp->sl_nextp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sap = slp->sl_sap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, (CE_CONT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip_accept: checking next sap = %x, type = %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sap, type));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((slp->sl_fcip == fptr) && (type == sap)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (slp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle DL_UNITDATA_IND messages
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic mblk_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_addudind(struct fcip *fptr, mblk_t *mp, fcph_network_hdr_t *nhdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dl_unitdata_ind_t *dludindp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipdladdr *dlap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mblk_t *nmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t hdrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct ether_addr src_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct ether_addr dest_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdrlen = (sizeof (llc_snap_hdr_t) + sizeof (fcph_network_hdr_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mp->b_rptr += hdrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_addudind, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip addudind"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate an M_PROTO mblk for the DL_UNITDATA_IND.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size = sizeof (dl_unitdata_ind_t) + FCIPADDRL + FCIPADDRL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((nmp = allocb(size, BPRI_LO)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_allocbfail++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DB_TYPE(nmp) = M_PROTO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nmp->b_wptr = nmp->b_datap->db_lim;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nmp->b_rptr = nmp->b_wptr - size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Construct a DL_UNITDATA_IND primitive.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dludindp = (dl_unitdata_ind_t *)nmp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dludindp->dl_primitive = DL_UNITDATA_IND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dludindp->dl_dest_addr_length = FCIPADDRL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dludindp->dl_dest_addr_offset = sizeof (dl_unitdata_ind_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dludindp->dl_src_addr_length = FCIPADDRL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dludindp->dl_src_addr_offset = sizeof (dl_unitdata_ind_t) + FCIPADDRL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dludindp->dl_group_address = 0; /* not DL_MULTI */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlap = (struct fcipdladdr *)(nmp->b_rptr + sizeof (dl_unitdata_ind_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wwn_to_ether(&nhdr->net_dest_addr, &dest_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_bcopy(&dest_addr, &dlap->dl_phys);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlap->dl_sap = (uint16_t)type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlap = (struct fcipdladdr *)(nmp->b_rptr + sizeof (dl_unitdata_ind_t)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte + FCIPADDRL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wwn_to_ether(&nhdr->net_src_addr, &src_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_bcopy(&src_addr, &dlap->dl_phys);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlap->dl_sap = (uint16_t)type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Link the M_PROTO and M_DATA together.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nmp->b_cont = mp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (nmp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The open routine. For clone opens, we return the next available minor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no. for the stream to use
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr **prevslp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte minor_t minor;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "in fcip_open"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_open, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need to ensure that the port driver is loaded before
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we proceed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_hold_installed_driver(ddi_name_to_major(PORT_DRIVER)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* no port driver instances found */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_STARTUP, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!ddi_hold_installed_driver of fp failed\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* serialize opens */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fcipstruplock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prevslp = &fcipstrup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sflag == CLONEOPEN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte minor = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; (slp = *prevslp) != NULL; prevslp = &slp->sl_nextp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (minor < slp->sl_minor) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte minor ++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "getmajor returns 0x%x", getmajor(*devp)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *devp = makedevice(getmajor(*devp), minor);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte minor = getminor(*devp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check if our qp's private area is already initialized. If yes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the stream is already open - just return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rq->q_ptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = GETSTRUCT(struct fcipstr, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_minor = minor;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_rq = rq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_sap = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_state = DL_UNATTACHED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_fcip = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&slp->sl_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * link this new stream entry into list of active streams
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_nextp = *prevslp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *prevslp = slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rq->q_ptr = WR(rq)->q_ptr = (char *)slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Disable automatic enabling of our write service procedures
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we need to control this explicitly. This will prevent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * anyone scheduling of our write service procedures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte noenable(WR(rq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedone:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * enable our put and service routines on the read side
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte qprocson(rq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There is only one instance of fcip (instance = 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for multiple instances of hardware
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) qassociate(rq, 0); /* don't allow drcompat to be pushed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * close an opened stream. The minor no. will then be available for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * future opens.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_close(queue_t *rq, int flag, int otyp, cred_t *credp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr **prevslp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "in fcip_close"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_close, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(rq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we should also have the active stream pointer in q_ptr */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(rq->q_ptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_rele_driver(ddi_name_to_major(PORT_DRIVER));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * disable our put and service procedures. We had enabled them
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on open
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte qprocsoff(rq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)rq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Implicitly detach stream a stream from an interface.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_fcip) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_dodetach(slp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) qassociate(rq, -1); /* undo association in open */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fcipstruplock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unlink this stream from the active stream list and free it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (prevslp = &fcipstrup; (slp = *prevslp) != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prevslp = &slp->sl_nextp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp == (struct fcipstr *)rq->q_ptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we should have found slp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(slp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *prevslp = slp->sl_nextp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&slp->sl_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(slp, sizeof (struct fcipstr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rq->q_ptr = WR(rq)->q_ptr = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is not an extension of the DDI_DETACH request. This routine
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * only detaches a stream from an interface
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_dodetach(struct fcipstr *slp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *tslp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_NOTE, "in fcip_dodetach"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_dodetach, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(slp->sl_fcip != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = slp->sl_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_fcip = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we don't support promiscuous mode currently but check
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for and disable any promiscuous mode operation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_flags & SLALLPHYS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_flags &= ~SLALLPHYS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * disable ALLMULTI mode if all mulitcast addr are ON
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_flags & SLALLMULTI) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_flags &= ~SLALLMULTI;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we are most likely going to perform multicast by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * broadcasting to the well known addr (D_ID) 0xFFFFFF or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ALPA 0x00 in case of public loops
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * detach unit from device structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (tslp = fcipstrup; tslp != NULL; tslp = tslp->sl_nextp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tslp->sl_fcip == fptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tslp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip_dodeatch - active stream struct not found"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* unregister with Fabric nameserver?? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_state = DL_UNATTACHED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_setipq(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set or clear device ipq pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Walk thru all the streams on this device, if a ETHERTYPE_IP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stream is found, assign device ipq to its sl_rq.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_setipq(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ok = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte queue_t *ipq = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE, "entered fcip_setipq"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fcipstruplock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (slp = fcipstrup; slp != NULL; slp = slp->sl_nextp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_fcip == fptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_flags & (SLALLPHYS|SLALLSAP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ok = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_sap == ETHERTYPE_IP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ipq == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ipq = slp->sl_rq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ok = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fcipstruplock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_check_port_exists(fptr)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fptr passed to us is stale */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ok) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ipq = ipq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ipq = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_ioctl(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "in fcip ioctl : %d", iocp->ioc_cmd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_ioctl, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (iocp->ioc_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DLIOCRAW:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_flags |= FCIP_SLRAW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte miocack(wq, mp, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_IOC_HDR_INFO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_dl_ioc_hdr_info(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte miocnak(wq, mp, 0, EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The streams 'Put' routine.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_wput(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcph_network_hdr_t *headerp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "in fcip_wput :: type:%x", DB_TYPE(mp)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (DB_TYPE(mp)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case M_DATA: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = slp->sl_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((slp->sl_flags & (FCIP_SLFAST|FCIP_SLRAW)) == 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (slp->sl_state != DL_IDLE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fptr == NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set error in the message block and send a reply
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * back upstream. Sun's merror routine does this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for us more cleanly.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte merror(wq, mp, EPROTO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if any messages are already enqueued or if the interface
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is in promiscuous mode, causing the packets to loop back
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * up, then enqueue the message. Otherwise just transmit
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the message. putq() puts the message on fcip's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * write queue and qenable() puts the queue (wq) on
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the list of queues to be called by the streams scheduler.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (wq->q_first) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) putq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_wantw = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte qenable(wq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (fptr->fcip_flags & FCIP_PROMISC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Promiscous mode not supported but add this code in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * case it will be supported in future.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) putq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte qenable(wq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte headerp = (fcph_network_hdr_t *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_get_dest(fptr, &headerp->net_dest_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte merror(wq, mp, EPROTO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fdestp != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_start(wq, mp, fptr, fdestp, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case M_PROTO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case M_PCPROTO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to prevent recursive calls into fcip_proto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (PROTO and PCPROTO messages are handled by fcip_proto)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * let the service procedure handle these messages by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * calling putq here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) putq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte qenable(wq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case M_IOCTL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ioctl(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case M_FLUSH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*mp->b_rptr & FLUSHW) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flushq(wq, FLUSHALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *mp->b_rptr &= ~FLUSHW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we have both FLUSHW and FLUSHR set with FLUSHRW
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*mp->b_rptr & FLUSHR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * send msg back upstream. qreply() takes care
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of using the RD(wq) queue on its reply
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte qreply(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "default msg type: %x", DB_TYPE(mp)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle M_PROTO and M_PCPROTO messages
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_proto(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union DL_primitives *dlp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t_uscalar_t prim;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlp = (union DL_primitives *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prim = dlp->dl_primitive; /* the DLPI command */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_5((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, wq, wq,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, mp, mp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, MP_DB_TYPE, DB_TYPE(mp),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, dl_primitive, dlp->dl_primitive));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE, "dl_primitve : %x", prim));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&slp->sl_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (prim) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_UNITDATA_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "unit data request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "unit data request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_udreq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_ATTACH_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "Attach request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "Attach request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_areq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_DETACH_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "Detach request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "Detach request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_dreq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_BIND_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "Bind request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "Bind request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_breq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_UNBIND_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "unbind request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "unbind request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ubreq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_INFO_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "Info request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "Info request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ireq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_SET_PHYS_ADDR_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "set phy addr request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "set phy addr request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_spareq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_PHYS_ADDR_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "phy addr request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "phy addr request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pareq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_ENABMULTI_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "Enable Multicast request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "Enable Multicast request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_DISABMULTI_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "Disable Multicast request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "Disable Multicast request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_PROMISCON_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "Promiscuous mode ON request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "Promiscuous mode ON request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_PROMISCOFF_REQ:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "Promiscuous mode OFF request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "Promiscuous mode OFF request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "Unsupported request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&slp->sl_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Always enqueue M_PROTO and M_PCPROTO messages pn the wq and M_DATA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * messages sometimes. Processing of M_PROTO and M_PCPROTO messages
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * require us to hold fcip's internal locks across (upstream) putnext
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * calls. Specifically fcip_intr could hold fcip_intrlock and fcipstruplock
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when it calls putnext(). That thread could loop back around to call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_wput and eventually fcip_init() to cause a recursive mutex panic
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * M_DATA messages are enqueued only if we are out of xmit resources. Once
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the transmit resources are available the service procedure is enabled
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and an attempt is made to xmit all messages on the wq.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_wsrv(queue_t *wq)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mblk_t *mp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcph_network_hdr_t *headerp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = slp->sl_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_wsrv, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, wq, wq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "fcip wsrv"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (mp = getq(wq)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (DB_TYPE(mp)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case M_DATA:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr && mp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte headerp = (fcph_network_hdr_t *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_get_dest(fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &headerp->net_dest_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_start(wq, mp, fptr, fdestp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case M_PROTO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case M_PCPROTO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "PROT msg in wsrv"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_proto(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedone:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine is called from fcip_wsrv to send a message downstream
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on the fibre towards its destination. This routine performs the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * actual WWN to D_ID mapping by looking up the routing and destination
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tables.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_start(queue_t *wq, mblk_t *mp, struct fcip *fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp, int flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int free;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t datalen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_4((fcip_start, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter", tnf_opaque, wq, wq,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, mp, mp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, MP_DB_TYPE, DB_TYPE(mp)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "in fcipstart"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fdestp != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only return if port has gone offline and not come back online
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in a while
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_flags & FCIP_LINK_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The message block coming in here already has the network and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * llc_snap hdr stuffed in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Traditionally ethernet drivers at sun handle 3 cases here -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1. messages with one mblk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 2. messages with 2 mblks
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 3. messages with >2 mblks
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For now lets handle all the 3 cases in a single case where we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * put them together in one mblk that has all the data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mp->b_cont != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!pullupmsg(mp, -1)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "failed to concat message"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte datalen = msgsize(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "msgsize with nhdr & llcsnap hdr in fcip_pkt_alloc 0x%lx",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte datalen));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We cannot have requests larger than FCIPMTU+Headers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (datalen > (FCIPMTU + sizeof (llc_snap_hdr_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fcph_network_hdr_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip_pkt_alloc: datalen is larger than "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "max possible size."));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = fcip_pkt_alloc(fptr, mp, flags, datalen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) putbq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_mp = mp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_wq = wq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the device dynamically disappeared, just fail the request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp->fcipd_rtable == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_free(fcip_pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now that we've assigned pkt_pd, we can call fc_ulp_init_packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_pd = fdestp->fcipd_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_init_packet((opaque_t)fport->fcipp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt, flags) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_free(fcip_pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_fdestp_enqueue_pkt(fdestp, fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dest = fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_fca_device = fdestp->fcipd_fca_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "setting cmdlen to 0x%x: rsp 0x%x : data 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmdlen, fc_pkt->pkt_rsplen, fc_pkt->pkt_datalen));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_init_unicast_pkt(fcip_pkt, fport->fcipp_sid,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp->fcipd_did, fcip_pkt_callback);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp->fcipd_ncmds++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = fcip_transport(fcip_pkt)) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_opackets++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free = (rval == FC_STATEC_BUSY || rval == FC_OFFLINE ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval == FC_TRAN_BUSY) ? 0 : 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fcip_fdestp_dequeue_pkt(fdestp, fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rval) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp->fcipd_ncmds--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_free(fcip_pkt, free);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!free) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) putbq(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine enqueus a packet marked to be issued to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * transport in the dest structure. This enables us to timeout any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * request stuck with the FCA/transport for long periods of time
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * without a response. fcip_pkt_timeout will attempt to clean up
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * any packets hung in this state of limbo.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_fdestp_enqueue_pkt(struct fcip_dest *fdestp, fcip_pkt_t *fcip_pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&fdestp->fcipd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_fdestp_enqueue_pkt, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "destp enq pkt"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Just hang it off the head of packet list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_next = fdestp->fcipd_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags |= FCIP_PKT_IN_LIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp->fcipd_head != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fdestp->fcipd_head->fcip_pkt_prev == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp->fcipd_head->fcip_pkt_prev = fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp->fcipd_head = fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dequeues any packets after the transport/FCA tells us it has
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * been successfully sent on its way. Ofcourse it doesn't mean that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the packet will actually reach its destination but its atleast
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a step closer in that direction
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_fdestp_dequeue_pkt(struct fcip_dest *fdestp, fcip_pkt_t *fcip_pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcipd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&fdestp->fcipd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_flags & FCIP_PKT_IN_TIMEOUT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipd_pkt = fdestp->fcipd_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fcipd_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcipd_pkt == fcip_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *pptr = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcipd_pkt == fdestp->fcipd_head) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcipd_pkt->fcip_pkt_prev ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp->fcipd_head =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipd_pkt->fcip_pkt_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pptr = fcipd_pkt->fcip_pkt_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pptr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pptr->fcip_pkt_next =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipd_pkt->fcip_pkt_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcipd_pkt->fcip_pkt_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pptr = fcipd_pkt->fcip_pkt_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pptr->fcip_pkt_prev =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipd_pkt->fcip_pkt_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_LIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipd_pkt = fcipd_pkt->fcip_pkt_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_prev == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fdestp->fcipd_head == fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp->fcipd_head = fcip_pkt->fcip_pkt_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_prev->fcip_pkt_next =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_next->fcip_pkt_prev =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipd_pkt = fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_LIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fcipd_pkt == fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The transport routine - this is the routine that actually calls
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * into the FCA driver (through the transport ofcourse) to transmit a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * datagram on the fibre. The dest struct assoicated with the port to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which the data is intended is already bound to the packet, this routine
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * only takes care of marking the packet a broadcast packet if it is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * intended to be a broadcast request. This permits the transport to send
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the packet down on the wire even if it doesn't have an entry for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * D_ID in its d_id hash tables.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_transport(fcip_pkt_t *fcip_pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_transport, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fcip_pkt->fcip_pkt_fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_pkt->fcip_pkt_dest;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_WARN, "fcip_transport called"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = fptr->fcip_broadcast_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_cmd_fhdr.d_id == did &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_type != FC_PKT_BROADCAST) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "trantype set to BROADCAST"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_type = FC_PKT_BROADCAST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fc_pkt->pkt_tran_type != FC_PKT_BROADCAST) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fc_pkt->pkt_pd == NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_transport, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip transport no pd"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (fptr->fcip_port_state == FCIP_PORT_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_transport, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip transport port offline"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_TRAN_BUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fdestp->fcipd_rtable;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((frp == NULL) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (frp && FCIP_RTE_UNAVAIL(frp->fcipr_state))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (frp->fcipr_state == FCIP_RT_INVALID)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_transport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip transport - TRANBUSY"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_TRAN_BUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_transport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip transport: frp unavailable"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_pkt->fcip_pkt_flags & FCIP_PKT_IN_LIST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Explicitly invalidate this field till fcip decides to use it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_ulp_rscn_infop = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fc_ulp_transport(fport->fcipp_handle, fc_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_STATEC_BUSY || rval == FC_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Need to queue up the command for retry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "ulp_transport failed: 0x%x", rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (rval == FC_LOGINREQ && (frp != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_do_plogi(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (rval == FC_BADPACKET && (frp != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There is a distinct possiblity in our scheme of things
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that we have a routing table entry with a NULL pd struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark the routing table entry for removal if it is not a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * broadcast entry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((frp->fcipr_d_id.port_id != 0x0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (frp->fcipr_d_id.port_id != 0xffffff)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_transport, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip transport done"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call back routine. Called by the FCA/transport when the messages
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * has been put onto the wire towards its intended destination. We can
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * now free the fc_packet associated with the message
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_pkt_callback(fc_packet_t *fc_pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = (fcip_pkt_t *)fc_pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_pkt->fcip_pkt_dest;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * take the lock early so that we don't have a race condition
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with fcip_timeout
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fdestp->fcipd_mutex isn't really intended to lock per
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * packet struct - see bug 5105592 for permanent solution
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags |= FCIP_PKT_RETURNED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_ABORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_flags & FCIP_PKT_IN_TIMEOUT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "pkt callback"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fdestp->fcipd_rtable != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_pkt->fcip_pkt_flags & FCIP_PKT_IN_LIST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fcip_fdestp_dequeue_pkt(fdestp, fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp->fcipd_ncmds--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_free(fcip_pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_pkt_callback, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "pkt callback done"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "pkt callback done"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return 1 if the topology is supported, else return 0.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Topology support is consistent with what the whole
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stack supports together.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_is_supported_fc_topology(int fc_topology)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (fc_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_NO_NS :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle any topology specific initializations here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this routine must be called while holding fcip_mutex
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_handle_topology(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&fptr->fcip_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Since we know the port's topology - handle topology
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * specific details here. In Point to Point and Private Loop
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * topologies - we would probably not have a name server
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_3((fcip_handle_topology, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_uint, port_state, fport->fcipp_pstate,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_uint, topology, fport->fcipp_topology));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE, "port state: %x, topology %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_pstate, fport->fcipp_topology));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_broadcast_did = fcip_get_broadcast_did(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_dest_add_broadcast_entry(fptr, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fcip_is_supported_fc_topology(fport->fcipp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "fcip(0x%x): Unsupported port topology (0x%x)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_instance, fport->fcipp_topology));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (fport->fcipp_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *port_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen, alloclen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we may have to maintain routing. Get a list of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * all devices on this port that the transport layer is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * aware of. Check if any of them is a IS8802 type port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if yes get its WWN and DID mapping and cache it in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the purport routing table. Since there is no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * State Change notification for private loop/point_point
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * topologies - this table may not be accurate. The static
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routing table is updated on a state change callback.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_WARN, "port state valid!!"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen = alloclen = FCIP_MAX_PORTS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map = (fc_portmap_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc((FCIP_MAX_PORTS * sizeof (fc_portmap_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_getportmap(fport->fcipp_handle, &port_map,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &listlen, FC_ULP_PLOGI_PRESERVE) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, port_map, listlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listlen > alloclen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte alloclen = listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port_map, (alloclen * sizeof (fc_portmap_t)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now fall through and register with the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that this port is IP capable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_NO_NS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we don't have a nameserver, lets wait until we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have to send out a packet to a remote port and then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * try and discover the port using ARP/FARP.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *port_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen, alloclen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FC_TYPE of 0x05 goes to word 0, LSB */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(fptr->fcip_flags & FCIP_REG_INPROGRESS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_REG_INPROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (taskq_dispatch(fptr->fcip_tq, fcip_port_ns,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr, KM_NOSLEEP) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~FCIP_REG_INPROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If fcip_create_nodes_on_demand is overridden to force
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * discovery of all nodes in Fabric/Public loop topologies
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we need to query for and obtain all nodes and log into
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * them as with private loop devices
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fcip_create_nodes_on_demand) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen = alloclen = FCIP_MAX_PORTS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map = (fc_portmap_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc((FCIP_MAX_PORTS *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_portmap_t)), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_getportmap(fport->fcipp_handle, &port_map,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &listlen, FC_ULP_PLOGI_PRESERVE) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, port_map, listlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listlen > alloclen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte alloclen = listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port_map,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (alloclen * sizeof (fc_portmap_t)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_port_ns(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = (struct fcip *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ns_cmd_t ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t types[8];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_rfc_type_t rfc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fptr->fcip_flags & (FCIP_DETACHING | FCIP_DETACHED)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fptr->fcip_flags & (FCIP_SUSPENDED | FCIP_POWER_DOWN))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~FCIP_REG_INPROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prepare the Name server structure to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * register with the transport in case of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fabric configuration.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&rfc, sizeof (rfc));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(types, sizeof (types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte types[FC4_TYPE_WORD_POS(FC_TYPE_IS8802_SNAP)] = (1 <<
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC4_TYPE_BIT_POS(FC_TYPE_IS8802_SNAP));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rfc.rfc_port_id.port_id = fport->fcipp_sid.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(types, rfc.rfc_types, sizeof (types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd.ns_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd.ns_cmd = NS_RFT_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd.ns_req_len = sizeof (rfc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd.ns_req_payload = (caddr_t)&rfc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd.ns_resp_len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd.ns_resp_payload = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform the Name Server Registration for FC IS8802_SNAP Type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We don't expect a reply for registering port type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_port_ns(fptr->fcip_port_info->fcipp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (opaque_t)0, &ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~FCIP_REG_INPROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * setup this instance of fcip. This routine inits kstats, allocates
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unsolicited buffers, determines' this port's siblings and handles
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * topology specific details which includes registering with the name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * server and also setting up the routing table for this port for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * private loops and point to point topologies
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_init_port(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static char buf[64];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t tok_buf_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fport != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_init_port, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * setup mac address for this port. Don't be too worried if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the WWN is zero, there is probably nothing attached to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the port. There is no point allocating unsolicited buffers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for an unused port so return success if we don't have a MAC
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * address. Do the port init on a state change notification.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_setup_mac_addr(fptr) == FCIP_INVALID_WWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * clear routing table hash list for this port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_flush(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * init kstats for this instance
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_kstat_init(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate unsolicited buffers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_nbufs = fcip_ub_nbufs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tok_buf_size = sizeof (*fptr->fcip_ub_tokens) * fcip_ub_nbufs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_init_port, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "debug",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_int, tokBufsize, tok_buf_size));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "tokBufsize: 0x%lx", tok_buf_size));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_tokens = kmem_zalloc(tok_buf_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_ub_tokens == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "fcip(%d): failed to allocate unsol buf",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_instance));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fc_ulp_uballoc(fport->fcipp_handle, &fptr->fcip_ub_nbufs,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ub_size, FC_TYPE_IS8802_SNAP, fptr->fcip_ub_tokens);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "fcip(%d): fc_ulp_uballoc failed with 0x%x!!",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_instance, rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (rval) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_SUCCESS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_OFFLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_port_state = FCIP_PORT_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_UB_ERROR:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_init_port, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "invalid ub alloc request"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "invalid ub alloc request !!"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_FAILURE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * requested bytes could not be alloced
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_ub_nbufs != fcip_ub_nbufs) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!fcip(0x%x): Failed to alloc unsolicited bufs",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(fport->fcipp_dip));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Preallocate a Cache of fcip packets for transmit and receive
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We don't want to be holding on to unsolicited buffers while
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we transmit the message upstream
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE, "allocating fcip_pkt cache"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(buf, "fcip%d_cache", fptr->fcip_instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_xmit_cache = kmem_cache_create(buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fport->fcipp_fca_pkt_size + sizeof (fcip_pkt_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 8, fcip_cache_constructor, fcip_cache_destructor,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, (void *)fport, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(buf, "fcip%d_sendup_cache", fptr->fcip_instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_cache = kmem_cache_create(buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct fcip_sendup_elem),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 8, fcip_sendup_constructor, NULL, NULL, (void *)fport, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_xmit_cache == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_init_port, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "unable to allocate xmit cache",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_int, instance, fptr->fcip_instance));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "fcip%d unable to allocate xmit cache",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_instance));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We may need to handle routing tables for point to point and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcal topologies and register with NameServer for Fabric
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * topologies.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_handle_topology(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_dest_add_broadcast_entry(fptr, 1) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "fcip(0x%x):add broadcast entry failed!!",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_instance));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedone:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we don't always come here from port_attach - so cleanup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * anything done in the init_port routine
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_kstatp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_delete(fptr->fcip_kstatp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_kstatp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_xmit_cache) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_destroy(fptr->fcip_xmit_cache);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_xmit_cache = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_sendup_cache) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_destroy(fptr->fcip_sendup_cache);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_cache = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* release unsolicited buffers */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_ub_tokens) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t *tokens = fptr->fcip_ub_tokens;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_tokens = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_ubfree(fport->fcipp_handle, fptr->fcip_ub_nbufs,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tokens);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(tokens, tok_buf_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sets up a port's MAC address from its WWN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_setup_mac_addr(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&fptr->fcip_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_addrflags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we cannot choose a MAC address for our interface - we have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to live with whatever node WWN we get (minus the top two
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * MSbytes for the MAC address) from the transport layer. We will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * treat the WWN as our factory MAC address.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fport->fcipp_nwwn.w.wwn_hi != 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fport->fcipp_nwwn.w.wwn_lo != 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char etherstr[ETHERSTRL];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wwn_to_ether(&fport->fcipp_nwwn, &fptr->fcip_macaddr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ether_to_str(&fptr->fcip_macaddr, etherstr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "setupmacaddr ouraddr %s", etherstr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_addrflags = (FCIP_FACTADDR_PRESENT |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_FACTADDR_USE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No WWN - just return failure - there's not much
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we can do since we cannot set the WWN.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "Port does not have a valid WWN"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCIP_INVALID_WWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flush routing table entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_rt_flush(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frtp, *frtp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = fptr->fcip_rtable[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (frtp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp_next = frtp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(frtp, sizeof (struct fcip_routing_table));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = frtp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_rtable[index] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free up the fcip softstate and all allocated resources for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip instance assoicated with a given port driver instance
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Given that the list of structures pointed to by fcip_port_head,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function is called from multiple sources, and the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_global_mutex that protects fcip_port_head must be dropped,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * our best solution is to return a value that indicates the next
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port in the list. This way the caller doesn't need to worry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * about the race condition where he saves off a pointer to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * next structure in the list and by the time this routine returns,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that next structure has already been freed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fcip_port_info_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_softstate_free(fcip_port_info_t *fport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_id_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opaque_t phandle = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *prev_fport, *cur_fport, *next_fport = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&fcip_global_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phandle = fport->fcipp_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (next_fport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = ddi_get_instance(fptr->fcip_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dismantle timeout thread for this instance of fcip
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tid = fptr->fcip_timeout_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_timeout_id = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fcip_num_instances >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_num_instances--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stop sendup thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_sendup_thr_initted) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_thr_initted = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&fptr->fcip_sendup_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&fptr->fcip_sendup_cv,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr->fcip_sendup_head == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_head = fptr->fcip_sendup_tail = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dismantle taskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_tq) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte taskq_t *tq = fptr->fcip_tq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_tq = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte taskq_destroy(tq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_kstatp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kstat_delete(fptr->fcip_kstatp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_kstatp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* flush the routing table entries */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_flush(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_xmit_cache) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_destroy(fptr->fcip_xmit_cache);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_xmit_cache = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_sendup_cache) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_destroy(fptr->fcip_sendup_cache);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_sendup_cache = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_cleanup_dest(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* release unsolicited buffers */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_ub_tokens) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t *tokens = fptr->fcip_ub_tokens;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_tokens = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (phandle) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * release the global mutex here to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * permit any data pending callbacks to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * complete. Else we will deadlock in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCA waiting for all unsol buffers to be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_ubfree(phandle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_ub_nbufs, tokens);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(tokens, (sizeof (*tokens) * fcip_ub_nbufs));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fptr->fcip_ub_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fptr->fcip_sendup_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&fptr->fcip_farp_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&fptr->fcip_sendup_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&fptr->fcip_ub_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_soft_state_free(fcip_softp, instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now dequeue the fcip_port_info from the port list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cur_fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev_fport = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (cur_fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cur_fport == fport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev_fport = cur_fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cur_fport = cur_fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Assert that we found a port in our port list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cur_fport == fport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev_fport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Not the first port in the port list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev_fport->fcipp_next = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * first port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_head = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next_fport = fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fport, sizeof (fcip_port_info_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (next_fport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is called by transport for any ioctl operations performed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on the devctl or other transport minor nodes. It is currently
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unused for fcip
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_port_ioctl(opaque_t ulp_handle, opaque_t port_handle, dev_t dev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cmd, intptr_t data, int mode, cred_t *credp, int *rval,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t claimed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_UNCLAIMED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DL_INFO_REQ - returns information about the DLPI stream to the DLS user
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * requesting information about this interface
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_ireq(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dl_info_ack_t *dlip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipdladdr *dlap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *ep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char etherstr[ETHERSTRL];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = slp->sl_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "fcip_ireq: info request req rcvd"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_ireq, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip ireq entered"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (MBLKL(mp) < DL_INFO_REQ_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_INFO_REQ, DL_BADPRIM, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Exchange current message for a DL_INFO_ACK
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size = sizeof (dl_info_ack_t) + FCIPADDRL + ETHERADDRL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((mp = mexchange(wq, mp, size, M_PCPROTO, DL_INFO_ACK)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FILL in the DL_INFO_ACK fields and reply
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlip = (dl_info_ack_t *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *dlip = fcip_infoack;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlip->dl_current_state = slp->sl_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlap = (struct fcipdladdr *)(mp->b_rptr + dlip->dl_addr_offset);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlap->dl_sap = slp->sl_sap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ether_to_str(&fptr->fcip_macaddr, etherstr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "ireq - our mac: %s", etherstr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_bcopy(&fptr->fcip_macaddr, &dlap->dl_phys);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&dlap->dl_phys, ETHERADDRL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ep = (la_wwn_t *)(mp->b_rptr + dlip->dl_brdcst_addr_offset);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_bcopy(&fcip_arpbroadcast_addr, ep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "sending back info req.."));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte qreply(wq, mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * To handle DL_UNITDATA_REQ requests.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_udreq(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dl_unitdata_req_t *dludp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mblk_t *nmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipdladdr *dlap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcph_network_hdr_t *headerp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llc_snap_hdr_t *lsnap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t_uscalar_t off, len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t wwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hdr_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "inside fcip_udreq"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_udreq, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "fcip udreq entered"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_state != DL_IDLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_UNITDATA_REQ, DL_OUTSTATE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = slp->sl_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_UNITDATA_REQ, DL_OUTSTATE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dludp = (dl_unitdata_req_t *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte off = dludp->dl_dest_addr_offset;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = dludp->dl_dest_addr_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Validate destination address format
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!MBLKIN(mp, off, len) || (len != FCIPADDRL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dluderrorind(wq, mp, (mp->b_rptr + off), len, DL_BADADDR, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Error if no M_DATA follows
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nmp = mp->b_cont;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nmp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dluderrorind(wq, mp, (mp->b_rptr + off), len, DL_BADDATA, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlap = (struct fcipdladdr *)(mp->b_rptr + off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now get the destination structure for the remote NPORT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&dlap->dl_phys, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_get_dest(fptr, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "udreq - couldn't find dest struct for remote port");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dluderrorind(wq, mp, (mp->b_rptr + off), len, DL_BADDATA, 0));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Network header + SAP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr_size = sizeof (fcph_network_hdr_t) + sizeof (llc_snap_hdr_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* DB_REF gives the no. of msgs pointing to this block */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((DB_REF(nmp) == 1) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (MBLKHEAD(nmp) >= hdr_size) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (((uintptr_t)mp->b_rptr & 0x1) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t wwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nmp->b_rptr -= hdr_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* first put the network header */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte headerp = (fcph_network_hdr_t *)nmp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ether_cmp(&dlap->dl_phys, &fcip_arpbroadcast_addr) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&fcipnhbroadcastaddr, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&dlap->dl_phys, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&wwn, &headerp->net_dest_addr, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&fptr->fcip_macaddr, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&wwn, &headerp->net_src_addr, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now the snap header */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap = (llc_snap_hdr_t *)(nmp->b_rptr +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fcph_network_hdr_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->dsap = 0xAA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->ssap = 0xAA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->ctrl = 0x03;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->oui[0] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->oui[1] = 0x00; /* 80 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->oui[2] = 0x00; /* C2 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->pid = BE_16((dlap->dl_sap));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freeb(mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mp = nmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t wwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DB_TYPE(mp) = M_DATA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte headerp = (fcph_network_hdr_t *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only fill in the low 48bits of WWN for now - we can
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fill in the NAA_ID after we find the port in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routing tables
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ether_cmp(&dlap->dl_phys, &fcip_arpbroadcast_addr) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&fcipnhbroadcastaddr, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&dlap->dl_phys, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&wwn, &headerp->net_dest_addr, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* need to send our PWWN */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&fport->fcipp_pwwn, &headerp->net_src_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap = (llc_snap_hdr_t *)(nmp->b_rptr +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fcph_network_hdr_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->dsap = 0xAA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->ssap = 0xAA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->ctrl = 0x03;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->oui[0] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->oui[1] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->oui[2] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->pid = BE_16(dlap->dl_sap);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mp->b_wptr = mp->b_rptr + hdr_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Ethernet drivers have a lot of gunk here to put the Type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information (for Ethernet encapsulation (RFC 894) or the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Length (for 802.2/802.3) - I guess we'll just ignore that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Start the I/O on this port. If fcip_start failed for some reason
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we call putbq in fcip_start so we don't need to check the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return value from fcip_start
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_start(wq, mp, fptr, fdestp, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DL_ATTACH_REQ: attaches a PPA with a stream. ATTACH requets are needed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for style 2 DLS providers to identify the physical medium through which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the streams communication will happen
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_areq(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union DL_primitives *dlp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ppa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlp = (union DL_primitives *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (MBLKL(mp) < DL_ATTACH_REQ_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_ATTACH_REQ, DL_BADPRIM, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_state != DL_UNATTACHED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_ATTACH_REQ, DL_OUTSTATE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ppa = dlp->attach_req.dl_ppa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "attach req: ppa %x", ppa));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check if the PPA is valid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fport = fcip_port_head; fport; fport = fport->fcipp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fptr = fport->fcipp_fcip) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "ppa %x, inst %x", ppa,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(fptr->fcip_dip)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ppa == ddi_get_instance(fptr->fcip_dip)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "ppa found %x", ppa));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "dlerrorack coz fport==NULL"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_get_port_handle(ppa) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_ATTACH_REQ, DL_BADPPA, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wait for Port attach callback to trigger. If port_detach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * got in while we were waiting, then ddi_get_soft_state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will return NULL, and we'll return error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(drv_usectohz(FCIP_INIT_DELAY));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = ddi_get_soft_state(fcip_softp, ppa);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_ATTACH_REQ, DL_BADPPA, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set link to device and update our state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_fcip = fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_state = DL_UNBOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_flags & FCIP_LINK_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_WARN, "port not online yet"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlokack(wq, mp, DL_ATTACH_REQ);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DL_DETACH request - detaches a PPA from a stream
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_dreq(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (MBLKL(mp) < DL_DETACH_REQ_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_DETACH_REQ, DL_BADPRIM, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_state != DL_UNBOUND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_DETACH_REQ, DL_OUTSTATE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_dodetach(slp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlokack(wq, mp, DL_DETACH_REQ);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DL_BIND request: requests a DLS provider to bind a DLSAP to the stream.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DLS users communicate with a physical interface through DLSAPs. Multiple
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DLSAPs can be bound to the same stream (PPA)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_breq(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union DL_primitives *dlp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipdladdr fcipaddr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t_uscalar_t sap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int xidtest;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (MBLKL(mp) < DL_BIND_REQ_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_BIND_REQ, DL_BADPRIM, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_state != DL_UNBOUND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_BIND_REQ, DL_OUTSTATE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlp = (union DL_primitives *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = slp->sl_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_BIND_REQ, DL_OUTSTATE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sap = dlp->bind_req.dl_sap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "fcip_breq - sap: %x", sap));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xidtest = dlp->bind_req.dl_xidtest_flg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (xidtest) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_BIND_REQ, DL_NOAUTO, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "DLBIND: sap : %x", sap));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sap > ETHERTYPE_MAX) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, dlp->dl_primitive, DL_BADSAP, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * save SAP for this stream and change the link state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_sap = sap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_state = DL_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcipaddr.dl_sap = sap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_bcopy(&fptr->fcip_macaddr, &fcipaddr.dl_phys);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlbindack(wq, mp, sap, &fcipaddr, FCIPADDRL, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_setipq(fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DL_UNBIND request to unbind a previously bound DLSAP, from this stream
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_ubreq(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (MBLKL(mp) < DL_UNBIND_REQ_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_UNBIND_REQ, DL_BADPRIM, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (slp->sl_state != DL_IDLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_UNBIND_REQ, DL_OUTSTATE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_state = DL_UNBOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_sap = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) putnextctl1(RD(wq), M_FLUSH, FLUSHRW);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlokack(wq, mp, DL_UNBIND_REQ);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_setipq(slp->sl_fcip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return our physical address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_pareq(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union DL_primitives *dlp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct ether_addr addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (MBLKL(mp) < DL_PHYS_ADDR_REQ_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_BADPRIM, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlp = (union DL_primitives *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte type = dlp->physaddr_req.dl_addr_type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = slp->sl_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_OUTSTATE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (type) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_FACT_PHYS_ADDR:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "returning factory phys addr"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wwn_to_ether(&fport->fcipp_pwwn, &addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DL_CURR_PHYS_ADDR:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "returning current phys addr"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_bcopy(&fptr->fcip_macaddr, &addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "Not known cmd type in phys addr"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_NOTSUPPORTED, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlphysaddrack(wq, mp, &addr, ETHERADDRL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set physical address DLPI request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_spareq(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union DL_primitives *dlp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t_uscalar_t off, len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct ether_addr *addrp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t wwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ns_cmd_t fcip_ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (MBLKL(mp) < DL_SET_PHYS_ADDR_REQ_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlp = (union DL_primitives *)mp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = dlp->set_physaddr_req.dl_addr_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte off = dlp->set_physaddr_req.dl_addr_offset;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!MBLKIN(mp, off, len)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte addrp = (struct ether_addr *)(mp->b_rptr + off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the length of physical address is not correct or address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * specified is a broadcast address or multicast addr -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return an error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((len != ETHERADDRL) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((addrp->ether_addr_octet[0] & 01) == 1) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ether_cmp(addrp, &fcip_arpbroadcast_addr) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADADDR, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check if a stream is attached to this device. Else return an error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fptr = slp->sl_fcip) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_OUTSTATE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set the new interface local address. We request the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * layer to change the Port WWN for this device - return an error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if we don't succeed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(addrp, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_set_wwn(&wwn) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "WWN changed in spareq"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADADDR, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * register The new Port WWN and Node WWN with the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and Nameserver. Hope the transport ensures all current I/O
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * has stopped before actually attempting to register a new
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port and Node WWN else we are hosed. Maybe a Link reset
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will get everyone's attention.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ns_cmd.ns_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ns_cmd.ns_cmd = NS_RPN_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ns_cmd.ns_req_len = sizeof (la_wwn_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ns_cmd.ns_req_payload = (caddr_t)&wwn.raw_wwn[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ns_cmd.ns_resp_len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ns_cmd.ns_resp_payload = (caddr_t)0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_port_ns(fptr->fcip_port_info->fcipp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (opaque_t)0, &fcip_ns_cmd) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DLPI,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "setting Port WWN failed"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlokack(wq, mp, DL_SET_PHYS_ADDR_REQ);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * change our port's WWN if permitted by hardware
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_set_wwn(la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We're usually not allowed to change the WWN of adapters
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but some adapters do permit us to change the WWN - don't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * permit setting of WWNs (yet?) - This behavior could be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * modified if needed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine fills in the header for fastpath data requests. What this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * does in simple terms is, instead of sending all data through the Unitdata
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * request dlpi code paths (which will then append the protocol specific
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * header - network and snap headers in our case), the upper layers issue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a M_IOCTL with a DL_IOC_HDR_INFO request and ask the streams endpoint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * driver to give the header it needs appended and the upper layer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocates and fills in the header and calls our put routine
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_dl_ioc_hdr_info(queue_t *wq, mblk_t *mp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mblk_t *nmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipstr *slp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcipdladdr *dlap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dl_unitdata_req_t *dlup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcph_network_hdr_t *headerp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t wwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llc_snap_hdr_t *lsnap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t_uscalar_t off, len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t hdrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp = (struct fcipstr *)wq->q_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = slp->sl_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "dliochdr : returns EINVAL1"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte miocnak(wq, mp, 0, EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = miocpullup(mp, sizeof (dl_unitdata_req_t) + FCIPADDRL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (error != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "dliochdr : returns %d", error));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte miocnak(wq, mp, 0, error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check if the DL_UNITDATA_REQ destination addr has valid offset
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and length values
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlup = (dl_unitdata_req_t *)mp->b_cont->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte off = dlup->dl_dest_addr_offset;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = dlup->dl_dest_addr_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dlup->dl_primitive != DL_UNITDATA_REQ ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !MBLKIN(mp->b_cont, off, len) || (len != FCIPADDRL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "dliochdr : returns EINVAL2"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte miocnak(wq, mp, 0, EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlap = (struct fcipdladdr *)(mp->b_cont->b_rptr + off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate a new mblk to hold the ether header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * setup space for network header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdrlen = (sizeof (llc_snap_hdr_t) + sizeof (fcph_network_hdr_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((nmp = allocb(hdrlen, BPRI_MED)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "dliochdr : returns ENOMEM"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte miocnak(wq, mp, 0, ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nmp->b_wptr += hdrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fill in the Network Hdr and LLC SNAP header;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte headerp = (fcph_network_hdr_t *)nmp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just fill in the Node WWN here - we can fill in the NAA_ID when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we search the routing table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ether_cmp(&dlap->dl_phys, &fcip_arpbroadcast_addr) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&fcipnhbroadcastaddr, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&dlap->dl_phys, &wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&wwn, &headerp->net_dest_addr, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&fport->fcipp_pwwn, &headerp->net_src_addr, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap = (llc_snap_hdr_t *)(nmp->b_rptr + sizeof (fcph_network_hdr_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->dsap = 0xAA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->ssap = 0xAA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->ctrl = 0x03;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->oui[0] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->oui[1] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->oui[2] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsnap->pid = BE_16(dlap->dl_sap);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Link new mblk in after the "request" mblks.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte linkb(mp, nmp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slp->sl_flags |= FCIP_SLFAST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "dliochdr : returns success "));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte miocack(wq, mp, msgsize(mp->b_cont), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Establish a kmem cache for fcip packets
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_cache_constructor(void *buf, void *arg, int flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt = buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = (fcip_port_info_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*cb) (caddr_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb = (flags == KM_SLEEP) ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fport != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we allocated space for our private area at the end of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc packet. Make sure we point to it correctly. Ideally we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * should just push fc_packet_private to the beginning or end
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the fc_packet structure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dest = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_state = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_reason = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_fptr = fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dma_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_ulp_rscn_infop = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We use pkt_cmd_dma for OUTBOUND requests. We don't expect
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * any responses for outbound IP data so no need to setup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * response or data dma handles.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_dma_alloc_handle(fport->fcipp_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fport->fcipp_cmd_dma_attr, cb, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fc_pkt->pkt_cmd_dma) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCIP_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmd_acc = fc_pkt->pkt_resp_acc = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_fca_private = (opaque_t)((caddr_t)buf +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fcip_pkt_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_ulp_private = (opaque_t)fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmd_cookie_cnt = fc_pkt->pkt_resp_cookie_cnt =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_data_cookie_cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmd_cookie = fc_pkt->pkt_resp_cookie =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_data_cookie = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCIP_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * destroy the fcip kmem cache
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_cache_destructor(void *buf, void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt = (fcip_pkt_t *)buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = (fcip_port_info_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fport != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fport->fcipp_fcip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr == fcip_pkt->fcip_pkt_fptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_cmd_dma) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_free_handle(&fc_pkt->pkt_cmd_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fcip destination structure is hashed on Node WWN assuming
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a NAA_ID of 0x1 (IEEE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fcip_dest *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_get_dest(struct fcip *fptr, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hash_bucket;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opaque_t pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t twwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *twwnp = (uint32_t *)&twwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hash_bucket = FCIP_DEST_HASH(pwwn->raw_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "get dest hashbucket : 0x%x", hash_bucket));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn->raw_wwn[2], pwwn->raw_wwn[3], pwwn->raw_wwn[4],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn->raw_wwn[5], pwwn->raw_wwn[6], pwwn->raw_wwn[7]));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(hash_bucket < FCIP_DEST_HASH_ELEMS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_check_port_exists(fptr)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fptr is stale, return fdestp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * First check if we have active I/Os going on with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * destination port (an entry would exist in fcip_dest hash table)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fptr->fcip_dest[hash_bucket];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fdestp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp->fcipd_rtable) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_wwn_compare(pwwn, &fdestp->fcipd_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_COMPARE_NWWN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "found fdestp"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fdestp->fcipd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We did not find the destination port information in our
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * active port list so search for an entry in our routing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, pwwn, FCIP_COMPARE_NWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp == NULL || (frp && (!FCIP_RTE_UNAVAIL(frp->fcipr_state)) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state != PORT_DEVICE_LOGGED_IN) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (frp && frp->fcipr_pd == NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No entry for the destination port in our routing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * table too. First query the transport to see if it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * already has structures for the destination port in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * its hash tables. This must be done for all topologies
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * since we could have retired entries in the hash tables
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which may have to be re-added without a statechange
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * callback happening. Its better to try and get an entry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for the destination port rather than simply failing a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * request though it may be an overkill in private loop
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * topologies.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If a entry for the remote port exists in the transport's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hash tables, we are fine and can add the entry to our
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routing and dest hash lists, Else for fabric configs we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * query the nameserver if one exists or issue FARP ELS.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need to do a PortName based Nameserver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * query operation. So get the right PortWWN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for the adapter.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(pwwn, &twwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try IEEE Name (Format 1) first, this is the default and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Emulex uses this format.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fc_ulp_get_remote_port(fport->fcipp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &twwn, &rval, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If IEEE Name (Format 1) query failed, try IEEE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Extended Name (Format 2) which Qlogic uses.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * And try port 1 on Qlogic FC-HBA first.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: On x86, we need to byte swap the 32-bit
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * word first, after the modification, swap it back.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *twwnp = BE_32(*twwnp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte twwn.w.nport_id = QLC_PORT_1_ID_BITS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte twwn.w.naa_id = QLC_PORT_NAA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *twwnp = BE_32(*twwnp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fc_ulp_get_remote_port(fport->fcipp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &twwn, &rval, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If still failed, try port 2 on Qlogic FC-HBA. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *twwnp = BE_32(*twwnp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte twwn.w.nport_id = QLC_PORT_2_ID_BITS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *twwnp = BE_32(*twwnp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fc_ulp_get_remote_port(fport->fcipp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &twwn, &rval, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add the newly found destination structure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to our routing table. Create a map with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the device we found. We could ask the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * transport to give us the list of all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices connected to our port but we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * probably don't need to know all the devices
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so let us just constuct a list with only
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one device instead.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_copy_portmap(&map, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, &map, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_COMPARE_NWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_add_dest(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (fcip_farp_supported &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FC_TOP_EXTERNAL(fport->fcipp_topology) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fport->fcipp_topology == FC_TOP_PT_PT))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The Name server request failed so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * issue an FARP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_do_farp(fptr, pwwn, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (frp && frp->fcipr_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prepare a dest structure to return to caller
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_add_dest(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "in fcip get dest non fabric"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Endian clean WWN compare.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if they compare OK, else return non zero value.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flag can be bitwise OR of FCIP_COMPARE_NWWN, FCIP_COMPARE_PWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCIP_COMPARE_BROADCAST.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_wwn_compare(la_wwn_t *wwn1, la_wwn_t *wwn2, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((wwn1->raw_wwn[2] != wwn2->raw_wwn[2]) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (wwn1->raw_wwn[3] != wwn2->raw_wwn[3]) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (wwn1->raw_wwn[4] != wwn2->raw_wwn[4]) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (wwn1->raw_wwn[5] != wwn2->raw_wwn[5]) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (wwn1->raw_wwn[6] != wwn2->raw_wwn[6]) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (wwn1->raw_wwn[7] != wwn2->raw_wwn[7])) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((flag == FCIP_COMPARE_PWWN) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (((wwn1->raw_wwn[0] & 0xf0) != (wwn2->raw_wwn[0] & 0xf0)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (wwn1->raw_wwn[1] != wwn2->raw_wwn[1]))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add an entry for a remote port in the dest hash table. Dest hash table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * has entries for ports in the routing hash table with which we decide
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to establish IP communication with. The no. of entries in the dest hash
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * table must always be less than or equal to the entries in the routing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hash table. Every entry in the dest hash table ofcourse must have a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * corresponding entry in the routing hash table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fcip_dest *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_add_dest(struct fcip *fptr, struct fcip_routing_table *frp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hash_bucket;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdest_new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = &frp->fcipr_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hash_bucket = FCIP_DEST_HASH(pwwn->raw_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "add dest hash_bucket: 0x%x", hash_bucket));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(hash_bucket < FCIP_DEST_HASH_ELEMS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fptr->fcip_dest[hash_bucket];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fdestp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp->fcipd_rtable) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_wwn_compare(pwwn, &fdestp->fcipd_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_COMPARE_PWWN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fdestp->fcipd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fdestp == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdest_new = (struct fcip_dest *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(sizeof (struct fcip_dest), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fdest_new->fcipd_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdest_new->fcipd_next = fptr->fcip_dest[hash_bucket];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdest_new->fcipd_refcnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdest_new->fcipd_rtable = frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdest_new->fcipd_ncmds = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_dest[hash_bucket] = fdest_new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdest_new->fcipd_flags = FCIP_PORT_NOTLOGGED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdest_new);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Cleanup the dest hash table and remove all entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_cleanup_dest(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdest_delp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < FCIP_DEST_HASH_ELEMS; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fptr->fcip_dest[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fdestp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdest_delp = fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fdestp->fcipd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fdest_delp, sizeof (struct fcip_dest));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_dest[i] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send FARP requests for Fabric ports when we don't have the port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we wish to talk to in our routing hash table. FARP is specially required
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to talk to FC switches for inband switch management. Most FC switches
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * today have a switch FC IP address for IP over FC inband switch management
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but the WWN and Port_ID for this traffic is not available through the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Nameservers since the switch themeselves are transparent.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fcip_dest *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_do_farp(struct fcip *fptr, la_wwn_t *pwwn, char *ip_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t ip_addr_len, int flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_farp_t farp_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_farp_t *fcmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t farp_lbolt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t broadcast_wwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *bdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bdestp = fcip_get_dest(fptr, &broadcast_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bdestp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = fcip_ipkt_alloc(fptr, sizeof (la_els_farp_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_farp_t), bdestp->fcipd_pd, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&fcip_arpbroadcast_addr, &broadcast_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&bdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bdestp->fcipd_rtable == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&bdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ipkt_free(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dest = bdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_fca_device = bdestp->fcipd_fca_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bdestp->fcipd_ncmds++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&bdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_init_broadcast_pkt(fcip_pkt, NULL, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags |= FCIP_PKT_IN_LIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now initialize the FARP payload itself
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd = &farp_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->ls_code.ls_code = LA_ELS_FARP_REQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for now just match the Port WWN since the other match addr
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * code points are optional. We can explore matching the IP address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if needed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ip_addr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->match_addr = FARP_MATCH_WW_PN_IPv4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->match_addr = FARP_MATCH_WW_PN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Request the responder port to log into us - that way
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the Transport is aware of the remote port when we create
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * an entry for it in our tables
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->resp_flags = FARP_INIT_REPLY | FARP_INIT_P_LOGI;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->req_id = fport->fcipp_sid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcmd->dest_id.port_id = fc_pkt->pkt_cmd_fhdr.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&fport->fcipp_pwwn, &fcmd->req_pwwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&fport->fcipp_nwwn, &fcmd->req_nwwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(pwwn, &fcmd->resp_pwwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copy in source IP address if we get to know it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ip_addr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(ip_addr, fcmd->resp_ip, ip_addr_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmdlen = sizeof (la_els_farp_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_rsplen = sizeof (la_els_farp_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_ulp_private = (opaque_t)fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Endian safe copy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_CP_OUT(fcmd, fc_pkt->pkt_cmd, fc_pkt->pkt_cmd_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_farp_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * send the packet in polled mode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fc_ulp_issue_els(fport->fcipp_handle, fc_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip_transport of farp pkt failed 0x%x", rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_LIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ipkt_free(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&bdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bdestp->fcipd_ncmds--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&bdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte farp_lbolt = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte farp_lbolt += drv_usectohz(FCIP_FARP_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_farp_rsp_flag = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (!fptr->fcip_farp_rsp_flag) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cv_timedwait(&fptr->fcip_farp_cv, &fptr->fcip_mutex,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte farp_lbolt) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No FARP response from any destination port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so bail out.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_farp_rsp_flag = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We received a FARP response - check to see if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * response was in reply to our FARP request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, pwwn, FCIP_COMPARE_NWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((frp != NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !FCIP_RTE_UNAVAIL(frp->fcipr_state)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_get_dest(fptr, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Not our FARP response so go back and wait
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * again till FARP_TIMEOUT expires
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_farp_rsp_flag = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags |= FCIP_PKT_IN_LIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ipkt_free(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&bdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bdestp->fcipd_ncmds--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&bdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fdestp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Helper routine to PLOGI to a remote port we wish to talk to.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This may not be required since the port driver does logins anyway,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but this can be required in fabric cases since FARP requests/responses
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't require you to be logged in?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_do_plogi(struct fcip *fptr, struct fcip_routing_table *frp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_logi_t logi;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_frame_hdr_t *fr_hdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Don't bother to login for broadcast RTE entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((frp->fcipr_d_id.port_id == 0x0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (frp->fcipr_d_id.port_id == 0xffffff)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We shouldn't pound in too many logins here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp->fcipr_state == FCIP_RT_LOGIN_PROGRESS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = fcip_ipkt_alloc(fptr, sizeof (la_els_logi_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_logi_t), frp->fcipr_pd, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update back pointer for login state update
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_frp = frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = FCIP_RT_LOGIN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize frame header for ELS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr = &fc_pkt->pkt_cmd_fhdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->r_ctl = R_CTL_ELS_REQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->type = FC_TYPE_EXTENDED_LS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->df_ctl = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->s_id = fport->fcipp_sid.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->d_id = frp->fcipr_d_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->seq_cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->ox_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->rx_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->ro = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_rsplen = sizeof (la_els_logi_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_comp = fcip_ipkt_callback;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_timeout = 10; /* 10 seconds */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_ttl = fptr->fcip_timeout_ticks + fc_pkt->pkt_timeout;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_ulp_private = (opaque_t)fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Everybody does class 3, so let's just set it. If the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * knows better, it will deal with the class appropriately.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_flags = FC_TRAN_INTR | FC_TRAN_CLASS3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we need only fill in the ls_code and the cmd frame header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((void *)&logi, sizeof (la_els_logi_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logi.ls_code.ls_code = LA_ELS_PLOGI;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logi.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_CP_OUT((uint8_t *)&logi, fc_pkt->pkt_cmd, fc_pkt->pkt_cmd_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_logi_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fc_ulp_login(fport->fcipp_handle, &fc_pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!fc_ulp_login failed for d_id: 0x%x, rval: 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_d_id.port_id, rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ipkt_free(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The packet callback routine - called from the transport/FCA after
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it is done DMA'ing/sending out the packet contents on the wire so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that the alloc'ed packet can be freed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_ipkt_callback(fc_packet_t *fc_pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t logi_req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t logi_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_frame_hdr_t *fr_hdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr = &fc_pkt->pkt_cmd_fhdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_CP_IN(fc_pkt->pkt_resp, (uint8_t *)&logi_resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_resp_acc, sizeof (logi_resp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_CP_IN(fc_pkt->pkt_cmd, (uint8_t *)&logi_req, fc_pkt->pkt_cmd_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (logi_req));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = (fcip_pkt_t *)fc_pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_pkt->fcip_pkt_frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fcip_pkt->fcip_pkt_fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(logi_req.ls_code == LA_ELS_PLOGI);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_state != FC_PKT_SUCCESS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logi_resp.ls_code != LA_ELS_ACC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* EMPTY */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "opcode : 0x%x to d_id: 0x%x failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logi_req.ls_code, fr_hdr->d_id));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_invalid_timeout = fptr->fcip_timeout_ticks +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FCIP_RTE_TIMEOUT / 2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portid_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id.port_id = fr_hdr->d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update PLOGI results; FCA Handle, and Port device handles
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_pd = fc_pkt->pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_fca_dev =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_get_fca_device(fport->fcipp_handle, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp->fcipr_state = PORT_DEVICE_LOGGED_IN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ipkt_free(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pkt_alloc routine for outbound IP datagrams. The cache constructor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only initializes the pkt_cmd_dma (which is where the outbound datagram
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is stuffed) since we don't expect response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fcip_pkt_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_pkt_alloc(struct fcip *fptr, mblk_t *bp, int flags, int datalen)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_cookie_t pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_cookie_t *cp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = kmem_cache_alloc(fptr->fcip_xmit_cache, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip_pkt_alloc: kmem_cache_alloc failed"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_fcpktp = fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dma_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the cache constructor has allocated the dma handle
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmd = (caddr_t)bp->b_rptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_dma_addr_bind_handle(fc_pkt->pkt_cmd_dma, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)bp->b_rptr, datalen, DDI_DMA_WRITE | DDI_DMA_CONSISTENT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DMA_DONTWAIT, NULL, &pkt_cookie,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fc_pkt->pkt_cmd_cookie_cnt) != DDI_DMA_MAPPED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dma_flags |= FCIP_CMD_DMA_BOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_cmd_cookie_cnt >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_cmd_dma_attr.dma_attr_sgllen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fc_pkt->pkt_cmd_cookie_cnt != 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp = fc_pkt->pkt_cmd_cookie = (ddi_dma_cookie_t *)kmem_alloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 1; cnt < fc_pkt->pkt_cmd_cookie_cnt; cnt++, cp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_nextcookie(fc_pkt->pkt_cmd_dma, &pkt_cookie);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmdlen = datalen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_mp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_wq = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dest = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_state = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_reason = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_frp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefail:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_free(fcip_pkt, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return ((fcip_pkt_t *)0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free a packet and all its associated resources
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_pkt_free(struct fcip_pkt *fcip_pkt, int free_mblk)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = fcip_pkt->fcip_pkt_fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_cmd_cookie != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fc_pkt->pkt_cmd_cookie, fc_pkt->pkt_cmd_cookie_cnt *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ddi_dma_cookie_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmd_cookie = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_free_pkt_dma(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (free_mblk && fcip_pkt->fcip_pkt_mp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freemsg(fcip_pkt->fcip_pkt_mp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_mp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_uninit_packet(fptr->fcip_port_info->fcipp_handle, fc_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_free(fptr->fcip_xmit_cache, (void *)fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate a Packet for internal driver use. This is for requests
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that originate from within the driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fcip_pkt_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_ipkt_alloc(struct fcip *fptr, int cmdlen, int resplen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opaque_t pd, int flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*cb)(caddr_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t real_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint_t held_here = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_cookie_t pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_cookie_t *cp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb = (flags == KM_SLEEP) ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = kmem_zalloc((sizeof (fcip_pkt_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_fca_pkt_size), flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_WARN, "pkt alloc of ineternal pkt failed"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags = FCIP_PKT_INTERNAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_fptr = fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_fcpktp = fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmdlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_datalen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_fca_private = (opaque_t)((caddr_t)fcip_pkt +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fcip_pkt_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_ulp_private = (opaque_t)fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmdlen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_dma_alloc_handle(fptr->fcip_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fport->fcipp_cmd_dma_attr, cb, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fc_pkt->pkt_cmd_dma) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_dma_mem_alloc(fc_pkt->pkt_cmd_dma, cmdlen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fport->fcipp_fca_acc_attr, DDI_DMA_CONSISTENT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb, NULL, (caddr_t *)&fc_pkt->pkt_cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &real_len, &fc_pkt->pkt_cmd_acc) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dma_flags |= FCIP_CMD_DMA_MEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmdlen = cmdlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (real_len < cmdlen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_dma_addr_bind_handle(fc_pkt->pkt_cmd_dma, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)fc_pkt->pkt_cmd, real_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DMA_WRITE | DDI_DMA_CONSISTENT, cb, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pkt_cookie, &fc_pkt->pkt_cmd_cookie_cnt) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DMA_MAPPED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dma_flags |= FCIP_CMD_DMA_BOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_cmd_cookie_cnt >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_cmd_dma_attr.dma_attr_sgllen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fc_pkt->pkt_cmd_cookie_cnt != 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp = fc_pkt->pkt_cmd_cookie = (ddi_dma_cookie_t *)kmem_alloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 1; cnt < fc_pkt->pkt_cmd_cookie_cnt; cnt++, cp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_nextcookie(fc_pkt->pkt_cmd_dma, &pkt_cookie);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (resplen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_dma_alloc_handle(fptr->fcip_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fport->fcipp_resp_dma_attr, cb, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fc_pkt->pkt_resp_dma) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_dma_mem_alloc(fc_pkt->pkt_resp_dma, resplen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fport->fcipp_fca_acc_attr, DDI_DMA_CONSISTENT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb, NULL, (caddr_t *)&fc_pkt->pkt_resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &real_len, &fc_pkt->pkt_resp_acc) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dma_flags |= FCIP_RESP_DMA_MEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (real_len < resplen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_dma_addr_bind_handle(fc_pkt->pkt_resp_dma, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)fc_pkt->pkt_resp, real_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DMA_WRITE | DDI_DMA_CONSISTENT, cb, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pkt_cookie, &fc_pkt->pkt_resp_cookie_cnt) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DMA_MAPPED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dma_flags |= FCIP_RESP_DMA_BOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_rsplen = resplen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_resp_cookie_cnt >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport->fcipp_resp_dma_attr.dma_attr_sgllen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fc_pkt->pkt_resp_cookie_cnt != 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp = fc_pkt->pkt_resp_cookie = (ddi_dma_cookie_t *)kmem_alloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_resp_cookie_cnt * sizeof (pkt_cookie),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 1; cnt < fc_pkt->pkt_resp_cookie_cnt; cnt++, cp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_nextcookie(fc_pkt->pkt_resp_dma, &pkt_cookie);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize pkt_pd prior to calling fc_ulp_init_packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Ask the FCA to bless the internal packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_init_packet((opaque_t)fport->fcipp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt, flags) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Keep track of # of ipkts alloc-ed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function can get called with mutex either held or not. So, we'll
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * grab mutex if it is not already held by this thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This has to be cleaned up someday.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!MUTEX_HELD(&fptr->fcip_mutex)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte held_here = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_num_ipkts_pending++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (held_here)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefail:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_ipkt_free(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free up an internal IP packet (like a FARP pkt etc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_ipkt_free(fcip_pkt_t *fcip_pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = fcip_pkt->fcip_pkt_fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fptr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!mutex_owned(&fptr->fcip_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* One less ipkt to wait for */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_num_ipkts_pending) /* Safety check */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_num_ipkts_pending--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_cmd_cookie != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fc_pkt->pkt_cmd_cookie, fc_pkt->pkt_cmd_cookie_cnt *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ddi_dma_cookie_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_cmd_cookie = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_resp_cookie != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fc_pkt->pkt_resp_cookie, fc_pkt->pkt_resp_cookie_cnt *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ddi_dma_cookie_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_resp_cookie = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_uninit_packet(fport->fcipp_handle, fc_pkt) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fc_ulp_uninit_pkt failed for internal fc pkt 0x%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fc_pkt));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_free_pkt_dma(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fcip_pkt, (sizeof (fcip_pkt_t) + fport->fcipp_fca_pkt_size));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * initialize a unicast request. This is a misnomer because even the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * broadcast requests are initialized with this routine
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_init_unicast_pkt(fcip_pkt_t *fcip_pkt, fc_portid_t sid, fc_portid_t did,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void (*comp) ())
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_frame_hdr_t *fr_hdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = fcip_pkt->fcip_pkt_fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr = &fc_pkt->pkt_cmd_fhdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->r_ctl = R_CTL_DEVICE_DATA | R_CTL_UNSOL_DATA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->s_id = sid.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->d_id = did.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->type = FC_TYPE_IS8802_SNAP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->f_ctl = F_CTL_FIRST_SEQ | F_CTL_LAST_SEQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->df_ctl = DF_CTL_NET_HDR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->seq_cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->ox_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->rx_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->ro = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reset all the length fields
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_datalen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_comp = comp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (comp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_flags |= FC_TRAN_INTR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_flags |= FC_TRAN_NO_INTR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_type = FC_PKT_OUTBOUND | FC_PKT_IP_WRITE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_timeout = fcip_pkt_ttl_ticks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_ttl = fptr->fcip_timeout_ticks + fc_pkt->pkt_timeout;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize a fcip_packet for broadcast data transfers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_init_broadcast_pkt(fcip_pkt_t *fcip_pkt, void (*comp) (), int is_els)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_frame_hdr_t *fr_hdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = fcip_pkt->fcip_pkt_fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t sid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_1((fcip_init_broadcast_pkt, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr = &fc_pkt->pkt_cmd_fhdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sid = fport->fcipp_sid.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (is_els) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->r_ctl = R_CTL_ELS_REQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->r_ctl = R_CTL_DEVICE_DATA | R_CTL_UNSOL_DATA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->s_id = sid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The destination broadcast address depends on the topology
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the underlying port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = fptr->fcip_broadcast_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mark pkt a broadcast pkt
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_type = FC_PKT_BROADCAST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->d_id = did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->type = FC_TYPE_IS8802_SNAP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->f_ctl = F_CTL_FIRST_SEQ | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->f_ctl &= ~(F_CTL_SEQ_INITIATIVE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->df_ctl = DF_CTL_NET_HDR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->seq_cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->ox_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->rx_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fr_hdr->ro = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_comp = comp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (comp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_flags |= FC_TRAN_INTR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_flags |= FC_TRAN_NO_INTR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_tran_type = FC_PKT_BROADCAST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt->pkt_timeout = fcip_pkt_ttl_ticks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_ttl = fptr->fcip_timeout_ticks + fc_pkt->pkt_timeout;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free up all DMA resources associated with an allocated packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_free_pkt_dma(fcip_pkt_t *fcip_pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "in freepktdma : flags 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_dma_flags));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_dma_flags & FCIP_CMD_DMA_BOUND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_dma_unbind_handle(fc_pkt->pkt_cmd_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_dma_flags & FCIP_CMD_DMA_MEM) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_mem_free(&fc_pkt->pkt_cmd_acc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_dma_flags & FCIP_RESP_DMA_BOUND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_dma_unbind_handle(fc_pkt->pkt_resp_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_dma_flags & FCIP_RESP_DMA_MEM) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_mem_free(&fc_pkt->pkt_resp_acc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for internal commands, we need to free up the dma handles too.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is done in the cache destructor for non internal cmds
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_flags & FCIP_PKT_INTERNAL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_cmd_dma) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_free_handle(&fc_pkt->pkt_cmd_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_pkt->pkt_resp_dma) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_free_handle(&fc_pkt->pkt_resp_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * helper routine to generate a string, given an ether addr
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_ether_to_str(struct ether_addr *e, caddr_t s)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < sizeof (struct ether_addr); i++, s += 2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_MISC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_CONT, "0x%02X:", e->ether_addr_octet[i]));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(s, "%02X", e->ether_addr_octet[i]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *s = '\0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When a broadcast request comes from the upper streams modules, it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is ugly to look into every datagram to figure out if it is a broadcast
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * datagram or a unicast packet. Instead just add the broadcast entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * into our routing and dest tables and the standard hash table look ups
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will find the entries. It is a lot cleaner this way. Also Solaris ifconfig
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * seems to be very ethernet specific and it requires broadcasts to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ether broadcast addr of 0xffffffffff to succeed even though we specified
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the dl_info request that our broadcast MAC addr is 0x0000000000
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (can't figure out why RFC2625 did this though). So add broadcast entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for both MAC address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_dest_add_broadcast_entry(struct fcip *fptr, int new_flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t broadcast_wwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get port_id of destination for broadcast - this is topology
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dependent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = fptr->fcip_broadcast_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&fcip_arpbroadcast_addr, &broadcast_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&broadcast_wwn, (void *)&map.map_pwwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&broadcast_wwn, (void *)&map.map_nwwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_did.port_id = did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_hard_addr.hard_addr = did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new_flag) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_type = PORT_DEVICE_NEW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_type = PORT_DEVICE_CHANGED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map.map_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&map.map_fc4_types, sizeof (map.map_fc4_types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, &map, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, &broadcast_wwn, FCIP_COMPARE_NWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_add_dest(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The Upper IP layers expect the traditional broadcast MAC addr
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of 0xff ff ff ff ff ff to work too if we want to plumb the fcip
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stream through the /etc/hostname.fcipXX file. Instead of checking
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * each phys addr for a match with fcip's ARP header broadcast
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * addr (0x00 00 00 00 00 00), its simply easier to add another
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * broadcast entry for 0xff ff ff ff ff ff.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ether_to_wwn(&fcipnhbroadcastaddr, &broadcast_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&broadcast_wwn, (void *)&map.map_pwwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)&broadcast_wwn, (void *)&map.map_nwwn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rt_update(fptr, &map, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fcip_lookup_rtable(fptr, &broadcast_wwn, FCIP_COMPARE_NWWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fcip_add_dest(fptr, frp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need to obtain the D_ID of the broadcast port for transmitting all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * our broadcast (and multicast) requests. The broadcast D_ID as we know
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is dependent on the link topology
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_get_broadcast_did(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t did = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t sid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_get_broadcast_did, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "enter",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, fptr, fptr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sid = fport->fcipp_sid.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (fport->fcipp_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PT_PT: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *port_map = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_getportmap(fport->fcipp_handle, &port_map,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &listlen, FC_ULP_PLOGI_DONTCARE) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip_gpmap: listlen : 0x%x", listlen));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listlen == 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = port_map->map_did.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port_map) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port_map, listlen * sizeof (fc_portmap_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listlen != 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Dummy return value */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0x00FFFFFF);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_NO_NS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The broadcast address is the same whether or not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the switch/fabric contains a Name service.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = 0x00FFFFFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The open replicate primitive must not be used. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * broadcast sequence is simply sent to ALPA 0x00. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fabric controller then propagates the broadcast to all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * other ports. The fabric propagates the broadcast by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * using the OPNfr primitive.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The source port for broadcast in private loop mode
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * must send an OPN(fr) signal forcing all ports in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * loop to replicate the frames that they receive.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = 0x00FFFFFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_UNKNOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did = sid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip(0x%x):unknown topology in init_broadcast_pkt",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_instance));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_get_broadcast_did, "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg, "return",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_opaque, did, did));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (did);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip timeout performs 2 operations:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1. timeout any packets sent to the FCA for which a callback hasn't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * happened. If you are wondering why we need a callback since all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * traffic in FCIP is unidirectional, hence all exchanges are unidirectional
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but wait, we can only free up the resources after we know the FCA has
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DMA'ed out the data. pretty obvious eh :)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 2. Retire and routing table entries we marked up for retiring. This is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to give the link a chance to recover instead of marking a port down
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when we have lost all communication with it after a link transition
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_timeout(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = (struct fcip *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frtp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int dispatch_rte_removal = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_IN_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_timeout_ticks += fcip_tick_incr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_flags & (FCIP_DETACHED | FCIP_DETACHING | \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_SUSPENDED | FCIP_POWER_DOWN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_IN_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_port_state == FCIP_PORT_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_timeout_ticks > fptr->fcip_mark_offline) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_LINK_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fptr->fcip_flags & FCIP_RTE_REMOVING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dispatch_rte_removal = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if we have any Invalid routing table entries in our
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hashtable we have marked off for deferred removal. If any,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we can spawn a taskq thread to do the cleanup for us. We
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * need to avoid cleanup in the timeout thread since we may
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have to wait for outstanding commands to complete before
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we retire a routing table entry. Also dispatch the taskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * thread only if we are already do not have a taskq thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dispatched.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dispatch_rte_removal) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = fptr->fcip_rtable[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (frtp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((frtp->fcipr_state == FCIP_RT_INVALID) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fptr->fcip_timeout_ticks >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp->fcipr_invalid_timeout)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we cannot schedule a task thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * let us attempt again on the next
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tick rather than call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_rte_remove_deferred() from here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * directly since the routine can sleep.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp->fcipr_state = FCIP_RT_RETIRED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags |= FCIP_RTE_REMOVING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (taskq_dispatch(fptr->fcip_tq,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_rte_remove_deferred, fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * failed - so mark the entry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as invalid again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp->fcipr_state =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_RT_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~FCIP_RTE_REMOVING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = frtp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now timeout any packets stuck with the transport/FCA for too long
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < FCIP_DEST_HASH_ELEMS; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fptr->fcip_dest[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fdestp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fcip_pkt = fdestp->fcipd_head; fcip_pkt != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = fcip_pkt->fcip_pkt_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_flags &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FCIP_PKT_RETURNED | FCIP_PKT_IN_TIMEOUT |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_PKT_IN_ABORT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fptr->fcip_timeout_ticks >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_ttl) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags |=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_PKT_IN_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (taskq_dispatch(fptr->fcip_tq,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_timeout, fcip_pkt,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * timeout immediately
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_timeout(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The linked list is altered because
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of one of the following reasons:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a. Timeout code dequeued a pkt
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * b. Pkt completion happened
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So restart the spin starting at
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the head again; This is a bit
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * excessive, but okay since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcip_timeout_ticks isn't incremented
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for this spin, we will skip the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not-to-be-timedout packets quickly
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt = fdestp->fcipd_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fdestp->fcipd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reschedule the timeout thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_timeout_id = timeout(fcip_timeout, fptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(1000000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~(FCIP_IN_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine is either called from taskq or directly from fcip_timeout
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * does the actual job of aborting the packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_pkt_timeout(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_t *fcip_pkt = (fcip_pkt_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *fc_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fcip_pkt->fcip_pkt_dest;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr = fcip_pkt->fcip_pkt_fptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * try to abort the pkt
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags |= FCIP_PKT_IN_ABORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fc_ulp_abort(fport->fcipp_handle, fc_pkt, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (CE_NOTE, "fc_ulp_abort returns: 0x%x", rval));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fdestp != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dequeue the pkt from the dest structure pkt list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_ABORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fcip_fdestp_dequeue_pkt(fdestp, fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(rval == 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now cleanup the pkt and free the mblk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_free(fcip_pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * abort failed - just mark the pkt as done and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait for it to complete in fcip_pkt_callback since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the pkt has already been xmitted by the FCA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_pkt->fcip_pkt_flags & FCIP_PKT_RETURNED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_ABORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fcip_fdestp_dequeue_pkt(fdestp, fcip_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(rval == 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_pkt_free(fcip_pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove a routing table entry marked for deferred removal. This routine
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unlike fcip_pkt_timeout, is always called from a taskq context
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_rte_remove_deferred(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip *fptr = (struct fcip *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hash_bucket;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frtp, *frtp_next, *frtp_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = fptr->fcip_rtable[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp_prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (frtp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp_next = frtp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frtp->fcipr_state == FCIP_RT_RETIRED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = &frtp->fcipr_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get hold of destination pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hash_bucket = FCIP_DEST_HASH(pwwn->raw_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(hash_bucket < FCIP_DEST_HASH_ELEMS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fptr->fcip_dest[hash_bucket];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fdestp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp->fcipd_rtable) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcip_wwn_compare(pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fdestp->fcipd_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_COMPARE_PWWN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fdestp->fcipd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_dest_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp_prev = frtp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = frtp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp->fcipd_ncmds) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Instead of waiting to drain commands
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * let us revisit this RT entry in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the next pass.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp_prev = frtp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = frtp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We are clean, so remove the RTE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp->fcipd_rtable = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCIP_TNF_PROBE_2((fcip_rte_remove_deferred,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcip io", /* CSTYLED */,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_string, msg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "remove retired routing entry",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnf_int, index, index));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frtp_prev == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* first element */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_rtable[index] =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp_prev->fcipr_next =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(frtp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct fcip_routing_table));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = frtp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp_prev = frtp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frtp = frtp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_rt_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Clear the RTE_REMOVING flag
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fptr->fcip_flags &= ~FCIP_RTE_REMOVING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fptr->fcip_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Walk through all the dest hash table entries and count up the total
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no. of packets outstanding against a given port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_port_get_num_pkts(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int num_cmds = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_dest *fdestp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&fptr->fcip_dest_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < FCIP_DEST_HASH_ELEMS; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fptr->fcip_dest[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fdestp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fdestp->fcipd_ncmds >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdestp->fcipd_ncmds > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_cmds += fdestp->fcipd_ncmds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fdestp->fcipd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdestp = fdestp->fcipd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (num_cmds);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Walk through the routing table for this state instance and see if there is a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGI in progress for any of the entries. Return success even if we find one.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_plogi_in_progress(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_routing_table *frp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&fptr->fcip_rt_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < FCIP_RT_HASH_ELEMS; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = fptr->fcip_rtable[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (frp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (frp->fcipr_state == FCIP_RT_LOGIN_PROGRESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Found an entry where PLOGI is in progress */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frp = frp->fcipr_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Walk through the fcip port global list and check if the given port exists in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the list. Returns "0" if port exists and "1" if otherwise.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_check_port_exists(struct fcip *fptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *cur_fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fport = fptr->fcip_port_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cur_fport = fcip_port_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (cur_fport != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cur_fport == fport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Found */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cur_fport = cur_fport->fcipp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fcip_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Constructor to initialize the sendup elements for callback into
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * modules upstream
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefcip_sendup_constructor(void *buf, void *arg, int flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcip_sendup_elem *msg_elem = (struct fcip_sendup_elem *)buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcip_port_info_t *fport = (fcip_port_info_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fport != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg_elem->fcipsu_mp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg_elem->fcipsu_func = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg_elem->fcipsu_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCIP_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}