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.
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.
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]
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/types.h>
30 #include <sys/sunddi.h>
31 #include <sys/ksynch.h>
33 #include <sys/ib/clients/eoib/eib_impl.h>
36 * Definitions private to this file
38 ib_gid_t eib_reserved_gid
;
40 uint8_t eib_zero_mac
[] = {
41 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
44 uint8_t eib_broadcast_mac
[] = {
45 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
48 int eib_setbit_mod67
[] = {
49 -1, 0, 1, 39, 2, 15, 40, 23,
50 3, 12, 16, 59, 41, 19, 24, 54,
51 4, -1, 13, 10, 17, 62, 60, 28,
52 42, 30, 20, 51, 25, 44, 55, 47,
53 5, 32, -1, 38, 14, 22, 11, 58,
54 18, 53, 63, 9, 61, 27, 29, 50,
55 43, 46, 31, 37, 21, 57, 52, 8,
56 26, 49, 45, 36, 56, 7, 48, 35,
60 char *eib_pvt_props
[] = {
61 EIB_DLPROP_GW_EPORT_STATE
,
67 #define eib_prop_get_and_test(inst, dp, propname, propval) \
69 (propval) = ddi_prop_get_int(DDI_DEV_T_ANY, (dp), \
70 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, (propname), -1); \
71 if ((propval) == -1) { \
72 EIB_DPRINTF_WARN((inst), "eib_get_props: " \
73 "ddi_prop_get_int() could not find " \
74 "property '%s'", (propname)); \
75 goto get_props_fail; \
79 #define eib_prop64_get_and_test(inst, dp, propname, propval) \
81 (propval) = ddi_prop_get_int64(DDI_DEV_T_ANY, (dp), \
82 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, (propname), -1); \
83 if ((propval) == -1) { \
84 EIB_DPRINTF_WARN((inst), "eib_get_props: " \
85 "ddi_prop_get_int64() could not find " \
86 "property '%s'", (propname)); \
87 goto get_props_fail; \
91 #define eib_propstr_get_and_test(inst, dp, propname, propval_p) \
95 *(propval_p) = NULL; \
97 rv = ddi_prop_lookup_string(DDI_DEV_T_ANY, (dp), \
98 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, (propname), \
100 if (rv != DDI_PROP_SUCCESS) { \
101 EIB_DPRINTF_WARN((inst), "eib_get_props: " \
102 "ddi_prop_lookup_string() could not find " \
103 "property '%s'", (propname)); \
104 goto get_props_fail; \
113 * 1. Verification of descriptor list length in the received packets is
114 * disabled, since experimentation shows that BX does not set the desc
115 * list length correctly. True for EoIB nexus as well.
117 int eib_wa_no_desc_list_len
= 1;
120 * 2. LSO/Checksum_Offload for EoIB packets does not seem to be supported
121 * currently, so we'll disable both temporarily.
123 int eib_wa_no_cksum_offload
= 1;
124 int eib_wa_no_lso
= 1;
127 * 3. The "multicast entry" types are not clearly defined in the spec
128 * at the moment. The current BX software/firmware appears to ignore
129 * the type of the context table entries, so we will treat these
130 * addresses just like regular vnic addresses.
132 int eib_wa_no_mcast_entries
= 1;
135 * 4. VHUB updates from the gateways provide us with destination LIDs,
136 * and we will hand-create these address vectors.
138 int eib_wa_no_av_discover
= 1;
141 * 5. The older BX software does not seem to set the VP flag correctly
142 * in the login acknowledgements even when it successfully allocates
143 * a vlan, so we will ignore it for now.
145 int eib_wa_no_good_vp_flag
= 1;
148 * 6. Each vhub table is expected to carry a checksum at the end to
149 * verify the contents of the received vhub table. The current BX
150 * software/firmware does not seem to fill this field with the
151 * correct value (and/or the spec description is ambiguous). We
152 * will ignore the vhub table checksum verification for now.
154 int eib_wa_no_good_vhub_cksum
= 1;
157 eib_get_props(eib_t
*ss
)
163 clock_t vnic_ka_usecs
;
165 ss
->ei_gw_props
= kmem_zalloc(sizeof (eib_gw_props_t
), KM_SLEEP
);
166 ss
->ei_props
= kmem_zalloc(sizeof (eib_props_t
), KM_SLEEP
);
168 mutex_init(&ss
->ei_gw_props
->pp_gw_lock
, NULL
, MUTEX_DRIVER
, NULL
);
171 * The interface speed is currently set to 10Gb/s, since we don't
172 * have a way yet to figure this virtual-wire specific data from
173 * the gateway. The rest of the properties are handed over to us
176 ss
->ei_props
->ep_ifspeed
= 10000000000;
178 eib_prop64_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
179 EIB_PROP_HCA_GUID
, val64
);
180 ss
->ei_props
->ep_hca_guid
= (ib_guid_t
)val64
;
182 eib_prop64_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
183 EIB_PROP_GW_SYS_GUID
, val64
);
184 ss
->ei_gw_props
->pp_gw_system_guid
= (ib_guid_t
)val64
;
186 eib_prop64_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
187 EIB_PROP_GW_GUID
, val64
);
188 ss
->ei_gw_props
->pp_gw_guid
= (ib_guid_t
)val64
;
190 eib_prop64_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
191 EIB_PROP_GW_SN_PREFIX
, val64
);
192 ss
->ei_gw_props
->pp_gw_sn_prefix
= (ib_sn_prefix_t
)val64
;
194 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
195 EIB_PROP_GW_ADV_PERIOD
, val
);
196 ss
->ei_gw_props
->pp_gw_adv_period
= (uint_t
)val
;
198 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
199 EIB_PROP_GW_KA_PERIOD
, val
);
200 ss
->ei_gw_props
->pp_gw_ka_period
= (uint_t
)val
;
202 gw_ka_usecs
= ss
->ei_gw_props
->pp_gw_ka_period
* 1000;
203 gw_ka_usecs
= ((gw_ka_usecs
<< 2) + gw_ka_usecs
) >> 1;
204 ss
->ei_gw_props
->pp_gw_ka_ticks
= drv_usectohz(gw_ka_usecs
);
206 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
207 EIB_PROP_VNIC_KA_PERIOD
, val
);
208 ss
->ei_gw_props
->pp_vnic_ka_period
= (uint_t
)val
;
210 vnic_ka_usecs
= ss
->ei_gw_props
->pp_vnic_ka_period
* 1000;
211 ss
->ei_gw_props
->pp_vnic_ka_ticks
= drv_usectohz(vnic_ka_usecs
);
213 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
214 EIB_PROP_GW_CTRL_QPN
, val
);
215 ss
->ei_gw_props
->pp_gw_ctrl_qpn
= (ib_qpn_t
)val
;
217 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
218 EIB_PROP_GW_LID
, val
);
219 ss
->ei_gw_props
->pp_gw_lid
= (ib_lid_t
)val
;
221 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
222 EIB_PROP_GW_PORTID
, val
);
223 ss
->ei_gw_props
->pp_gw_portid
= (uint16_t)val
;
225 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
226 EIB_PROP_GW_NUM_NET_VNICS
, val
);
227 ss
->ei_gw_props
->pp_gw_num_net_vnics
= (uint16_t)val
;
229 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
230 EIB_PROP_GW_AVAILABLE
, val
);
231 ss
->ei_gw_props
->pp_gw_flag_available
= (uint8_t)val
;
233 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
234 EIB_PROP_GW_HOST_VNICS
, val
);
235 ss
->ei_gw_props
->pp_gw_is_host_adm_vnics
= (uint8_t)val
;
237 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
238 EIB_PROP_GW_SL
, val
);
239 ss
->ei_gw_props
->pp_gw_sl
= (uint8_t)val
;
241 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
242 EIB_PROP_GW_N_RSS_QPN
, val
);
243 ss
->ei_gw_props
->pp_gw_n_rss_qpn
= (uint8_t)val
;
245 eib_prop_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
246 EIB_PROP_HCA_PORTNUM
, val
);
247 ss
->ei_props
->ep_port_num
= (uint8_t)val
;
249 eib_propstr_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
250 EIB_PROP_GW_SYS_NAME
, &str
);
251 ss
->ei_gw_props
->pp_gw_system_name
= (uint8_t *)str
;
253 eib_propstr_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
254 EIB_PROP_GW_PORT_NAME
, &str
);
255 ss
->ei_gw_props
->pp_gw_port_name
= (uint8_t *)str
;
257 eib_propstr_get_and_test(ss
->ei_instance
, ss
->ei_dip
,
258 EIB_PROP_GW_VENDOR_ID
, &str
);
259 ss
->ei_gw_props
->pp_gw_vendor_id
= (uint8_t *)str
;
261 return (EIB_E_SUCCESS
);
264 eib_rb_get_props(ss
);
265 return (EIB_E_FAILURE
);
269 eib_update_props(eib_t
*ss
, eib_gw_info_t
*new_gw_info
)
271 eib_gw_props_t
*gwp
= ss
->ei_gw_props
;
272 dev_info_t
*dip
= ss
->ei_dip
;
275 ASSERT(gwp
!= NULL
&& dip
!= NULL
);
277 mutex_enter(&gwp
->pp_gw_lock
);
279 gwp
->pp_gw_system_guid
= new_gw_info
->gi_system_guid
;
280 (void) ddi_prop_update_int64(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_SYS_GUID
,
281 gwp
->pp_gw_system_guid
);
283 gwp
->pp_gw_guid
= new_gw_info
->gi_guid
;
284 (void) ddi_prop_update_int64(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_GUID
,
287 gwp
->pp_gw_sn_prefix
= new_gw_info
->gi_sn_prefix
;
288 (void) ddi_prop_update_int64(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_SN_PREFIX
,
289 gwp
->pp_gw_sn_prefix
);
291 gwp
->pp_gw_adv_period
= new_gw_info
->gi_adv_period
;
292 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_ADV_PERIOD
,
293 gwp
->pp_gw_adv_period
);
295 gwp
->pp_gw_ka_period
= new_gw_info
->gi_ka_period
;
296 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_KA_PERIOD
,
297 gwp
->pp_gw_ka_period
);
299 gwp
->pp_vnic_ka_period
= new_gw_info
->gi_vnic_ka_period
;
300 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_VNIC_KA_PERIOD
,
301 gwp
->pp_vnic_ka_period
);
303 gwp
->pp_gw_ctrl_qpn
= new_gw_info
->gi_ctrl_qpn
;
304 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_CTRL_QPN
,
305 gwp
->pp_gw_ctrl_qpn
);
307 gwp
->pp_gw_lid
= new_gw_info
->gi_lid
;
308 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_LID
,
311 gwp
->pp_gw_portid
= new_gw_info
->gi_portid
;
312 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_PORTID
,
315 gwp
->pp_gw_num_net_vnics
= new_gw_info
->gi_num_net_vnics
;
316 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
,
317 EIB_PROP_GW_NUM_NET_VNICS
, gwp
->pp_gw_num_net_vnics
);
319 gwp
->pp_gw_flag_available
= new_gw_info
->gi_flag_available
;
320 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_AVAILABLE
,
321 gwp
->pp_gw_flag_available
);
323 gwp
->pp_gw_is_host_adm_vnics
= new_gw_info
->gi_is_host_adm_vnics
;
324 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_HOST_VNICS
,
325 gwp
->pp_gw_is_host_adm_vnics
);
327 gwp
->pp_gw_sl
= new_gw_info
->gi_sl
;
328 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_SL
,
331 gwp
->pp_gw_n_rss_qpn
= new_gw_info
->gi_n_rss_qpn
;
332 (void) ddi_prop_update_int(DDI_DEV_T_NONE
, dip
, EIB_PROP_GW_N_RSS_QPN
,
333 gwp
->pp_gw_n_rss_qpn
);
335 (void) ddi_prop_update_string(DDI_DEV_T_NONE
, dip
,
336 EIB_PROP_GW_SYS_NAME
, (char *)(new_gw_info
->gi_system_name
));
337 (void) ddi_prop_lookup_string(DDI_DEV_T_ANY
, dip
,
338 DDI_PROP_DONTPASS
| DDI_PROP_NOTPROM
, EIB_PROP_GW_SYS_NAME
, &str
);
339 if (gwp
->pp_gw_system_name
) {
340 ddi_prop_free(gwp
->pp_gw_system_name
);
342 gwp
->pp_gw_system_name
= (uint8_t *)str
;
344 (void) ddi_prop_update_string(DDI_DEV_T_NONE
, dip
,
345 EIB_PROP_GW_PORT_NAME
, (char *)(new_gw_info
->gi_port_name
));
346 (void) ddi_prop_lookup_string(DDI_DEV_T_ANY
, dip
,
347 DDI_PROP_DONTPASS
| DDI_PROP_NOTPROM
, EIB_PROP_GW_PORT_NAME
, &str
);
348 if (gwp
->pp_gw_port_name
) {
349 ddi_prop_free(gwp
->pp_gw_port_name
);
351 gwp
->pp_gw_port_name
= (uint8_t *)str
;
353 (void) ddi_prop_update_string(DDI_DEV_T_NONE
, dip
,
354 EIB_PROP_GW_VENDOR_ID
, (char *)(new_gw_info
->gi_vendor_id
));
355 (void) ddi_prop_lookup_string(DDI_DEV_T_ANY
, dip
,
356 DDI_PROP_DONTPASS
| DDI_PROP_NOTPROM
, EIB_PROP_GW_VENDOR_ID
, &str
);
357 if (gwp
->pp_gw_vendor_id
) {
358 ddi_prop_free(gwp
->pp_gw_vendor_id
);
360 gwp
->pp_gw_vendor_id
= (uint8_t *)str
;
362 mutex_exit(&gwp
->pp_gw_lock
);
366 eib_rb_get_props(eib_t
*ss
)
369 * Free any allocations
371 if (ss
->ei_gw_props
->pp_gw_vendor_id
) {
372 ddi_prop_free(ss
->ei_gw_props
->pp_gw_vendor_id
);
373 ss
->ei_gw_props
->pp_gw_vendor_id
= NULL
;
375 if (ss
->ei_gw_props
->pp_gw_port_name
) {
376 ddi_prop_free(ss
->ei_gw_props
->pp_gw_port_name
);
377 ss
->ei_gw_props
->pp_gw_port_name
= NULL
;
379 if (ss
->ei_gw_props
->pp_gw_system_name
) {
380 ddi_prop_free(ss
->ei_gw_props
->pp_gw_system_name
);
381 ss
->ei_gw_props
->pp_gw_system_name
= NULL
;
384 mutex_destroy(&ss
->ei_gw_props
->pp_gw_lock
);
387 * Free space allocated for holding the props
389 kmem_free(ss
->ei_props
, sizeof (eib_props_t
));
390 kmem_free(ss
->ei_gw_props
, sizeof (eib_gw_props_t
));
393 ss
->ei_gw_props
= NULL
;