xref: /illumos-gate/usr/src/uts/common/io/aggr/aggr_dev.c (revision da14cebe459d3275048785f25bd869cb09b5307f)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5f12af565Snd99603  * Common Development and Distribution License (the "License").
6f12af565Snd99603  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22d62bc4baSyz147064  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * IEEE 802.3ad Link Aggregation.
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <sys/conf.h>
317c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
327c478bd9Sstevel@tonic-gate #include <sys/aggr.h>
337c478bd9Sstevel@tonic-gate #include <sys/aggr_impl.h>
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate /* module description */
367c478bd9Sstevel@tonic-gate #define	AGGR_LINKINFO	"Link Aggregation MAC"
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /* device info ptr, only one for instance 0 */
39c0192a57Sericheng dev_info_t *aggr_dip = NULL;
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate static int aggr_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
427c478bd9Sstevel@tonic-gate static int aggr_attach(dev_info_t *, ddi_attach_cmd_t);
437c478bd9Sstevel@tonic-gate static int aggr_detach(dev_info_t *, ddi_detach_cmd_t);
447c478bd9Sstevel@tonic-gate 
45*da14cebeSEric Cheng DDI_DEFINE_STREAM_OPS(aggr_dev_ops, nulldev, nulldev, aggr_attach, aggr_detach,
46*da14cebeSEric Cheng     nodev, aggr_getinfo, D_MP, NULL, ddi_quiesce_not_supported);
477c478bd9Sstevel@tonic-gate 
48210db224Sericheng static struct modldrv aggr_modldrv = {
49210db224Sericheng 	&mod_driverops,		/* Type of module.  This one is a driver */
50210db224Sericheng 	AGGR_LINKINFO,		/* short description */
51210db224Sericheng 	&aggr_dev_ops		/* driver specific ops */
527c478bd9Sstevel@tonic-gate };
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = {
55*da14cebeSEric Cheng 	MODREV_1, &aggr_modldrv, NULL
567c478bd9Sstevel@tonic-gate };
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate int
_init(void)597c478bd9Sstevel@tonic-gate _init(void)
607c478bd9Sstevel@tonic-gate {
61eae72b5bSSebastien Roy 	int	err;
62eae72b5bSSebastien Roy 
63eae72b5bSSebastien Roy 	mac_init_ops(&aggr_dev_ops, "aggr");
64eae72b5bSSebastien Roy 	if ((err = mod_install(&modlinkage)) != 0)
65eae72b5bSSebastien Roy 		mac_fini_ops(&aggr_dev_ops);
66eae72b5bSSebastien Roy 	return (err);
677c478bd9Sstevel@tonic-gate }
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate int
_fini(void)707c478bd9Sstevel@tonic-gate _fini(void)
717c478bd9Sstevel@tonic-gate {
72eae72b5bSSebastien Roy 	int	err;
73eae72b5bSSebastien Roy 
74eae72b5bSSebastien Roy 	if ((err = mod_remove(&modlinkage)) == 0)
75eae72b5bSSebastien Roy 		mac_fini_ops(&aggr_dev_ops);
76eae72b5bSSebastien Roy 	return (err);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate int
_info(struct modinfo * modinfop)807c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop)
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate 	return (mod_info(&modlinkage, modinfop));
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate /*ARGSUSED*/
867c478bd9Sstevel@tonic-gate static int
aggr_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)877c478bd9Sstevel@tonic-gate aggr_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
887c478bd9Sstevel@tonic-gate     void **result)
897c478bd9Sstevel@tonic-gate {
907c478bd9Sstevel@tonic-gate 	switch (infocmd) {
917c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2DEVINFO:
927c478bd9Sstevel@tonic-gate 		*result = aggr_dip;
937c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
947c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2INSTANCE:
95eae72b5bSSebastien Roy 		*result = 0;
967c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
977c478bd9Sstevel@tonic-gate 	}
987c478bd9Sstevel@tonic-gate 	return (DDI_FAILURE);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate static int
aggr_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)1027c478bd9Sstevel@tonic-gate aggr_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1037c478bd9Sstevel@tonic-gate {
1047c478bd9Sstevel@tonic-gate 	switch (cmd) {
1057c478bd9Sstevel@tonic-gate 	case DDI_ATTACH:
1067c478bd9Sstevel@tonic-gate 		if (ddi_get_instance(dip) != 0) {
1077c478bd9Sstevel@tonic-gate 			/* we only allow instance 0 to attach */
1087c478bd9Sstevel@tonic-gate 			return (DDI_FAILURE);
1097c478bd9Sstevel@tonic-gate 		}
110eae72b5bSSebastien Roy 		if (aggr_ioc_init() != 0)
1117c478bd9Sstevel@tonic-gate 			return (DDI_FAILURE);
1127c478bd9Sstevel@tonic-gate 		aggr_dip = dip;
113c0192a57Sericheng 		aggr_port_init();
114c0192a57Sericheng 		aggr_grp_init();
115c0192a57Sericheng 		aggr_lacp_init();
1167c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	case DDI_RESUME:
1197c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	default:
1227c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
1237c478bd9Sstevel@tonic-gate 	}
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1277c478bd9Sstevel@tonic-gate static int
aggr_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)1287c478bd9Sstevel@tonic-gate aggr_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1297c478bd9Sstevel@tonic-gate {
1307c478bd9Sstevel@tonic-gate 	switch (cmd) {
1317c478bd9Sstevel@tonic-gate 	case DDI_DETACH:
132210db224Sericheng 		if (aggr_grp_count() > 0)
133210db224Sericheng 			return (DDI_FAILURE);
134210db224Sericheng 
1357c478bd9Sstevel@tonic-gate 		aggr_dip = NULL;
136c0192a57Sericheng 		aggr_port_fini();
137c0192a57Sericheng 		aggr_grp_fini();
138c0192a57Sericheng 		aggr_lacp_fini();
139eae72b5bSSebastien Roy 		aggr_ioc_fini();
1407c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	case DDI_SUSPEND:
1437c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	default:
1467c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
1477c478bd9Sstevel@tonic-gate 	}
1487c478bd9Sstevel@tonic-gate }
149