06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * CDDL HEADER START
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * The contents of this file are subject to the terms of the
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Common Development and Distribution License (the "License").
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * You may not use this file except in compliance with the License.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * or http://www.opensolaris.org/os/licensing.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * See the License for the specific language governing permissions
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * and limitations under the License.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * When distributing Covered Code, include this CDDL HEADER in each
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * If applicable, add the following below this CDDL HEADER, with the
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * fields enclosed by brackets "[]" replaced with your own identifying
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * information: Portions Copyright [yyyy] [name of copyright owner]
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * CDDL HEADER END
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Use is subject to license terms.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/types.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/errno.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/debug.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/time.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/sysmacros.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/systm.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/user.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/stropts.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/stream.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/strlog.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/strsubr.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/cmn_err.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/cpu.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/kmem.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/conf.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/ddi.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/sunddi.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/ksynch.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/stat.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/kstat.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/vtrace.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/strsun.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/dlpi.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/ethernet.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <net/if.h>
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb#include <netinet/arp.h>
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb#include <inet/arp.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/varargs.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/machsystm.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/modctl.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/modhash.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/mac_client.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/mac_provider.h>
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna#include <sys/mac_client_priv.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/mac_ether.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/taskq.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/note.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/mach_descrip.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/mac.h>
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG#include <sys/mac_flow.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/mdeg.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#include <sys/vsw.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sys/vlan.h>
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/* MAC Ring table functions. */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void vsw_port_rx_cb(void *, mac_resource_handle_t, mblk_t *,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng boolean_t);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void vsw_if_rx_cb(void *, mac_resource_handle_t, mblk_t *, boolean_t);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/* MAC layer routines */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int vsw_set_port_hw_addr(vsw_port_t *port);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int vsw_set_if_hw_addr(vsw_t *vswp);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void vsw_unset_hw_addr(vsw_t *, vsw_port_t *, int);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int vsw_maccl_open(vsw_t *vswp, vsw_port_t *port, int type);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void vsw_maccl_close(vsw_t *vswp, vsw_port_t *port, int type);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void vsw_mac_multicast_add_all(vsw_t *vswp, vsw_port_t *portp, int type);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void vsw_mac_multicast_remove_all(vsw_t *vswp,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_port_t *portp, int type);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void vsw_mac_add_vlans(vsw_t *vswp, mac_client_handle_t mch,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint8_t *macaddr, uint16_t flags, vsw_vlanid_t *vids, int nvids);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void vsw_mac_remove_vlans(mac_client_handle_t mch, vsw_vlanid_t *vids,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int nvids);
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatnastatic void vsw_mac_set_mtu(vsw_t *vswp, uint32_t mtu);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGstatic void vsw_maccl_set_bandwidth(vsw_t *vswp, vsw_port_t *port, int type,
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG uint64_t maxbw);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnastatic int vsw_notify_add(vsw_t *vswp);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnastatic int vsw_notify_rem(vsw_t *vswp);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnastatic void vsw_notify_cb(void *arg, mac_notify_type_t type);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnastatic void vsw_notify_link(vsw_t *vswp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/* Support functions */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramint vsw_set_hw(vsw_t *, vsw_port_t *, int);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid vsw_unset_hw(vsw_t *, vsw_port_t *, int);
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvoid vsw_reconfig_hw(vsw_t *);
06db247c678f0e3956535e8a6dec31d6c2108827raghuramint vsw_mac_open(vsw_t *vswp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvoid vsw_mac_close(vsw_t *vswp);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengint vsw_mac_multicast_add(vsw_t *vswp, vsw_port_t *port, mcst_addr_t *mcst_p,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int type);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid vsw_mac_multicast_remove(vsw_t *vswp, vsw_port_t *port,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcst_addr_t *mcst_p, int type);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengint vsw_mac_client_init(vsw_t *vswp, vsw_port_t *port, int type);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid vsw_mac_client_cleanup(vsw_t *vswp, vsw_port_t *port, int type);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid vsw_mac_cleanup_ports(vsw_t *vswp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvoid vsw_unset_addrs(vsw_t *vswp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvoid vsw_set_addrs(vsw_t *vswp);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengmblk_t *vsw_tx_msg(vsw_t *, mblk_t *, int, vsw_port_t *);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid vsw_publish_macaddr(vsw_t *vswp, vsw_port_t *portp);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid vsw_port_mac_reconfig(vsw_port_t *portp, boolean_t update_vlans,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint16_t new_pvid, vsw_vlanid_t *new_vids, int new_nvids);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid vsw_mac_port_reconfig_vlans(vsw_port_t *portp, uint16_t new_pvid,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_vlanid_t *new_vids, int new_nvids);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid vsw_if_mac_reconfig(vsw_t *vswp, boolean_t update_vlans,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint16_t new_pvid, vsw_vlanid_t *new_vids, int new_nvids);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGvoid vsw_update_bandwidth(vsw_t *vswp, vsw_port_t *port, int type,
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG uint64_t maxbw);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Functions imported from other files.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengextern int vsw_portsend(vsw_port_t *port, mblk_t *mp);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengextern void vsw_hio_stop_port(vsw_port_t *portp);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengextern void vsw_hio_port_reset(vsw_port_t *portp, boolean_t immediate);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengextern uint32_t vsw_publish_macaddr_count;
da14cebe459d3275048785f25bd869cb09b5307fEric Chengextern uint32_t vsw_vlan_frame_untag(void *arg, int type, mblk_t **np,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mblk_t **npt);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnaextern void vsw_physlink_state_update(vsw_t *vswp);
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatnastatic char mac_mtu_propname[] = "mtu";
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Tunables used in this file.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramextern int vsw_mac_open_retries;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#define WRITE_MACCL_ENTER(vswp, port, type) \
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (type == VSW_LOCALDEV) ? rw_enter(&vswp->maccl_rwlock, RW_WRITER) :\
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rw_enter(&port->maccl_rwlock, RW_WRITER)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#define READ_MACCL_ENTER(vswp, port, type) \
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (type == VSW_LOCALDEV) ? rw_enter(&vswp->maccl_rwlock, RW_READER) :\
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rw_enter(&port->maccl_rwlock, RW_READER)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#define RW_MACCL_EXIT(vswp, port, type) \
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (type == VSW_LOCALDEV) ? rw_exit(&vswp->maccl_rwlock) : \
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rw_exit(&port->maccl_rwlock)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Locking strategy in this file is explained as follows:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * - A global lock(vswp->mac_lock) is used to protect the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * MAC calls that deal with entire device. That is, the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * operations that deal with mac_handle which include
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * mac_open()/close() and mac_client_open().
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * - A per port/interface RW lock(maccl_rwlock) is used protect
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * the operations that deal with the MAC client.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * When both mac_lock and maccl_rwlock need to be held, the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * mac_lock need be acquired first and then maccl_rwlock. That is,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * mac_lock---->maccl_rwlock
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * The 'mca_lock' that protects the mcast list is also acquired
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * within the context of maccl_rwlock. The hierarchy for this
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * one is as below:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * maccl_rwlock---->mca_lock
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Program unicast and multicast addresses of vsw interface and the ports
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * into the network device.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvoid
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvsw_set_addrs(vsw_t *vswp)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
06db247c678f0e3956535e8a6dec31d6c2108827raghuram vsw_port_list_t *plist = &vswp->plist;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram vsw_port_t *port;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram int rv;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram READ_ENTER(&vswp->if_lockrw);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (vswp->if_state & VSW_IF_UP) {
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Open a mac client and program addresses */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = vsw_mac_client_init(vswp, NULL, VSW_LOCALDEV);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_NOTE,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "!vsw%d: failed to program interface "
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "unicast address\n", vswp->instance);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Notify the MAC layer of the changed address.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_unicst_update(vswp->if_mh,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (uint8_t *)&vswp->if_addr);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram RW_EXIT(&vswp->if_lockrw);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram WRITE_ENTER(&plist->lockrw);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* program unicast address of ports in the network device */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram for (port = plist->head; port != NULL; port = port->p_next) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (port->addr_set) /* addr already set */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram continue;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Open a mac client and program addresses */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = vsw_mac_client_init(vswp, port, VSW_VNETPORT);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_NOTE,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "!vsw%d: failed to program port(%d) "
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "unicast address\n", vswp->instance,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng port->p_instance);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb /* announce macaddr of vnets to the physical switch */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb if (vsw_publish_macaddr_count != 0) { /* enabled */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb for (port = plist->head; port != NULL; port = port->p_next) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_publish_macaddr(vswp, port);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb }
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb }
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
06db247c678f0e3956535e8a6dec31d6c2108827raghuram RW_EXIT(&plist->lockrw);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Remove unicast, multicast addresses and close mac clients
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * for the vsw interface and all ports.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvoid
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvsw_unset_addrs(vsw_t *vswp)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
06db247c678f0e3956535e8a6dec31d6c2108827raghuram READ_ENTER(&vswp->if_lockrw);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (vswp->if_state & VSW_IF_UP) {
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Cleanup and close the mac client for the interface */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_client_cleanup(vswp, NULL, VSW_LOCALDEV);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram RW_EXIT(&vswp->if_lockrw);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Cleanup and close the mac clients for all ports */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_cleanup_ports(vswp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Open the underlying network device for access in layer2 mode.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Returns:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * 0 on success
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * EAGAIN if mac_open() fails due to the device being not available yet.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * EIO on any other failures.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramint
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvsw_mac_open(vsw_t *vswp)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(MUTEX_HELD(&vswp->mac_lock));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (vswp->mh != NULL) {
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* already open */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram return (0);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (vswp->mac_open_retries++ >= vsw_mac_open_retries) {
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* exceeded max retries */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram return (EIO);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((rv = mac_open_by_linkname(vswp->physname, &vswp->mh)) != 0) {
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If mac_open() failed and the error indicates that either
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * the dlmgmtd door or the device is not available yet, we
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * return EAGAIN to indicate that mac_open() needs to be
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * retried. For example, this may happen during boot up, if
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * the required link aggregation groups(devices) have not
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * been created yet.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rv == ENOENT || rv == EBADF) {
06db247c678f0e3956535e8a6dec31d6c2108827raghuram return (EAGAIN);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram } else {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna cmn_err(CE_WARN, "!vsw%d: mac_open %s failed rv:%x\n",
06db247c678f0e3956535e8a6dec31d6c2108827raghuram vswp->instance, vswp->physname, rv);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram return (EIO);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram vswp->mac_open_retries = 0;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_set_mtu(vswp, vswp->mtu);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna rv = vsw_notify_add(vswp);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna if (rv != 0) {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna cmn_err(CE_CONT, "!vsw%d: mac_notify_add %s failed rv:%x\n",
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vswp->instance, vswp->physname, rv);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna }
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
06db247c678f0e3956535e8a6dec31d6c2108827raghuram return (0);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Close the underlying physical device.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvoid
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvsw_mac_close(vsw_t *vswp)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(MUTEX_HELD(&vswp->mac_lock));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (vswp->mh != NULL) {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna if (vswp->mnh != 0) {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna (void) vsw_notify_rem(vswp);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vswp->mnh = 0;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vswp->mtu != vswp->mtu_physdev_orig) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_set_mtu(vswp, vswp->mtu_physdev_orig);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram mac_close(vswp->mh);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram vswp->mh = NULL;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Add multicast addr.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramint
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_multicast_add(vsw_t *vswp, vsw_port_t *port, mcst_addr_t *mcst_p,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int type)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int ret = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_handle_t mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng WRITE_MACCL_ENTER(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mch = (type == VSW_LOCALDEV) ? vswp->mch : port->p_mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (mch != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ret = mac_multicast_add(mch, mcst_p->mca.ether_addr_octet);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (ret != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_WARN, "!vsw%d: unable to "
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "program multicast address(%s) err=%d",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->instance,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ether_sprintf((void *)&mcst_p->mca), ret);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_MACCL_EXIT(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (ret);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcst_p->mac_added = B_TRUE;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_MACCL_EXIT(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (ret);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Remove multicast addr.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramvoid
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_multicast_remove(vsw_t *vswp, vsw_port_t *port, mcst_addr_t *mcst_p,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int type)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_handle_t mch;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng WRITE_MACCL_ENTER(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mch = (type == VSW_LOCALDEV) ? vswp->mch : port->p_mch;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (mch != NULL && mcst_p->mac_added) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_multicast_remove(mch, mcst_p->mca.ether_addr_octet);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcst_p->mac_added = B_FALSE;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_MACCL_EXIT(vswp, port, type);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Add all multicast addresses of the port.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_multicast_add_all(vsw_t *vswp, vsw_port_t *portp, int type)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcst_addr_t *mcap;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_handle_t mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng kmutex_t *mca_lockp;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram ASSERT((type == VSW_LOCALDEV) || (type == VSW_VNETPORT));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (type == VSW_LOCALDEV) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(RW_WRITE_HELD(&vswp->maccl_rwlock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mch = vswp->mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcap = vswp->mcap;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mca_lockp = &vswp->mca_lock;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(RW_WRITE_HELD(&portp->maccl_rwlock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mch = portp->p_mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcap = portp->mcap;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mca_lockp = &portp->mca_lock;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (mch == NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(mca_lockp);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (mcap = mcap; mcap != NULL; mcap = mcap->nextp) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (mcap->mac_added)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng continue;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = mac_multicast_add(mch, (uchar_t *)&mcap->mca);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcap->mac_added = B_TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_WARN, "!vsw%d: unable to program "
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "multicast address(%s) err=%d", vswp->instance,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ether_sprintf((void *)&mcap->mca), rv);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(mca_lockp);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Remove all multicast addresses of the port.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_multicast_remove_all(vsw_t *vswp, vsw_port_t *portp, int type)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_handle_t mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcst_addr_t *mcap;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng kmutex_t *mca_lockp;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT((type == VSW_LOCALDEV) || (type == VSW_VNETPORT));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (type == VSW_LOCALDEV) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(RW_WRITE_HELD(&vswp->maccl_rwlock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mch = vswp->mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcap = vswp->mcap;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mca_lockp = &vswp->mca_lock;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(RW_WRITE_HELD(&portp->maccl_rwlock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mch = portp->p_mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcap = portp->mcap;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mca_lockp = &portp->mca_lock;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (mch == NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(mca_lockp);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (; mcap != NULL; mcap = mcap->nextp) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (!mcap->mac_added)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng continue;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_multicast_remove(mch, (uchar_t *)&mcap->mca);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mcap->mac_added = B_FALSE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(mca_lockp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGvoid
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGvsw_update_bandwidth(vsw_t *vswp, vsw_port_t *port, int type, uint64_t maxbw)
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG{
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG ASSERT((type == VSW_LOCALDEV) || (type == VSW_VNETPORT));
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG WRITE_MACCL_ENTER(vswp, port, type);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG vsw_maccl_set_bandwidth(vswp, port, type, maxbw);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG RW_MACCL_EXIT(vswp, port, type);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG}
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Open a mac client and program uncast and multicast addresses
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * for a port or the interface.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Returns:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * 0 on success
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * non-zero for failure.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramint
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_client_init(vsw_t *vswp, vsw_port_t *port, int type)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng WRITE_MACCL_ENTER(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = vsw_maccl_open(vswp, port, type);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Release mac_lock now */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) vsw_set_hw(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_multicast_add_all(vswp, port, type);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_MACCL_EXIT(vswp, port, type);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram return (rv);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Open a MAC client for a port or an interface.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * The flags and their purpose as below:
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * MAC_OPEN_FLAGS_SHARES_DESIRED -- This flag is used to indicate
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * that a port desires a Share. This will be the case with the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * the ports that have hybrid mode enabled. This will only cause
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * MAC layer to allocate a share and corresponding resources
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * ahead of time. Ports that are not HybridIO enabled are
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * associated with default group & resources.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
4c91d6c6d1d6ebdbbead0feb5d56622622f0498dVenugopal Iyer * MAC_UNICAST_TAG_DISABLE -- This flag is used for VLAN
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * support. It will cause MAC to not add any tags, but expect
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * vsw to tag the packets.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
4c91d6c6d1d6ebdbbead0feb5d56622622f0498dVenugopal Iyer * MAC_UNICAST_STRIP_DISABLE -- This flag is used for VLAN
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * support. It will case the MAC layer to not strip the tags.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Vsw may have to strip the tag for pvid case.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramstatic int
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_maccl_open(vsw_t *vswp, vsw_port_t *port, int type)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int instance;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng char mac_cl_name[MAXNAMELEN];
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *dev_name;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_handle_t *mchp;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer uint64_t flags = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(MUTEX_HELD(&vswp->mac_lock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vswp->mh == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * In case net-dev is changed (either set to nothing or
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * using aggregation device), return success here as the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * timeout mechanism will handle it.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mchp = (type == VSW_LOCALDEV) ? &vswp->mch : &port->p_mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (*mchp != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* already open */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng dev_name = ddi_driver_name(vswp->dip);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng instance = ddi_get_instance(vswp->dip);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (type == VSW_VNETPORT) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (port->p_hio_enabled)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng flags |= MAC_OPEN_FLAGS_SHARES_DESIRED;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) snprintf(mac_cl_name, MAXNAMELEN, "%s%d%s%d", dev_name,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng instance, "_port", port->p_instance);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) snprintf(mac_cl_name, MAXNAMELEN, "%s%s%d",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng dev_name, "_if", instance);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = mac_client_open(vswp->mh, mchp, mac_cl_name, flags);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_NOTE, "!vsw%d:%s mac_client_open() failed\n",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->instance, mac_cl_name);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (type != VSW_VNETPORT || !port->p_hio_enabled)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_client_set_rings(*mchp, MAC_RXRINGS_NONE, MAC_TXRINGS_NONE);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
06db247c678f0e3956535e8a6dec31d6c2108827raghuram return (rv);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Clean up by removing uncast, multicast addresses and
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * closing the MAC client for a port or the interface.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_client_cleanup(vsw_t *vswp, vsw_port_t *port, int type)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng WRITE_MACCL_ENTER(vswp, port, type);
7c9e7ed05a9e15467029d9a41f891a25e989426dWENTAO YANG vsw_mac_multicast_remove_all(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_unset_hw(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_maccl_close(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_MACCL_EXIT(vswp, port, type);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Close a MAC client for a port or an interface.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_maccl_close(vsw_t *vswp, vsw_port_t *port, int type)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_handle_t *mchp;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT((type == VSW_LOCALDEV) || (type == VSW_VNETPORT));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mchp = (type == VSW_LOCALDEV) ? &vswp->mch : &port->p_mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (*mchp != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_close(*mchp, 0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *mchp = NULL;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Cleanup MAC client related stuff for all ports.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_cleanup_ports(vsw_t *vswp)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_port_list_t *plist = &vswp->plist;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_port_t *port;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng READ_ENTER(&plist->lockrw);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (port = plist->head; port != NULL; port = port->p_next) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_client_cleanup(vswp, port, VSW_VNETPORT);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_EXIT(&plist->lockrw);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Depending on the mode specified, the capabilites and capacity
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * of the underlying device setup the physical device.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If in layer 3 mode, then do nothing.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If in layer 2 mode, open a mac client and program the mac-address
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * and vlan-ids. The MAC layer will take care of programming
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * the address into h/w or set the h/w into promiscuous mode.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Returns 0 success, 1 on failure.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengint
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_set_hw(vsw_t *vswp, vsw_port_t *port, int type)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int err = 1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: enter", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram ASSERT((type == VSW_LOCALDEV) || (type == VSW_VNETPORT));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vswp->smode == VSW_LAYER3)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (0);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (type == VSW_VNETPORT) {
06db247c678f0e3956535e8a6dec31d6c2108827raghuram ASSERT(port != NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = vsw_set_port_hw_addr(port);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng err = vsw_set_if_hw_addr(vswp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: exit", __func__);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (err);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If in layer 3 mode do nothing.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If in layer 2 switched mode remove the address from the physical
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * device.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If in layer 2 promiscuous mode disable promisc mode.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Returns 0 on success.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_unset_hw(vsw_t *vswp, vsw_port_t *port, int type)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D1(vswp, "%s: enter", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram ASSERT((type == VSW_LOCALDEV) || (type == VSW_VNETPORT));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vswp->smode == VSW_LAYER3)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (type == VSW_VNETPORT) {
06db247c678f0e3956535e8a6dec31d6c2108827raghuram ASSERT(port != NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_unset_hw_addr(vswp, port, type);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_unset_hw_addr(vswp, NULL, type);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: exit", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Program the macaddress and vlans of a port.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Returns 0 on sucess, 1 on failure.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_set_port_hw_addr(vsw_port_t *port)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_t *vswp = port->p_vswp;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_diag_t diag;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint8_t *macaddr;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint16_t vid = VLAN_ID_NONE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv;
4c91d6c6d1d6ebdbbead0feb5d56622622f0498dVenugopal Iyer uint16_t mac_flags = MAC_UNICAST_TAG_DISABLE |
4c91d6c6d1d6ebdbbead0feb5d56622622f0498dVenugopal Iyer MAC_UNICAST_STRIP_DISABLE;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: enter", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(RW_WRITE_HELD(&port->maccl_rwlock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (port->p_mch == NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (0);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If the port has a specific 'pvid', then
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * register with that vlan-id, otherwise register
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * with VLAN_ID_NONE.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (port->pvid != vswp->default_vlan_id) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vid = port->pvid;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng macaddr = (uint8_t *)port->p_macaddr.ether_addr_octet;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (!(vswp->smode & VSW_LAYER2_PROMISC)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_flags |= MAC_UNICAST_HW;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (port->addr_set == B_FALSE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng port->p_muh = NULL;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = mac_unicast_add(port->p_mch, macaddr, mac_flags,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng &port->p_muh, vid, &diag);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_WARN, "vsw%d: Failed to program"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "macaddr,vid(%s, %d) err=%d",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->instance, ether_sprintf((void *)macaddr),
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vid, rv);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (rv);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng port->addr_set = B_TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D2(vswp, "%s:programmed macaddr(%s) vid(%d) into device %s",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng __func__, ether_sprintf((void *)macaddr), vid,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->physname);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Add vlans to the MAC layer */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_add_vlans(vswp, port->p_mch, macaddr,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_flags, port->vids, port->nvids);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG /* Configure bandwidth to the MAC layer */
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG vsw_maccl_set_bandwidth(NULL, port, VSW_VNETPORT, port->p_bandwidth);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_rx_set(port->p_mch, vsw_port_rx_cb, (void *)port);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: exit", __func__);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (rv);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Program the macaddress and vlans of a port.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Returns 0 on sucess, 1 on failure.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramstatic int
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_set_if_hw_addr(vsw_t *vswp)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_diag_t diag;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint8_t *macaddr;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint8_t primary_addr[ETHERADDRL];
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint16_t vid = VLAN_ID_NONE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv;
4c91d6c6d1d6ebdbbead0feb5d56622622f0498dVenugopal Iyer uint16_t mac_flags = MAC_UNICAST_TAG_DISABLE |
4c91d6c6d1d6ebdbbead0feb5d56622622f0498dVenugopal Iyer MAC_UNICAST_STRIP_DISABLE;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: enter", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(RW_WRITE_HELD(&vswp->maccl_rwlock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vswp->mch == NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (0);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng macaddr = (uint8_t *)vswp->if_addr.ether_addr_octet;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* check if it is the primary macaddr of the card. */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_unicast_primary_get(vswp->mh, primary_addr);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (ether_cmp((void *)primary_addr, (void*)macaddr) == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_flags |= MAC_UNICAST_PRIMARY;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If the interface has a specific 'pvid', then
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * register with that vlan-id, otherwise register
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * with VLAN_ID_NONE.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vswp->pvid != vswp->default_vlan_id) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vid = vswp->pvid;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (!(vswp->smode & VSW_LAYER2_PROMISC)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_flags |= MAC_UNICAST_HW;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vswp->addr_set == B_FALSE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->muh = NULL;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = mac_unicast_add(vswp->mch, macaddr, mac_flags,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng &vswp->muh, vid, &diag);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_WARN, "vsw%d: Failed to program"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "macaddr,vid(%s, %d) err=%d",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->instance, ether_sprintf((void *)macaddr),
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vid, rv);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (rv);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->addr_set = B_TRUE;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D2(vswp, "%s:programmed macaddr(%s) vid(%d) into device %s",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng __func__, ether_sprintf((void *)macaddr), vid,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->physname);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_add_vlans(vswp, vswp->mch, macaddr, mac_flags,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->vids, vswp->nvids);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG vsw_maccl_set_bandwidth(vswp, NULL, VSW_LOCALDEV, vswp->bandwidth);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_rx_set(vswp->mch, vsw_if_rx_cb, (void *)vswp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: exit", __func__);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (rv);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Remove a unicast mac address which has previously been programmed
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * into HW.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Returns 0 on sucess, 1 on failure.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_unset_hw_addr(vsw_t *vswp, vsw_port_t *port, int type)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_vlanid_t *vids;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int nvids;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_handle_t mch = NULL;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: enter", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT((type == VSW_LOCALDEV) || (type == VSW_VNETPORT));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (type == VSW_VNETPORT) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(port != NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(RW_WRITE_HELD(&port->maccl_rwlock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vids = port->vids;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng nvids = port->nvids;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(RW_WRITE_HELD(&vswp->maccl_rwlock));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vids = vswp->vids;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng nvids = vswp->nvids;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* First clear the callback */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (type == VSW_LOCALDEV) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mch = vswp->mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else if (type == VSW_VNETPORT) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mch = port->p_mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (mch == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_rx_clear(mch);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Remove vlans */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_remove_vlans(mch, vids, nvids);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if ((type == VSW_LOCALDEV) && (vswp->addr_set == B_TRUE)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_unicast_remove(vswp->mch, vswp->muh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->muh = NULL;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D2(vswp, "removed vsw interface mac-addr from "
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "the device %s", vswp->physname);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->addr_set = B_FALSE;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else if ((type == VSW_VNETPORT) && (port->addr_set == B_TRUE)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) mac_unicast_remove(port->p_mch, port->p_muh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng port->p_muh = NULL;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D2(vswp, "removed port(0x%p) mac-addr from "
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "the device %s", port, vswp->physname);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng port->addr_set = B_FALSE;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D1(vswp, "%s: exit", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * receive callback routine for vsw interface. Invoked by MAC layer when there
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * are pkts being passed up from physical device for this vsw interface.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* ARGSUSED */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_if_rx_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng boolean_t loopback)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng _NOTE(ARGUNUSED(mrh))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
06db247c678f0e3956535e8a6dec31d6c2108827raghuram vsw_t *vswp = (vsw_t *)arg;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mblk_t *mpt;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int count;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram ASSERT(vswp != NULL);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: enter", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng READ_ENTER(&vswp->if_lockrw);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vswp->if_state & VSW_IF_UP) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_EXIT(&vswp->if_lockrw);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng count = vsw_vlan_frame_untag(vswp, VSW_LOCALDEV, &mp, &mpt);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (count != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_rx(vswp->if_mh, NULL, mp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_EXIT(&vswp->if_lockrw);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng freemsgchain(mp);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: exit", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * receive callback routine for port. Invoked by MAC layer when there
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * are pkts being passed up from physical device for this port.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* ARGSUSED */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_port_rx_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng boolean_t loopback)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng _NOTE(ARGUNUSED(mrh))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_t *vswp;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_port_t *port = arg;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ASSERT(port != NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp = port->p_vswp;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D1(vswp, "vsw_port_rx_cb: enter");
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Send the packets to the peer directly.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (void) vsw_portsend(port, mp);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D1(vswp, "vsw_port_rx_cb: exit");
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Send a message out over the physical device
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * via the MAC layer.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Returns any mblks that it was unable to transmit.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengmblk_t *
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_tx_msg(vsw_t *vswp, mblk_t *mp, int caller, vsw_port_t *port)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_client_handle_t mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_unicast_handle_t muh;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng READ_MACCL_ENTER(vswp, port, caller);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mch = (caller == VSW_LOCALDEV) ? vswp->mch : port->p_mch;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng muh = (caller == VSW_LOCALDEV) ? vswp->muh : port->p_muh;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (mch == NULL || muh == NULL) {
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG RW_MACCL_EXIT(vswp, port, caller);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG return (mp);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* packets are sent or dropped */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG (void) mac_tx(mch, mp, 0, MAC_DROP_ON_NO_DESC, NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_MACCL_EXIT(vswp, port, caller);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return (NULL);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * vsw_port_mac_reconfig -- Cleanup and close the MAC client
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * and reopen and re-configure the MAC client with new flags etc.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * This function is useful for two different purposes:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * 1) To update the MAC client with new vlan-ids. This is done
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * by freeing the existing vlan-ids and reopen with the new
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * vlan-ids.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * 2) If the Hybrid mode status of a port changes, then the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * MAC client need to be closed and re-opened, otherwise,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Share related resources may not be freed(hybird mode disabled)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * or assigned(hybrid mode enabled). To accomplish this,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * this function simply closes and reopens the MAC client.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * The reopen will result in using the flags based on the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * new hybrid mode of the port.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_port_mac_reconfig(vsw_port_t *portp, boolean_t update_vlans,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint16_t new_pvid, vsw_vlanid_t *new_vids, int new_nvids)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_t *vswp = portp->p_vswp;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D1(vswp, "%s: enter", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Remove the multi-cast addresses, unicast address
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * and close the mac-client.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng WRITE_ENTER(&portp->maccl_rwlock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_multicast_remove_all(vswp, portp, VSW_VNETPORT);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_unset_hw(vswp, portp, VSW_VNETPORT);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_maccl_close(vswp, portp, VSW_VNETPORT);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (update_vlans == B_TRUE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (portp->nvids != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng kmem_free(portp->vids,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng sizeof (vsw_vlanid_t) * portp->nvids);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng portp->vids = NULL;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng portp->nvids = 0;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng portp->vids = new_vids;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng portp->nvids = new_nvids;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng portp->pvid = new_pvid;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Now re-open the mac-client and
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * configure unicast addr and multicast addrs.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = vsw_maccl_open(vswp, portp, VSW_VNETPORT);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto recret;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vsw_set_hw(vswp, portp, VSW_VNETPORT)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_NOTE, "!vsw%d: port:%d failed to "
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "set unicast address\n", vswp->instance, portp->p_instance);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto recret;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_multicast_add_all(vswp, portp, VSW_VNETPORT);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengrecret:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_EXIT(&portp->maccl_rwlock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D1(vswp, "%s: exit", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * vsw_if_mac_reconfig -- Reconfigure the vsw interfaace's mac-client
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * by closing and re-opening it. This function is used handle the
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * following two cases:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * 1) Handle the MAC address change for the interface.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * 2) Handle vlan update.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_if_mac_reconfig(vsw_t *vswp, boolean_t update_vlans,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint16_t new_pvid, vsw_vlanid_t *new_vids, int new_nvids)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: enter", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Remove the multi-cast addresses, unicast address
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * and close the mac-client.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_enter(&vswp->mac_lock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng WRITE_ENTER(&vswp->maccl_rwlock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_multicast_remove_all(vswp, NULL, VSW_LOCALDEV);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_unset_hw(vswp, NULL, VSW_LOCALDEV);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_maccl_close(vswp, NULL, VSW_LOCALDEV);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (update_vlans == B_TRUE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vswp->nvids != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng kmem_free(vswp->vids,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng sizeof (vsw_vlanid_t) * vswp->nvids);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->vids = NULL;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->nvids = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->vids = new_vids;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->nvids = new_nvids;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->pvid = new_pvid;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Now re-open the mac-client and
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * configure unicast addr and multicast addrs.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = vsw_maccl_open(vswp, NULL, VSW_LOCALDEV);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto ifrecret;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vsw_set_hw(vswp, NULL, VSW_LOCALDEV)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_NOTE, "!vsw%d:failed to set unicast address\n",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->instance);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto ifrecret;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_mac_multicast_add_all(vswp, NULL, VSW_LOCALDEV);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Chengifrecret:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RW_EXIT(&vswp->maccl_rwlock);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mutex_exit(&vswp->mac_lock);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram D1(vswp, "%s: exit", __func__);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * vsw_mac_port_reconfig_vlans -- Reconfigure a port to handle
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * vlan configuration update. As the removal of the last unicast-address,vid
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * from the MAC client results in releasing all resources, it expects
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * no Shares to be associated with such MAC client.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram *
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * To handle vlan configuration update for a port that already has
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * a Share bound, then we need to free that share prior to reconfiguration.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Initiate the hybrdIO setup again after the completion of reconfiguration.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvoid
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_port_reconfig_vlans(vsw_port_t *portp, uint16_t new_pvid,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_vlanid_t *new_vids, int new_nvids)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * As the reconfiguration involves the close of
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * mac client, cleanup HybridIO and later restart
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * HybridIO setup again.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (portp->p_hio_enabled == B_TRUE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_hio_stop_port(portp);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_port_mac_reconfig(portp, B_TRUE, new_pvid, new_vids, new_nvids);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (portp->p_hio_enabled == B_TRUE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* reset to setup the HybridIO again. */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_hio_port_reset(portp, B_FALSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* Add vlans to MAC client */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_add_vlans(vsw_t *vswp, mac_client_handle_t mch, uint8_t *macaddr,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint16_t flags, vsw_vlanid_t *vids, int nvids)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_vlanid_t *vidp;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_diag_t diag;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int i;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
4c91d6c6d1d6ebdbbead0feb5d56622622f0498dVenugopal Iyer flags |= MAC_UNICAST_TAG_DISABLE | MAC_UNICAST_STRIP_DISABLE;
4c91d6c6d1d6ebdbbead0feb5d56622622f0498dVenugopal Iyer
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Add vlans to the MAC layer */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (i = 0; i < nvids; i++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vidp = &vids[i];
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vidp->vl_set == B_TRUE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng continue;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = mac_unicast_add(mch, macaddr, flags,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng &vidp->vl_muh, vidp->vl_vid, &diag);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (rv != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng cmn_err(CE_WARN, "vsw%d: Failed to program"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "macaddr,vid(%s, %d) err=%d",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->instance, ether_sprintf((void *)macaddr),
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vidp->vl_vid, rv);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vidp->vl_set = B_TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng D2(vswp, "%s:programmed macaddr(%s) vid(%d) "
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "into device %s", __func__,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ether_sprintf((void *)macaddr),
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vidp->vl_vid, vswp->physname);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* Remove vlans from the MAC client */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_mac_remove_vlans(mac_client_handle_t mch, vsw_vlanid_t *vids, int nvids)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int i;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vsw_vlanid_t *vidp;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (i = 0; i < nvids; i++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vidp = &vids[i];
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (vidp->vl_set == B_FALSE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng continue;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mac_unicast_remove(mch, vidp->vl_muh);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vidp->vl_set = B_FALSE;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram }
06db247c678f0e3956535e8a6dec31d6c2108827raghuram}
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb#define ARH_FIXED_LEN 8 /* Length of fixed part of ARP header(see arp.h) */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb/*
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * Send a gratuitous RARP packet to notify the physical switch to update its
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * Layer2 forwarding table for the given mac address. This is done to allow the
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * switch to quickly learn the macaddr-port association when a guest is live
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * migrated or when vsw's physical device is changed dynamically. Any protocol
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * packet would serve this purpose, but we choose RARP, as it allows us to
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * accomplish this within L2 (ie, no need to specify IP addr etc in the packet)
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * The macaddr of vnet is retained across migration. Hence, we don't need to
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * update the arp cache of other hosts within the broadcast domain. Note that
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * it is harmless to send these RARP packets during normal port attach of a
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * client vnet. This can can be turned off if needed, by setting
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb * vsw_publish_macaddr_count to zero in /etc/system.
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csbvoid
da14cebe459d3275048785f25bd869cb09b5307fEric Chengvsw_publish_macaddr(vsw_t *vswp, vsw_port_t *portp)
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb{
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb mblk_t *mp;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb mblk_t *bp;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb struct arphdr *arh;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb struct ether_header *ehp;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb int count = 0;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb int plen = 4;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb uint8_t *cp;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb mp = allocb(ETHERMIN, BPRI_MED);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb if (mp == NULL) {
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb return;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb }
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb /* Initialize eth header */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb ehp = (struct ether_header *)mp->b_rptr;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb bcopy(&etherbroadcastaddr, &ehp->ether_dhost, ETHERADDRL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bcopy(&portp->p_macaddr, &ehp->ether_shost, ETHERADDRL);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb ehp->ether_type = htons(ETHERTYPE_REVARP);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb /* Initialize arp packet */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb arh = (struct arphdr *)(mp->b_rptr + sizeof (struct ether_header));
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb cp = (uint8_t *)arh;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb arh->ar_hrd = htons(ARPHRD_ETHER); /* Hardware type: ethernet */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb arh->ar_pro = htons(ETHERTYPE_IP); /* Protocol type: IP */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb arh->ar_hln = ETHERADDRL; /* Length of hardware address: 6 */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb arh->ar_pln = plen; /* Length of protocol address: 4 */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb arh->ar_op = htons(REVARP_REQUEST); /* Opcode: REVARP Request */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb cp += ARH_FIXED_LEN;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb /* Sender's hardware address and protocol address */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bcopy(&portp->p_macaddr, cp, ETHERADDRL);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb cp += ETHERADDRL;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb bzero(cp, plen); /* INADDR_ANY */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb cp += plen;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb /* Target hardware address and protocol address */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bcopy(&portp->p_macaddr, cp, ETHERADDRL);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb cp += ETHERADDRL;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb bzero(cp, plen); /* INADDR_ANY */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb cp += plen;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb mp->b_wptr += ETHERMIN; /* total size is 42; round up to ETHERMIN */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb for (count = 0; count < vsw_publish_macaddr_count; count++) {
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb bp = dupmsg(mp);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb if (bp == NULL) {
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb continue;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb }
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb /* transmit the packet */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bp = vsw_tx_msg(vswp, bp, VSW_VNETPORT, portp);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb if (bp != NULL) {
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb freemsg(bp);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb }
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb }
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb freemsg(mp);
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb}
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatnastatic void
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatnavsw_mac_set_mtu(vsw_t *vswp, uint32_t mtu)
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint_t mtu_orig;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int rv;
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rv = mac_set_mtu(vswp->mh, mtu, &mtu_orig);
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna if (rv != 0) {
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna cmn_err(CE_NOTE,
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna "!vsw%d: Unable to set the mtu:%d, in the "
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna "physical device:%s\n",
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna vswp->instance, mtu, vswp->physname);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return;
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* save the original mtu of physdev to reset it back later if needed */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng vswp->mtu_physdev_orig = mtu_orig;
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna}
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna/*
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * Register a callback with underlying mac layer for notifications.
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * We are currently interested in only link-state events.
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnastatic int
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnavsw_notify_add(vsw_t *vswp)
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna{
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna mac_notify_handle_t mnh;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna uint32_t note;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna /*
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * Check if the underlying MAC supports link update notification.
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna note = mac_no_notification(vswp->mh);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna if ((note & (DL_NOTE_LINK_UP | DL_NOTE_LINK_DOWN)) != 0) {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vswp->phys_no_link_update = B_TRUE;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna } else {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vswp->phys_no_link_update = B_FALSE;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna }
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna /*
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * Read the current link state of the device and cache it.
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vswp->phys_link_state = vswp->phys_no_link_update ? LINK_STATE_UP :
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna mac_stat_get(vswp->mh, MAC_STAT_LINK_STATE);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna /*
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * Add notify callback function, if link update is supported.
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna if (vswp->phys_no_link_update == B_TRUE) {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna return (0);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna }
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna mnh = mac_notify_add(vswp->mh, vsw_notify_cb, vswp);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna if (mnh == 0) {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna /* failed */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna return (1);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna }
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vswp->mnh = mnh;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna return (0);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna}
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna/*
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * Remove notify callback.
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnastatic int
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnavsw_notify_rem(vsw_t *vswp)
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna{
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna int rv;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna rv = mac_notify_remove(vswp->mnh, B_FALSE);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna return (rv);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna}
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna/*
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * Notification callback invoked by the MAC service
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * module. Note that we process only link state updates.
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnastatic void
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnavsw_notify_cb(void *arg, mac_notify_type_t type)
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna{
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vsw_t *vswp = arg;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna switch (type) {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna case MAC_NOTE_LINK:
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vsw_notify_link(vswp);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna break;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna default:
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna break;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna }
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna}
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna/*
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * Invoked upon receiving a MAC_NOTE_LINK
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * notification for the underlying physical device.
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnastatic void
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnavsw_notify_link(vsw_t *vswp)
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna{
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna link_state_t link_state;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna /* link state change notification */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna link_state = mac_stat_get(vswp->mh, MAC_STAT_LINK_STATE);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna if (vswp->phys_link_state != link_state) {
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna D3(vswp, "%s: phys_link_state(%d)\n",
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna __func__, vswp->phys_link_state);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vswp->phys_link_state = link_state;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna vsw_physlink_state_update(vswp);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna }
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna}
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG/*
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * Configure the bandwidth limit on the vsw or vnet devices via the MAC layer.
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * Note that bandwidth limit is not supported on a HybridIO enabled
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * vnet, as the HybridIO assigns a specific unit of hardware resource
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * that cannot be changed to limit bandwidth.
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG */
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGstatic void
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGvsw_maccl_set_bandwidth(vsw_t *vswp, vsw_port_t *port, int type, uint64_t maxbw)
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG{
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG int rv = 0;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG uint64_t *bw;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_resource_props_t *mrp;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG mac_client_handle_t mch;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG ASSERT((type == VSW_LOCALDEV) || (type == VSW_VNETPORT));
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG if (type == VSW_VNETPORT) {
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG ASSERT(RW_WRITE_HELD(&port->maccl_rwlock));
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG mch = port->p_mch;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG bw = &port->p_bandwidth;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG } else {
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG ASSERT(RW_WRITE_HELD(&vswp->maccl_rwlock));
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG mch = vswp->mch;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG bw = &vswp->bandwidth;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG }
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG if (mch == NULL) {
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG return;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG }
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG if (maxbw >= MRP_MAXBW_MINVAL || maxbw == 0) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mrp = kmem_zalloc(sizeof (*mrp), KM_SLEEP);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG if (maxbw == 0) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mrp->mrp_maxbw = MRP_MAXBW_RESETVAL;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG } else {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mrp->mrp_maxbw = maxbw;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG }
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mrp->mrp_mask |= MRP_MAXBW;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer rv = mac_client_set_resources(mch, mrp);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG if (rv != 0) {
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG if (type == VSW_VNETPORT) {
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG cmn_err(CE_NOTE, "!port%d: cannot set "
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG "bandwidth limit to (%ld), error(%d)\n",
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG port->p_instance, maxbw, rv);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG } else {
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG cmn_err(CE_NOTE, "!vsw%d: cannot set "
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG "bandwidth limit to (%ld), error(%d)\n",
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG vswp->instance, maxbw, rv);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG }
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG } else {
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG /*
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * update with successfully configured bandwidth.
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG */
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG *bw = maxbw;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG }
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer kmem_free(mrp, sizeof (*mrp));
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG }
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG}