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 }