2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * CDDL HEADER START
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * The contents of this file are subject to the terms of the
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Common Development and Distribution License (the "License").
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * You may not use this file except in compliance with the License.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * or http://www.opensolaris.org/os/licensing.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * See the License for the specific language governing permissions
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * and limitations under the License.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * When distributing Covered Code, include this CDDL HEADER in each
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * If applicable, add the following below this CDDL HEADER, with the
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * fields enclosed by brackets "[]" replaced with your own identifying
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * information: Portions Copyright [yyyy] [name of copyright owner]
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * CDDL HEADER END
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Use is subject to license terms.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore/*
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * The following notice accompanied the original version of this file:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * BSD LICENSE
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Copyright(c) 2007 Intel Corporation. All rights reserved.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * All rights reserved.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Redistribution and use in source and binary forms, with or without
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * modification, are permitted provided that the following conditions
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * are met:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * * Redistributions of source code must retain the above copyright
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * notice, this list of conditions and the following disclaimer.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * * Redistributions in binary form must reproduce the above copyright
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * notice, this list of conditions and the following disclaimer in
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * the documentation and/or other materials provided with the
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * distribution.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * * Neither the name of Intel Corporation nor the names of its
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * contributors may be used to endorse or promote products derived
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * from this software without specific prior written permission.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Common FCoE interface interacts with MAC and FCoE clients, managing
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * FCoE ports, doing MAC address discovery/managment, and FC frame
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * encapsulation/decapsulation
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/stat.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/conf.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/file.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/cred.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/ddi.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/sunddi.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/sunndi.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/byteorder.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/atomic.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/sysmacros.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/cmn_err.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/crc32.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/strsubr.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/mac_client.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * FCoE header files
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/fcoe/fcoeio.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <sys/fcoe/fcoe_common.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Driver's own header files
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <fcoe.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <fcoe_fc.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#include <fcoe_eth.h>
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Function forward declaration
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_bus_ctl(dev_info_t *fca_dip, dev_info_t *rip,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_ctl_enum_t op, void *arg, void *result);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_open(dev_t *devp, int flag, int otype, cred_t *credp);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_close(dev_t dev, int flag, int otype, cred_t *credp);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cred_t *credp, int *rval);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_copyin_iocdata(intptr_t data, int mode, fcoeio_t **fcoeio,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang void **ibuf, void **abuf, void **obuf);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_copyout_iocdata(intptr_t data, int mode, fcoeio_t *fcoeio,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang void *obuf);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_iocmd(fcoe_soft_state_t *ss, intptr_t data, int mode);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_attach_init(fcoe_soft_state_t *this_ss);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_detach_uninit(fcoe_soft_state_t *this_ss);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_initchild(dev_info_t *fcoe_dip, dev_info_t *client_dip);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_uninitchild(dev_info_t *fcoe_dip, dev_info_t *client_dip);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic void fcoe_init_wwn_from_mac(uint8_t *wwn, uint8_t *mac,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int is_pwwn, uint8_t idx);
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hustatic fcoe_mac_t *fcoe_create_mac_by_id(datalink_id_t linkid);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_cmp_wwn(fcoe_mac_t *checkedmac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic void fcoe_watchdog(void *arg);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic void fcoe_worker_init();
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_worker_fini();
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic void fcoe_worker_frame();
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_get_port_list(fcoe_port_instance_t *ports, int count);
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yustatic boolean_t fcoe_mac_existed(fcoe_mac_t *pmac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Driver identificaton stuff
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic struct cb_ops fcoe_cb_ops = {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_open,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_close,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_ioctl,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nochpoll,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_prop_op,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang 0,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang D_MP | D_NEW | D_HOTPLUG,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang CB_REV,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang};
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic struct bus_ops fcoe_busops = {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang BUSO_REV,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nullbusmap, /* bus_map */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_get_intrspec */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_add_intrspec */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_remove_intrspec */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang i_ddi_map_fault, /* bus_map_fault */
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore NULL, /* bus_dma_map */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_dma_allochdl, /* bus_dma_allochdl */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_dma_freehdl, /* bus_dma_freehdl */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_dma_bindhdl, /* bus_dma_bindhdl */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_dma_unbindhdl, /* bus_unbindhdl */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_dma_flush, /* bus_dma_flush */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_dma_win, /* bus_dma_win */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_dma_mctl, /* bus_dma_ctl */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_bus_ctl, /* bus_ctl */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_bus_prop_op, /* bus_prop_op */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_get_eventcookie */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_add_eventcall */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_remove_event */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_post_event */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_intr_ctl */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_config */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_unconfig */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_fm_init */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_fm_fini */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_fm_access_enter */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_fm_access_exit */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL, /* bus_power */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang NULL
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang};
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic struct dev_ops fcoe_ops = {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang DEVO_REV,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang 0,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nulldev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nulldev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_attach,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_detach,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nodev,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang &fcoe_cb_ops,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang &fcoe_busops,
3b753e0506d00a3cd038199bce20003b3210a1b8Zhong Wang ddi_power,
3b753e0506d00a3cd038199bce20003b3210a1b8Zhong Wang ddi_quiesce_not_needed
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang};
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu#define FCOE_VERSION "20091123-1.02"
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#define FCOE_NAME "FCoE Transport v" FCOE_VERSION
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang#define TASKQ_NAME_LEN 32
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic struct modldrv modldrv = {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang &mod_driverops,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_NAME,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang &fcoe_ops,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang};
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic struct modlinkage modlinkage = {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang MODREV_1, &modldrv, NULL
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang};
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * TRACE for all FCoE related modules
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic kmutex_t fcoe_trace_buf_lock;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_trace_buf_curndx = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_trace_on = 1;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic caddr_t fcoe_trace_buf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic clock_t fcoe_trace_start = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic caddr_t ftb = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int fcoe_trace_buf_size = (1 * 1024 * 1024);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Driver's global variables
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangconst fcoe_ver_e fcoe_ver_now = FCOE_VER_NOW;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic void *fcoe_state = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_soft_state_t *fcoe_global_ss = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangint fcoe_use_ext_log = 1;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic ddi_taskq_t *fcoe_worker_taskq;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic fcoe_worker_t *fcoe_workers;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic uint32_t fcoe_nworkers_running;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangconst char *fcoe_workers_num = "workers-number";
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangvolatile int fcoe_nworkers;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Common loadable module entry points _init, _fini, _info
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangint
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang_init(void)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = ddi_soft_state_init(&fcoe_state, sizeof (fcoe_soft_state_t), 0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = mod_install(&modlinkage);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_soft_state_fini(&fcoe_state);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang } else {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_trace_start = ddi_get_lbolt();
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ftb = kmem_zalloc(fcoe_trace_buf_size,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang KM_SLEEP);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_trace_buf = ftb;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_init(&fcoe_trace_buf_lock, NULL, MUTEX_DRIVER, 0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG("fcoe", "exit _init with %x", ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangint
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang_fini(void)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = mod_remove(&modlinkage);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_soft_state_fini(&fcoe_state);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG("fcoe", "exit _fini with %x", ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(fcoe_trace_buf, fcoe_trace_buf_size);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_destroy(&fcoe_trace_buf_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangint
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang_info(struct modinfo *modinfop)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (mod_info(&modlinkage, modinfop));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Autoconfiguration entry points: attach, detach, getinfo
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret = DDI_FAILURE;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int fcoe_ret;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int instance;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_soft_state_t *ss;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang instance = ddi_get_instance(dip);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang switch (cmd) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case DDI_ATTACH:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = ddi_soft_state_zalloc(fcoe_state, instance);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret == DDI_FAILURE) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG(0, "soft_state_zalloc-%x/%x", ret, instance);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss = ddi_get_soft_state(fcoe_state, instance);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_dip = dip;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ASSERT(fcoe_global_ss == NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_global_ss = ss;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_ret = fcoe_attach_init(ss);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoe_ret == FCOE_SUCCESS) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = DDI_SUCCESS;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG("fcoe", "fcoe_attach_init end with-%x", fcoe_ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case DDI_RESUME:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = DDI_SUCCESS;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang default:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG("fcoe", "unsupported attach cmd-%x", cmd);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret = DDI_FAILURE;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int fcoe_ret;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int instance;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_soft_state_t *ss;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang instance = ddi_get_instance(dip);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss = ddi_get_soft_state(fcoe_state, instance);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ss == NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ASSERT(fcoe_global_ss != NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ASSERT(dip == fcoe_global_ss->ss_dip);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang switch (cmd) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case DDI_DETACH:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_ret = fcoe_detach_uninit(ss);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoe_ret == FCOE_SUCCESS) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = DDI_SUCCESS;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_global_ss = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case DDI_SUSPEND:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = DDI_SUCCESS;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang default:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG(0, "unsupported detach cmd-%x", cmd);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * FCA driver's intercepted bus control operations.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_bus_ctl(dev_info_t *fcoe_dip, dev_info_t *rip,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_ctl_enum_t op, void *clientarg, void *result)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang switch (op) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case DDI_CTLOPS_REPORTDEV:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case DDI_CTLOPS_IOMIN:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = DDI_SUCCESS;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case DDI_CTLOPS_INITCHILD:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = fcoe_initchild(fcoe_dip, (dev_info_t *)clientarg);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case DDI_CTLOPS_UNINITCHILD:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = fcoe_uninitchild(fcoe_dip, (dev_info_t *)clientarg);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang default:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = ddi_ctlops(fcoe_dip, rip, op, clientarg, result);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * We need specify the dev address for client driver's instance, or we
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * can't online client driver's instance.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/* ARGSUSED */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_initchild(dev_info_t *fcoe_dip, dev_info_t *client_dip)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang char client_addr[FCOE_STR_LEN];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int rval;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang rval = ddi_prop_get_int(DDI_DEV_T_ANY, client_dip,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "mac_id", -1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (rval == -1) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_LOG(__FUNCTION__, "no mac_id property: %p", client_dip);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bzero(client_addr, FCOE_STR_LEN);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) sprintf((char *)client_addr, "%x,0", rval);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_set_name_addr(client_dip, client_addr);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (DDI_SUCCESS);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/* ARGSUSED */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_uninitchild(dev_info_t *fcoe_dip, dev_info_t *client_dip)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_set_name_addr(client_dip, NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (DDI_SUCCESS);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Device access entry points
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_open(dev_t *devp, int flag, int otype, cred_t *credp)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int instance;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_soft_state_t *ss;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (otype != OTYP_CHR) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (EINVAL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Since this is for debugging only, only allow root to issue ioctl now
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (drv_priv(credp) != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (EPERM);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang instance = (int)getminor(*devp);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss = ddi_get_soft_state(fcoe_state, instance);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ss == NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ENXIO);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ss->ss_ioctl_flags & FCOE_IOCTL_FLAG_EXCL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * It is already open for exclusive access.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * So shut the door on this caller.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (EBUSY);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (flag & FEXCL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ss->ss_ioctl_flags & FCOE_IOCTL_FLAG_OPEN) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Exclusive operation not possible
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * as it is already opened
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (EBUSY);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_ioctl_flags |= FCOE_IOCTL_FLAG_EXCL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_ioctl_flags |= FCOE_IOCTL_FLAG_OPEN;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/* ARGSUSED */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_close(dev_t dev, int flag, int otype, cred_t *credp)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int instance;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_soft_state_t *ss;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (otype != OTYP_CHR) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (EINVAL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang instance = (int)getminor(dev);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss = ddi_get_soft_state(fcoe_state, instance);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ss == NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ENXIO);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((ss->ss_ioctl_flags & FCOE_IOCTL_FLAG_OPEN) == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ENODEV);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_ioctl_flags &= ~FCOE_IOCTL_FLAG_MASK;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/* ARGSUSED */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cred_t *credp, int *rval)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_soft_state_t *ss;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (drv_priv(credp) != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (EPERM);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss = ddi_get_soft_state(fcoe_state, (int32_t)getminor(dev));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ss == NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ENXIO);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((ss->ss_ioctl_flags & FCOE_IOCTL_FLAG_OPEN) == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ENXIO);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang switch (cmd) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case FCOEIO_CMD:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = fcoe_iocmd(ss, data, mode);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang default:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG(0, "fcoe_ioctl: ioctl-0x%02X", cmd);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = ENOTTY;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_copyin_iocdata(intptr_t data, int mode, fcoeio_t **fcoeio,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang void **ibuf, void **abuf, void **obuf)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *ibuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *abuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *obuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *fcoeio = kmem_zalloc(sizeof (fcoeio_t), KM_SLEEP);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ddi_copyin((void *)data, *fcoeio, sizeof (fcoeio_t), mode) != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EFAULT;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang goto copyin_iocdata_fail;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((*fcoeio)->fcoeio_ilen > FCOEIO_MAX_BUF_LEN ||
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (*fcoeio)->fcoeio_alen > FCOEIO_MAX_BUF_LEN ||
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (*fcoeio)->fcoeio_olen > FCOEIO_MAX_BUF_LEN) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EFAULT;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang goto copyin_iocdata_fail;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((*fcoeio)->fcoeio_ilen) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *ibuf = kmem_zalloc((*fcoeio)->fcoeio_ilen, KM_SLEEP);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ddi_copyin((void *)(unsigned long)(*fcoeio)->fcoeio_ibuf,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *ibuf, (*fcoeio)->fcoeio_ilen, mode) != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EFAULT;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang goto copyin_iocdata_fail;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((*fcoeio)->fcoeio_alen) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *abuf = kmem_zalloc((*fcoeio)->fcoeio_alen, KM_SLEEP);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ddi_copyin((void *)(unsigned long)(*fcoeio)->fcoeio_abuf,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *abuf, (*fcoeio)->fcoeio_alen, mode) != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EFAULT;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang goto copyin_iocdata_fail;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((*fcoeio)->fcoeio_olen) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *obuf = kmem_zalloc((*fcoeio)->fcoeio_olen, KM_SLEEP);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangcopyin_iocdata_fail:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (*abuf) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(*abuf, (*fcoeio)->fcoeio_alen);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *abuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (*ibuf) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(*ibuf, (*fcoeio)->fcoeio_ilen);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang *ibuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(*fcoeio, sizeof (fcoeio_t));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_copyout_iocdata(intptr_t data, int mode, fcoeio_t *fcoeio, void *obuf)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoeio->fcoeio_olen) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ddi_copyout(obuf,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (void *)(unsigned long)fcoeio->fcoeio_obuf,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_olen, mode) != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (EFAULT);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ddi_copyout(fcoeio, (void *)data, sizeof (fcoeio_t), mode) != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (EFAULT);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_iocmd(fcoe_soft_state_t *ss, intptr_t data, int mode)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac_t *fcoe_mac;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang void *ibuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang void *obuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang void *abuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio_t *fcoeio;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = fcoe_copyin_iocdata(data, mode, &fcoeio, &ibuf, &abuf, &obuf);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang goto fcoeiocmd_release_buf;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * If an exclusive open was demanded during open, ensure that
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * only one thread can execute an ioctl at a time
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ss->ss_ioctl_flags & FCOE_IOCTL_FLAG_EXCL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ss->ss_ioctl_flags & FCOE_IOCTL_FLAG_EXCL_BUSY) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_BUSY;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EBUSY;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang goto fcoeiocmd_release_buf;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_ioctl_flags |= FCOE_IOCTL_FLAG_EXCL_BUSY;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang switch (fcoeio->fcoeio_cmd) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case FCOEIO_CREATE_FCOE_PORT: {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio_create_port_param_t *param =
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (fcoeio_create_port_param_t *)ibuf;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int cmpwwn = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_port_t *eport;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoeio->fcoeio_ilen !=
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang sizeof (fcoeio_create_port_param_t) ||
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_xfer != FCOEIO_XFER_WRITE) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_INVAL_ARG;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EINVAL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_ioctl_mutex);
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu fcoe_mac = fcoe_create_mac_by_id(param->fcp_mac_linkid);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoe_mac == NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_CREATE_MAC;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EIO;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoe_mac->fm_flags & FCOE_MAC_FLAG_ENABLED) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_ALREADY;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EALREADY;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang } else {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = fcoe_open_mac(fcoe_mac, param->fcp_force_promisc,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang &fcoeio->fcoeio_status);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_destroy_mac(fcoe_mac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoeio->fcoeio_status == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status =
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOEIOE_OPEN_MAC;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EIO;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang } else {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac->fm_flags |= FCOE_MAC_FLAG_ENABLED;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Provide PWWN and NWWN based on mac address
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang eport = &fcoe_mac->fm_eport;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (!param->fcp_pwwn_provided) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_init_wwn_from_mac(eport->eport_portwwn,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac->fm_current_addr, 1, 0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang } else {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (void) memcpy(eport->eport_portwwn, param->fcp_pwwn, 8);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (!param->fcp_nwwn_provided) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_init_wwn_from_mac(eport->eport_nodewwn,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac->fm_current_addr, 0, 0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang } else {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (void) memcpy(eport->eport_nodewwn, param->fcp_nwwn, 8);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cmpwwn = fcoe_cmp_wwn(fcoe_mac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (cmpwwn != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (cmpwwn == 1) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_PWWN_CONFLICTED;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang } else if (cmpwwn == -1) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_NWWN_CONFLICTED;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (void) fcoe_close_mac(fcoe_mac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_destroy_mac(fcoe_mac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = ENOTUNIQ;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = fcoe_create_port(ss->ss_dip,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (param->fcp_port_type == FCOE_CLIENT_TARGET));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret != 0) {
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu if (fcoe_mac_existed(fcoe_mac) == B_TRUE) {
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu (void) fcoe_close_mac(fcoe_mac);
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu fcoe_destroy_mac(fcoe_mac);
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_CREATE_PORT;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EIO;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case FCOEIO_DELETE_FCOE_PORT: {
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu fcoeio_delete_port_param_t *del_port_param =
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu (fcoeio_delete_port_param_t *)ibuf;
e6eb57e72471348376359efe9105d50bf487a312Kevin Yu uint64_t *is_target = (uint64_t *)obuf;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu if (fcoeio->fcoeio_ilen < sizeof (fcoeio_delete_port_param_t) ||
e6eb57e72471348376359efe9105d50bf487a312Kevin Yu fcoeio->fcoeio_olen != sizeof (uint64_t) ||
e6eb57e72471348376359efe9105d50bf487a312Kevin Yu fcoeio->fcoeio_xfer != FCOEIO_XFER_RW) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_INVAL_ARG;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EINVAL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_ioctl_mutex);
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu ret = fcoe_delete_port(ss->ss_dip, fcoeio,
e6eb57e72471348376359efe9105d50bf487a312Kevin Yu del_port_param->fdp_mac_linkid, is_target);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_LOG("fcoe", "fcoe_delete_port %x return: %d",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang del_port_param->fdp_mac_linkid, ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case FCOEIO_GET_FCOE_PORT_LIST: {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_port_list_t *list = (fcoe_port_list_t *)obuf;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int count;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoeio->fcoeio_xfer != FCOEIO_XFER_READ ||
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_olen < sizeof (fcoe_port_list_t)) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_INVAL_ARG;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = EINVAL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list->numPorts = 1 + (fcoeio->fcoeio_olen -
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang sizeof (fcoe_port_list_t))/sizeof (fcoe_port_instance_t);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang count = fcoe_get_port_list(list->ports, list->numPorts);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (count > list->numPorts) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoeio->fcoeio_status = FCOEIOE_MORE_DATA;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = ENOSPC;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list->numPorts = count;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang default:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ENOTTY);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_LOG("fcoe", "fcoe_ioctl %x returned %d, fcoeio_status = %d",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoeio->fcoeio_cmd, ret, fcoeio->fcoeio_status);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoeiocmd_release_buf:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = fcoe_copyout_iocdata(data, mode, fcoeio, obuf);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang } else if (fcoeio->fcoeio_status) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (void) fcoe_copyout_iocdata(data, mode, fcoeio, obuf);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (obuf != NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(obuf, fcoeio->fcoeio_olen);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang obuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (abuf != NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(abuf, fcoeio->fcoeio_alen);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang abuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ibuf != NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(ibuf, fcoeio->fcoeio_ilen);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ibuf = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(fcoeio, sizeof (fcoeio_t));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Finish final initialization
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_attach_init(fcoe_soft_state_t *ss)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang char taskq_name[TASKQ_NAME_LEN];
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ddi_create_minor_node(ss->ss_dip, "admin", S_IFCHR,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_get_instance(ss->ss_dip), DDI_PSEUDO, 0) != DDI_SUCCESS) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG("FCOE", "ddi_create_minor_node failed");
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (FCOE_FAILURE);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * watchdog responsible for release frame and dispatch events
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (void) snprintf(taskq_name, sizeof (taskq_name), "fcoe_mac");
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang taskq_name[TASKQ_NAME_LEN - 1] = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((ss->ss_watchdog_taskq = ddi_taskq_create(NULL,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang taskq_name, 2, TASKQ_DEFAULTPRI, 0)) == NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (FCOE_FAILURE);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_ioctl_flags = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_init(&ss->ss_ioctl_mutex, NULL, MUTEX_DRIVER, NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_create(&ss->ss_mac_list, sizeof (fcoe_mac_t),
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang offsetof(fcoe_mac_t, fm_ss_node));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_create(&ss->ss_pfrm_list, sizeof (fcoe_i_frame_t),
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang offsetof(fcoe_i_frame_t, fmi_pending_node));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_init(&ss->ss_watch_mutex, 0, MUTEX_DRIVER, 0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cv_init(&ss->ss_watch_cv, NULL, CV_DRIVER, NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_flags &= ~SS_FLAG_TERMINATE_WATCHDOG;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (void) ddi_taskq_dispatch(ss->ss_watchdog_taskq,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_watchdog, ss, DDI_SLEEP);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang while ((ss->ss_flags & SS_FLAG_WATCHDOG_RUNNING) == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang delay(10);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_nworkers = ddi_prop_get_int(DDI_DEV_T_ANY, ss->ss_dip,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, (char *)fcoe_workers_num, 4);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoe_nworkers < 1) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_nworkers = 4;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_worker_init();
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_report_dev(ss->ss_dip);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (FCOE_SUCCESS);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Finish final uninitialization
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_detach_uninit(fcoe_soft_state_t *ss)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (!list_is_empty(&ss->ss_mac_list)) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG("fcoe", "ss_mac_list is not empty when detach");
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (FCOE_FAILURE);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((ret = fcoe_worker_fini()) != FCOE_SUCCESS) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (ret);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Stop watchdog
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ss->ss_flags & SS_FLAG_WATCHDOG_RUNNING) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_watch_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_flags |= SS_FLAG_TERMINATE_WATCHDOG;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cv_broadcast(&ss->ss_watch_cv);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_watch_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang while (ss->ss_flags & SS_FLAG_WATCHDOG_RUNNING) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang delay(10);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_taskq_destroy(ss->ss_watchdog_taskq);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_destroy(&ss->ss_watch_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cv_destroy(&ss->ss_watch_cv);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_remove_minor_node(ss->ss_dip, NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_destroy(&ss->ss_ioctl_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_destroy(&ss->ss_mac_list);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (FCOE_SUCCESS);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Return mac instance if it exist, or else return NULL.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_mac_t *
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hufcoe_lookup_mac_by_id(datalink_id_t linkid)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac_t *mac = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu ASSERT(MUTEX_HELD(&fcoe_global_ss->ss_ioctl_mutex));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang for (mac = list_head(&fcoe_global_ss->ss_mac_list); mac;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac = list_next(&fcoe_global_ss->ss_mac_list, mac)) {
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu if (linkid != mac->fm_linkid) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang continue;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (mac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu/*
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu * Return B_TRUE if mac exists, or else return B_FALSE
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu */
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yustatic boolean_t
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yufcoe_mac_existed(fcoe_mac_t *pmac)
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu{
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu fcoe_mac_t *mac = NULL;
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu ASSERT(MUTEX_HELD(&fcoe_global_ss->ss_ioctl_mutex));
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu for (mac = list_head(&fcoe_global_ss->ss_mac_list); mac;
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu mac = list_next(&fcoe_global_ss->ss_mac_list, mac)) {
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu if (mac == pmac) {
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu return (B_TRUE);
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu }
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu }
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu return (B_FALSE);
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu}
87dcbdbdce8044d5199e015edd8fb347d16ee0b5Kevin Yu
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * port wwn will start with 20:..., node wwn will start with 10:...
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic void
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_init_wwn_from_mac(uint8_t *wwn, uint8_t *mac, int is_pwwn, uint8_t idx)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ASSERT(wwn != NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ASSERT(mac != NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang wwn[0] = (is_pwwn + 1) << 4;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang wwn[1] = idx;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang bcopy(mac, wwn + 2, ETHERADDRL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Return fcoe_mac if it exists, otherwise create a new one
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic fcoe_mac_t *
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hufcoe_create_mac_by_id(datalink_id_t linkid)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac_t *mac = NULL;
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu ASSERT(MUTEX_HELD(&fcoe_global_ss->ss_ioctl_mutex));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu mac = fcoe_lookup_mac_by_id(linkid);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (mac != NULL) {
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu FCOE_LOG("fcoe", "fcoe_create_mac_by_id found one mac %d",
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu linkid);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (mac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac = kmem_zalloc(sizeof (fcoe_mac_t), KM_SLEEP);
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu mac->fm_linkid = linkid;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac->fm_flags = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac->fm_ss = fcoe_global_ss;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_insert_tail(&mac->fm_ss->ss_mac_list, mac);
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu FCOE_LOG("fcoe", "fcoe_create_mac_by_id created one mac %d", linkid);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (mac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangvoid
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_destroy_mac(fcoe_mac_t *mac)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ASSERT(mac != NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_remove(&mac->fm_ss->ss_mac_list, mac);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(mac, sizeof (fcoe_mac_t));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * raw frame layout:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * ethernet header + vlan header (optional) + FCoE header +
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * FC frame + FCoE tailer
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/* ARGSUSED */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangmblk_t *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_get_mblk(fcoe_mac_t *mac, uint32_t raw_frame_size)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mblk_t *mp;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int err;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * FCFH_SIZE + PADDING_SIZE
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ASSERT(raw_frame_size >= 60);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang while ((mp = allocb((size_t)raw_frame_size, 0)) == NULL) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((err = strwaitbuf((size_t)raw_frame_size, BPRI_LO)) != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG("fcoe_get_mblk", "strwaitbuf return %d", err);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mp->b_wptr = mp->b_rptr + raw_frame_size;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * We should always zero FC frame header
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang bzero(mp->b_rptr + PADDING_HEADER_SIZE,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang sizeof (fcoe_fc_frame_header_t));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (mp);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic void
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_watchdog(void *arg)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_soft_state_t *ss = (fcoe_soft_state_t *)arg;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_i_frame_t *fmi;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac_t *mac = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang FCOE_LOG("fcoe", "fcoe_soft_state is %p", ss);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_watch_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_flags |= SS_FLAG_WATCHDOG_RUNNING;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang while ((ss->ss_flags & SS_FLAG_TERMINATE_WATCHDOG) == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang while (fmi = (fcoe_i_frame_t *)list_head(&ss->ss_pfrm_list)) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_remove(&ss->ss_pfrm_list, fmi);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_watch_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac = EPORT2MAC(fmi->fmi_frame->frm_eport);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac->fm_client.ect_release_sol_frame(fmi->fmi_frame);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&ss->ss_watch_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac->fm_frm_cnt--;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_flags |= SS_FLAG_DOG_WAITING;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (void) cv_wait(&ss->ss_watch_cv, &ss->ss_watch_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_flags &= ~SS_FLAG_DOG_WAITING;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ss->ss_flags &= ~SS_FLAG_WATCHDOG_RUNNING;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&ss->ss_watch_mutex);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic void
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_worker_init()
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang uint32_t i;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_nworkers_running = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_worker_taskq = ddi_taskq_create(0, "FCOE_WORKER_TASKQ",
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_nworkers, TASKQ_DEFAULTPRI, 0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_workers = (fcoe_worker_t *)kmem_zalloc(sizeof (fcoe_worker_t) *
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_nworkers, KM_SLEEP);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang for (i = 0; i < fcoe_nworkers; i++) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_worker_t *w = &fcoe_workers[i];
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_init(&w->worker_lock, NULL, MUTEX_DRIVER, NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cv_init(&w->worker_cv, NULL, CV_DRIVER, NULL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w->worker_flags &= ~FCOE_WORKER_TERMINATE;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_create(&w->worker_frm_list, sizeof (fcoe_i_frame_t),
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang offsetof(fcoe_i_frame_t, fmi_pending_node));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (void) ddi_taskq_dispatch(fcoe_worker_taskq, fcoe_worker_frame,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w, DDI_SLEEP);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang while (fcoe_nworkers_running != fcoe_nworkers) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang delay(10);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_worker_fini()
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang uint32_t i;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang for (i = 0; i < fcoe_nworkers; i++) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_worker_t *w = &fcoe_workers[i];
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&w->worker_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (w->worker_flags & FCOE_WORKER_STARTED) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w->worker_flags |= FCOE_WORKER_TERMINATE;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cv_signal(&w->worker_cv);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&w->worker_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang while (fcoe_nworkers_running != 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang delay(drv_usectohz(10000));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ddi_taskq_destroy(fcoe_worker_taskq);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang kmem_free(fcoe_workers, sizeof (fcoe_worker_t) * fcoe_nworkers);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_workers = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (FCOE_SUCCESS);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_crc_verify(fcoe_frame_t *frm)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang uint32_t crc;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang uint8_t *crc_array = FRM2FMI(frm)->fmi_fft->fft_crc;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang uint32_t crc_from_frame = ~(crc_array[0] | (crc_array[1] << 8) |
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (crc_array[2] << 16) | (crc_array[3] << 24));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang CRC32(crc, frm->frm_fc_frame, frm->frm_fc_frame_size, -1U, crc32_table);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (crc == crc_from_frame ? FCOE_SUCCESS : FCOE_FAILURE);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic void
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_worker_frame(void *arg)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_worker_t *w = (fcoe_worker_t *)arg;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_i_frame_t *fmi;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int ret;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_32(&fcoe_nworkers_running);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&w->worker_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w->worker_flags |= FCOE_WORKER_STARTED | FCOE_WORKER_ACTIVE;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang while ((w->worker_flags & FCOE_WORKER_TERMINATE) == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * loop through the frames
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang while (fmi = list_head(&w->worker_frm_list)) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_remove(&w->worker_frm_list, fmi);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&w->worker_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang /*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * do the checksum
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ret = fcoe_crc_verify(fmi->fmi_frame);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (ret == FCOE_SUCCESS) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fmi->fmi_mac->fm_client.ect_rx_frame(
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fmi->fmi_frame);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang } else {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_release_frame(fmi->fmi_frame);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&w->worker_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w->worker_ntasks--;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w->worker_flags &= ~FCOE_WORKER_ACTIVE;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cv_wait(&w->worker_cv, &w->worker_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w->worker_flags |= FCOE_WORKER_ACTIVE;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w->worker_flags &= ~(FCOE_WORKER_STARTED | FCOE_WORKER_ACTIVE);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&w->worker_lock);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&fcoe_nworkers_running);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_destroy(&w->worker_frm_list);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangvoid
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_post_frame(fcoe_frame_t *frm)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_worker_t *w;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang uint16_t oxid = FRM_OXID(frm);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w = &fcoe_workers[oxid % fcoe_nworkers_running];
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&w->worker_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang list_insert_tail(&w->worker_frm_list, frm->frm_fcoe_private);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang w->worker_ntasks++;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if ((w->worker_flags & FCOE_WORKER_ACTIVE) == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cv_signal(&w->worker_cv);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&w->worker_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * The max length of every LOG is 158
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangvoid
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_trace(caddr_t ident, const char *fmt, ...)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang va_list args;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang char tbuf[160];
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int len;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang clock_t curclock;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang clock_t usec;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoe_trace_on == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang curclock = ddi_get_lbolt();
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang usec = (curclock - fcoe_trace_start) * usec_per_tick;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang len = snprintf(tbuf, 158, "%lu.%03lus 0t%lu %s ", (usec /
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang (1000 * 1000)), ((usec % (1000 * 1000)) / 1000),
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang curclock, (ident ? ident : "unknown"));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang va_start(args, fmt);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang len += vsnprintf(tbuf + len, 158 - len, fmt, args);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang va_end(args);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (len > 158) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang len = 158;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang tbuf[len++] = '\n';
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang tbuf[len] = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_enter(&fcoe_trace_buf_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang bcopy(tbuf, &fcoe_trace_buf[fcoe_trace_buf_curndx], len+1);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_trace_buf_curndx += len;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (fcoe_trace_buf_curndx > (fcoe_trace_buf_size - 320)) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_trace_buf_curndx = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mutex_exit(&fcoe_trace_buf_lock);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang/*
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Check whether the pwwn or nwwn already exist or not
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * Return value:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * 1: PWWN conflicted
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * -1: NWWN conflicted
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * 0: No conflict
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang */
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_cmp_wwn(fcoe_mac_t *checkedmac)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac_t *mac;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang uint8_t *nwwn, *pwwn, *cnwwn, *cpwwn;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cnwwn = checkedmac->fm_eport.eport_nodewwn;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang cpwwn = checkedmac->fm_eport.eport_portwwn;
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu ASSERT(MUTEX_HELD(&fcoe_global_ss->ss_ioctl_mutex));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang for (mac = list_head(&fcoe_global_ss->ss_mac_list); mac;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac = list_next(&fcoe_global_ss->ss_mac_list, mac)) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (mac == checkedmac) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang continue;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang nwwn = mac->fm_eport.eport_nodewwn;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang pwwn = mac->fm_eport.eport_portwwn;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (memcmp(nwwn, cnwwn, 8) == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (-1);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (memcmp(pwwn, cpwwn, 8) == 0) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (1);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (0);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangstatic int
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wangfcoe_get_port_list(fcoe_port_instance_t *ports, int count)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang{
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang fcoe_mac_t *mac = NULL;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang int i = 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ASSERT(ports != NULL);
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu ASSERT(MUTEX_HELD(&fcoe_global_ss->ss_ioctl_mutex));
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang for (mac = list_head(&fcoe_global_ss->ss_mac_list); mac;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac = list_next(&fcoe_global_ss->ss_mac_list, mac)) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (i < count) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang bcopy(mac->fm_eport.eport_portwwn,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ports[i].fpi_pwwn, 8);
d4401b99a36e5170ccaa7defc0d2ac65b23f08c6Kelly Hu ports[i].fpi_mac_linkid = mac->fm_linkid;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang bcopy(mac->fm_current_addr,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ports[i].fpi_mac_current_addr, ETHERADDRL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang bcopy(mac->fm_primary_addr,
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ports[i].fpi_mac_factory_addr, ETHERADDRL);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ports[i].fpi_port_type =
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang EPORT_CLT_TYPE(&mac->fm_eport);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ports[i].fpi_mtu_size =
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac->fm_eport.eport_mtu;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang ports[i].fpi_mac_promisc =
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang mac->fm_promisc_handle != NULL ? 1 : 0;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang i++;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang }
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang return (i);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang}