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 #ifndef _SYS_SOFTMAC_IMPL_H 27 #define _SYS_SOFTMAC_IMPL_H 28 29 #include <sys/types.h> 30 #include <sys/ethernet.h> 31 #include <sys/taskq.h> 32 #include <sys/sunddi.h> 33 #include <sys/sunldi.h> 34 #include <sys/strsun.h> 35 #include <sys/stream.h> 36 #include <sys/dlpi.h> 37 #include <sys/mac.h> 38 #include <sys/mac_provider.h> 39 #include <sys/mac_client.h> 40 #include <sys/mac_client_priv.h> 41 #include <sys/mac_ether.h> 42 43 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 typedef struct softmac_lower_s { 48 struct softmac *sl_softmac; 49 queue_t *sl_wq; 50 51 /* 52 * sl_ctl_inprogress is used to serialize the control path. It will 53 * be set when either an ioctl or an M_{PC,}PROTO message is received 54 * from the upper layer, and will be cleared when processing done. 55 */ 56 kmutex_t sl_ctl_mutex; 57 kcondvar_t sl_ctl_cv; 58 boolean_t sl_ctl_inprogress; 59 60 /* 61 * When a control message is processed, either sl_pending_prim or 62 * sl_pending_ioctl will be set. They will be cleared when the 63 * acknowledgement of the specific control message is received 64 * from the underlying legacy driver. 65 */ 66 kmutex_t sl_mutex; 67 kcondvar_t sl_cv; 68 t_uscalar_t sl_pending_prim; 69 boolean_t sl_pending_ioctl; 70 mblk_t *sl_ack_mp; 71 72 ldi_handle_t sl_lh; 73 } softmac_lower_t; 74 75 typedef enum { 76 SOFTMAC_INITIALIZED, 77 SOFTMAC_READY 78 } softmac_lower_state_t; 79 80 typedef enum { 81 SOFTMAC_UNINIT, 82 SOFTMAC_ATTACH_INPROG, 83 SOFTMAC_ATTACH_DONE, 84 SOFTMAC_DETACH_INPROG, 85 } softmac_state_t; 86 87 typedef struct softmac_dev_s { 88 dev_t sd_dev; 89 } softmac_dev_t; 90 91 /* 92 * smac_flag values. 93 */ 94 #define SOFTMAC_GLDV3 0x01 95 #define SOFTMAC_NOSUPP 0x02 96 #define SOFTMAC_NEED_RECREATE 0x04 97 #define SOFTMAC_NOTIFY_QUIT 0x08 98 99 #define SMAC_NONZERO_NODECNT(softmac) \ 100 ((softmac->smac_softmac[0] != NULL) + \ 101 (softmac->smac_softmac[1] != NULL)) 102 103 /* 104 * The softmac structure allows all minor nodes (at most two, style-1 and 105 * style-2) for the same device to be processed. A softmac_dev_t will be 106 * created for each minor node. 107 * 108 * We try to "register" the mac after all the softmac_dev_t's are processed so 109 * that even if DLPI operations fail (because of driver bugs) for one minor 110 * node, the other minor node can still be used to register the mac. 111 * (Specifically, an incorrect xxx_getinfo() implementation will cause style-2 112 * minor node mac registration to fail.) 113 */ 114 typedef struct softmac { 115 /* 116 * The following fields will be set when the softmac is created and 117 * will not change. No lock is required. 118 */ 119 char smac_devname[MAXNAMELEN]; 120 major_t smac_umajor; 121 int smac_uppa; 122 uint32_t smac_cnt; /* # of minor nodes for this device */ 123 124 /* 125 * The following fields are protected by smac_mutex. 126 * 127 * The smac_hold_cnt field increases when softmac_hold_device() is 128 * called to force the dls_vlan_t of the device to be created. The 129 * device pre-detach fails if this counter is not 0. 130 */ 131 softmac_state_t smac_state; 132 uint32_t smac_hold_cnt; 133 kmutex_t smac_mutex; 134 kcondvar_t smac_cv; 135 uint32_t smac_flags; 136 int smac_attacherr; 137 mac_handle_t smac_mh; 138 softmac_dev_t *smac_softmac[2]; 139 taskqid_t smac_taskq; 140 /* 141 * Number of minor nodes whose post-attach routine has succeeded. 142 * This should be the same as the numbers of softmac_dev_t. 143 * Note that it does not imply SOFTMAC_ATTACH_DONE as the taskq might 144 * be still ongoing. 145 */ 146 uint32_t smac_attachok_cnt; 147 /* 148 * Number of softmac_dev_t left when pre-detach fails. This is used 149 * to indicate whether postattach is called because of a failed 150 * pre-detach. 151 */ 152 uint32_t smac_attached_left; 153 154 /* 155 * Thread handles the DL_NOTIFY_IND message from the lower stream. 156 */ 157 kthread_t *smac_notify_thread; 158 /* 159 * Head and tail of the DL_NOTIFY_IND messsages. 160 */ 161 mblk_t *smac_notify_head; 162 mblk_t *smac_notify_tail; 163 164 /* 165 * The remaining fields are used to register the MAC for a legacy 166 * device. They are set in softmac_mac_register() and do not change. 167 * One can access them when mac_register() is done without locks. 168 */ 169 170 /* 171 * media type is needed for create <link name, linkid> mapping, so 172 * it is set for GLDv3 device as well 173 */ 174 uint_t smac_media; 175 /* DLPI style of the underlying device */ 176 int smac_style; 177 dev_t smac_dev; 178 size_t smac_saplen; 179 size_t smac_addrlen; 180 uchar_t smac_unicst_addr[MAXMACADDRLEN]; 181 uint_t smac_min_sdu; 182 uint_t smac_max_sdu; 183 uint32_t smac_margin; 184 185 /* Notifications the underlying driver can support. */ 186 uint32_t smac_notifications; 187 188 /* 189 * Capabilities of the underlying driver. 190 */ 191 uint32_t smac_capab_flags; 192 uint32_t smac_hcksum_txflags; 193 boolean_t smac_no_capability_req; 194 dl_capab_mdt_t smac_mdt_capab; 195 boolean_t smac_mdt; 196 197 /* Following fields protected by the mac perimeter */ 198 softmac_lower_state_t smac_lower_state; 199 /* Lower stream structure */ 200 softmac_lower_t *smac_lower; 201 } softmac_t; 202 203 typedef struct smac_ioc_start_s { 204 softmac_lower_t *si_slp; 205 } smac_ioc_start_t; 206 207 #define SMAC_IOC ('S' << 24 | 'M' << 16 | 'C' << 8) 208 #define SMAC_IOC_START (SMAC_IOC | 0x01) 209 210 extern dev_info_t *softmac_dip; 211 #define SOFTMAC_DEV_NAME "softmac" 212 213 extern int softmac_send_bind_req(softmac_lower_t *, uint_t); 214 extern int softmac_send_notify_req(softmac_lower_t *, uint32_t); 215 extern int softmac_send_promisc_req(softmac_lower_t *, t_uscalar_t, 216 boolean_t); 217 extern void softmac_init(void); 218 extern void softmac_fini(void); 219 extern boolean_t softmac_busy(void); 220 extern int softmac_fill_capab(ldi_handle_t, softmac_t *); 221 extern int softmac_capab_enable(softmac_lower_t *); 222 extern void softmac_rput_process_notdata(queue_t *, mblk_t *); 223 extern void softmac_rput_process_data(softmac_lower_t *, mblk_t *); 224 225 extern int softmac_m_promisc(void *, boolean_t); 226 extern int softmac_m_multicst(void *, boolean_t, const uint8_t *); 227 extern int softmac_m_unicst(void *, const uint8_t *); 228 extern void softmac_m_ioctl(void *, queue_t *, mblk_t *); 229 extern int softmac_m_stat(void *, uint_t, uint64_t *); 230 extern mblk_t *softmac_m_tx(void *, mblk_t *); 231 extern int softmac_proto_tx(softmac_lower_t *, mblk_t *, mblk_t **); 232 extern void softmac_ioctl_tx(softmac_lower_t *, mblk_t *, mblk_t **); 233 extern void softmac_notify_thread(void *); 234 235 #ifdef __cplusplus 236 } 237 #endif 238 239 #endif /* _SYS_SOFTMAC_IMPL_H */ 240