xref: /illumos-gate/usr/src/uts/common/io/aggr/aggr_dev.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * IEEE 802.3ad Link Aggregation.
28  */
29 
30 #include <sys/conf.h>
31 #include <sys/modctl.h>
32 #include <sys/aggr.h>
33 #include <sys/aggr_impl.h>
34 
35 /* module description */
36 #define	AGGR_LINKINFO	"Link Aggregation MAC"
37 
38 /* device info ptr, only one for instance 0 */
39 dev_info_t *aggr_dip = NULL;
40 
41 static int aggr_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
42 static int aggr_attach(dev_info_t *, ddi_attach_cmd_t);
43 static int aggr_detach(dev_info_t *, ddi_detach_cmd_t);
44 
45 DDI_DEFINE_STREAM_OPS(aggr_dev_ops, nulldev, nulldev, aggr_attach, aggr_detach,
46     nodev, aggr_getinfo, D_MP, NULL, ddi_quiesce_not_supported);
47 
48 static struct modldrv aggr_modldrv = {
49 	&mod_driverops,		/* Type of module.  This one is a driver */
50 	AGGR_LINKINFO,		/* short description */
51 	&aggr_dev_ops		/* driver specific ops */
52 };
53 
54 static struct modlinkage modlinkage = {
55 	MODREV_1, &aggr_modldrv, NULL
56 };
57 
58 int
59 _init(void)
60 {
61 	int	err;
62 
63 	mac_init_ops(&aggr_dev_ops, "aggr");
64 	if ((err = mod_install(&modlinkage)) != 0)
65 		mac_fini_ops(&aggr_dev_ops);
66 	return (err);
67 }
68 
69 int
70 _fini(void)
71 {
72 	int	err;
73 
74 	if ((err = mod_remove(&modlinkage)) == 0)
75 		mac_fini_ops(&aggr_dev_ops);
76 	return (err);
77 }
78 
79 int
80 _info(struct modinfo *modinfop)
81 {
82 	return (mod_info(&modlinkage, modinfop));
83 }
84 
85 /*ARGSUSED*/
86 static int
87 aggr_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
88     void **result)
89 {
90 	switch (infocmd) {
91 	case DDI_INFO_DEVT2DEVINFO:
92 		*result = aggr_dip;
93 		return (DDI_SUCCESS);
94 	case DDI_INFO_DEVT2INSTANCE:
95 		*result = 0;
96 		return (DDI_SUCCESS);
97 	}
98 	return (DDI_FAILURE);
99 }
100 
101 static int
102 aggr_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
103 {
104 	switch (cmd) {
105 	case DDI_ATTACH:
106 		if (ddi_get_instance(dip) != 0) {
107 			/* we only allow instance 0 to attach */
108 			return (DDI_FAILURE);
109 		}
110 		if (aggr_ioc_init() != 0)
111 			return (DDI_FAILURE);
112 		aggr_dip = dip;
113 		aggr_port_init();
114 		aggr_grp_init();
115 		aggr_lacp_init();
116 		return (DDI_SUCCESS);
117 
118 	case DDI_RESUME:
119 		return (DDI_SUCCESS);
120 
121 	default:
122 		return (DDI_FAILURE);
123 	}
124 }
125 
126 /*ARGSUSED*/
127 static int
128 aggr_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
129 {
130 	switch (cmd) {
131 	case DDI_DETACH:
132 		if (aggr_grp_count() > 0)
133 			return (DDI_FAILURE);
134 
135 		aggr_dip = NULL;
136 		aggr_port_fini();
137 		aggr_grp_fini();
138 		aggr_lacp_fini();
139 		aggr_ioc_fini();
140 		return (DDI_SUCCESS);
141 
142 	case DDI_SUSPEND:
143 		return (DDI_SUCCESS);
144 
145 	default:
146 		return (DDI_FAILURE);
147 	}
148 }
149