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 /* 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2020 Joyent, Inc. 25 * Copyright 2015 Garrett D'Amore <garrett@damore.org> 26 * Copyright 2020 RackTop Systems, Inc. 27 * Copyright 2026 Oxide Computer Company 28 * Copyright 2026 Edgecast Cloud LLC. 29 */ 30 31 /* 32 * MAC Services Module 33 * 34 * The GLDv3 framework locking - The MAC layer 35 * -------------------------------------------- 36 * 37 * The MAC layer is central to the GLD framework and can provide the locking 38 * framework needed for itself and for the use of MAC clients. MAC end points 39 * are fairly disjoint and don't share a lot of state. So a coarse grained 40 * multi-threading scheme is to single thread all create/modify/delete or set 41 * type of control operations on a per mac end point while allowing data threads 42 * concurrently. 43 * 44 * Control operations (set) that modify a mac end point are always serialized on 45 * a per mac end point basis, We have at most 1 such thread per mac end point 46 * at a time. 47 * 48 * All other operations that are not serialized are essentially multi-threaded. 49 * For example a control operation (get) like getting statistics which may not 50 * care about reading values atomically or data threads sending or receiving 51 * data. Mostly these type of operations don't modify the control state. Any 52 * state these operations care about are protected using traditional locks. 53 * 54 * The perimeter only serializes serial operations. It does not imply there 55 * aren't any other concurrent operations. However a serialized operation may 56 * sometimes need to make sure it is the only thread. In this case it needs 57 * to use reference counting mechanisms to cv_wait until any current data 58 * threads are done. 59 * 60 * The mac layer itself does not hold any locks across a call to another layer. 61 * The perimeter is however held across a down call to the driver to make the 62 * whole control operation atomic with respect to other control operations. 63 * Also the data path and get type control operations may proceed concurrently. 64 * These operations synchronize with the single serial operation on a given mac 65 * end point using regular locks. The perimeter ensures that conflicting 66 * operations like say a mac_multicast_add and a mac_multicast_remove on the 67 * same mac end point don't interfere with each other and also ensures that the 68 * changes in the mac layer and the call to the underlying driver to say add a 69 * multicast address are done atomically without interference from a thread 70 * trying to delete the same address. 71 * 72 * For example, consider 73 * mac_multicst_add() 74 * { 75 * mac_perimeter_enter(); serialize all control operations 76 * 77 * grab list lock protect against access by data threads 78 * add to list 79 * drop list lock 80 * 81 * call driver's mi_multicst 82 * 83 * mac_perimeter_exit(); 84 * } 85 * 86 * To lessen the number of serialization locks and simplify the lock hierarchy, 87 * we serialize all the control operations on a per mac end point by using a 88 * single serialization lock called the perimeter. We allow recursive entry into 89 * the perimeter to facilitate use of this mechanism by both the mac client and 90 * the MAC layer itself. 91 * 92 * MAC client means an entity that does an operation on a mac handle 93 * obtained from a mac_open/mac_client_open. Similarly MAC driver means 94 * an entity that does an operation on a mac handle obtained from a 95 * mac_register. An entity could be both client and driver but on different 96 * handles eg. aggr. and should only make the corresponding mac interface calls 97 * i.e. mac driver interface or mac client interface as appropriate for that 98 * mac handle. 99 * 100 * General rules. 101 * ------------- 102 * 103 * R1. The lock order of upcall threads is natually opposite to downcall 104 * threads. Hence upcalls must not hold any locks across layers for fear of 105 * recursive lock enter and lock order violation. This applies to all layers. 106 * 107 * R2. The perimeter is just another lock. Since it is held in the down 108 * direction, acquiring the perimeter in an upcall is prohibited as it would 109 * cause a deadlock. This applies to all layers. 110 * 111 * Note that upcalls that need to grab the mac perimeter (for example 112 * mac_notify upcalls) can still achieve that by posting the request to a 113 * thread, which can then grab all the required perimeters and locks in the 114 * right global order. Note that in the above example the mac layer iself 115 * won't grab the mac perimeter in the mac_notify upcall, instead the upcall 116 * to the client must do that. Please see the aggr code for an example. 117 * 118 * MAC client rules 119 * ---------------- 120 * 121 * R3. A MAC client may use the MAC provided perimeter facility to serialize 122 * control operations on a per mac end point. It does this by by acquring 123 * and holding the perimeter across a sequence of calls to the mac layer. 124 * This ensures atomicity across the entire block of mac calls. In this 125 * model the MAC client must not hold any client locks across the calls to 126 * the mac layer. This model is the preferred solution. 127 * 128 * R4. However if a MAC client has a lot of global state across all mac end 129 * points the per mac end point serialization may not be sufficient. In this 130 * case the client may choose to use global locks or use its own serialization. 131 * To avoid deadlocks, these client layer locks held across the mac calls 132 * in the control path must never be acquired by the data path for the reason 133 * mentioned below. 134 * 135 * (Assume that a control operation that holds a client lock blocks in the 136 * mac layer waiting for upcall reference counts to drop to zero. If an upcall 137 * data thread that holds this reference count, tries to acquire the same 138 * client lock subsequently it will deadlock). 139 * 140 * A MAC client may follow either the R3 model or the R4 model, but can't 141 * mix both. In the former, the hierarchy is Perim -> client locks, but in 142 * the latter it is client locks -> Perim. 143 * 144 * R5. MAC clients must make MAC calls (excluding data calls) in a cv_wait'able 145 * context since they may block while trying to acquire the perimeter. 146 * In addition some calls may block waiting for upcall refcnts to come down to 147 * zero. 148 * 149 * R6. MAC clients must make sure that they are single threaded and all threads 150 * from the top (in particular data threads) have finished before calling 151 * mac_client_close. The MAC framework does not track the number of client 152 * threads using the mac client handle. Also mac clients must make sure 153 * they have undone all the control operations before calling mac_client_close. 154 * For example mac_unicast_remove/mac_multicast_remove to undo the corresponding 155 * mac_unicast_add/mac_multicast_add. 156 * 157 * MAC framework rules 158 * ------------------- 159 * 160 * R7. The mac layer itself must not hold any mac layer locks (except the mac 161 * perimeter) across a call to any other layer from the mac layer. The call to 162 * any other layer could be via mi_* entry points, classifier entry points into 163 * the driver or via upcall pointers into layers above. The mac perimeter may 164 * be acquired or held only in the down direction, for e.g. when calling into 165 * a mi_* driver enty point to provide atomicity of the operation. 166 * 167 * R8. Since it is not guaranteed (see R14) that drivers won't hold locks across 168 * mac driver interfaces, the MAC layer must provide a cut out for control 169 * interfaces like upcall notifications and start them in a separate thread. 170 * 171 * R9. Note that locking order also implies a plumbing order. For example 172 * VNICs are allowed to be created over aggrs, but not vice-versa. An attempt 173 * to plumb in any other order must be failed at mac_open time, otherwise it 174 * could lead to deadlocks due to inverse locking order. 175 * 176 * R10. MAC driver interfaces must not block since the driver could call them 177 * in interrupt context. 178 * 179 * R11. Walkers must preferably not hold any locks while calling walker 180 * callbacks. Instead these can operate on reference counts. In simple 181 * callbacks it may be ok to hold a lock and call the callbacks, but this is 182 * harder to maintain in the general case of arbitrary callbacks. 183 * 184 * R12. The MAC layer must protect upcall notification callbacks using reference 185 * counts rather than holding locks across the callbacks. 186 * 187 * R13. Given the variety of drivers, it is preferable if the MAC layer can make 188 * sure that any pointers (such as mac ring pointers) it passes to the driver 189 * remain valid until mac unregister time. Currently the mac layer achieves 190 * this by using generation numbers for rings and freeing the mac rings only 191 * at unregister time. The MAC layer must provide a layer of indirection and 192 * must not expose underlying driver rings or driver data structures/pointers 193 * directly to MAC clients. 194 * 195 * MAC driver rules 196 * ---------------- 197 * 198 * R14. It would be preferable if MAC drivers don't hold any locks across any 199 * mac call. However at a minimum they must not hold any locks across data 200 * upcalls. They must also make sure that all references to mac data structures 201 * are cleaned up and that it is single threaded at mac_unregister time. 202 * 203 * R15. MAC driver interfaces don't block and so the action may be done 204 * asynchronously in a separate thread as for example handling notifications. 205 * The driver must not assume that the action is complete when the call 206 * returns. 207 * 208 * R16. Drivers must maintain a generation number per Rx ring, and pass it 209 * back to mac_rx_ring(); They are expected to increment the generation 210 * number whenever the ring's stop routine is invoked. 211 * See comments in mac_rx_ring(); 212 * 213 * R17 Similarly mi_stop is another synchronization point and the driver must 214 * ensure that all upcalls are done and there won't be any future upcall 215 * before returning from mi_stop. 216 * 217 * R18. The driver may assume that all set/modify control operations via 218 * the mi_* entry points are single threaded on a per mac end point. 219 * 220 * Lock and Perimeter hierarchy scenarios 221 * --------------------------------------- 222 * 223 * i_mac_impl_lock -> mi_rw_lock -> srs_lock -> s_ring_lock[i_mac_tx_srs_notify] 224 * 225 * ft_lock -> fe_lock [mac_flow_lookup] 226 * 227 * mi_rw_lock -> fe_lock [mac_bcast_send] 228 * 229 * srs_lock -> mac_bw_lock [mac_rx_srs_drain_bw] 230 * 231 * cpu_lock -> mac_srs_g_lock -> srs_lock -> s_ring_lock [mac_walk_srs_and_bind] 232 * 233 * i_dls_devnet_lock -> mac layer locks [dls_devnet_rename] 234 * 235 * Perimeters are ordered P1 -> P2 -> P3 from top to bottom in order of mac 236 * client to driver. In the case of clients that explictly use the mac provided 237 * perimeter mechanism for its serialization, the hierarchy is 238 * Perimeter -> mac layer locks, since the client never holds any locks across 239 * the mac calls. In the case of clients that use its own locks the hierarchy 240 * is Client locks -> Mac Perim -> Mac layer locks. The client never explicitly 241 * calls mac_perim_enter/exit in this case. 242 * 243 * Subflow creation rules 244 * --------------------------- 245 * o In case of a user specified cpulist present on underlying link and flows, 246 * the flows cpulist must be a subset of the underlying link. 247 * o In case of a user specified fanout mode present on link and flow, the 248 * subflow fanout count has to be less than or equal to that of the 249 * underlying link. The cpu-bindings for the subflows will be a subset of 250 * the underlying link. 251 * o In case if no cpulist specified on both underlying link and flow, the 252 * underlying link relies on a MAC tunable to provide out of box fanout. 253 * The subflow will have no cpulist (the subflow will be unbound) 254 * o In case if no cpulist is specified on the underlying link, a subflow can 255 * carry either a user-specified cpulist or fanout count. The cpu-bindings 256 * for the subflow will not adhere to restriction that they need to be subset 257 * of the underlying link. 258 * o In case where the underlying link is carrying either a user specified 259 * cpulist or fanout mode and for a unspecified subflow, the subflow will be 260 * created unbound. 261 * o While creating unbound subflows, bandwidth mode changes attempt to 262 * figure a right fanout count. In such cases the fanout count will override 263 * the unbound cpu-binding behavior. 264 * o In addition to this, while cycling between flow and link properties, we 265 * impose a restriction that if a link property has a subflow with 266 * user-specified attributes, we will not allow changing the link property. 267 * The administrator needs to reset all the user specified properties for the 268 * subflows before attempting a link property change. 269 * Some of the above rules can be overridden by specifying additional command 270 * line options while creating or modifying link or subflow properties. 271 * 272 * Datapath 273 * -------- 274 * 275 * For information on the datapath, the world of soft rings, hardware rings, how 276 * it is structured, and the path of an mblk_t between a driver and a mac 277 * client, see mac_sched.c. 278 */ 279 280 #include <sys/types.h> 281 #include <sys/conf.h> 282 #include <sys/id_space.h> 283 #include <sys/esunddi.h> 284 #include <sys/stat.h> 285 #include <sys/mkdev.h> 286 #include <sys/stream.h> 287 #include <sys/strsun.h> 288 #include <sys/strsubr.h> 289 #include <sys/dlpi.h> 290 #include <sys/list.h> 291 #include <sys/modhash.h> 292 #include <sys/mac_provider.h> 293 #include <sys/mac_client_impl.h> 294 #include <sys/mac_soft_ring.h> 295 #include <sys/mac_stat.h> 296 #include <sys/mac_impl.h> 297 #include <sys/mac.h> 298 #include <sys/dls.h> 299 #include <sys/dld.h> 300 #include <sys/modctl.h> 301 #include <sys/fs/dv_node.h> 302 #include <sys/thread.h> 303 #include <sys/proc.h> 304 #include <sys/callb.h> 305 #include <sys/cpuvar.h> 306 #include <sys/atomic.h> 307 #include <sys/bitmap.h> 308 #include <sys/sdt.h> 309 #include <sys/mac_flow.h> 310 #include <sys/ddi_intr_impl.h> 311 #include <sys/disp.h> 312 #include <sys/sdt.h> 313 #include <sys/vnic.h> 314 #include <sys/vnic_impl.h> 315 #include <sys/vlan.h> 316 #include <inet/ip.h> 317 #include <inet/ip6.h> 318 #include <sys/exacct.h> 319 #include <sys/exacct_impl.h> 320 #include <inet/nd.h> 321 #include <sys/ethernet.h> 322 #include <sys/pool.h> 323 #include <sys/pool_pset.h> 324 #include <sys/cpupart.h> 325 #include <inet/wifi_ioctl.h> 326 #include <net/wpa.h> 327 #include <sys/mac_ether.h> 328 329 #define IMPL_HASHSZ 67 /* prime */ 330 331 kmem_cache_t *i_mac_impl_cachep; 332 mod_hash_t *i_mac_impl_hash; 333 krwlock_t i_mac_impl_lock; 334 uint_t i_mac_impl_count; 335 static kmem_cache_t *mac_ring_cache; 336 static id_space_t *minor_ids; 337 static uint32_t minor_count; 338 static pool_event_cb_t mac_pool_event_reg; 339 340 /* 341 * Logging stuff. Perhaps mac_logging_interval could be broken into 342 * mac_flow_log_interval and mac_link_log_interval if we want to be 343 * able to schedule them differently. 344 */ 345 uint_t mac_logging_interval; 346 boolean_t mac_flow_log_enable; 347 boolean_t mac_link_log_enable; 348 timeout_id_t mac_logging_timer; 349 350 #define MACTYPE_KMODDIR "mac" 351 #define MACTYPE_HASHSZ 67 352 static mod_hash_t *i_mactype_hash; 353 /* 354 * i_mactype_lock synchronizes threads that obtain references to mactype_t 355 * structures through i_mactype_getplugin(). 356 */ 357 static kmutex_t i_mactype_lock; 358 359 /* 360 * mac_tx_percpu_cnt 361 * 362 * Number of per cpu locks per mac_client_impl_t. Used by the transmit side 363 * in mac_tx to reduce lock contention. This is sized at boot time in mac_init. 364 * mac_tx_percpu_cnt_max is settable in /etc/system and must be a power of 2. 365 * Per cpu locks may be disabled by setting mac_tx_percpu_cnt_max to 1. 366 */ 367 int mac_tx_percpu_cnt; 368 int mac_tx_percpu_cnt_max = 128; 369 370 /* 371 * Call back functions for the bridge module. These are guaranteed to be valid 372 * when holding a reference on a link or when holding mip->mi_bridge_lock and 373 * mi_bridge_link is non-NULL. 374 */ 375 mac_bridge_tx_t mac_bridge_tx_cb; 376 mac_bridge_rx_t mac_bridge_rx_cb; 377 mac_bridge_ref_t mac_bridge_ref_cb; 378 mac_bridge_ls_t mac_bridge_ls_cb; 379 380 static int i_mac_constructor(void *, void *, int); 381 static void i_mac_destructor(void *, void *); 382 static int i_mac_ring_ctor(void *, void *, int); 383 static void i_mac_ring_dtor(void *, void *); 384 static flow_entry_t *mac_rx_classify(mac_impl_t *, mac_resource_handle_t, 385 mblk_t *); 386 void mac_tx_client_flush(mac_client_impl_t *); 387 void mac_tx_client_block(mac_client_impl_t *); 388 static void mac_rx_ring_quiesce(mac_ring_t *, uint_t); 389 static int mac_start_group_and_rings(mac_group_t *); 390 static void mac_stop_group_and_rings(mac_group_t *); 391 static void mac_pool_event_cb(pool_event_t, int, void *); 392 393 typedef struct netinfo_s { 394 list_node_t ni_link; 395 void *ni_record; 396 int ni_size; 397 int ni_type; 398 } netinfo_t; 399 400 /* 401 * Module initialization functions. 402 */ 403 404 void 405 mac_init(void) 406 { 407 mac_tx_percpu_cnt = ((boot_max_ncpus == -1) ? max_ncpus : 408 boot_max_ncpus); 409 410 /* Upper bound is mac_tx_percpu_cnt_max */ 411 if (mac_tx_percpu_cnt > mac_tx_percpu_cnt_max) 412 mac_tx_percpu_cnt = mac_tx_percpu_cnt_max; 413 414 if (mac_tx_percpu_cnt < 1) { 415 /* Someone set max_tx_percpu_cnt_max to 0 or less */ 416 mac_tx_percpu_cnt = 1; 417 } 418 419 ASSERT(mac_tx_percpu_cnt >= 1); 420 mac_tx_percpu_cnt = (1 << highbit(mac_tx_percpu_cnt - 1)); 421 /* 422 * Make it of the form 2**N - 1 in the range 423 * [0 .. mac_tx_percpu_cnt_max - 1] 424 */ 425 mac_tx_percpu_cnt--; 426 427 i_mac_impl_cachep = kmem_cache_create("mac_impl_cache", 428 sizeof (mac_impl_t), 0, i_mac_constructor, i_mac_destructor, 429 NULL, NULL, NULL, 0); 430 ASSERT(i_mac_impl_cachep != NULL); 431 432 mac_ring_cache = kmem_cache_create("mac_ring_cache", 433 sizeof (mac_ring_t), 0, i_mac_ring_ctor, i_mac_ring_dtor, NULL, 434 NULL, NULL, 0); 435 ASSERT(mac_ring_cache != NULL); 436 437 i_mac_impl_hash = mod_hash_create_extended("mac_impl_hash", 438 IMPL_HASHSZ, mod_hash_null_keydtor, mod_hash_null_valdtor, 439 mod_hash_bystr, NULL, mod_hash_strkey_cmp, KM_SLEEP); 440 rw_init(&i_mac_impl_lock, NULL, RW_DEFAULT, NULL); 441 442 mac_flow_init(); 443 mac_soft_ring_init(); 444 mac_bcast_init(); 445 mac_client_init(); 446 447 i_mac_impl_count = 0; 448 449 i_mactype_hash = mod_hash_create_extended("mactype_hash", 450 MACTYPE_HASHSZ, 451 mod_hash_null_keydtor, mod_hash_null_valdtor, 452 mod_hash_bystr, NULL, mod_hash_strkey_cmp, KM_SLEEP); 453 454 /* 455 * Allocate an id space to manage minor numbers. The range of the 456 * space will be from MAC_MAX_MINOR+1 to MAC_PRIVATE_MINOR-1. This 457 * leaves half of the 32-bit minors available for driver private use. 458 */ 459 minor_ids = id_space_create("mac_minor_ids", MAC_MAX_MINOR+1, 460 MAC_PRIVATE_MINOR-1); 461 ASSERT(minor_ids != NULL); 462 minor_count = 0; 463 464 /* Let's default to 20 seconds */ 465 mac_logging_interval = 20; 466 mac_flow_log_enable = B_FALSE; 467 mac_link_log_enable = B_FALSE; 468 mac_logging_timer = NULL; 469 470 /* Register to be notified of noteworthy pools events */ 471 mac_pool_event_reg.pec_func = mac_pool_event_cb; 472 mac_pool_event_reg.pec_arg = NULL; 473 pool_event_cb_register(&mac_pool_event_reg); 474 } 475 476 int 477 mac_fini(void) 478 { 479 480 if (i_mac_impl_count > 0 || minor_count > 0) 481 return (EBUSY); 482 483 pool_event_cb_unregister(&mac_pool_event_reg); 484 485 id_space_destroy(minor_ids); 486 mac_flow_fini(); 487 488 mod_hash_destroy_hash(i_mac_impl_hash); 489 rw_destroy(&i_mac_impl_lock); 490 491 mac_client_fini(); 492 kmem_cache_destroy(mac_ring_cache); 493 494 mod_hash_destroy_hash(i_mactype_hash); 495 mac_soft_ring_finish(); 496 497 498 return (0); 499 } 500 501 /* 502 * Initialize a GLDv3 driver's device ops. A driver that manages its own ops 503 * (e.g. softmac) may pass in a NULL ops argument. 504 */ 505 void 506 mac_init_ops(struct dev_ops *ops, const char *name) 507 { 508 major_t major = ddi_name_to_major((char *)name); 509 510 /* 511 * By returning on error below, we are not letting the driver continue 512 * in an undefined context. The mac_register() function will faill if 513 * DN_GLDV3_DRIVER isn't set. 514 */ 515 if (major == DDI_MAJOR_T_NONE) 516 return; 517 LOCK_DEV_OPS(&devnamesp[major].dn_lock); 518 devnamesp[major].dn_flags |= (DN_GLDV3_DRIVER | DN_NETWORK_DRIVER); 519 UNLOCK_DEV_OPS(&devnamesp[major].dn_lock); 520 if (ops != NULL) 521 dld_init_ops(ops, name); 522 } 523 524 void 525 mac_fini_ops(struct dev_ops *ops) 526 { 527 dld_fini_ops(ops); 528 } 529 530 /*ARGSUSED*/ 531 static int 532 i_mac_constructor(void *buf, void *arg, int kmflag) 533 { 534 mac_impl_t *mip = buf; 535 536 bzero(buf, sizeof (mac_impl_t)); 537 538 mip->mi_linkstate = LINK_STATE_UNKNOWN; 539 540 rw_init(&mip->mi_rw_lock, NULL, RW_DRIVER, NULL); 541 mutex_init(&mip->mi_notify_lock, NULL, MUTEX_DRIVER, NULL); 542 mutex_init(&mip->mi_promisc_lock, NULL, MUTEX_DRIVER, NULL); 543 mutex_init(&mip->mi_ring_lock, NULL, MUTEX_DEFAULT, NULL); 544 545 mip->mi_notify_cb_info.mcbi_lockp = &mip->mi_notify_lock; 546 cv_init(&mip->mi_notify_cb_info.mcbi_cv, NULL, CV_DRIVER, NULL); 547 mip->mi_promisc_cb_info.mcbi_lockp = &mip->mi_promisc_lock; 548 cv_init(&mip->mi_promisc_cb_info.mcbi_cv, NULL, CV_DRIVER, NULL); 549 550 mutex_init(&mip->mi_bridge_lock, NULL, MUTEX_DEFAULT, NULL); 551 552 return (0); 553 } 554 555 /*ARGSUSED*/ 556 static void 557 i_mac_destructor(void *buf, void *arg) 558 { 559 mac_impl_t *mip = buf; 560 mac_cb_info_t *mcbi; 561 562 ASSERT(mip->mi_ref == 0); 563 ASSERT(mip->mi_active == 0); 564 ASSERT(mip->mi_linkstate == LINK_STATE_UNKNOWN); 565 ASSERT(mip->mi_devpromisc == 0); 566 ASSERT(mip->mi_ksp == NULL); 567 ASSERT(mip->mi_kstat_count == 0); 568 ASSERT(mip->mi_nclients == 0); 569 ASSERT(mip->mi_nactiveclients == 0); 570 ASSERT(mip->mi_single_active_client == NULL); 571 ASSERT(mip->mi_state_flags == 0); 572 ASSERT(mip->mi_factory_addr == NULL); 573 ASSERT(mip->mi_factory_addr_num == 0); 574 ASSERT(mip->mi_default_tx_ring == NULL); 575 576 mcbi = &mip->mi_notify_cb_info; 577 ASSERT(mcbi->mcbi_del_cnt == 0 && mcbi->mcbi_walker_cnt == 0); 578 ASSERT(mip->mi_notify_bits == 0); 579 ASSERT(mip->mi_notify_thread == NULL); 580 ASSERT(mcbi->mcbi_lockp == &mip->mi_notify_lock); 581 mcbi->mcbi_lockp = NULL; 582 583 mcbi = &mip->mi_promisc_cb_info; 584 ASSERT(mcbi->mcbi_del_cnt == 0 && mip->mi_promisc_list == NULL); 585 ASSERT(mip->mi_promisc_list == NULL); 586 ASSERT(mcbi->mcbi_lockp == &mip->mi_promisc_lock); 587 mcbi->mcbi_lockp = NULL; 588 589 ASSERT(mip->mi_bcast_ngrps == 0 && mip->mi_bcast_grp == NULL); 590 ASSERT(mip->mi_perim_owner == NULL && mip->mi_perim_ocnt == 0); 591 592 rw_destroy(&mip->mi_rw_lock); 593 594 mutex_destroy(&mip->mi_promisc_lock); 595 cv_destroy(&mip->mi_promisc_cb_info.mcbi_cv); 596 mutex_destroy(&mip->mi_notify_lock); 597 cv_destroy(&mip->mi_notify_cb_info.mcbi_cv); 598 mutex_destroy(&mip->mi_ring_lock); 599 600 ASSERT(mip->mi_bridge_link == NULL); 601 } 602 603 /* ARGSUSED */ 604 static int 605 i_mac_ring_ctor(void *buf, void *arg, int kmflag) 606 { 607 mac_ring_t *ring = (mac_ring_t *)buf; 608 609 bzero(ring, sizeof (mac_ring_t)); 610 cv_init(&ring->mr_cv, NULL, CV_DEFAULT, NULL); 611 mutex_init(&ring->mr_lock, NULL, MUTEX_DEFAULT, NULL); 612 ring->mr_state = MR_FREE; 613 return (0); 614 } 615 616 /* ARGSUSED */ 617 static void 618 i_mac_ring_dtor(void *buf, void *arg) 619 { 620 mac_ring_t *ring = (mac_ring_t *)buf; 621 622 cv_destroy(&ring->mr_cv); 623 mutex_destroy(&ring->mr_lock); 624 } 625 626 /* 627 * Common functions to do mac callback addition and deletion. Currently this is 628 * used by promisc callbacks and notify callbacks. List addition and deletion 629 * need to take care of list walkers. List walkers in general, can't hold list 630 * locks and make upcall callbacks due to potential lock order and recursive 631 * reentry issues. Instead list walkers increment the list walker count to mark 632 * the presence of a walker thread. Addition can be carefully done to ensure 633 * that the list walker always sees either the old list or the new list. 634 * However the deletion can't be done while the walker is active, instead the 635 * deleting thread simply marks the entry as logically deleted. The last walker 636 * physically deletes and frees up the logically deleted entries when the walk 637 * is complete. 638 */ 639 void 640 mac_callback_add(mac_cb_info_t *mcbi, mac_cb_t **mcb_head, 641 mac_cb_t *mcb_elem) 642 { 643 mac_cb_t *p; 644 mac_cb_t **pp; 645 646 /* Verify it is not already in the list */ 647 for (pp = mcb_head; (p = *pp) != NULL; pp = &p->mcb_nextp) { 648 if (p == mcb_elem) 649 break; 650 } 651 VERIFY(p == NULL); 652 653 /* 654 * Add it to the head of the callback list. The membar ensures that 655 * the following list pointer manipulations reach global visibility 656 * in exactly the program order below. 657 */ 658 ASSERT(MUTEX_HELD(mcbi->mcbi_lockp)); 659 660 mcb_elem->mcb_nextp = *mcb_head; 661 membar_producer(); 662 *mcb_head = mcb_elem; 663 } 664 665 /* 666 * Mark the entry as logically deleted. If there aren't any walkers unlink 667 * from the list. In either case return the corresponding status. 668 */ 669 boolean_t 670 mac_callback_remove(mac_cb_info_t *mcbi, mac_cb_t **mcb_head, 671 mac_cb_t *mcb_elem) 672 { 673 mac_cb_t *p; 674 mac_cb_t **pp; 675 676 ASSERT(MUTEX_HELD(mcbi->mcbi_lockp)); 677 /* 678 * Search the callback list for the entry to be removed 679 */ 680 for (pp = mcb_head; (p = *pp) != NULL; pp = &p->mcb_nextp) { 681 if (p == mcb_elem) 682 break; 683 } 684 VERIFY(p != NULL); 685 686 /* 687 * If there are walkers just mark it as deleted and the last walker 688 * will remove from the list and free it. 689 */ 690 if (mcbi->mcbi_walker_cnt != 0) { 691 p->mcb_flags |= MCB_CONDEMNED; 692 mcbi->mcbi_del_cnt++; 693 return (B_FALSE); 694 } 695 696 ASSERT(mcbi->mcbi_del_cnt == 0); 697 *pp = p->mcb_nextp; 698 p->mcb_nextp = NULL; 699 return (B_TRUE); 700 } 701 702 /* 703 * Wait for all pending callback removals to be completed 704 */ 705 void 706 mac_callback_remove_wait(mac_cb_info_t *mcbi) 707 { 708 ASSERT(MUTEX_HELD(mcbi->mcbi_lockp)); 709 while (mcbi->mcbi_del_cnt != 0) { 710 DTRACE_PROBE1(need_wait, mac_cb_info_t *, mcbi); 711 cv_wait(&mcbi->mcbi_cv, mcbi->mcbi_lockp); 712 } 713 } 714 715 void 716 mac_callback_barrier(mac_cb_info_t *mcbi) 717 { 718 ASSERT(MUTEX_HELD(mcbi->mcbi_lockp)); 719 ASSERT3U(mcbi->mcbi_barrier_cnt, <, UINT_MAX); 720 721 if (mcbi->mcbi_walker_cnt == 0) { 722 return; 723 } 724 725 mcbi->mcbi_barrier_cnt++; 726 do { 727 cv_wait(&mcbi->mcbi_cv, mcbi->mcbi_lockp); 728 } while (mcbi->mcbi_walker_cnt > 0); 729 mcbi->mcbi_barrier_cnt--; 730 cv_broadcast(&mcbi->mcbi_cv); 731 } 732 733 void 734 mac_callback_walker_enter(mac_cb_info_t *mcbi) 735 { 736 mutex_enter(mcbi->mcbi_lockp); 737 /* 738 * Incoming walkers should give precedence to timely clean-up of 739 * deleted callback entries and requested barriers. 740 */ 741 while (mcbi->mcbi_del_cnt > 0 || mcbi->mcbi_barrier_cnt > 0) { 742 cv_wait(&mcbi->mcbi_cv, mcbi->mcbi_lockp); 743 } 744 mcbi->mcbi_walker_cnt++; 745 mutex_exit(mcbi->mcbi_lockp); 746 } 747 748 /* 749 * The last mac callback walker does the cleanup. Walk the list and unlik 750 * all the logically deleted entries and construct a temporary list of 751 * removed entries. Return the list of removed entries to the caller. 752 */ 753 static mac_cb_t * 754 mac_callback_walker_cleanup(mac_cb_info_t *mcbi, mac_cb_t **mcb_head) 755 { 756 mac_cb_t *p; 757 mac_cb_t **pp; 758 mac_cb_t *rmlist = NULL; /* List of removed elements */ 759 int cnt = 0; 760 761 ASSERT(MUTEX_HELD(mcbi->mcbi_lockp)); 762 ASSERT(mcbi->mcbi_del_cnt != 0 && mcbi->mcbi_walker_cnt == 0); 763 764 pp = mcb_head; 765 while (*pp != NULL) { 766 if ((*pp)->mcb_flags & MCB_CONDEMNED) { 767 p = *pp; 768 *pp = p->mcb_nextp; 769 p->mcb_nextp = rmlist; 770 rmlist = p; 771 cnt++; 772 continue; 773 } 774 pp = &(*pp)->mcb_nextp; 775 } 776 777 ASSERT(mcbi->mcbi_del_cnt == cnt); 778 mcbi->mcbi_del_cnt = 0; 779 return (rmlist); 780 } 781 782 void 783 mac_callback_walker_exit(mac_cb_info_t *mcbi, mac_cb_t **headp, 784 boolean_t is_promisc) 785 { 786 boolean_t do_wake = B_FALSE; 787 788 mutex_enter(mcbi->mcbi_lockp); 789 790 /* If walkers remain, nothing more can be done for now */ 791 if (--mcbi->mcbi_walker_cnt != 0) { 792 mutex_exit(mcbi->mcbi_lockp); 793 return; 794 } 795 796 if (mcbi->mcbi_del_cnt != 0) { 797 mac_cb_t *rmlist; 798 799 rmlist = mac_callback_walker_cleanup(mcbi, headp); 800 801 if (!is_promisc) { 802 /* The "normal" non-promisc callback clean-up */ 803 mac_callback_free(rmlist); 804 } else { 805 mac_cb_t *mcb, *mcb_next; 806 807 /* 808 * The promisc callbacks are in 2 lists, one off the 809 * 'mip' and another off the 'mcip' threaded by 810 * mpi_mi_link and mpi_mci_link respectively. There 811 * is, however, only a single shared total walker 812 * count, and an entry cannot be physically unlinked if 813 * a walker is active on either list. The last walker 814 * does this cleanup of logically deleted entries. 815 * 816 * With a list of callbacks deleted from above from 817 * mi_promisc_list (headp), remove the corresponding 818 * entry from mci_promisc_list (headp_pair) and free 819 * the structure. 820 */ 821 for (mcb = rmlist; mcb != NULL; mcb = mcb_next) { 822 mac_promisc_impl_t *mpip; 823 mac_client_impl_t *mcip; 824 825 mcb_next = mcb->mcb_nextp; 826 mpip = (mac_promisc_impl_t *)mcb->mcb_objp; 827 mcip = mpip->mpi_mcip; 828 829 ASSERT3P(&mcip->mci_mip->mi_promisc_cb_info, 830 ==, mcbi); 831 ASSERT3P(&mcip->mci_mip->mi_promisc_list, 832 ==, headp); 833 834 VERIFY(mac_callback_remove(mcbi, 835 &mcip->mci_promisc_list, 836 &mpip->mpi_mci_link)); 837 mcb->mcb_flags = 0; 838 mcb->mcb_nextp = NULL; 839 kmem_cache_free(mac_promisc_impl_cache, mpip); 840 } 841 } 842 843 /* 844 * Wake any walker threads that could be waiting in 845 * mac_callback_walker_enter() until deleted items have been 846 * cleaned from the list. 847 */ 848 do_wake = B_TRUE; 849 } 850 851 if (mcbi->mcbi_barrier_cnt != 0) { 852 /* 853 * One or more threads are waiting for all walkers to exit the 854 * callback list. Notify them, now that the list is clear. 855 */ 856 do_wake = B_TRUE; 857 } 858 859 if (do_wake) { 860 cv_broadcast(&mcbi->mcbi_cv); 861 } 862 mutex_exit(mcbi->mcbi_lockp); 863 } 864 865 static boolean_t 866 mac_callback_lookup(mac_cb_t **mcb_headp, mac_cb_t *mcb_elem) 867 { 868 mac_cb_t *mcb; 869 870 /* Verify it is not already in the list */ 871 for (mcb = *mcb_headp; mcb != NULL; mcb = mcb->mcb_nextp) { 872 if (mcb == mcb_elem) 873 return (B_TRUE); 874 } 875 876 return (B_FALSE); 877 } 878 879 static boolean_t 880 mac_callback_find(mac_cb_info_t *mcbi, mac_cb_t **mcb_headp, mac_cb_t *mcb_elem) 881 { 882 boolean_t found; 883 884 mutex_enter(mcbi->mcbi_lockp); 885 found = mac_callback_lookup(mcb_headp, mcb_elem); 886 mutex_exit(mcbi->mcbi_lockp); 887 888 return (found); 889 } 890 891 /* Free the list of removed callbacks */ 892 void 893 mac_callback_free(mac_cb_t *rmlist) 894 { 895 mac_cb_t *mcb; 896 mac_cb_t *mcb_next; 897 898 for (mcb = rmlist; mcb != NULL; mcb = mcb_next) { 899 mcb_next = mcb->mcb_nextp; 900 kmem_free(mcb->mcb_objp, mcb->mcb_objsize); 901 } 902 } 903 904 void 905 i_mac_notify(mac_impl_t *mip, mac_notify_type_t type) 906 { 907 mac_cb_info_t *mcbi; 908 909 /* 910 * Signal the notify thread even after mi_ref has become zero and 911 * mi_disabled is set. The synchronization with the notify thread 912 * happens in mac_unregister and that implies the driver must make 913 * sure it is single-threaded (with respect to mac calls) and that 914 * all pending mac calls have returned before it calls mac_unregister 915 */ 916 rw_enter(&i_mac_impl_lock, RW_READER); 917 if (mip->mi_state_flags & MIS_DISABLED) 918 goto exit; 919 920 /* 921 * Guard against incorrect notifications. (Running a newer 922 * mac client against an older implementation?) 923 */ 924 if (type >= MAC_NNOTE) 925 goto exit; 926 927 mcbi = &mip->mi_notify_cb_info; 928 mutex_enter(mcbi->mcbi_lockp); 929 mip->mi_notify_bits |= (1 << type); 930 cv_broadcast(&mcbi->mcbi_cv); 931 mutex_exit(mcbi->mcbi_lockp); 932 933 exit: 934 rw_exit(&i_mac_impl_lock); 935 } 936 937 /* 938 * Mac serialization primitives. Please see the block comment at the 939 * top of the file. 940 */ 941 void 942 i_mac_perim_enter(mac_impl_t *mip) 943 { 944 mac_client_impl_t *mcip; 945 946 if (mip->mi_state_flags & MIS_IS_VNIC) { 947 /* 948 * This is a VNIC. Return the lower mac since that is what 949 * we want to serialize on. 950 */ 951 mcip = mac_vnic_lower(mip); 952 mip = mcip->mci_mip; 953 } 954 955 mutex_enter(&mip->mi_perim_lock); 956 if (mip->mi_perim_owner == curthread) { 957 mip->mi_perim_ocnt++; 958 mutex_exit(&mip->mi_perim_lock); 959 return; 960 } 961 962 while (mip->mi_perim_owner != NULL) 963 cv_wait(&mip->mi_perim_cv, &mip->mi_perim_lock); 964 965 mip->mi_perim_owner = curthread; 966 ASSERT(mip->mi_perim_ocnt == 0); 967 mip->mi_perim_ocnt++; 968 #ifdef DEBUG 969 mip->mi_perim_stack_depth = getpcstack(mip->mi_perim_stack, 970 MAC_PERIM_STACK_DEPTH); 971 #endif 972 mutex_exit(&mip->mi_perim_lock); 973 } 974 975 int 976 i_mac_perim_enter_nowait(mac_impl_t *mip) 977 { 978 /* 979 * The vnic is a special case, since the serialization is done based 980 * on the lower mac. If the lower mac is busy, it does not imply the 981 * vnic can't be unregistered. But in the case of other drivers, 982 * a busy perimeter or open mac handles implies that the mac is busy 983 * and can't be unregistered. 984 */ 985 if (mip->mi_state_flags & MIS_IS_VNIC) { 986 i_mac_perim_enter(mip); 987 return (0); 988 } 989 990 mutex_enter(&mip->mi_perim_lock); 991 if (mip->mi_perim_owner != NULL) { 992 mutex_exit(&mip->mi_perim_lock); 993 return (EBUSY); 994 } 995 ASSERT(mip->mi_perim_ocnt == 0); 996 mip->mi_perim_owner = curthread; 997 mip->mi_perim_ocnt++; 998 mutex_exit(&mip->mi_perim_lock); 999 1000 return (0); 1001 } 1002 1003 void 1004 i_mac_perim_exit(mac_impl_t *mip) 1005 { 1006 mac_client_impl_t *mcip; 1007 1008 if (mip->mi_state_flags & MIS_IS_VNIC) { 1009 /* 1010 * This is a VNIC. Return the lower mac since that is what 1011 * we want to serialize on. 1012 */ 1013 mcip = mac_vnic_lower(mip); 1014 mip = mcip->mci_mip; 1015 } 1016 1017 ASSERT(mip->mi_perim_owner == curthread && mip->mi_perim_ocnt != 0); 1018 1019 mutex_enter(&mip->mi_perim_lock); 1020 if (--mip->mi_perim_ocnt == 0) { 1021 mip->mi_perim_owner = NULL; 1022 cv_signal(&mip->mi_perim_cv); 1023 } 1024 mutex_exit(&mip->mi_perim_lock); 1025 } 1026 1027 /* 1028 * Returns whether the current thread holds the mac perimeter. Used in making 1029 * assertions. 1030 */ 1031 boolean_t 1032 mac_perim_held(mac_handle_t mh) 1033 { 1034 mac_impl_t *mip = (mac_impl_t *)mh; 1035 mac_client_impl_t *mcip; 1036 1037 if (mip->mi_state_flags & MIS_IS_VNIC) { 1038 /* 1039 * This is a VNIC. Return the lower mac since that is what 1040 * we want to serialize on. 1041 */ 1042 mcip = mac_vnic_lower(mip); 1043 mip = mcip->mci_mip; 1044 } 1045 return (mip->mi_perim_owner == curthread); 1046 } 1047 1048 /* 1049 * mac client interfaces to enter the mac perimeter of a mac end point, given 1050 * its mac handle, or macname or linkid. 1051 */ 1052 void 1053 mac_perim_enter_by_mh(mac_handle_t mh, mac_perim_handle_t *mphp) 1054 { 1055 mac_impl_t *mip = (mac_impl_t *)mh; 1056 1057 i_mac_perim_enter(mip); 1058 /* 1059 * The mac_perim_handle_t returned encodes the 'mip' and whether a 1060 * mac_open has been done internally while entering the perimeter. 1061 * This information is used in mac_perim_exit 1062 */ 1063 MAC_ENCODE_MPH(*mphp, mip, 0); 1064 } 1065 1066 int 1067 mac_perim_enter_by_macname(const char *name, mac_perim_handle_t *mphp) 1068 { 1069 int err; 1070 mac_handle_t mh; 1071 1072 if ((err = mac_open(name, &mh)) != 0) 1073 return (err); 1074 1075 mac_perim_enter_by_mh(mh, mphp); 1076 MAC_ENCODE_MPH(*mphp, mh, 1); 1077 return (0); 1078 } 1079 1080 int 1081 mac_perim_enter_by_linkid(datalink_id_t linkid, mac_perim_handle_t *mphp) 1082 { 1083 int err; 1084 mac_handle_t mh; 1085 1086 if ((err = mac_open_by_linkid(linkid, &mh)) != 0) 1087 return (err); 1088 1089 mac_perim_enter_by_mh(mh, mphp); 1090 MAC_ENCODE_MPH(*mphp, mh, 1); 1091 return (0); 1092 } 1093 1094 void 1095 mac_perim_exit(mac_perim_handle_t mph) 1096 { 1097 mac_impl_t *mip; 1098 boolean_t need_close; 1099 1100 MAC_DECODE_MPH(mph, mip, need_close); 1101 i_mac_perim_exit(mip); 1102 if (need_close) 1103 mac_close((mac_handle_t)mip); 1104 } 1105 1106 int 1107 mac_hold(const char *macname, mac_impl_t **pmip) 1108 { 1109 mac_impl_t *mip; 1110 int err; 1111 1112 /* 1113 * Check the device name length to make sure it won't overflow our 1114 * buffer. 1115 */ 1116 if (strlen(macname) >= MAXNAMELEN) 1117 return (EINVAL); 1118 1119 /* 1120 * Look up its entry in the global hash table. 1121 */ 1122 rw_enter(&i_mac_impl_lock, RW_WRITER); 1123 err = mod_hash_find(i_mac_impl_hash, (mod_hash_key_t)macname, 1124 (mod_hash_val_t *)&mip); 1125 1126 if (err != 0) { 1127 rw_exit(&i_mac_impl_lock); 1128 return (ENOENT); 1129 } 1130 1131 if (mip->mi_state_flags & MIS_DISABLED) { 1132 rw_exit(&i_mac_impl_lock); 1133 return (ENOENT); 1134 } 1135 1136 if (mip->mi_state_flags & MIS_EXCLUSIVE_HELD) { 1137 rw_exit(&i_mac_impl_lock); 1138 return (EBUSY); 1139 } 1140 1141 mip->mi_ref++; 1142 rw_exit(&i_mac_impl_lock); 1143 1144 *pmip = mip; 1145 return (0); 1146 } 1147 1148 void 1149 mac_rele(mac_impl_t *mip) 1150 { 1151 rw_enter(&i_mac_impl_lock, RW_WRITER); 1152 ASSERT(mip->mi_ref != 0); 1153 if (--mip->mi_ref == 0) { 1154 ASSERT(mip->mi_nactiveclients == 0 && 1155 !(mip->mi_state_flags & MIS_EXCLUSIVE)); 1156 } 1157 rw_exit(&i_mac_impl_lock); 1158 } 1159 1160 /* 1161 * Private GLDv3 function to start a MAC instance. 1162 */ 1163 int 1164 mac_start(mac_handle_t mh) 1165 { 1166 mac_impl_t *mip = (mac_impl_t *)mh; 1167 int err = 0; 1168 mac_group_t *defgrp; 1169 1170 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 1171 ASSERT(mip->mi_start != NULL); 1172 1173 /* 1174 * Check whether the device is already started. 1175 */ 1176 if (mip->mi_active++ == 0) { 1177 mac_ring_t *ring = NULL; 1178 1179 /* 1180 * Start the device. 1181 */ 1182 err = mip->mi_start(mip->mi_driver); 1183 if (err != 0) { 1184 mip->mi_active--; 1185 return (err); 1186 } 1187 1188 /* 1189 * Start the default tx ring. 1190 */ 1191 if (mip->mi_default_tx_ring != NULL) { 1192 1193 ring = (mac_ring_t *)mip->mi_default_tx_ring; 1194 if (ring->mr_state != MR_INUSE) { 1195 err = mac_start_ring(ring); 1196 if (err != 0) { 1197 mip->mi_active--; 1198 return (err); 1199 } 1200 } 1201 } 1202 1203 if ((defgrp = MAC_DEFAULT_RX_GROUP(mip)) != NULL) { 1204 /* 1205 * Start the default group which is responsible 1206 * for receiving broadcast and multicast 1207 * traffic for both primary and non-primary 1208 * MAC clients. 1209 */ 1210 ASSERT(defgrp->mrg_state == MAC_GROUP_STATE_REGISTERED); 1211 err = mac_start_group_and_rings(defgrp); 1212 if (err != 0) { 1213 mip->mi_active--; 1214 if ((ring != NULL) && 1215 (ring->mr_state == MR_INUSE)) 1216 mac_stop_ring(ring); 1217 return (err); 1218 } 1219 mac_set_group_state(defgrp, MAC_GROUP_STATE_SHARED); 1220 } 1221 } 1222 1223 return (err); 1224 } 1225 1226 /* 1227 * Private GLDv3 function to stop a MAC instance. 1228 */ 1229 void 1230 mac_stop(mac_handle_t mh) 1231 { 1232 mac_impl_t *mip = (mac_impl_t *)mh; 1233 mac_group_t *grp; 1234 1235 ASSERT(mip->mi_stop != NULL); 1236 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 1237 1238 /* 1239 * Check whether the device is still needed. 1240 */ 1241 ASSERT(mip->mi_active != 0); 1242 if (--mip->mi_active == 0) { 1243 if ((grp = MAC_DEFAULT_RX_GROUP(mip)) != NULL) { 1244 /* 1245 * There should be no more active clients since the 1246 * MAC is being stopped. Stop the default RX group 1247 * and transition it back to registered state. 1248 * 1249 * When clients are torn down, the groups 1250 * are release via mac_release_rx_group which 1251 * knows the the default group is always in 1252 * started mode since broadcast uses it. So 1253 * we can assert that their are no clients 1254 * (since mac_bcast_add doesn't register itself 1255 * as a client) and group is in SHARED state. 1256 */ 1257 ASSERT(grp->mrg_state == MAC_GROUP_STATE_SHARED); 1258 ASSERT(MAC_GROUP_NO_CLIENT(grp) && 1259 mip->mi_nactiveclients == 0); 1260 mac_stop_group_and_rings(grp); 1261 mac_set_group_state(grp, MAC_GROUP_STATE_REGISTERED); 1262 } 1263 1264 if (mip->mi_default_tx_ring != NULL) { 1265 mac_ring_t *ring; 1266 1267 ring = (mac_ring_t *)mip->mi_default_tx_ring; 1268 if (ring->mr_state == MR_INUSE) { 1269 mac_stop_ring(ring); 1270 ring->mr_flag = 0; 1271 } 1272 } 1273 1274 /* 1275 * Stop the device. 1276 */ 1277 mip->mi_stop(mip->mi_driver); 1278 } 1279 } 1280 1281 int 1282 i_mac_promisc_set(mac_impl_t *mip, boolean_t on) 1283 { 1284 int err = 0; 1285 1286 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 1287 ASSERT(mip->mi_setpromisc != NULL); 1288 1289 if (on) { 1290 /* 1291 * Enable promiscuous mode on the device if not yet enabled. 1292 */ 1293 if (mip->mi_devpromisc++ == 0) { 1294 err = mip->mi_setpromisc(mip->mi_driver, B_TRUE); 1295 if (err != 0) { 1296 mip->mi_devpromisc--; 1297 return (err); 1298 } 1299 i_mac_notify(mip, MAC_NOTE_DEVPROMISC); 1300 } 1301 } else { 1302 if (mip->mi_devpromisc == 0) 1303 return (EPROTO); 1304 1305 /* 1306 * Disable promiscuous mode on the device if this is the last 1307 * enabling. 1308 */ 1309 if (--mip->mi_devpromisc == 0) { 1310 err = mip->mi_setpromisc(mip->mi_driver, B_FALSE); 1311 if (err != 0) { 1312 mip->mi_devpromisc++; 1313 return (err); 1314 } 1315 i_mac_notify(mip, MAC_NOTE_DEVPROMISC); 1316 } 1317 } 1318 1319 return (0); 1320 } 1321 1322 /* 1323 * The promiscuity state can change any time. If the caller needs to take 1324 * actions that are atomic with the promiscuity state, then the caller needs 1325 * to bracket the entire sequence with mac_perim_enter/exit 1326 */ 1327 boolean_t 1328 mac_promisc_get(mac_handle_t mh) 1329 { 1330 mac_impl_t *mip = (mac_impl_t *)mh; 1331 1332 /* 1333 * Return the current promiscuity. 1334 */ 1335 return (mip->mi_devpromisc != 0); 1336 } 1337 1338 /* 1339 * Invoked at MAC instance attach time to initialize the list 1340 * of factory MAC addresses supported by a MAC instance. This function 1341 * builds a local cache in the mac_impl_t for the MAC addresses 1342 * supported by the underlying hardware. The MAC clients themselves 1343 * use the mac_addr_factory*() functions to query and reserve 1344 * factory MAC addresses. 1345 */ 1346 void 1347 mac_addr_factory_init(mac_impl_t *mip) 1348 { 1349 mac_capab_multifactaddr_t capab; 1350 uint8_t *addr; 1351 int i; 1352 1353 /* 1354 * First round to see how many factory MAC addresses are available. 1355 */ 1356 bzero(&capab, sizeof (capab)); 1357 if (!i_mac_capab_get((mac_handle_t)mip, MAC_CAPAB_MULTIFACTADDR, 1358 &capab) || (capab.mcm_naddr == 0)) { 1359 /* 1360 * The MAC instance doesn't support multiple factory 1361 * MAC addresses, we're done here. 1362 */ 1363 return; 1364 } 1365 1366 /* 1367 * Allocate the space and get all the factory addresses. 1368 */ 1369 addr = kmem_alloc(capab.mcm_naddr * MAXMACADDRLEN, KM_SLEEP); 1370 capab.mcm_getaddr(mip->mi_driver, capab.mcm_naddr, addr); 1371 1372 mip->mi_factory_addr_num = capab.mcm_naddr; 1373 mip->mi_factory_addr = kmem_zalloc(mip->mi_factory_addr_num * 1374 sizeof (mac_factory_addr_t), KM_SLEEP); 1375 1376 for (i = 0; i < capab.mcm_naddr; i++) { 1377 bcopy(addr + i * MAXMACADDRLEN, 1378 mip->mi_factory_addr[i].mfa_addr, 1379 mip->mi_type->mt_addr_length); 1380 mip->mi_factory_addr[i].mfa_in_use = B_FALSE; 1381 } 1382 1383 kmem_free(addr, capab.mcm_naddr * MAXMACADDRLEN); 1384 } 1385 1386 void 1387 mac_addr_factory_fini(mac_impl_t *mip) 1388 { 1389 if (mip->mi_factory_addr == NULL) { 1390 ASSERT(mip->mi_factory_addr_num == 0); 1391 return; 1392 } 1393 1394 kmem_free(mip->mi_factory_addr, mip->mi_factory_addr_num * 1395 sizeof (mac_factory_addr_t)); 1396 1397 mip->mi_factory_addr = NULL; 1398 mip->mi_factory_addr_num = 0; 1399 } 1400 1401 /* 1402 * Reserve a factory MAC address. If *slot is set to -1, the function 1403 * attempts to reserve any of the available factory MAC addresses and 1404 * returns the reserved slot id. If no slots are available, the function 1405 * returns ENOSPC. If *slot is not set to -1, the function reserves 1406 * the specified slot if it is available, or returns EBUSY is the slot 1407 * is already used. Returns ENOTSUP if the underlying MAC does not 1408 * support multiple factory addresses. If the slot number is not -1 but 1409 * is invalid, returns EINVAL. 1410 */ 1411 int 1412 mac_addr_factory_reserve(mac_client_handle_t mch, int *slot) 1413 { 1414 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1415 mac_impl_t *mip = mcip->mci_mip; 1416 int i, ret = 0; 1417 1418 i_mac_perim_enter(mip); 1419 /* 1420 * Protect against concurrent readers that may need a self-consistent 1421 * view of the factory addresses 1422 */ 1423 rw_enter(&mip->mi_rw_lock, RW_WRITER); 1424 1425 if (mip->mi_factory_addr_num == 0) { 1426 ret = ENOTSUP; 1427 goto bail; 1428 } 1429 1430 if (*slot != -1) { 1431 /* check the specified slot */ 1432 if (*slot < 1 || *slot > mip->mi_factory_addr_num) { 1433 ret = EINVAL; 1434 goto bail; 1435 } 1436 if (mip->mi_factory_addr[*slot-1].mfa_in_use) { 1437 ret = EBUSY; 1438 goto bail; 1439 } 1440 } else { 1441 /* pick the next available slot */ 1442 for (i = 0; i < mip->mi_factory_addr_num; i++) { 1443 if (!mip->mi_factory_addr[i].mfa_in_use) 1444 break; 1445 } 1446 1447 if (i == mip->mi_factory_addr_num) { 1448 ret = ENOSPC; 1449 goto bail; 1450 } 1451 *slot = i+1; 1452 } 1453 1454 mip->mi_factory_addr[*slot-1].mfa_in_use = B_TRUE; 1455 mip->mi_factory_addr[*slot-1].mfa_client = mcip; 1456 1457 bail: 1458 rw_exit(&mip->mi_rw_lock); 1459 i_mac_perim_exit(mip); 1460 return (ret); 1461 } 1462 1463 /* 1464 * Release the specified factory MAC address slot. 1465 */ 1466 void 1467 mac_addr_factory_release(mac_client_handle_t mch, uint_t slot) 1468 { 1469 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1470 mac_impl_t *mip = mcip->mci_mip; 1471 1472 i_mac_perim_enter(mip); 1473 /* 1474 * Protect against concurrent readers that may need a self-consistent 1475 * view of the factory addresses 1476 */ 1477 rw_enter(&mip->mi_rw_lock, RW_WRITER); 1478 1479 ASSERT(slot > 0 && slot <= mip->mi_factory_addr_num); 1480 ASSERT(mip->mi_factory_addr[slot-1].mfa_in_use); 1481 1482 mip->mi_factory_addr[slot-1].mfa_in_use = B_FALSE; 1483 1484 rw_exit(&mip->mi_rw_lock); 1485 i_mac_perim_exit(mip); 1486 } 1487 1488 /* 1489 * Stores in mac_addr the value of the specified MAC address. Returns 1490 * 0 on success, or EINVAL if the slot number is not valid for the MAC. 1491 * The caller must provide a string of at least MAXNAMELEN bytes. 1492 */ 1493 void 1494 mac_addr_factory_value(mac_handle_t mh, int slot, uchar_t *mac_addr, 1495 uint_t *addr_len, char *client_name, boolean_t *in_use_arg) 1496 { 1497 mac_impl_t *mip = (mac_impl_t *)mh; 1498 boolean_t in_use; 1499 1500 ASSERT(slot > 0 && slot <= mip->mi_factory_addr_num); 1501 1502 /* 1503 * Readers need to hold mi_rw_lock. Writers need to hold mac perimeter 1504 * and mi_rw_lock 1505 */ 1506 rw_enter(&mip->mi_rw_lock, RW_READER); 1507 bcopy(mip->mi_factory_addr[slot-1].mfa_addr, mac_addr, MAXMACADDRLEN); 1508 *addr_len = mip->mi_type->mt_addr_length; 1509 in_use = mip->mi_factory_addr[slot-1].mfa_in_use; 1510 if (in_use && client_name != NULL) { 1511 bcopy(mip->mi_factory_addr[slot-1].mfa_client->mci_name, 1512 client_name, MAXNAMELEN); 1513 } 1514 if (in_use_arg != NULL) 1515 *in_use_arg = in_use; 1516 rw_exit(&mip->mi_rw_lock); 1517 } 1518 1519 /* 1520 * Returns the number of factory MAC addresses (in addition to the 1521 * primary MAC address), 0 if the underlying MAC doesn't support 1522 * that feature. 1523 */ 1524 uint_t 1525 mac_addr_factory_num(mac_handle_t mh) 1526 { 1527 mac_impl_t *mip = (mac_impl_t *)mh; 1528 1529 return (mip->mi_factory_addr_num); 1530 } 1531 1532 1533 void 1534 mac_rx_group_unmark(mac_group_t *grp, uint_t flag) 1535 { 1536 mac_ring_t *ring; 1537 1538 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next) 1539 ring->mr_flag &= ~flag; 1540 } 1541 1542 /* 1543 * The following mac_hwrings_xxx() functions are private mac client functions 1544 * used by the aggr driver to access and control the underlying HW Rx group 1545 * and rings. In this case, the aggr driver has exclusive control of the 1546 * underlying HW Rx group/rings, it calls the following functions to 1547 * start/stop the HW Rx rings, disable/enable polling, add/remove MAC 1548 * addresses, or set up the Rx callback. 1549 */ 1550 /* ARGSUSED */ 1551 static void 1552 mac_hwrings_rx_process(void *arg, mac_resource_handle_t srs, 1553 mblk_t *mp_chain, boolean_t loopback) 1554 { 1555 mac_soft_ring_set_t *mac_srs = (mac_soft_ring_set_t *)srs; 1556 mac_srs_rx_t *srs_rx = &mac_srs->srs_rx; 1557 mac_direct_rx_t proc; 1558 void *arg1; 1559 mac_resource_handle_t arg2; 1560 1561 proc = srs_rx->sr_func; 1562 arg1 = srs_rx->sr_arg1; 1563 arg2 = mac_srs->srs_mrh; 1564 1565 proc(arg1, arg2, mp_chain, NULL); 1566 } 1567 1568 /* 1569 * This function is called to get the list of HW rings that are reserved by 1570 * an exclusive mac client. 1571 * 1572 * Return value: the number of HW rings. 1573 */ 1574 int 1575 mac_hwrings_get(mac_client_handle_t mch, mac_group_handle_t *hwgh, 1576 mac_ring_handle_t *hwrh, mac_ring_type_t rtype) 1577 { 1578 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1579 flow_entry_t *flent = mcip->mci_flent; 1580 mac_group_t *grp; 1581 mac_ring_t *ring; 1582 int cnt = 0; 1583 1584 if (rtype == MAC_RING_TYPE_RX) { 1585 grp = flent->fe_rx_ring_group; 1586 } else if (rtype == MAC_RING_TYPE_TX) { 1587 grp = flent->fe_tx_ring_group; 1588 } else { 1589 ASSERT(B_FALSE); 1590 return (-1); 1591 } 1592 1593 /* 1594 * The MAC client did not reserve an Rx group, return directly. 1595 * This is probably because the underlying MAC does not support 1596 * any groups. 1597 */ 1598 if (hwgh != NULL) 1599 *hwgh = NULL; 1600 if (grp == NULL) 1601 return (0); 1602 /* 1603 * This group must be reserved by this MAC client. 1604 */ 1605 ASSERT((grp->mrg_state == MAC_GROUP_STATE_RESERVED) && 1606 (mcip == MAC_GROUP_ONLY_CLIENT(grp))); 1607 1608 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next, cnt++) { 1609 ASSERT(cnt < MAX_RINGS_PER_GROUP); 1610 hwrh[cnt] = (mac_ring_handle_t)ring; 1611 } 1612 if (hwgh != NULL) 1613 *hwgh = (mac_group_handle_t)grp; 1614 1615 return (cnt); 1616 } 1617 1618 /* 1619 * Get the HW ring handles of the given group index. If the MAC 1620 * doesn't have a group at this index, or any groups at all, then 0 is 1621 * returned and hwgh is set to NULL. This is a private client API. The 1622 * MAC perimeter must be held when calling this function. 1623 * 1624 * mh: A handle to the MAC that owns the group. 1625 * 1626 * idx: The index of the HW group to be read. 1627 * 1628 * hwgh: If non-NULL, contains a handle to the HW group on return. 1629 * 1630 * hwrh: An array of ring handles pointing to the HW rings in the 1631 * group. The array must be large enough to hold a handle to each ring 1632 * in the group. To be safe, this array should be of size MAX_RINGS_PER_GROUP. 1633 * 1634 * rtype: Used to determine if we are fetching Rx or Tx rings. 1635 * 1636 * Returns the number of rings in the group. 1637 */ 1638 uint_t 1639 mac_hwrings_idx_get(mac_handle_t mh, uint_t idx, mac_group_handle_t *hwgh, 1640 mac_ring_handle_t *hwrh, mac_ring_type_t rtype) 1641 { 1642 mac_impl_t *mip = (mac_impl_t *)mh; 1643 mac_group_t *grp; 1644 mac_ring_t *ring; 1645 uint_t cnt = 0; 1646 1647 /* 1648 * The MAC perimeter must be held when accessing the 1649 * mi_{rx,tx}_groups fields. 1650 */ 1651 ASSERT(MAC_PERIM_HELD(mh)); 1652 ASSERT(rtype == MAC_RING_TYPE_RX || rtype == MAC_RING_TYPE_TX); 1653 1654 if (rtype == MAC_RING_TYPE_RX) { 1655 grp = mip->mi_rx_groups; 1656 } else { 1657 ASSERT(rtype == MAC_RING_TYPE_TX); 1658 grp = mip->mi_tx_groups; 1659 } 1660 1661 while (grp != NULL && grp->mrg_index != idx) 1662 grp = grp->mrg_next; 1663 1664 /* 1665 * If the MAC doesn't have a group at this index or doesn't 1666 * impelement RINGS capab, then set hwgh to NULL and return 0. 1667 */ 1668 if (hwgh != NULL) 1669 *hwgh = NULL; 1670 1671 if (grp == NULL) 1672 return (0); 1673 1674 ASSERT3U(idx, ==, grp->mrg_index); 1675 1676 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next, cnt++) { 1677 ASSERT3U(cnt, <, MAX_RINGS_PER_GROUP); 1678 hwrh[cnt] = (mac_ring_handle_t)ring; 1679 } 1680 1681 /* A group should always have at least one ring. */ 1682 ASSERT3U(cnt, >, 0); 1683 1684 if (hwgh != NULL) 1685 *hwgh = (mac_group_handle_t)grp; 1686 1687 return (cnt); 1688 } 1689 1690 /* 1691 * This function is called to get info about Tx/Rx rings. 1692 * 1693 * Return value: returns uint_t which will have various bits set 1694 * that indicates different properties of the ring. 1695 */ 1696 uint_t 1697 mac_hwring_getinfo(mac_ring_handle_t rh) 1698 { 1699 mac_ring_t *ring = (mac_ring_t *)rh; 1700 mac_ring_info_t *info = &ring->mr_info; 1701 1702 return (info->mri_flags); 1703 } 1704 1705 /* 1706 * Set the passthru callback on the hardware ring. 1707 */ 1708 void 1709 mac_hwring_set_passthru(mac_ring_handle_t hwrh, mac_rx_t fn, void *arg1, 1710 mac_resource_handle_t arg2) 1711 { 1712 mac_ring_t *hwring = (mac_ring_t *)hwrh; 1713 1714 ASSERT3S(hwring->mr_type, ==, MAC_RING_TYPE_RX); 1715 1716 hwring->mr_classify_type = MAC_PASSTHRU_CLASSIFIER; 1717 1718 hwring->mr_pt_fn = fn; 1719 hwring->mr_pt_arg1 = arg1; 1720 hwring->mr_pt_arg2 = arg2; 1721 } 1722 1723 /* 1724 * Clear the passthru callback on the hardware ring. 1725 */ 1726 void 1727 mac_hwring_clear_passthru(mac_ring_handle_t hwrh) 1728 { 1729 mac_ring_t *hwring = (mac_ring_t *)hwrh; 1730 1731 ASSERT3S(hwring->mr_type, ==, MAC_RING_TYPE_RX); 1732 1733 hwring->mr_classify_type = MAC_NO_CLASSIFIER; 1734 1735 hwring->mr_pt_fn = NULL; 1736 hwring->mr_pt_arg1 = NULL; 1737 hwring->mr_pt_arg2 = NULL; 1738 } 1739 1740 void 1741 mac_client_set_flow_cb(mac_client_handle_t mch, mac_rx_t func, void *arg1) 1742 { 1743 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1744 flow_entry_t *flent = mcip->mci_flent; 1745 1746 mutex_enter(&flent->fe_lock); 1747 flent->fe_cb_fn = (flow_fn_t)func; 1748 flent->fe_cb_arg1 = arg1; 1749 flent->fe_cb_arg2 = NULL; 1750 flent->fe_flags &= ~FE_MC_NO_DATAPATH; 1751 mutex_exit(&flent->fe_lock); 1752 } 1753 1754 void 1755 mac_client_clear_flow_cb(mac_client_handle_t mch) 1756 { 1757 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1758 flow_entry_t *flent = mcip->mci_flent; 1759 1760 mutex_enter(&flent->fe_lock); 1761 flent->fe_cb_fn = (flow_fn_t)mac_rx_def; 1762 flent->fe_cb_arg1 = NULL; 1763 flent->fe_cb_arg2 = NULL; 1764 flent->fe_flags |= FE_MC_NO_DATAPATH; 1765 mutex_exit(&flent->fe_lock); 1766 } 1767 1768 /* 1769 * Export ddi interrupt handles from the HW ring to the pseudo ring and 1770 * setup the RX callback of the mac client which exclusively controls 1771 * HW ring. 1772 */ 1773 void 1774 mac_hwring_setup(mac_ring_handle_t hwrh, mac_resource_handle_t prh, 1775 mac_ring_handle_t pseudo_rh) 1776 { 1777 mac_ring_t *hw_ring = (mac_ring_t *)hwrh; 1778 mac_ring_t *pseudo_ring; 1779 mac_soft_ring_set_t *mac_srs = hw_ring->mr_srs; 1780 1781 if (pseudo_rh != NULL) { 1782 pseudo_ring = (mac_ring_t *)pseudo_rh; 1783 /* Export the ddi handles to pseudo ring */ 1784 pseudo_ring->mr_info.mri_intr.mi_ddi_handle = 1785 hw_ring->mr_info.mri_intr.mi_ddi_handle; 1786 pseudo_ring->mr_info.mri_intr.mi_ddi_shared = 1787 hw_ring->mr_info.mri_intr.mi_ddi_shared; 1788 /* 1789 * Save a pointer to pseudo ring in the hw ring. If 1790 * interrupt handle changes, the hw ring will be 1791 * notified of the change (see mac_ring_intr_set()) 1792 * and the appropriate change has to be made to 1793 * the pseudo ring that has exported the ddi handle. 1794 */ 1795 hw_ring->mr_prh = pseudo_rh; 1796 } 1797 1798 if (hw_ring->mr_type == MAC_RING_TYPE_RX) { 1799 ASSERT(!(mac_srs->srs_type & SRST_TX)); 1800 mac_srs->srs_mrh = prh; 1801 mac_srs->srs_rx.sr_lower_proc = mac_hwrings_rx_process; 1802 } 1803 } 1804 1805 void 1806 mac_hwring_teardown(mac_ring_handle_t hwrh) 1807 { 1808 mac_ring_t *hw_ring = (mac_ring_t *)hwrh; 1809 mac_soft_ring_set_t *mac_srs; 1810 1811 if (hw_ring == NULL) 1812 return; 1813 hw_ring->mr_prh = NULL; 1814 if (hw_ring->mr_type == MAC_RING_TYPE_RX) { 1815 mac_srs = hw_ring->mr_srs; 1816 ASSERT(!(mac_srs->srs_type & SRST_TX)); 1817 mac_srs->srs_rx.sr_lower_proc = mac_rx_srs_process; 1818 mac_srs->srs_mrh = NULL; 1819 } 1820 } 1821 1822 int 1823 mac_hwring_disable_intr(mac_ring_handle_t rh) 1824 { 1825 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1826 mac_intr_t *intr = &rr_ring->mr_info.mri_intr; 1827 1828 return (intr->mi_disable(intr->mi_handle)); 1829 } 1830 1831 int 1832 mac_hwring_enable_intr(mac_ring_handle_t rh) 1833 { 1834 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1835 mac_intr_t *intr = &rr_ring->mr_info.mri_intr; 1836 1837 return (intr->mi_enable(intr->mi_handle)); 1838 } 1839 1840 /* 1841 * Start the HW ring pointed to by rh. 1842 * 1843 * This is used by special MAC clients that are MAC themselves and 1844 * need to exert control over the underlying HW rings of the NIC. 1845 */ 1846 int 1847 mac_hwring_start(mac_ring_handle_t rh) 1848 { 1849 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1850 int rv = 0; 1851 1852 if (rr_ring->mr_state != MR_INUSE) 1853 rv = mac_start_ring(rr_ring); 1854 1855 return (rv); 1856 } 1857 1858 /* 1859 * Stop the HW ring pointed to by rh. Also see mac_hwring_start(). 1860 */ 1861 void 1862 mac_hwring_stop(mac_ring_handle_t rh) 1863 { 1864 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1865 1866 if (rr_ring->mr_state != MR_FREE) 1867 mac_stop_ring(rr_ring); 1868 } 1869 1870 /* 1871 * Remove the quiesced flag from the HW ring pointed to by rh. 1872 * 1873 * This is used by special MAC clients that are MAC themselves and 1874 * need to exert control over the underlying HW rings of the NIC. 1875 */ 1876 int 1877 mac_hwring_activate(mac_ring_handle_t rh) 1878 { 1879 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1880 1881 MAC_RING_UNMARK(rr_ring, MR_QUIESCE); 1882 return (0); 1883 } 1884 1885 /* 1886 * Quiesce the HW ring pointed to by rh. Also see mac_hwring_activate(). 1887 */ 1888 void 1889 mac_hwring_quiesce(mac_ring_handle_t rh) 1890 { 1891 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1892 1893 mac_rx_ring_quiesce(rr_ring, MR_QUIESCE); 1894 } 1895 1896 mblk_t * 1897 mac_hwring_poll(mac_ring_handle_t rh, int bytes_to_pickup) 1898 { 1899 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1900 mac_ring_info_t *info = &rr_ring->mr_info; 1901 1902 return (info->mri_poll(info->mri_driver, bytes_to_pickup)); 1903 } 1904 1905 /* 1906 * Send packets through a selected tx ring. 1907 */ 1908 mblk_t * 1909 mac_hwring_tx(mac_ring_handle_t rh, mblk_t *mp) 1910 { 1911 mac_ring_t *ring = (mac_ring_t *)rh; 1912 mac_ring_info_t *info = &ring->mr_info; 1913 1914 ASSERT(ring->mr_type == MAC_RING_TYPE_TX && 1915 ring->mr_state >= MR_INUSE); 1916 return (info->mri_tx(info->mri_driver, mp)); 1917 } 1918 1919 /* 1920 * Query stats for a particular rx/tx ring 1921 */ 1922 int 1923 mac_hwring_getstat(mac_ring_handle_t rh, uint_t stat, uint64_t *val) 1924 { 1925 mac_ring_t *ring = (mac_ring_t *)rh; 1926 mac_ring_info_t *info = &ring->mr_info; 1927 1928 return (info->mri_stat(info->mri_driver, stat, val)); 1929 } 1930 1931 /* 1932 * Private function that is only used by aggr to send packets through 1933 * a port/Tx ring. Since aggr exposes a pseudo Tx ring even for ports 1934 * that does not expose Tx rings, aggr_ring_tx() entry point needs 1935 * access to mac_impl_t to send packets through m_tx() entry point. 1936 * It accomplishes this by calling mac_hwring_send_priv() function. 1937 */ 1938 mblk_t * 1939 mac_hwring_send_priv(mac_client_handle_t mch, mac_ring_handle_t rh, mblk_t *mp) 1940 { 1941 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1942 mac_impl_t *mip = mcip->mci_mip; 1943 1944 return (mac_provider_tx(mip, rh, mp, mcip)); 1945 } 1946 1947 /* 1948 * Private function that is only used by aggr to update the default transmission 1949 * ring. Because aggr exposes a pseudo Tx ring even for ports that may 1950 * temporarily be down, it may need to update the default ring that is used by 1951 * MAC such that it refers to a link that can actively be used to send traffic. 1952 * Note that this is different from the case where the port has been removed 1953 * from the group. In those cases, all of the rings will be torn down because 1954 * the ring will no longer exist. It's important to give aggr a case where the 1955 * rings can still exist such that it may be able to continue to send LACP PDUs 1956 * to potentially restore the link. 1957 */ 1958 void 1959 mac_hwring_set_default(mac_handle_t mh, mac_ring_handle_t rh) 1960 { 1961 mac_impl_t *mip = (mac_impl_t *)mh; 1962 mac_ring_t *ring = (mac_ring_t *)rh; 1963 1964 ASSERT(MAC_PERIM_HELD(mh)); 1965 VERIFY(mip->mi_state_flags & MIS_IS_AGGR); 1966 1967 /* 1968 * We used to condition this assignment on the ring's 1969 * 'mr_state' being one of 'MR_INUSE'. However, there are 1970 * cases where this is called before the ring has any active 1971 * clients, and therefore is not marked as in use. Since the 1972 * sole purpose of this function is for aggr to make sure 1973 * 'mi_default_tx_ring' matches 'lg_tx_ports[0]', its 1974 * imperative that we update its value regardless of ring 1975 * state. Otherwise, we can end up in a state where 1976 * 'mi_default_tx_ring' points to a pseudo ring of a downed 1977 * port, even when 'lg_tx_ports[0]' points to a port that is 1978 * up. 1979 */ 1980 mip->mi_default_tx_ring = rh; 1981 } 1982 1983 int 1984 mac_hwgroup_addmac(mac_group_handle_t gh, const uint8_t *addr) 1985 { 1986 mac_group_t *group = (mac_group_t *)gh; 1987 1988 return (mac_group_addmac(group, addr)); 1989 } 1990 1991 int 1992 mac_hwgroup_remmac(mac_group_handle_t gh, const uint8_t *addr) 1993 { 1994 mac_group_t *group = (mac_group_t *)gh; 1995 1996 return (mac_group_remmac(group, addr)); 1997 } 1998 1999 /* 2000 * Program the group's HW VLAN filter if it has such support. 2001 * Otherwise, the group will implicitly accept tagged traffic and 2002 * there is nothing to do. 2003 */ 2004 int 2005 mac_hwgroup_addvlan(mac_group_handle_t gh, uint16_t vid) 2006 { 2007 mac_group_t *group = (mac_group_t *)gh; 2008 2009 if (!MAC_GROUP_HW_VLAN(group)) 2010 return (0); 2011 2012 return (mac_group_addvlan(group, vid)); 2013 } 2014 2015 int 2016 mac_hwgroup_remvlan(mac_group_handle_t gh, uint16_t vid) 2017 { 2018 mac_group_t *group = (mac_group_t *)gh; 2019 2020 if (!MAC_GROUP_HW_VLAN(group)) 2021 return (0); 2022 2023 return (mac_group_remvlan(group, vid)); 2024 } 2025 2026 /* 2027 * Determine if a MAC has HW VLAN support. This is a private API 2028 * consumed by aggr. In the future it might be nice to have a bitfield 2029 * in mac_capab_rings_t to track which forms of HW filtering are 2030 * supported by the MAC. 2031 */ 2032 boolean_t 2033 mac_has_hw_vlan(mac_handle_t mh) 2034 { 2035 mac_impl_t *mip = (mac_impl_t *)mh; 2036 2037 return (MAC_GROUP_HW_VLAN(mip->mi_rx_groups)); 2038 } 2039 2040 /* 2041 * Get the number of Rx HW groups on this MAC. 2042 */ 2043 uint_t 2044 mac_get_num_rx_groups(mac_handle_t mh) 2045 { 2046 mac_impl_t *mip = (mac_impl_t *)mh; 2047 2048 ASSERT(MAC_PERIM_HELD(mh)); 2049 return (mip->mi_rx_group_count); 2050 } 2051 2052 int 2053 mac_set_promisc(mac_handle_t mh, boolean_t value) 2054 { 2055 mac_impl_t *mip = (mac_impl_t *)mh; 2056 2057 ASSERT(MAC_PERIM_HELD(mh)); 2058 return (i_mac_promisc_set(mip, value)); 2059 } 2060 2061 /* 2062 * Set the RX group to be shared/reserved. Note that the group must be 2063 * started/stopped outside of this function. 2064 */ 2065 void 2066 mac_set_group_state(mac_group_t *grp, mac_group_state_t state) 2067 { 2068 /* 2069 * If there is no change in the group state, just return. 2070 */ 2071 if (grp->mrg_state == state) 2072 return; 2073 2074 switch (state) { 2075 case MAC_GROUP_STATE_RESERVED: 2076 /* 2077 * Successfully reserved the group. 2078 * 2079 * Given that there is an exclusive client controlling this 2080 * group, we enable the group level polling when available, 2081 * so that SRSs get to turn on/off individual rings they's 2082 * assigned to. 2083 */ 2084 ASSERT(MAC_PERIM_HELD(grp->mrg_mh)); 2085 2086 if (grp->mrg_type == MAC_RING_TYPE_RX && 2087 GROUP_INTR_DISABLE_FUNC(grp) != NULL) { 2088 GROUP_INTR_DISABLE_FUNC(grp)(GROUP_INTR_HANDLE(grp)); 2089 } 2090 break; 2091 2092 case MAC_GROUP_STATE_SHARED: 2093 /* 2094 * Set all rings of this group to software classified. 2095 * If the group has an overriding interrupt, then re-enable it. 2096 */ 2097 ASSERT(MAC_PERIM_HELD(grp->mrg_mh)); 2098 2099 if (grp->mrg_type == MAC_RING_TYPE_RX && 2100 GROUP_INTR_ENABLE_FUNC(grp) != NULL) { 2101 GROUP_INTR_ENABLE_FUNC(grp)(GROUP_INTR_HANDLE(grp)); 2102 } 2103 /* The ring is not available for reservations any more */ 2104 break; 2105 2106 case MAC_GROUP_STATE_REGISTERED: 2107 /* Also callable from mac_register, perim is not held */ 2108 break; 2109 2110 default: 2111 ASSERT(B_FALSE); 2112 break; 2113 } 2114 2115 grp->mrg_state = state; 2116 } 2117 2118 /* 2119 * Quiesce future hardware classified packets for the specified Rx ring 2120 */ 2121 static void 2122 mac_rx_ring_quiesce(mac_ring_t *rx_ring, uint_t ring_flag) 2123 { 2124 ASSERT(rx_ring->mr_classify_type == MAC_HW_CLASSIFIER); 2125 ASSERT(ring_flag == MR_CONDEMNED || ring_flag == MR_QUIESCE); 2126 2127 mutex_enter(&rx_ring->mr_lock); 2128 rx_ring->mr_flag |= ring_flag; 2129 while (rx_ring->mr_refcnt != 0) 2130 cv_wait(&rx_ring->mr_cv, &rx_ring->mr_lock); 2131 mutex_exit(&rx_ring->mr_lock); 2132 } 2133 2134 /* 2135 * Please see mac_tx for details about the per cpu locking scheme 2136 */ 2137 static void 2138 mac_tx_lock_all(mac_client_impl_t *mcip) 2139 { 2140 int i; 2141 2142 for (i = 0; i <= mac_tx_percpu_cnt; i++) 2143 mutex_enter(&mcip->mci_tx_pcpu[i].pcpu_tx_lock); 2144 } 2145 2146 static void 2147 mac_tx_unlock_all(mac_client_impl_t *mcip) 2148 { 2149 int i; 2150 2151 for (i = mac_tx_percpu_cnt; i >= 0; i--) 2152 mutex_exit(&mcip->mci_tx_pcpu[i].pcpu_tx_lock); 2153 } 2154 2155 static void 2156 mac_tx_unlock_allbutzero(mac_client_impl_t *mcip) 2157 { 2158 int i; 2159 2160 for (i = mac_tx_percpu_cnt; i > 0; i--) 2161 mutex_exit(&mcip->mci_tx_pcpu[i].pcpu_tx_lock); 2162 } 2163 2164 static int 2165 mac_tx_sum_refcnt(mac_client_impl_t *mcip) 2166 { 2167 int i; 2168 int refcnt = 0; 2169 2170 for (i = 0; i <= mac_tx_percpu_cnt; i++) 2171 refcnt += mcip->mci_tx_pcpu[i].pcpu_tx_refcnt; 2172 2173 return (refcnt); 2174 } 2175 2176 /* 2177 * Stop future Tx packets coming down from the client in preparation for 2178 * quiescing the Tx side. This is needed for dynamic reclaim and reassignment 2179 * of rings between clients 2180 */ 2181 void 2182 mac_tx_client_block(mac_client_impl_t *mcip) 2183 { 2184 mac_tx_lock_all(mcip); 2185 mcip->mci_tx_flag |= MCI_TX_QUIESCE; 2186 while (mac_tx_sum_refcnt(mcip) != 0) { 2187 mac_tx_unlock_allbutzero(mcip); 2188 cv_wait(&mcip->mci_tx_cv, &mcip->mci_tx_pcpu[0].pcpu_tx_lock); 2189 mutex_exit(&mcip->mci_tx_pcpu[0].pcpu_tx_lock); 2190 mac_tx_lock_all(mcip); 2191 } 2192 mac_tx_unlock_all(mcip); 2193 } 2194 2195 void 2196 mac_tx_client_unblock(mac_client_impl_t *mcip) 2197 { 2198 mac_tx_lock_all(mcip); 2199 mcip->mci_tx_flag &= ~MCI_TX_QUIESCE; 2200 mac_tx_unlock_all(mcip); 2201 /* 2202 * We may fail to disable flow control for the last MAC_NOTE_TX 2203 * notification because the MAC client is quiesced. Send the 2204 * notification again. 2205 */ 2206 i_mac_notify(mcip->mci_mip, MAC_NOTE_TX); 2207 } 2208 2209 /* 2210 * Wait for an SRS to quiesce. The SRS worker will signal us when the 2211 * quiesce is done. 2212 */ 2213 static void 2214 mac_srs_quiesce_wait(mac_soft_ring_set_t *srs, 2215 const mac_soft_ring_set_state_t srs_flag) 2216 { 2217 mutex_enter(&srs->srs_lock); 2218 while (!(srs->srs_state & srs_flag)) 2219 cv_wait(&srs->srs_quiesce_done_cv, &srs->srs_lock); 2220 mutex_exit(&srs->srs_lock); 2221 } 2222 2223 /* 2224 * Quiescing an Rx SRS is achieved by the following sequence. The protocol 2225 * works bottom up by cutting off packet flow from the bottommost point in the 2226 * mac, then the SRS, and then the soft rings. There are 2 use cases of this 2227 * mechanism. One is a temporary quiesce of the SRS, such as say while changing 2228 * the Rx callbacks. Another use case is Rx SRS teardown. In the former case 2229 * the QUIESCE prefix/suffix is used and in the latter the CONDEMNED is used 2230 * for the SRS and MR flags. In the former case the threads pause waiting for 2231 * a restart, while in the latter case the threads exit. The Tx SRS teardown 2232 * is also mostly similar to the above. 2233 * 2234 * 1. Stop future hardware classified packets at the lowest level in the mac. 2235 * Remove any hardware classification rule (CONDEMNED case) and mark the 2236 * rings as CONDEMNED or QUIESCE as appropriate. This prevents the mr_refcnt 2237 * from increasing. Upcalls from the driver that come through hardware 2238 * classification will be dropped in mac_rx from now on. Then we wait for 2239 * the mr_refcnt to drop to zero. When the mr_refcnt reaches zero we are 2240 * sure there aren't any upcall threads from the driver through hardware 2241 * classification. In the case of SRS teardown we also remove the 2242 * classification rule in the driver. 2243 * 2244 * 2. Stop future software classified packets by marking the flow entry with 2245 * FE_QUIESCE or FE_CONDEMNED as appropriate which prevents the refcnt from 2246 * increasing. We also remove the flow entry from the table in the latter 2247 * case. Then wait for the fe_refcnt to reach an appropriate quiescent value 2248 * that indicates there aren't any active threads using that flow entry. 2249 * 2250 * 3. Quiesce the SRS and softrings by signaling the SRS. The SRS poll thread, 2251 * SRS worker thread, and the soft ring threads are quiesced in sequence 2252 * with the SRS worker thread serving as a master controller. This 2253 * mechansim is explained in mac_srs_worker_quiesce(). 2254 * 2255 * The restart mechanism to reactivate the SRS and softrings is explained 2256 * in mac_srs_worker_restart(). Here we just signal the SRS worker to start the 2257 * restart sequence. 2258 */ 2259 void 2260 mac_rx_srs_quiesce(mac_soft_ring_set_t *srs, 2261 const mac_soft_ring_set_state_t srs_quiesce_flag) 2262 { 2263 flow_entry_t *flent = srs->srs_flent; 2264 uint_t mr_flag; 2265 mac_soft_ring_set_state_t srs_done_flag; 2266 2267 VERIFY(mac_perim_held((mac_handle_t)FLENT_TO_MIP(flent))); 2268 VERIFY0(srs->srs_type & SRST_TX); 2269 2270 if (srs_quiesce_flag == SRS_CONDEMNED) { 2271 mr_flag = MR_CONDEMNED; 2272 srs_done_flag = SRS_CONDEMNED_DONE; 2273 2274 if (srs->srs_type & SRST_CLIENT_POLL_V4) { 2275 mac_srs_client_poll_disable(srs->srs_mcip, srs, 2276 B_FALSE); 2277 } 2278 2279 if (srs->srs_type & SRST_CLIENT_POLL_V6) { 2280 mac_srs_client_poll_disable(srs->srs_mcip, srs, 2281 B_TRUE); 2282 } 2283 } else { 2284 VERIFY3U(srs_quiesce_flag, ==, SRS_QUIESCE); 2285 mr_flag = MR_QUIESCE; 2286 srs_done_flag = SRS_QUIESCE_DONE; 2287 mac_srs_client_poll_quiesce(srs->srs_mcip, srs); 2288 } 2289 2290 if (srs->srs_ring != NULL) { 2291 mac_rx_ring_quiesce(srs->srs_ring, mr_flag); 2292 } else { 2293 /* 2294 * SRS is driven by software classification. In case 2295 * of CONDEMNED, the top level teardown functions will 2296 * deal with flow removal. 2297 */ 2298 if (srs_quiesce_flag != SRS_CONDEMNED) { 2299 FLOW_MARK(flent, FE_QUIESCE); 2300 mac_flow_wait(flent, FLOW_DRIVER_UPCALL); 2301 } 2302 } 2303 2304 /* 2305 * Signal the SRS to quiesce itself, and then cv_wait for the 2306 * SRS quiesce to complete. The SRS worker thread will wake us 2307 * up when the quiesce is complete 2308 */ 2309 mac_srs_signal(srs, srs_quiesce_flag); 2310 mac_srs_quiesce_wait(srs, srs_done_flag); 2311 } 2312 2313 /* 2314 * Remove an SRS. 2315 */ 2316 void 2317 mac_rx_srs_remove(mac_soft_ring_set_t *srs) 2318 { 2319 flow_entry_t *flent = srs->srs_flent; 2320 int i; 2321 2322 mac_rx_srs_quiesce(srs, SRS_CONDEMNED); 2323 /* 2324 * Locate and remove our entry in the fe_rx_srs[] array, and 2325 * adjust the fe_rx_srs array entries and array count by 2326 * moving the last entry into the vacated spot. 2327 */ 2328 mutex_enter(&flent->fe_lock); 2329 for (i = 0; i < flent->fe_rx_srs_cnt; i++) { 2330 if (flent->fe_rx_srs[i] == srs) 2331 break; 2332 } 2333 2334 ASSERT(i != 0 && i < flent->fe_rx_srs_cnt); 2335 if (i != flent->fe_rx_srs_cnt - 1) { 2336 flent->fe_rx_srs[i] = 2337 flent->fe_rx_srs[flent->fe_rx_srs_cnt - 1]; 2338 i = flent->fe_rx_srs_cnt - 1; 2339 } 2340 2341 flent->fe_rx_srs[i] = NULL; 2342 flent->fe_rx_srs_cnt--; 2343 mutex_exit(&flent->fe_lock); 2344 2345 mac_srs_free(srs); 2346 } 2347 2348 static void 2349 mac_srs_clear_flag(mac_soft_ring_set_t *srs, 2350 const mac_soft_ring_set_state_t flag) 2351 { 2352 mutex_enter(&srs->srs_lock); 2353 srs->srs_state &= ~flag; 2354 mutex_exit(&srs->srs_lock); 2355 } 2356 2357 void 2358 mac_rx_srs_restart(mac_soft_ring_set_t *srs) 2359 { 2360 flow_entry_t *flent = srs->srs_flent; 2361 mac_ring_t *mr; 2362 2363 ASSERT(MAC_PERIM_HELD((mac_handle_t)FLENT_TO_MIP(flent))); 2364 ASSERT((srs->srs_type & SRST_TX) == 0); 2365 2366 /* 2367 * This handles a change in the number of SRSs between the quiesce and 2368 * and restart operation of a flow. 2369 */ 2370 if (!SRS_QUIESCED(srs)) 2371 return; 2372 2373 /* 2374 * Signal the SRS to restart itself. Wait for the restart to complete 2375 * Note that we only restart the SRS if it is not marked as 2376 * permanently quiesced. 2377 */ 2378 if (!SRS_QUIESCED_PERMANENT(srs)) { 2379 mac_srs_signal(srs, SRS_RESTART); 2380 mac_srs_quiesce_wait(srs, SRS_RESTART_DONE); 2381 mac_srs_clear_flag(srs, SRS_RESTART_DONE); 2382 2383 mac_srs_client_poll_restart(srs->srs_mcip, srs); 2384 } 2385 2386 /* Finally clear the flags to let the packets in */ 2387 mr = srs->srs_ring; 2388 if (mr != NULL) { 2389 MAC_RING_UNMARK(mr, MR_QUIESCE); 2390 /* In case the ring was stopped, safely restart it */ 2391 if (mr->mr_state != MR_INUSE) 2392 (void) mac_start_ring(mr); 2393 } else { 2394 FLOW_UNMARK(flent, FE_QUIESCE); 2395 } 2396 } 2397 2398 /* 2399 * Temporary quiesce of a flow and associated Rx SRS. 2400 * Please see block comment above mac_rx_classify_flow_rem. 2401 */ 2402 /* ARGSUSED */ 2403 int 2404 mac_rx_classify_flow_quiesce(flow_entry_t *flent, void *arg) 2405 { 2406 int i; 2407 2408 for (i = 0; i < flent->fe_rx_srs_cnt; i++) { 2409 mac_rx_srs_quiesce((mac_soft_ring_set_t *)flent->fe_rx_srs[i], 2410 SRS_QUIESCE); 2411 } 2412 return (0); 2413 } 2414 2415 /* 2416 * Restart a flow and associated Rx SRS that has been quiesced temporarily 2417 * Please see block comment above mac_rx_classify_flow_rem 2418 */ 2419 /* ARGSUSED */ 2420 int 2421 mac_rx_classify_flow_restart(flow_entry_t *flent, void *arg) 2422 { 2423 int i; 2424 2425 for (i = 0; i < flent->fe_rx_srs_cnt; i++) 2426 mac_rx_srs_restart((mac_soft_ring_set_t *)flent->fe_rx_srs[i]); 2427 2428 return (0); 2429 } 2430 2431 void 2432 mac_srs_perm_quiesce(mac_client_handle_t mch, boolean_t on) 2433 { 2434 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 2435 flow_entry_t *flent = mcip->mci_flent; 2436 mac_impl_t *mip = mcip->mci_mip; 2437 mac_soft_ring_set_t *mac_srs; 2438 int i; 2439 2440 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 2441 2442 if (flent == NULL) 2443 return; 2444 2445 for (i = 0; i < flent->fe_rx_srs_cnt; i++) { 2446 mac_srs = flent->fe_rx_srs[i]; 2447 mutex_enter(&mac_srs->srs_lock); 2448 if (on) 2449 mac_srs->srs_state |= SRS_QUIESCE_PERM; 2450 else 2451 mac_srs->srs_state &= ~SRS_QUIESCE_PERM; 2452 mutex_exit(&mac_srs->srs_lock); 2453 } 2454 } 2455 2456 void 2457 mac_rx_client_quiesce(mac_client_handle_t mch) 2458 { 2459 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 2460 mac_impl_t *mip = mcip->mci_mip; 2461 2462 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 2463 2464 if (MCIP_DATAPATH_SETUP(mcip)) { 2465 (void) mac_rx_classify_flow_quiesce(mcip->mci_flent, 2466 NULL); 2467 (void) mac_flow_walk_nolock(mcip->mci_subflow_tab, 2468 mac_rx_classify_flow_quiesce, NULL); 2469 } 2470 } 2471 2472 void 2473 mac_rx_client_restart(mac_client_handle_t mch) 2474 { 2475 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 2476 mac_impl_t *mip = mcip->mci_mip; 2477 2478 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 2479 2480 if (MCIP_DATAPATH_SETUP(mcip)) { 2481 (void) mac_rx_classify_flow_restart(mcip->mci_flent, NULL); 2482 (void) mac_flow_walk_nolock(mcip->mci_subflow_tab, 2483 mac_rx_classify_flow_restart, NULL); 2484 } 2485 } 2486 2487 /* 2488 * This function only quiesces the Tx SRS and softring worker threads. Callers 2489 * need to make sure that there aren't any mac client threads doing current or 2490 * future transmits in the mac before calling this function. 2491 */ 2492 void 2493 mac_tx_srs_quiesce(mac_soft_ring_set_t *srs, 2494 const mac_soft_ring_set_state_t srs_quiesce_flag) 2495 { 2496 mac_client_impl_t *mcip = srs->srs_mcip; 2497 2498 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 2499 2500 ASSERT(srs->srs_type & SRST_TX); 2501 ASSERT(srs_quiesce_flag == SRS_CONDEMNED || 2502 srs_quiesce_flag == SRS_QUIESCE); 2503 2504 /* 2505 * Signal the SRS to quiesce itself, and then cv_wait for the 2506 * SRS quiesce to complete. The SRS worker thread will wake us 2507 * up when the quiesce is complete 2508 */ 2509 mac_srs_signal(srs, srs_quiesce_flag); 2510 mac_srs_quiesce_wait(srs, srs_quiesce_flag == SRS_QUIESCE ? 2511 SRS_QUIESCE_DONE : SRS_CONDEMNED_DONE); 2512 } 2513 2514 void 2515 mac_tx_srs_restart(mac_soft_ring_set_t *srs) 2516 { 2517 /* 2518 * Resizing the fanout could result in creation of new SRSs. 2519 * They may not necessarily be in the quiesced state in which 2520 * case it need be restarted 2521 */ 2522 if (!SRS_QUIESCED(srs)) 2523 return; 2524 2525 mac_srs_signal(srs, SRS_RESTART); 2526 mac_srs_quiesce_wait(srs, SRS_RESTART_DONE); 2527 mac_srs_clear_flag(srs, SRS_RESTART_DONE); 2528 } 2529 2530 /* 2531 * Temporary quiesce of a flow and associated Rx SRS. 2532 * Please see block comment above mac_rx_srs_quiesce 2533 */ 2534 /* ARGSUSED */ 2535 int 2536 mac_tx_flow_quiesce(flow_entry_t *flent, void *arg) 2537 { 2538 /* 2539 * The fe_tx_srs is null for a subflow on an interface that is 2540 * not plumbed 2541 */ 2542 if (flent->fe_tx_srs != NULL) 2543 mac_tx_srs_quiesce(flent->fe_tx_srs, SRS_QUIESCE); 2544 return (0); 2545 } 2546 2547 /* ARGSUSED */ 2548 int 2549 mac_tx_flow_restart(flow_entry_t *flent, void *arg) 2550 { 2551 /* 2552 * The fe_tx_srs is null for a subflow on an interface that is 2553 * not plumbed 2554 */ 2555 if (flent->fe_tx_srs != NULL) 2556 mac_tx_srs_restart(flent->fe_tx_srs); 2557 return (0); 2558 } 2559 2560 static void 2561 i_mac_tx_client_quiesce(mac_client_handle_t mch, 2562 const mac_soft_ring_set_state_t srs_quiesce_flag) 2563 { 2564 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 2565 2566 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 2567 2568 mac_tx_client_block(mcip); 2569 if (MCIP_TX_SRS(mcip) != NULL) { 2570 mac_tx_srs_quiesce(MCIP_TX_SRS(mcip), srs_quiesce_flag); 2571 (void) mac_flow_walk_nolock(mcip->mci_subflow_tab, 2572 mac_tx_flow_quiesce, NULL); 2573 } 2574 } 2575 2576 void 2577 mac_tx_client_quiesce(mac_client_handle_t mch) 2578 { 2579 i_mac_tx_client_quiesce(mch, SRS_QUIESCE); 2580 } 2581 2582 void 2583 mac_tx_client_condemn(mac_client_handle_t mch) 2584 { 2585 i_mac_tx_client_quiesce(mch, SRS_CONDEMNED); 2586 } 2587 2588 void 2589 mac_tx_client_restart(mac_client_handle_t mch) 2590 { 2591 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 2592 2593 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 2594 2595 mac_tx_client_unblock(mcip); 2596 if (MCIP_TX_SRS(mcip) != NULL) { 2597 mac_tx_srs_restart(MCIP_TX_SRS(mcip)); 2598 (void) mac_flow_walk_nolock(mcip->mci_subflow_tab, 2599 mac_tx_flow_restart, NULL); 2600 } 2601 } 2602 2603 void 2604 mac_tx_client_flush(mac_client_impl_t *mcip) 2605 { 2606 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 2607 2608 mac_tx_client_quiesce((mac_client_handle_t)mcip); 2609 mac_tx_client_restart((mac_client_handle_t)mcip); 2610 } 2611 2612 void 2613 mac_client_quiesce(mac_client_impl_t *mcip) 2614 { 2615 mac_rx_client_quiesce((mac_client_handle_t)mcip); 2616 mac_tx_client_quiesce((mac_client_handle_t)mcip); 2617 } 2618 2619 void 2620 mac_client_restart(mac_client_impl_t *mcip) 2621 { 2622 mac_rx_client_restart((mac_client_handle_t)mcip); 2623 mac_tx_client_restart((mac_client_handle_t)mcip); 2624 } 2625 2626 /* 2627 * Allocate a minor number. 2628 */ 2629 minor_t 2630 mac_minor_hold(boolean_t sleep) 2631 { 2632 id_t id; 2633 2634 /* 2635 * Grab a value from the arena. 2636 */ 2637 atomic_inc_32(&minor_count); 2638 2639 if (sleep) 2640 return ((uint_t)id_alloc(minor_ids)); 2641 2642 if ((id = id_alloc_nosleep(minor_ids)) == -1) { 2643 atomic_dec_32(&minor_count); 2644 return (0); 2645 } 2646 2647 return ((uint_t)id); 2648 } 2649 2650 /* 2651 * Release a previously allocated minor number. 2652 */ 2653 void 2654 mac_minor_rele(minor_t minor) 2655 { 2656 /* 2657 * Return the value to the arena. 2658 */ 2659 id_free(minor_ids, minor); 2660 atomic_dec_32(&minor_count); 2661 } 2662 2663 uint32_t 2664 mac_no_notification(mac_handle_t mh) 2665 { 2666 mac_impl_t *mip = (mac_impl_t *)mh; 2667 2668 return (((mip->mi_state_flags & MIS_LEGACY) != 0) ? 2669 mip->mi_capab_legacy.ml_unsup_note : 0); 2670 } 2671 2672 /* 2673 * Prevent any new opens of this mac in preparation for unregister 2674 */ 2675 int 2676 i_mac_disable(mac_impl_t *mip) 2677 { 2678 mac_client_impl_t *mcip; 2679 2680 rw_enter(&i_mac_impl_lock, RW_WRITER); 2681 if (mip->mi_state_flags & MIS_DISABLED) { 2682 /* Already disabled, return success */ 2683 rw_exit(&i_mac_impl_lock); 2684 return (0); 2685 } 2686 /* 2687 * See if there are any other references to this mac_t (e.g., VLAN's). 2688 * If so return failure. If all the other checks below pass, then 2689 * set mi_disabled atomically under the i_mac_impl_lock to prevent 2690 * any new VLAN's from being created or new mac client opens of this 2691 * mac end point. 2692 */ 2693 if (mip->mi_ref > 0) { 2694 rw_exit(&i_mac_impl_lock); 2695 return (EBUSY); 2696 } 2697 2698 /* 2699 * mac clients must delete all multicast groups they join before 2700 * closing. bcast groups are reference counted, the last client 2701 * to delete the group will wait till the group is physically 2702 * deleted. Since all clients have closed this mac end point 2703 * mi_bcast_ngrps must be zero at this point 2704 */ 2705 ASSERT(mip->mi_bcast_ngrps == 0); 2706 2707 /* 2708 * Don't let go of this if it has some flows. 2709 * All other code guarantees no flows are added to a disabled 2710 * mac, therefore it is sufficient to check for the flow table 2711 * only here. 2712 */ 2713 mcip = mac_primary_client_handle(mip); 2714 if ((mcip != NULL) && mac_link_has_flows((mac_client_handle_t)mcip)) { 2715 rw_exit(&i_mac_impl_lock); 2716 return (ENOTEMPTY); 2717 } 2718 2719 mip->mi_state_flags |= MIS_DISABLED; 2720 rw_exit(&i_mac_impl_lock); 2721 return (0); 2722 } 2723 2724 int 2725 mac_disable_nowait(mac_handle_t mh) 2726 { 2727 mac_impl_t *mip = (mac_impl_t *)mh; 2728 int err; 2729 2730 if ((err = i_mac_perim_enter_nowait(mip)) != 0) 2731 return (err); 2732 err = i_mac_disable(mip); 2733 i_mac_perim_exit(mip); 2734 return (err); 2735 } 2736 2737 int 2738 mac_disable(mac_handle_t mh) 2739 { 2740 mac_impl_t *mip = (mac_impl_t *)mh; 2741 int err; 2742 2743 i_mac_perim_enter(mip); 2744 err = i_mac_disable(mip); 2745 i_mac_perim_exit(mip); 2746 2747 /* 2748 * Clean up notification thread and wait for it to exit. 2749 */ 2750 if (err == 0) 2751 i_mac_notify_exit(mip); 2752 2753 return (err); 2754 } 2755 2756 /* 2757 * Called when the MAC instance has a non empty flow table, to de-multiplex 2758 * incoming packets to the right flow. 2759 */ 2760 /* ARGSUSED */ 2761 static flow_entry_t * 2762 mac_rx_classify(mac_impl_t *mip, mac_resource_handle_t mrh, mblk_t *mp) 2763 { 2764 flow_entry_t *flent = NULL; 2765 uint_t flags = FLOW_INBOUND; 2766 int err; 2767 2768 err = mac_flow_lookup(mip->mi_flow_tab, mp, flags, &flent); 2769 if (err == 0) { 2770 mac_client_impl_t *mcip; 2771 2772 /* 2773 * This flent might just be an additional one on the MAC client, 2774 * i.e. for classification purposes (different fdesc), however 2775 * the resources, SRS et. al., are in the mci_flent, so if 2776 * this isn't the mci_flent, we need to get it. 2777 */ 2778 if ((mcip = flent->fe_mcip) != NULL && 2779 mcip->mci_flent != flent) { 2780 FLOW_REFRELE(flent); 2781 flent = mcip->mci_flent; 2782 FLOW_TRY_REFHOLD(flent, err); 2783 if (err != 0) 2784 return (NULL); 2785 } 2786 } 2787 2788 /* flent will be NULL if mac_flow_lookup fails to find a match. */ 2789 return (flent); 2790 } 2791 2792 mblk_t * 2793 mac_rx_flow(mac_handle_t mh, mac_resource_handle_t mrh, mblk_t *mp_chain) 2794 { 2795 mac_impl_t *mip = (mac_impl_t *)mh; 2796 mblk_t *mp_next, *tail, **unclass_nextp; 2797 mblk_t *unclass_list = NULL; 2798 flow_entry_t *prev_flent = NULL; 2799 2800 /* 2801 * We walk the chain and attempt to classify each packet. 2802 * The packets that couldn't be classified will be returned 2803 * back to the caller. 2804 * 2805 * We want to batch together runs of matched packets bound 2806 * for the same flent into the same callback. Unmatched 2807 * packets should not break an ongoing chain. 2808 */ 2809 mp_next = tail = mp_chain; 2810 unclass_nextp = &unclass_list; 2811 while (mp_next != NULL) { 2812 flow_entry_t *flent; 2813 mblk_t *mp = mp_next; 2814 mp_next = mp_next->b_next; 2815 mp->b_next = NULL; 2816 2817 flent = mac_rx_classify(mip, mrh, mp); 2818 if (flent == NULL) { 2819 /* 2820 * Add the current mblk_t to the end of the 2821 * unclassified packet chain at 'unclass_list'. 2822 * Move the current head forward if we have not 2823 * yet made any match. 2824 */ 2825 if (prev_flent == NULL) { 2826 mp_chain = mp_next; 2827 tail = mp_next; 2828 } 2829 *unclass_nextp = mp; 2830 unclass_nextp = &mp->b_next; 2831 continue; 2832 } 2833 2834 if (prev_flent == NULL || flent == prev_flent) { 2835 /* Either the first valid match, or in the same chain */ 2836 if (prev_flent != NULL) 2837 FLOW_REFRELE(prev_flent); 2838 if (mp != tail) 2839 tail->b_next = mp; 2840 } else { 2841 ASSERT3P(prev_flent, !=, NULL); 2842 (prev_flent->fe_cb_fn)(prev_flent->fe_cb_arg1, 2843 prev_flent->fe_cb_arg2, mp_chain, B_FALSE); 2844 FLOW_REFRELE(prev_flent); 2845 mp_chain = mp; 2846 } 2847 2848 prev_flent = flent; 2849 tail = mp; 2850 } 2851 /* Last chain */ 2852 if (mp_chain != NULL) { 2853 ASSERT3P(prev_flent, !=, NULL); 2854 (prev_flent->fe_cb_fn)(prev_flent->fe_cb_arg1, 2855 prev_flent->fe_cb_arg2, mp_chain, B_FALSE); 2856 FLOW_REFRELE(prev_flent); 2857 } 2858 return (unclass_list); 2859 } 2860 2861 static int 2862 mac_tx_flow_srs_wakeup(flow_entry_t *flent, void *arg) 2863 { 2864 mac_ring_handle_t ring = arg; 2865 2866 if (flent->fe_tx_srs) 2867 mac_tx_srs_wakeup(flent->fe_tx_srs, ring); 2868 return (0); 2869 } 2870 2871 void 2872 i_mac_tx_srs_notify(mac_impl_t *mip, mac_ring_handle_t ring) 2873 { 2874 mac_client_impl_t *cclient; 2875 mac_soft_ring_set_t *mac_srs; 2876 2877 /* 2878 * After grabbing the mi_rw_lock, the list of clients can't change. 2879 * If there are any clients mi_disabled must be B_FALSE and can't 2880 * get set since there are clients. If there aren't any clients we 2881 * don't do anything. In any case the mip has to be valid. The driver 2882 * must make sure that it goes single threaded (with respect to mac 2883 * calls) and wait for all pending mac calls to finish before calling 2884 * mac_unregister. 2885 */ 2886 rw_enter(&i_mac_impl_lock, RW_READER); 2887 if (mip->mi_state_flags & MIS_DISABLED) { 2888 rw_exit(&i_mac_impl_lock); 2889 return; 2890 } 2891 2892 /* 2893 * Get MAC tx srs from walking mac_client_handle list. 2894 */ 2895 rw_enter(&mip->mi_rw_lock, RW_READER); 2896 for (cclient = mip->mi_clients_list; cclient != NULL; 2897 cclient = cclient->mci_client_next) { 2898 if ((mac_srs = MCIP_TX_SRS(cclient)) != NULL) { 2899 mac_tx_srs_wakeup(mac_srs, ring); 2900 } else { 2901 /* 2902 * Aggr opens underlying ports in exclusive mode 2903 * and registers flow control callbacks using 2904 * mac_tx_client_notify(). When opened in 2905 * exclusive mode, Tx SRS won't be created 2906 * during mac_unicast_add(). 2907 */ 2908 if (cclient->mci_state_flags & MCIS_EXCLUSIVE) { 2909 mac_tx_invoke_callbacks(cclient, 2910 (mac_tx_cookie_t)ring); 2911 } 2912 } 2913 (void) mac_flow_walk(cclient->mci_subflow_tab, 2914 mac_tx_flow_srs_wakeup, ring); 2915 } 2916 rw_exit(&mip->mi_rw_lock); 2917 rw_exit(&i_mac_impl_lock); 2918 } 2919 2920 /* ARGSUSED */ 2921 void 2922 mac_multicast_refresh(mac_handle_t mh, mac_multicst_t refresh, void *arg, 2923 boolean_t add) 2924 { 2925 mac_impl_t *mip = (mac_impl_t *)mh; 2926 2927 i_mac_perim_enter((mac_impl_t *)mh); 2928 /* 2929 * If no specific refresh function was given then default to the 2930 * driver's m_multicst entry point. 2931 */ 2932 if (refresh == NULL) { 2933 refresh = mip->mi_multicst; 2934 arg = mip->mi_driver; 2935 } 2936 2937 mac_bcast_refresh(mip, refresh, arg, add); 2938 i_mac_perim_exit((mac_impl_t *)mh); 2939 } 2940 2941 void 2942 mac_promisc_refresh(mac_handle_t mh, mac_setpromisc_t refresh, void *arg) 2943 { 2944 mac_impl_t *mip = (mac_impl_t *)mh; 2945 2946 /* 2947 * If no specific refresh function was given then default to the 2948 * driver's m_promisc entry point. 2949 */ 2950 if (refresh == NULL) { 2951 refresh = mip->mi_setpromisc; 2952 arg = mip->mi_driver; 2953 } 2954 ASSERT(refresh != NULL); 2955 2956 /* 2957 * Call the refresh function with the current promiscuity. 2958 */ 2959 refresh(arg, (mip->mi_devpromisc != 0)); 2960 } 2961 2962 /* 2963 * The mac client requests that the mac not to change its margin size to 2964 * be less than the specified value. If "current" is B_TRUE, then the client 2965 * requests the mac not to change its margin size to be smaller than the 2966 * current size. Further, return the current margin size value in this case. 2967 * 2968 * We keep every requested size in an ordered list from largest to smallest. 2969 */ 2970 int 2971 mac_margin_add(mac_handle_t mh, uint32_t *marginp, boolean_t current) 2972 { 2973 mac_impl_t *mip = (mac_impl_t *)mh; 2974 mac_margin_req_t **pp, *p; 2975 int err = 0; 2976 2977 rw_enter(&(mip->mi_rw_lock), RW_WRITER); 2978 if (current) 2979 *marginp = mip->mi_margin; 2980 2981 /* 2982 * If the current margin value cannot satisfy the margin requested, 2983 * return ENOTSUP directly. 2984 */ 2985 if (*marginp > mip->mi_margin) { 2986 err = ENOTSUP; 2987 goto done; 2988 } 2989 2990 /* 2991 * Check whether the given margin is already in the list. If so, 2992 * bump the reference count. 2993 */ 2994 for (pp = &mip->mi_mmrp; (p = *pp) != NULL; pp = &p->mmr_nextp) { 2995 if (p->mmr_margin == *marginp) { 2996 /* 2997 * The margin requested is already in the list, 2998 * so just bump the reference count. 2999 */ 3000 p->mmr_ref++; 3001 goto done; 3002 } 3003 if (p->mmr_margin < *marginp) 3004 break; 3005 } 3006 3007 3008 p = kmem_zalloc(sizeof (mac_margin_req_t), KM_SLEEP); 3009 p->mmr_margin = *marginp; 3010 p->mmr_ref++; 3011 p->mmr_nextp = *pp; 3012 *pp = p; 3013 3014 done: 3015 rw_exit(&(mip->mi_rw_lock)); 3016 return (err); 3017 } 3018 3019 /* 3020 * The mac client requests to cancel its previous mac_margin_add() request. 3021 * We remove the requested margin size from the list. 3022 */ 3023 int 3024 mac_margin_remove(mac_handle_t mh, uint32_t margin) 3025 { 3026 mac_impl_t *mip = (mac_impl_t *)mh; 3027 mac_margin_req_t **pp, *p; 3028 int err = 0; 3029 3030 rw_enter(&(mip->mi_rw_lock), RW_WRITER); 3031 /* 3032 * Find the entry in the list for the given margin. 3033 */ 3034 for (pp = &(mip->mi_mmrp); (p = *pp) != NULL; pp = &(p->mmr_nextp)) { 3035 if (p->mmr_margin == margin) { 3036 if (--p->mmr_ref == 0) 3037 break; 3038 3039 /* 3040 * There is still a reference to this address so 3041 * there's nothing more to do. 3042 */ 3043 goto done; 3044 } 3045 } 3046 3047 /* 3048 * We did not find an entry for the given margin. 3049 */ 3050 if (p == NULL) { 3051 err = ENOENT; 3052 goto done; 3053 } 3054 3055 ASSERT(p->mmr_ref == 0); 3056 3057 /* 3058 * Remove it from the list. 3059 */ 3060 *pp = p->mmr_nextp; 3061 kmem_free(p, sizeof (mac_margin_req_t)); 3062 done: 3063 rw_exit(&(mip->mi_rw_lock)); 3064 return (err); 3065 } 3066 3067 boolean_t 3068 mac_margin_update(mac_handle_t mh, uint32_t margin) 3069 { 3070 mac_impl_t *mip = (mac_impl_t *)mh; 3071 uint32_t margin_needed = 0; 3072 3073 rw_enter(&(mip->mi_rw_lock), RW_WRITER); 3074 3075 if (mip->mi_mmrp != NULL) 3076 margin_needed = mip->mi_mmrp->mmr_margin; 3077 3078 if (margin_needed <= margin) 3079 mip->mi_margin = margin; 3080 3081 rw_exit(&(mip->mi_rw_lock)); 3082 3083 if (margin_needed <= margin) 3084 i_mac_notify(mip, MAC_NOTE_MARGIN); 3085 3086 return (margin_needed <= margin); 3087 } 3088 3089 /* 3090 * MAC clients use this interface to request that a MAC device not change its 3091 * MTU below the specified amount. At this time, that amount must be within the 3092 * range of the device's current minimum and the device's current maximum. eg. a 3093 * client cannot request a 3000 byte MTU when the device's MTU is currently 3094 * 2000. 3095 * 3096 * If "current" is set to B_TRUE, then the request is to simply to reserve the 3097 * current underlying mac's maximum for this mac client and return it in mtup. 3098 */ 3099 int 3100 mac_mtu_add(mac_handle_t mh, uint32_t *mtup, boolean_t current) 3101 { 3102 mac_impl_t *mip = (mac_impl_t *)mh; 3103 mac_mtu_req_t *prev, *cur; 3104 mac_propval_range_t mpr; 3105 int err; 3106 3107 i_mac_perim_enter(mip); 3108 rw_enter(&mip->mi_rw_lock, RW_WRITER); 3109 3110 if (current == B_TRUE) 3111 *mtup = mip->mi_sdu_max; 3112 mpr.mpr_count = 1; 3113 err = mac_prop_info(mh, MAC_PROP_MTU, "mtu", NULL, 0, &mpr, NULL); 3114 if (err != 0) { 3115 rw_exit(&mip->mi_rw_lock); 3116 i_mac_perim_exit(mip); 3117 return (err); 3118 } 3119 3120 if (*mtup > mip->mi_sdu_max || 3121 *mtup < mpr.mpr_range_uint32[0].mpur_min) { 3122 rw_exit(&mip->mi_rw_lock); 3123 i_mac_perim_exit(mip); 3124 return (ENOTSUP); 3125 } 3126 3127 prev = NULL; 3128 for (cur = mip->mi_mtrp; cur != NULL; cur = cur->mtr_nextp) { 3129 if (*mtup == cur->mtr_mtu) { 3130 cur->mtr_ref++; 3131 rw_exit(&mip->mi_rw_lock); 3132 i_mac_perim_exit(mip); 3133 return (0); 3134 } 3135 3136 if (*mtup > cur->mtr_mtu) 3137 break; 3138 3139 prev = cur; 3140 } 3141 3142 cur = kmem_alloc(sizeof (mac_mtu_req_t), KM_SLEEP); 3143 cur->mtr_mtu = *mtup; 3144 cur->mtr_ref = 1; 3145 if (prev != NULL) { 3146 cur->mtr_nextp = prev->mtr_nextp; 3147 prev->mtr_nextp = cur; 3148 } else { 3149 cur->mtr_nextp = mip->mi_mtrp; 3150 mip->mi_mtrp = cur; 3151 } 3152 3153 rw_exit(&mip->mi_rw_lock); 3154 i_mac_perim_exit(mip); 3155 return (0); 3156 } 3157 3158 int 3159 mac_mtu_remove(mac_handle_t mh, uint32_t mtu) 3160 { 3161 mac_impl_t *mip = (mac_impl_t *)mh; 3162 mac_mtu_req_t *cur, *prev; 3163 3164 i_mac_perim_enter(mip); 3165 rw_enter(&mip->mi_rw_lock, RW_WRITER); 3166 3167 prev = NULL; 3168 for (cur = mip->mi_mtrp; cur != NULL; cur = cur->mtr_nextp) { 3169 if (cur->mtr_mtu == mtu) { 3170 ASSERT(cur->mtr_ref > 0); 3171 cur->mtr_ref--; 3172 if (cur->mtr_ref == 0) { 3173 if (prev == NULL) { 3174 mip->mi_mtrp = cur->mtr_nextp; 3175 } else { 3176 prev->mtr_nextp = cur->mtr_nextp; 3177 } 3178 kmem_free(cur, sizeof (mac_mtu_req_t)); 3179 } 3180 rw_exit(&mip->mi_rw_lock); 3181 i_mac_perim_exit(mip); 3182 return (0); 3183 } 3184 3185 prev = cur; 3186 } 3187 3188 rw_exit(&mip->mi_rw_lock); 3189 i_mac_perim_exit(mip); 3190 return (ENOENT); 3191 } 3192 3193 /* 3194 * MAC Type Plugin functions. 3195 */ 3196 3197 mactype_t * 3198 mactype_getplugin(const char *pname) 3199 { 3200 mactype_t *mtype = NULL; 3201 boolean_t tried_modload = B_FALSE; 3202 3203 mutex_enter(&i_mactype_lock); 3204 3205 find_registered_mactype: 3206 if (mod_hash_find(i_mactype_hash, (mod_hash_key_t)pname, 3207 (mod_hash_val_t *)&mtype) != 0) { 3208 if (!tried_modload) { 3209 /* 3210 * If the plugin has not yet been loaded, then 3211 * attempt to load it now. If modload() succeeds, 3212 * the plugin should have registered using 3213 * mactype_register(), in which case we can go back 3214 * and attempt to find it again. 3215 */ 3216 if (modload(MACTYPE_KMODDIR, (char *)pname) != -1) { 3217 tried_modload = B_TRUE; 3218 goto find_registered_mactype; 3219 } 3220 } 3221 } else { 3222 /* 3223 * Note that there's no danger that the plugin we've loaded 3224 * could be unloaded between the modload() step and the 3225 * reference count bump here, as we're holding 3226 * i_mactype_lock, which mactype_unregister() also holds. 3227 */ 3228 atomic_inc_32(&mtype->mt_ref); 3229 } 3230 3231 mutex_exit(&i_mactype_lock); 3232 return (mtype); 3233 } 3234 3235 mactype_register_t * 3236 mactype_alloc(uint_t mactype_version) 3237 { 3238 mactype_register_t *mtrp; 3239 3240 /* 3241 * Make sure there isn't a version mismatch between the plugin and 3242 * the framework. In the future, if multiple versions are 3243 * supported, this check could become more sophisticated. 3244 */ 3245 if (mactype_version != MACTYPE_VERSION) 3246 return (NULL); 3247 3248 mtrp = kmem_zalloc(sizeof (mactype_register_t), KM_SLEEP); 3249 mtrp->mtr_version = mactype_version; 3250 return (mtrp); 3251 } 3252 3253 void 3254 mactype_free(mactype_register_t *mtrp) 3255 { 3256 kmem_free(mtrp, sizeof (mactype_register_t)); 3257 } 3258 3259 int 3260 mactype_register(mactype_register_t *mtrp) 3261 { 3262 mactype_t *mtp; 3263 mactype_ops_t *ops = mtrp->mtr_ops; 3264 3265 /* Do some sanity checking before we register this MAC type. */ 3266 if (mtrp->mtr_ident == NULL || ops == NULL) 3267 return (EINVAL); 3268 3269 /* 3270 * Verify that all mandatory callbacks are set in the ops 3271 * vector. 3272 */ 3273 if (ops->mtops_unicst_verify == NULL || 3274 ops->mtops_multicst_verify == NULL || 3275 ops->mtops_sap_verify == NULL || 3276 ops->mtops_header == NULL || 3277 ops->mtops_header_info == NULL) { 3278 return (EINVAL); 3279 } 3280 3281 mtp = kmem_zalloc(sizeof (*mtp), KM_SLEEP); 3282 mtp->mt_ident = mtrp->mtr_ident; 3283 mtp->mt_ops = *ops; 3284 mtp->mt_type = mtrp->mtr_mactype; 3285 mtp->mt_nativetype = mtrp->mtr_nativetype; 3286 mtp->mt_addr_length = mtrp->mtr_addrlen; 3287 if (mtrp->mtr_brdcst_addr != NULL) { 3288 mtp->mt_brdcst_addr = kmem_alloc(mtrp->mtr_addrlen, KM_SLEEP); 3289 bcopy(mtrp->mtr_brdcst_addr, mtp->mt_brdcst_addr, 3290 mtrp->mtr_addrlen); 3291 } 3292 3293 mtp->mt_stats = mtrp->mtr_stats; 3294 mtp->mt_statcount = mtrp->mtr_statcount; 3295 3296 mtp->mt_mapping = mtrp->mtr_mapping; 3297 mtp->mt_mappingcount = mtrp->mtr_mappingcount; 3298 3299 if (mod_hash_insert(i_mactype_hash, 3300 (mod_hash_key_t)mtp->mt_ident, (mod_hash_val_t)mtp) != 0) { 3301 kmem_free(mtp->mt_brdcst_addr, mtp->mt_addr_length); 3302 kmem_free(mtp, sizeof (*mtp)); 3303 return (EEXIST); 3304 } 3305 return (0); 3306 } 3307 3308 int 3309 mactype_unregister(const char *ident) 3310 { 3311 mactype_t *mtp; 3312 mod_hash_val_t val; 3313 int err; 3314 3315 /* 3316 * Let's not allow MAC drivers to use this plugin while we're 3317 * trying to unregister it. Holding i_mactype_lock also prevents a 3318 * plugin from unregistering while a MAC driver is attempting to 3319 * hold a reference to it in i_mactype_getplugin(). 3320 */ 3321 mutex_enter(&i_mactype_lock); 3322 3323 if ((err = mod_hash_find(i_mactype_hash, (mod_hash_key_t)ident, 3324 (mod_hash_val_t *)&mtp)) != 0) { 3325 /* A plugin is trying to unregister, but it never registered. */ 3326 err = ENXIO; 3327 goto done; 3328 } 3329 3330 if (mtp->mt_ref != 0) { 3331 err = EBUSY; 3332 goto done; 3333 } 3334 3335 err = mod_hash_remove(i_mactype_hash, (mod_hash_key_t)ident, &val); 3336 ASSERT(err == 0); 3337 if (err != 0) { 3338 /* This should never happen, thus the ASSERT() above. */ 3339 err = EINVAL; 3340 goto done; 3341 } 3342 ASSERT(mtp == (mactype_t *)val); 3343 3344 if (mtp->mt_brdcst_addr != NULL) 3345 kmem_free(mtp->mt_brdcst_addr, mtp->mt_addr_length); 3346 kmem_free(mtp, sizeof (mactype_t)); 3347 done: 3348 mutex_exit(&i_mactype_lock); 3349 return (err); 3350 } 3351 3352 /* 3353 * Checks the size of the value size specified for a property as 3354 * part of a property operation. Returns B_TRUE if the size is 3355 * correct, B_FALSE otherwise. 3356 */ 3357 boolean_t 3358 mac_prop_check_size(mac_prop_id_t id, uint_t valsize, boolean_t is_range) 3359 { 3360 uint_t minsize = 0; 3361 3362 if (is_range) 3363 return (valsize >= sizeof (mac_propval_range_t)); 3364 3365 switch (id) { 3366 case MAC_PROP_ZONE: 3367 minsize = sizeof (dld_ioc_zid_t); 3368 break; 3369 case MAC_PROP_AUTOPUSH: 3370 if (valsize != 0) 3371 minsize = sizeof (struct dlautopush); 3372 break; 3373 case MAC_PROP_TAGMODE: 3374 minsize = sizeof (link_tagmode_t); 3375 break; 3376 case MAC_PROP_RESOURCE: 3377 case MAC_PROP_RESOURCE_EFF: 3378 minsize = sizeof (mac_resource_props_t); 3379 break; 3380 case MAC_PROP_DUPLEX: 3381 minsize = sizeof (link_duplex_t); 3382 break; 3383 case MAC_PROP_SPEED: 3384 minsize = sizeof (uint64_t); 3385 break; 3386 case MAC_PROP_STATUS: 3387 minsize = sizeof (link_state_t); 3388 break; 3389 case MAC_PROP_AUTONEG: 3390 case MAC_PROP_EN_AUTONEG: 3391 minsize = sizeof (uint8_t); 3392 break; 3393 case MAC_PROP_MTU: 3394 case MAC_PROP_LLIMIT: 3395 case MAC_PROP_LDECAY: 3396 minsize = sizeof (uint32_t); 3397 break; 3398 case MAC_PROP_FLOWCTRL: 3399 minsize = sizeof (link_flowctrl_t); 3400 break; 3401 case MAC_PROP_ADV_FEC_CAP: 3402 case MAC_PROP_EN_FEC_CAP: 3403 minsize = sizeof (link_fec_t); 3404 break; 3405 case MAC_PROP_ADV_400GFDX_CAP: 3406 case MAC_PROP_EN_400GFDX_CAP: 3407 case MAC_PROP_ADV_200GFDX_CAP: 3408 case MAC_PROP_EN_200GFDX_CAP: 3409 case MAC_PROP_ADV_100GFDX_CAP: 3410 case MAC_PROP_EN_100GFDX_CAP: 3411 case MAC_PROP_ADV_50GFDX_CAP: 3412 case MAC_PROP_EN_50GFDX_CAP: 3413 case MAC_PROP_ADV_40GFDX_CAP: 3414 case MAC_PROP_EN_40GFDX_CAP: 3415 case MAC_PROP_ADV_25GFDX_CAP: 3416 case MAC_PROP_EN_25GFDX_CAP: 3417 case MAC_PROP_ADV_10GFDX_CAP: 3418 case MAC_PROP_EN_10GFDX_CAP: 3419 case MAC_PROP_ADV_5000FDX_CAP: 3420 case MAC_PROP_EN_5000FDX_CAP: 3421 case MAC_PROP_ADV_2500FDX_CAP: 3422 case MAC_PROP_EN_2500FDX_CAP: 3423 case MAC_PROP_ADV_1000HDX_CAP: 3424 case MAC_PROP_EN_1000HDX_CAP: 3425 case MAC_PROP_ADV_100FDX_CAP: 3426 case MAC_PROP_EN_100FDX_CAP: 3427 case MAC_PROP_ADV_100T4_CAP: 3428 case MAC_PROP_EN_100T4_CAP: 3429 case MAC_PROP_ADV_100HDX_CAP: 3430 case MAC_PROP_EN_100HDX_CAP: 3431 case MAC_PROP_ADV_10FDX_CAP: 3432 case MAC_PROP_EN_10FDX_CAP: 3433 case MAC_PROP_ADV_10HDX_CAP: 3434 case MAC_PROP_EN_10HDX_CAP: 3435 minsize = sizeof (uint8_t); 3436 break; 3437 case MAC_PROP_PVID: 3438 minsize = sizeof (uint16_t); 3439 break; 3440 case MAC_PROP_IPTUN_HOPLIMIT: 3441 minsize = sizeof (uint32_t); 3442 break; 3443 case MAC_PROP_IPTUN_ENCAPLIMIT: 3444 minsize = sizeof (uint32_t); 3445 break; 3446 case MAC_PROP_MAX_TX_RINGS_AVAIL: 3447 case MAC_PROP_MAX_RX_RINGS_AVAIL: 3448 case MAC_PROP_MAX_RXHWCLNT_AVAIL: 3449 case MAC_PROP_MAX_TXHWCLNT_AVAIL: 3450 minsize = sizeof (uint_t); 3451 break; 3452 case MAC_PROP_WL_ESSID: 3453 minsize = sizeof (wl_linkstatus_t); 3454 break; 3455 case MAC_PROP_WL_BSSID: 3456 minsize = sizeof (wl_bssid_t); 3457 break; 3458 case MAC_PROP_WL_BSSTYPE: 3459 minsize = sizeof (wl_bss_type_t); 3460 break; 3461 case MAC_PROP_WL_LINKSTATUS: 3462 minsize = sizeof (wl_linkstatus_t); 3463 break; 3464 case MAC_PROP_WL_DESIRED_RATES: 3465 minsize = sizeof (wl_rates_t); 3466 break; 3467 case MAC_PROP_WL_SUPPORTED_RATES: 3468 minsize = sizeof (wl_rates_t); 3469 break; 3470 case MAC_PROP_WL_AUTH_MODE: 3471 minsize = sizeof (wl_authmode_t); 3472 break; 3473 case MAC_PROP_WL_ENCRYPTION: 3474 minsize = sizeof (wl_encryption_t); 3475 break; 3476 case MAC_PROP_WL_RSSI: 3477 minsize = sizeof (wl_rssi_t); 3478 break; 3479 case MAC_PROP_WL_PHY_CONFIG: 3480 minsize = sizeof (wl_phy_conf_t); 3481 break; 3482 case MAC_PROP_WL_CAPABILITY: 3483 minsize = sizeof (wl_capability_t); 3484 break; 3485 case MAC_PROP_WL_WPA: 3486 minsize = sizeof (wl_wpa_t); 3487 break; 3488 case MAC_PROP_WL_SCANRESULTS: 3489 minsize = sizeof (wl_wpa_ess_t); 3490 break; 3491 case MAC_PROP_WL_POWER_MODE: 3492 minsize = sizeof (wl_ps_mode_t); 3493 break; 3494 case MAC_PROP_WL_RADIO: 3495 minsize = sizeof (wl_radio_t); 3496 break; 3497 case MAC_PROP_WL_ESS_LIST: 3498 minsize = sizeof (wl_ess_list_t); 3499 break; 3500 case MAC_PROP_WL_KEY_TAB: 3501 minsize = sizeof (wl_wep_key_tab_t); 3502 break; 3503 case MAC_PROP_WL_CREATE_IBSS: 3504 minsize = sizeof (wl_create_ibss_t); 3505 break; 3506 case MAC_PROP_WL_SETOPTIE: 3507 minsize = sizeof (wl_wpa_ie_t); 3508 break; 3509 case MAC_PROP_WL_DELKEY: 3510 minsize = sizeof (wl_del_key_t); 3511 break; 3512 case MAC_PROP_WL_KEY: 3513 minsize = sizeof (wl_key_t); 3514 break; 3515 case MAC_PROP_WL_MLME: 3516 minsize = sizeof (wl_mlme_t); 3517 break; 3518 case MAC_PROP_VN_PROMISC_FILTERED: 3519 minsize = sizeof (boolean_t); 3520 break; 3521 case MAC_PROP_MEDIA: 3522 /* 3523 * Our assumption is that each class of device uses an enum and 3524 * that all enums will be the same size so it is OK to use a 3525 * single one. 3526 */ 3527 minsize = sizeof (mac_ether_media_t); 3528 break; 3529 } 3530 3531 return (valsize >= minsize); 3532 } 3533 3534 /* 3535 * mac_set_prop() sets MAC or hardware driver properties: 3536 * 3537 * - MAC-managed properties such as resource properties include maxbw, 3538 * priority, and cpu binding list, as well as the default port VID 3539 * used by bridging. These properties are consumed by the MAC layer 3540 * itself and not passed down to the driver. For resource control 3541 * properties, this function invokes mac_set_resources() which will 3542 * cache the property value in mac_impl_t and may call 3543 * mac_client_set_resource() to update property value of the primary 3544 * mac client, if it exists. 3545 * 3546 * - Properties which act on the hardware and must be passed to the 3547 * driver, such as MTU, through the driver's mc_setprop() entry point. 3548 */ 3549 int 3550 mac_set_prop(mac_handle_t mh, mac_prop_id_t id, char *name, void *val, 3551 uint_t valsize) 3552 { 3553 int err = ENOTSUP; 3554 mac_impl_t *mip = (mac_impl_t *)mh; 3555 3556 ASSERT(MAC_PERIM_HELD(mh)); 3557 3558 switch (id) { 3559 case MAC_PROP_RESOURCE: { 3560 mac_resource_props_t *mrp; 3561 3562 /* call mac_set_resources() for MAC properties */ 3563 ASSERT(valsize >= sizeof (mac_resource_props_t)); 3564 mrp = kmem_zalloc(sizeof (*mrp), KM_SLEEP); 3565 bcopy(val, mrp, sizeof (*mrp)); 3566 err = mac_set_resources(mh, mrp); 3567 kmem_free(mrp, sizeof (*mrp)); 3568 break; 3569 } 3570 3571 case MAC_PROP_PVID: 3572 ASSERT(valsize >= sizeof (uint16_t)); 3573 if (mip->mi_state_flags & MIS_IS_VNIC) 3574 return (EINVAL); 3575 err = mac_set_pvid(mh, *(uint16_t *)val); 3576 break; 3577 3578 case MAC_PROP_MTU: { 3579 uint32_t mtu; 3580 3581 ASSERT(valsize >= sizeof (uint32_t)); 3582 bcopy(val, &mtu, sizeof (mtu)); 3583 err = mac_set_mtu(mh, mtu, NULL); 3584 break; 3585 } 3586 3587 case MAC_PROP_LLIMIT: 3588 case MAC_PROP_LDECAY: { 3589 uint32_t learnval; 3590 3591 if (valsize < sizeof (learnval) || 3592 (mip->mi_state_flags & MIS_IS_VNIC)) 3593 return (EINVAL); 3594 bcopy(val, &learnval, sizeof (learnval)); 3595 if (learnval == 0 && id == MAC_PROP_LDECAY) 3596 return (EINVAL); 3597 if (id == MAC_PROP_LLIMIT) 3598 mip->mi_llimit = learnval; 3599 else 3600 mip->mi_ldecay = learnval; 3601 err = 0; 3602 break; 3603 } 3604 3605 case MAC_PROP_ADV_FEC_CAP: 3606 case MAC_PROP_EN_FEC_CAP: { 3607 link_fec_t fec; 3608 3609 ASSERT(valsize >= sizeof (link_fec_t)); 3610 3611 /* 3612 * fec cannot be zero, and auto must be set exclusively. 3613 */ 3614 bcopy(val, &fec, sizeof (link_fec_t)); 3615 if (fec == 0) 3616 return (EINVAL); 3617 if ((fec & LINK_FEC_AUTO) != 0 && (fec & ~LINK_FEC_AUTO) != 0) 3618 return (EINVAL); 3619 3620 if (mip->mi_callbacks->mc_callbacks & MC_SETPROP) { 3621 err = mip->mi_callbacks->mc_setprop(mip->mi_driver, 3622 name, id, valsize, val); 3623 } 3624 break; 3625 } 3626 3627 default: 3628 /* For other driver properties, call driver's callback */ 3629 if (mip->mi_callbacks->mc_callbacks & MC_SETPROP) { 3630 err = mip->mi_callbacks->mc_setprop(mip->mi_driver, 3631 name, id, valsize, val); 3632 } 3633 } 3634 return (err); 3635 } 3636 3637 /* 3638 * mac_get_prop() gets MAC or device driver properties. 3639 * 3640 * If the property is a driver property, mac_get_prop() calls driver's callback 3641 * entry point to get it. 3642 * If the property is a MAC property, mac_get_prop() invokes mac_get_resources() 3643 * which returns the cached value in mac_impl_t. 3644 */ 3645 int 3646 mac_get_prop(mac_handle_t mh, mac_prop_id_t id, char *name, void *val, 3647 uint_t valsize) 3648 { 3649 int err = ENOTSUP; 3650 mac_impl_t *mip = (mac_impl_t *)mh; 3651 uint_t rings; 3652 uint_t vlinks; 3653 3654 bzero(val, valsize); 3655 3656 switch (id) { 3657 case MAC_PROP_RESOURCE: { 3658 mac_resource_props_t *mrp; 3659 3660 /* If mac property, read from cache */ 3661 ASSERT(valsize >= sizeof (mac_resource_props_t)); 3662 mrp = kmem_zalloc(sizeof (*mrp), KM_SLEEP); 3663 mac_get_resources(mh, mrp); 3664 bcopy(mrp, val, sizeof (*mrp)); 3665 kmem_free(mrp, sizeof (*mrp)); 3666 return (0); 3667 } 3668 case MAC_PROP_RESOURCE_EFF: { 3669 mac_resource_props_t *mrp; 3670 3671 /* If mac effective property, read from client */ 3672 ASSERT(valsize >= sizeof (mac_resource_props_t)); 3673 mrp = kmem_zalloc(sizeof (*mrp), KM_SLEEP); 3674 mac_get_effective_resources(mh, mrp); 3675 bcopy(mrp, val, sizeof (*mrp)); 3676 kmem_free(mrp, sizeof (*mrp)); 3677 return (0); 3678 } 3679 3680 case MAC_PROP_PVID: 3681 ASSERT(valsize >= sizeof (uint16_t)); 3682 if (mip->mi_state_flags & MIS_IS_VNIC) 3683 return (EINVAL); 3684 *(uint16_t *)val = mac_get_pvid(mh); 3685 return (0); 3686 3687 case MAC_PROP_LLIMIT: 3688 case MAC_PROP_LDECAY: 3689 ASSERT(valsize >= sizeof (uint32_t)); 3690 if (mip->mi_state_flags & MIS_IS_VNIC) 3691 return (EINVAL); 3692 if (id == MAC_PROP_LLIMIT) 3693 bcopy(&mip->mi_llimit, val, sizeof (mip->mi_llimit)); 3694 else 3695 bcopy(&mip->mi_ldecay, val, sizeof (mip->mi_ldecay)); 3696 return (0); 3697 3698 case MAC_PROP_MTU: { 3699 uint32_t sdu; 3700 3701 ASSERT(valsize >= sizeof (uint32_t)); 3702 mac_sdu_get2(mh, NULL, &sdu, NULL); 3703 bcopy(&sdu, val, sizeof (sdu)); 3704 3705 return (0); 3706 } 3707 case MAC_PROP_STATUS: { 3708 link_state_t link_state; 3709 3710 if (valsize < sizeof (link_state)) 3711 return (EINVAL); 3712 link_state = mac_link_get(mh); 3713 bcopy(&link_state, val, sizeof (link_state)); 3714 3715 return (0); 3716 } 3717 3718 case MAC_PROP_MAX_RX_RINGS_AVAIL: 3719 case MAC_PROP_MAX_TX_RINGS_AVAIL: 3720 ASSERT(valsize >= sizeof (uint_t)); 3721 rings = id == MAC_PROP_MAX_RX_RINGS_AVAIL ? 3722 mac_rxavail_get(mh) : mac_txavail_get(mh); 3723 bcopy(&rings, val, sizeof (uint_t)); 3724 return (0); 3725 3726 case MAC_PROP_MAX_RXHWCLNT_AVAIL: 3727 case MAC_PROP_MAX_TXHWCLNT_AVAIL: 3728 ASSERT(valsize >= sizeof (uint_t)); 3729 vlinks = id == MAC_PROP_MAX_RXHWCLNT_AVAIL ? 3730 mac_rxhwlnksavail_get(mh) : mac_txhwlnksavail_get(mh); 3731 bcopy(&vlinks, val, sizeof (uint_t)); 3732 return (0); 3733 3734 case MAC_PROP_RXRINGSRANGE: 3735 case MAC_PROP_TXRINGSRANGE: 3736 /* 3737 * The value for these properties are returned through 3738 * the MAC_PROP_RESOURCE property. 3739 */ 3740 return (0); 3741 3742 default: 3743 break; 3744 3745 } 3746 3747 /* If driver property, request from driver */ 3748 if (mip->mi_callbacks->mc_callbacks & MC_GETPROP) { 3749 err = mip->mi_callbacks->mc_getprop(mip->mi_driver, name, id, 3750 valsize, val); 3751 } 3752 3753 return (err); 3754 } 3755 3756 /* 3757 * Helper function to initialize the range structure for use in 3758 * mac_get_prop. If the type can be other than uint32, we can 3759 * pass that as an arg. 3760 */ 3761 static void 3762 _mac_set_range(mac_propval_range_t *range, uint32_t min, uint32_t max) 3763 { 3764 range->mpr_count = 1; 3765 range->mpr_type = MAC_PROPVAL_UINT32; 3766 range->mpr_range_uint32[0].mpur_min = min; 3767 range->mpr_range_uint32[0].mpur_max = max; 3768 } 3769 3770 /* 3771 * Returns information about the specified property, such as default 3772 * values or permissions. 3773 */ 3774 int 3775 mac_prop_info(mac_handle_t mh, mac_prop_id_t id, char *name, 3776 void *default_val, uint_t default_size, mac_propval_range_t *range, 3777 uint_t *perm) 3778 { 3779 mac_prop_info_state_t state; 3780 mac_impl_t *mip = (mac_impl_t *)mh; 3781 uint_t max; 3782 3783 /* 3784 * A property is read/write by default unless the driver says 3785 * otherwise. 3786 */ 3787 if (perm != NULL) 3788 *perm = MAC_PROP_PERM_RW; 3789 3790 if (default_val != NULL) 3791 bzero(default_val, default_size); 3792 3793 /* 3794 * First, handle framework properties for which we don't need to 3795 * involve the driver. 3796 */ 3797 switch (id) { 3798 case MAC_PROP_RESOURCE: 3799 case MAC_PROP_PVID: 3800 case MAC_PROP_LLIMIT: 3801 case MAC_PROP_LDECAY: 3802 return (0); 3803 3804 case MAC_PROP_MAX_RX_RINGS_AVAIL: 3805 case MAC_PROP_MAX_TX_RINGS_AVAIL: 3806 case MAC_PROP_MAX_RXHWCLNT_AVAIL: 3807 case MAC_PROP_MAX_TXHWCLNT_AVAIL: 3808 if (perm != NULL) 3809 *perm = MAC_PROP_PERM_READ; 3810 return (0); 3811 3812 case MAC_PROP_RXRINGSRANGE: 3813 case MAC_PROP_TXRINGSRANGE: 3814 /* 3815 * Currently, we support range for RX and TX rings properties. 3816 * When we extend this support to maxbw, cpus and priority, 3817 * we should move this to mac_get_resources. 3818 * There is no default value for RX or TX rings. 3819 */ 3820 if ((mip->mi_state_flags & MIS_IS_VNIC) && 3821 mac_is_vnic_primary(mh)) { 3822 /* 3823 * We don't support setting rings for a VLAN 3824 * data link because it shares its ring with the 3825 * primary MAC client. 3826 */ 3827 if (perm != NULL) 3828 *perm = MAC_PROP_PERM_READ; 3829 if (range != NULL) 3830 range->mpr_count = 0; 3831 } else if (range != NULL) { 3832 if (mip->mi_state_flags & MIS_IS_VNIC) 3833 mh = mac_get_lower_mac_handle(mh); 3834 mip = (mac_impl_t *)mh; 3835 if ((id == MAC_PROP_RXRINGSRANGE && 3836 mip->mi_rx_group_type == MAC_GROUP_TYPE_STATIC) || 3837 (id == MAC_PROP_TXRINGSRANGE && 3838 mip->mi_tx_group_type == MAC_GROUP_TYPE_STATIC)) { 3839 if (id == MAC_PROP_RXRINGSRANGE) { 3840 if ((mac_rxhwlnksavail_get(mh) + 3841 mac_rxhwlnksrsvd_get(mh)) <= 1) { 3842 /* 3843 * doesn't support groups or 3844 * rings 3845 */ 3846 range->mpr_count = 0; 3847 } else { 3848 /* 3849 * supports specifying groups, 3850 * but not rings 3851 */ 3852 _mac_set_range(range, 0, 0); 3853 } 3854 } else { 3855 if ((mac_txhwlnksavail_get(mh) + 3856 mac_txhwlnksrsvd_get(mh)) <= 1) { 3857 /* 3858 * doesn't support groups or 3859 * rings 3860 */ 3861 range->mpr_count = 0; 3862 } else { 3863 /* 3864 * supports specifying groups, 3865 * but not rings 3866 */ 3867 _mac_set_range(range, 0, 0); 3868 } 3869 } 3870 } else { 3871 max = id == MAC_PROP_RXRINGSRANGE ? 3872 mac_rxavail_get(mh) + mac_rxrsvd_get(mh) : 3873 mac_txavail_get(mh) + mac_txrsvd_get(mh); 3874 if (max <= 1) { 3875 /* 3876 * doesn't support groups or 3877 * rings 3878 */ 3879 range->mpr_count = 0; 3880 } else { 3881 /* 3882 * -1 because we have to leave out the 3883 * default ring. 3884 */ 3885 _mac_set_range(range, 1, max - 1); 3886 } 3887 } 3888 } 3889 return (0); 3890 3891 case MAC_PROP_STATUS: 3892 case MAC_PROP_MEDIA: 3893 if (perm != NULL) 3894 *perm = MAC_PROP_PERM_READ; 3895 return (0); 3896 } 3897 3898 /* 3899 * Get the property info from the driver if it implements the 3900 * property info entry point. 3901 */ 3902 bzero(&state, sizeof (state)); 3903 3904 if (mip->mi_callbacks->mc_callbacks & MC_PROPINFO) { 3905 state.pr_default = default_val; 3906 state.pr_default_size = default_size; 3907 3908 /* 3909 * The caller specifies the maximum number of ranges 3910 * it can accomodate using mpr_count. We don't touch 3911 * this value until the driver returns from its 3912 * mc_propinfo() callback, and ensure we don't exceed 3913 * this number of range as the driver defines 3914 * supported range from its mc_propinfo(). 3915 * 3916 * pr_range_cur_count keeps track of how many ranges 3917 * were defined by the driver from its mc_propinfo() 3918 * entry point. 3919 * 3920 * On exit, the user-specified range mpr_count returns 3921 * the number of ranges specified by the driver on 3922 * success, or the number of ranges it wanted to 3923 * define if that number of ranges could not be 3924 * accomodated by the specified range structure. In 3925 * the latter case, the caller will be able to 3926 * allocate a larger range structure, and query the 3927 * property again. 3928 */ 3929 state.pr_range_cur_count = 0; 3930 state.pr_range = range; 3931 3932 mip->mi_callbacks->mc_propinfo(mip->mi_driver, name, id, 3933 (mac_prop_info_handle_t)&state); 3934 3935 if (state.pr_flags & MAC_PROP_INFO_RANGE) 3936 range->mpr_count = state.pr_range_cur_count; 3937 3938 /* 3939 * The operation could fail if the buffer supplied by 3940 * the user was too small for the range or default 3941 * value of the property. 3942 */ 3943 if (state.pr_errno != 0) 3944 return (state.pr_errno); 3945 3946 if (perm != NULL && state.pr_flags & MAC_PROP_INFO_PERM) 3947 *perm = state.pr_perm; 3948 } 3949 3950 /* 3951 * The MAC layer may want to provide default values or allowed 3952 * ranges for properties if the driver does not provide a 3953 * property info entry point, or that entry point exists, but 3954 * it did not provide a default value or allowed ranges for 3955 * that property. 3956 */ 3957 switch (id) { 3958 case MAC_PROP_MTU: { 3959 uint32_t sdu; 3960 3961 mac_sdu_get2(mh, NULL, &sdu, NULL); 3962 3963 if (range != NULL && !(state.pr_flags & 3964 MAC_PROP_INFO_RANGE)) { 3965 /* MTU range */ 3966 _mac_set_range(range, sdu, sdu); 3967 } 3968 3969 if (default_val != NULL && !(state.pr_flags & 3970 MAC_PROP_INFO_DEFAULT)) { 3971 if (mip->mi_info.mi_media == DL_ETHER) 3972 sdu = ETHERMTU; 3973 /* default MTU value */ 3974 bcopy(&sdu, default_val, sizeof (sdu)); 3975 } 3976 } 3977 } 3978 3979 return (0); 3980 } 3981 3982 int 3983 mac_fastpath_disable(mac_handle_t mh) 3984 { 3985 mac_impl_t *mip = (mac_impl_t *)mh; 3986 3987 if ((mip->mi_state_flags & MIS_LEGACY) == 0) 3988 return (0); 3989 3990 return (mip->mi_capab_legacy.ml_fastpath_disable(mip->mi_driver)); 3991 } 3992 3993 void 3994 mac_fastpath_enable(mac_handle_t mh) 3995 { 3996 mac_impl_t *mip = (mac_impl_t *)mh; 3997 3998 if ((mip->mi_state_flags & MIS_LEGACY) == 0) 3999 return; 4000 4001 mip->mi_capab_legacy.ml_fastpath_enable(mip->mi_driver); 4002 } 4003 4004 void 4005 mac_register_priv_prop(mac_impl_t *mip, char **priv_props) 4006 { 4007 uint_t nprops, i; 4008 4009 if (priv_props == NULL) 4010 return; 4011 4012 nprops = 0; 4013 while (priv_props[nprops] != NULL) 4014 nprops++; 4015 if (nprops == 0) 4016 return; 4017 4018 4019 mip->mi_priv_prop = kmem_zalloc(nprops * sizeof (char *), KM_SLEEP); 4020 4021 for (i = 0; i < nprops; i++) { 4022 mip->mi_priv_prop[i] = kmem_zalloc(MAXLINKPROPNAME, KM_SLEEP); 4023 (void) strlcpy(mip->mi_priv_prop[i], priv_props[i], 4024 MAXLINKPROPNAME); 4025 } 4026 4027 mip->mi_priv_prop_count = nprops; 4028 } 4029 4030 void 4031 mac_unregister_priv_prop(mac_impl_t *mip) 4032 { 4033 uint_t i; 4034 4035 if (mip->mi_priv_prop_count == 0) { 4036 ASSERT(mip->mi_priv_prop == NULL); 4037 return; 4038 } 4039 4040 for (i = 0; i < mip->mi_priv_prop_count; i++) 4041 kmem_free(mip->mi_priv_prop[i], MAXLINKPROPNAME); 4042 kmem_free(mip->mi_priv_prop, mip->mi_priv_prop_count * 4043 sizeof (char *)); 4044 4045 mip->mi_priv_prop = NULL; 4046 mip->mi_priv_prop_count = 0; 4047 } 4048 4049 /* 4050 * mac_ring_t 'mr' macros. Some rogue drivers may access ring structure 4051 * (by invoking mac_rx()) even after processing mac_stop_ring(). In such 4052 * cases if MAC free's the ring structure after mac_stop_ring(), any 4053 * illegal access to the ring structure coming from the driver will panic 4054 * the system. In order to protect the system from such inadverent access, 4055 * we maintain a cache of rings in the mac_impl_t after they get free'd up. 4056 * When packets are received on free'd up rings, MAC (through the generation 4057 * count mechanism) will drop such packets. 4058 */ 4059 static mac_ring_t * 4060 mac_ring_alloc(mac_impl_t *mip) 4061 { 4062 mac_ring_t *ring; 4063 4064 mutex_enter(&mip->mi_ring_lock); 4065 if (mip->mi_ring_freelist != NULL) { 4066 ring = mip->mi_ring_freelist; 4067 mip->mi_ring_freelist = ring->mr_next; 4068 bzero(ring, sizeof (mac_ring_t)); 4069 mutex_exit(&mip->mi_ring_lock); 4070 } else { 4071 mutex_exit(&mip->mi_ring_lock); 4072 ring = kmem_cache_alloc(mac_ring_cache, KM_SLEEP); 4073 } 4074 ASSERT((ring != NULL) && (ring->mr_state == MR_FREE)); 4075 return (ring); 4076 } 4077 4078 static void 4079 mac_ring_free(mac_impl_t *mip, mac_ring_t *ring) 4080 { 4081 ASSERT(ring->mr_state == MR_FREE); 4082 4083 mutex_enter(&mip->mi_ring_lock); 4084 ring->mr_state = MR_FREE; 4085 ring->mr_flag = 0; 4086 ring->mr_next = mip->mi_ring_freelist; 4087 ring->mr_mip = NULL; 4088 mip->mi_ring_freelist = ring; 4089 mac_ring_stat_delete(ring); 4090 mutex_exit(&mip->mi_ring_lock); 4091 } 4092 4093 static void 4094 mac_ring_freeall(mac_impl_t *mip) 4095 { 4096 mac_ring_t *ring_next; 4097 mutex_enter(&mip->mi_ring_lock); 4098 mac_ring_t *ring = mip->mi_ring_freelist; 4099 while (ring != NULL) { 4100 ring_next = ring->mr_next; 4101 kmem_cache_free(mac_ring_cache, ring); 4102 ring = ring_next; 4103 } 4104 mip->mi_ring_freelist = NULL; 4105 mutex_exit(&mip->mi_ring_lock); 4106 } 4107 4108 int 4109 mac_start_ring(mac_ring_t *ring) 4110 { 4111 int rv = 0; 4112 4113 ASSERT(ring->mr_state == MR_FREE); 4114 4115 if (ring->mr_start != NULL) { 4116 rv = ring->mr_start(ring->mr_driver, ring->mr_gen_num); 4117 if (rv != 0) 4118 return (rv); 4119 } 4120 4121 ring->mr_state = MR_INUSE; 4122 return (rv); 4123 } 4124 4125 void 4126 mac_stop_ring(mac_ring_t *ring) 4127 { 4128 ASSERT(ring->mr_state == MR_INUSE); 4129 4130 if (ring->mr_stop != NULL) 4131 ring->mr_stop(ring->mr_driver); 4132 4133 ring->mr_state = MR_FREE; 4134 4135 /* 4136 * Increment the ring generation number for this ring. 4137 */ 4138 ring->mr_gen_num++; 4139 } 4140 4141 int 4142 mac_start_group(mac_group_t *group) 4143 { 4144 int rv = 0; 4145 4146 if (group->mrg_start != NULL) 4147 rv = group->mrg_start(group->mrg_driver); 4148 4149 return (rv); 4150 } 4151 4152 void 4153 mac_stop_group(mac_group_t *group) 4154 { 4155 if (group->mrg_stop != NULL) 4156 group->mrg_stop(group->mrg_driver); 4157 } 4158 4159 /* 4160 * Called from mac_start() on the default Rx group. Broadcast and multicast 4161 * packets are received only on the default group. Hence the default group 4162 * needs to be up even if the primary client is not up, for the other groups 4163 * to be functional. We do this by calling this function at mac_start time 4164 * itself. However the broadcast packets that are received can't make their 4165 * way beyond mac_rx until a mac client creates a broadcast flow. 4166 */ 4167 static int 4168 mac_start_group_and_rings(mac_group_t *group) 4169 { 4170 mac_ring_t *ring; 4171 int rv = 0; 4172 4173 ASSERT(group->mrg_state == MAC_GROUP_STATE_REGISTERED); 4174 if ((rv = mac_start_group(group)) != 0) 4175 return (rv); 4176 4177 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) { 4178 ASSERT(ring->mr_state == MR_FREE); 4179 4180 if ((rv = mac_start_ring(ring)) != 0) 4181 goto error; 4182 4183 /* 4184 * When aggr_set_port_sdu() is called, it will remove 4185 * the port client's unicast address. This will cause 4186 * MAC to stop the default group's rings on the port 4187 * MAC. After it modifies the SDU, it will then re-add 4188 * the unicast address. At which time, this function is 4189 * called to start the default group's rings. Normally 4190 * this function would set the classify type to 4191 * MAC_SW_CLASSIFIER; but that will break aggr which 4192 * relies on the passthru classify mode being set for 4193 * correct delivery (see mac_rx_common()). To avoid 4194 * that, we check for a passthru callback and set the 4195 * classify type to MAC_PASSTHRU_CLASSIFIER; as it was 4196 * before the rings were stopped. 4197 */ 4198 ring->mr_classify_type = (ring->mr_pt_fn != NULL) ? 4199 MAC_PASSTHRU_CLASSIFIER : MAC_SW_CLASSIFIER; 4200 } 4201 return (0); 4202 4203 error: 4204 mac_stop_group_and_rings(group); 4205 return (rv); 4206 } 4207 4208 /* Called from mac_stop on the default Rx group */ 4209 static void 4210 mac_stop_group_and_rings(mac_group_t *group) 4211 { 4212 mac_ring_t *ring; 4213 4214 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) { 4215 if (ring->mr_state != MR_FREE) { 4216 mac_stop_ring(ring); 4217 ring->mr_flag = 0; 4218 ring->mr_classify_type = MAC_NO_CLASSIFIER; 4219 } 4220 } 4221 mac_stop_group(group); 4222 } 4223 4224 4225 static mac_ring_t * 4226 mac_init_ring(mac_impl_t *mip, mac_group_t *group, int index, 4227 mac_capab_rings_t *cap_rings) 4228 { 4229 mac_ring_t *ring, *rnext; 4230 mac_ring_info_t ring_info; 4231 ddi_intr_handle_t ddi_handle; 4232 4233 ring = mac_ring_alloc(mip); 4234 4235 /* Prepare basic information of ring */ 4236 4237 /* 4238 * Ring index is numbered to be unique across a particular device. 4239 * Ring index computation makes following assumptions: 4240 * - For drivers with static grouping (e.g. ixgbe, bge), 4241 * ring index exchanged with the driver (e.g. during mr_rget) 4242 * is unique only across the group the ring belongs to. 4243 * - Drivers with dynamic grouping (e.g. nxge), start 4244 * with single group (mrg_index = 0). 4245 */ 4246 ring->mr_index = group->mrg_index * group->mrg_info.mgi_count + index; 4247 ring->mr_type = group->mrg_type; 4248 ring->mr_gh = (mac_group_handle_t)group; 4249 4250 /* Insert the new ring to the list. */ 4251 ring->mr_next = group->mrg_rings; 4252 group->mrg_rings = ring; 4253 4254 /* Zero to reuse the info data structure */ 4255 bzero(&ring_info, sizeof (ring_info)); 4256 4257 /* Query ring information from driver */ 4258 cap_rings->mr_rget(mip->mi_driver, group->mrg_type, group->mrg_index, 4259 index, &ring_info, (mac_ring_handle_t)ring); 4260 4261 ring->mr_info = ring_info; 4262 4263 /* 4264 * The interrupt handle could be shared among multiple rings. 4265 * Thus if there is a bunch of rings that are sharing an 4266 * interrupt, then only one ring among the bunch will be made 4267 * available for interrupt re-targeting; the rest will have 4268 * ddi_shared flag set to TRUE and would not be available for 4269 * be interrupt re-targeting. 4270 */ 4271 if ((ddi_handle = ring_info.mri_intr.mi_ddi_handle) != NULL) { 4272 rnext = ring->mr_next; 4273 while (rnext != NULL) { 4274 if (rnext->mr_info.mri_intr.mi_ddi_handle == 4275 ddi_handle) { 4276 /* 4277 * If default ring (mr_index == 0) is part 4278 * of a group of rings sharing an 4279 * interrupt, then set ddi_shared flag for 4280 * the default ring and give another ring 4281 * the chance to be re-targeted. 4282 */ 4283 if (rnext->mr_index == 0 && 4284 !rnext->mr_info.mri_intr.mi_ddi_shared) { 4285 rnext->mr_info.mri_intr.mi_ddi_shared = 4286 B_TRUE; 4287 } else { 4288 ring->mr_info.mri_intr.mi_ddi_shared = 4289 B_TRUE; 4290 } 4291 break; 4292 } 4293 rnext = rnext->mr_next; 4294 } 4295 /* 4296 * If rnext is NULL, then no matching ddi_handle was found. 4297 * Rx rings get registered first. So if this is a Tx ring, 4298 * then go through all the Rx rings and see if there is a 4299 * matching ddi handle. 4300 */ 4301 if (rnext == NULL && ring->mr_type == MAC_RING_TYPE_TX) { 4302 mac_compare_ddi_handle(mip->mi_rx_groups, 4303 mip->mi_rx_group_count, ring); 4304 } 4305 } 4306 4307 /* Update ring's status */ 4308 ring->mr_state = MR_FREE; 4309 ring->mr_flag = 0; 4310 4311 /* Update the ring count of the group */ 4312 group->mrg_cur_count++; 4313 4314 /* Create per ring kstats */ 4315 if (ring->mr_stat != NULL) { 4316 ring->mr_mip = mip; 4317 mac_ring_stat_create(ring); 4318 } 4319 4320 return (ring); 4321 } 4322 4323 /* 4324 * Rings are chained together for easy regrouping. 4325 */ 4326 static void 4327 mac_init_group(mac_impl_t *mip, mac_group_t *group, int size, 4328 mac_capab_rings_t *cap_rings) 4329 { 4330 int index; 4331 4332 /* 4333 * Initialize all ring members of this group. Size of zero will not 4334 * enter the loop, so it's safe for initializing an empty group. 4335 */ 4336 for (index = size - 1; index >= 0; index--) 4337 (void) mac_init_ring(mip, group, index, cap_rings); 4338 } 4339 4340 int 4341 mac_init_rings(mac_impl_t *mip, mac_ring_type_t rtype) 4342 { 4343 mac_capab_rings_t *cap_rings; 4344 mac_group_t *group; 4345 mac_group_t *groups; 4346 mac_group_info_t group_info; 4347 uint_t group_free = 0; 4348 uint_t ring_left; 4349 mac_ring_t *ring; 4350 int g; 4351 int err = 0; 4352 uint_t grpcnt; 4353 boolean_t pseudo_txgrp = B_FALSE; 4354 4355 switch (rtype) { 4356 case MAC_RING_TYPE_RX: 4357 ASSERT(mip->mi_rx_groups == NULL); 4358 4359 cap_rings = &mip->mi_rx_rings_cap; 4360 cap_rings->mr_type = MAC_RING_TYPE_RX; 4361 break; 4362 case MAC_RING_TYPE_TX: 4363 ASSERT(mip->mi_tx_groups == NULL); 4364 4365 cap_rings = &mip->mi_tx_rings_cap; 4366 cap_rings->mr_type = MAC_RING_TYPE_TX; 4367 break; 4368 default: 4369 ASSERT(B_FALSE); 4370 } 4371 4372 if (!i_mac_capab_get((mac_handle_t)mip, MAC_CAPAB_RINGS, cap_rings)) 4373 return (0); 4374 grpcnt = cap_rings->mr_gnum; 4375 4376 /* 4377 * If we have multiple TX rings, but only one TX group, we can 4378 * create pseudo TX groups (one per TX ring) in the MAC layer, 4379 * except for an aggr. For an aggr currently we maintain only 4380 * one group with all the rings (for all its ports), going 4381 * forwards we might change this. 4382 */ 4383 if (rtype == MAC_RING_TYPE_TX && 4384 cap_rings->mr_gnum == 0 && cap_rings->mr_rnum > 0 && 4385 (mip->mi_state_flags & MIS_IS_AGGR) == 0) { 4386 /* 4387 * The -1 here is because we create a default TX group 4388 * with all the rings in it. 4389 */ 4390 grpcnt = cap_rings->mr_rnum - 1; 4391 pseudo_txgrp = B_TRUE; 4392 } 4393 4394 /* 4395 * Allocate a contiguous buffer for all groups. 4396 */ 4397 groups = kmem_zalloc(sizeof (mac_group_t) * (grpcnt+ 1), KM_SLEEP); 4398 4399 ring_left = cap_rings->mr_rnum; 4400 4401 /* 4402 * Get all ring groups if any, and get their ring members 4403 * if any. 4404 */ 4405 for (g = 0; g < grpcnt; g++) { 4406 group = groups + g; 4407 4408 /* Prepare basic information of the group */ 4409 group->mrg_index = g; 4410 group->mrg_type = rtype; 4411 group->mrg_state = MAC_GROUP_STATE_UNINIT; 4412 group->mrg_mh = (mac_handle_t)mip; 4413 group->mrg_next = group + 1; 4414 4415 /* Zero to reuse the info data structure */ 4416 bzero(&group_info, sizeof (group_info)); 4417 4418 if (pseudo_txgrp) { 4419 /* 4420 * This is a pseudo group that we created, apart 4421 * from setting the state there is nothing to be 4422 * done. 4423 */ 4424 group->mrg_state = MAC_GROUP_STATE_REGISTERED; 4425 group_free++; 4426 continue; 4427 } 4428 /* Query group information from driver */ 4429 cap_rings->mr_gget(mip->mi_driver, rtype, g, &group_info, 4430 (mac_group_handle_t)group); 4431 4432 switch (cap_rings->mr_group_type) { 4433 case MAC_GROUP_TYPE_DYNAMIC: 4434 if (cap_rings->mr_gaddring == NULL || 4435 cap_rings->mr_gremring == NULL) { 4436 DTRACE_PROBE3( 4437 mac__init__rings_no_addremring, 4438 char *, mip->mi_name, 4439 mac_group_add_ring_t, 4440 cap_rings->mr_gaddring, 4441 mac_group_add_ring_t, 4442 cap_rings->mr_gremring); 4443 err = EINVAL; 4444 goto bail; 4445 } 4446 4447 switch (rtype) { 4448 case MAC_RING_TYPE_RX: 4449 /* 4450 * The first RX group must have non-zero 4451 * rings, and the following groups must 4452 * have zero rings. 4453 */ 4454 if (g == 0 && group_info.mgi_count == 0) { 4455 DTRACE_PROBE1( 4456 mac__init__rings__rx__def__zero, 4457 char *, mip->mi_name); 4458 err = EINVAL; 4459 goto bail; 4460 } 4461 if (g > 0 && group_info.mgi_count != 0) { 4462 DTRACE_PROBE3( 4463 mac__init__rings__rx__nonzero, 4464 char *, mip->mi_name, 4465 int, g, int, group_info.mgi_count); 4466 err = EINVAL; 4467 goto bail; 4468 } 4469 break; 4470 case MAC_RING_TYPE_TX: 4471 /* 4472 * All TX ring groups must have zero rings. 4473 */ 4474 if (group_info.mgi_count != 0) { 4475 DTRACE_PROBE3( 4476 mac__init__rings__tx__nonzero, 4477 char *, mip->mi_name, 4478 int, g, int, group_info.mgi_count); 4479 err = EINVAL; 4480 goto bail; 4481 } 4482 break; 4483 } 4484 break; 4485 case MAC_GROUP_TYPE_STATIC: 4486 /* 4487 * Note that an empty group is allowed, e.g., an aggr 4488 * would start with an empty group. 4489 */ 4490 break; 4491 default: 4492 /* unknown group type */ 4493 DTRACE_PROBE2(mac__init__rings__unknown__type, 4494 char *, mip->mi_name, 4495 int, cap_rings->mr_group_type); 4496 err = EINVAL; 4497 goto bail; 4498 } 4499 4500 4501 /* 4502 * The driver must register some form of hardware MAC 4503 * filter in order for Rx groups to support multiple 4504 * MAC addresses. 4505 */ 4506 if (rtype == MAC_RING_TYPE_RX && 4507 (group_info.mgi_addmac == NULL || 4508 group_info.mgi_remmac == NULL)) { 4509 DTRACE_PROBE1(mac__init__rings__no__mac__filter, 4510 char *, mip->mi_name); 4511 err = EINVAL; 4512 goto bail; 4513 } 4514 4515 /* Cache driver-supplied information */ 4516 group->mrg_info = group_info; 4517 4518 /* Update the group's status and group count. */ 4519 mac_set_group_state(group, MAC_GROUP_STATE_REGISTERED); 4520 group_free++; 4521 4522 group->mrg_rings = NULL; 4523 group->mrg_cur_count = 0; 4524 mac_init_group(mip, group, group_info.mgi_count, cap_rings); 4525 ring_left -= group_info.mgi_count; 4526 4527 /* The current group size should be equal to default value */ 4528 ASSERT(group->mrg_cur_count == group_info.mgi_count); 4529 } 4530 4531 /* Build up a dummy group for free resources as a pool */ 4532 group = groups + grpcnt; 4533 4534 /* Prepare basic information of the group */ 4535 group->mrg_index = -1; 4536 group->mrg_type = rtype; 4537 group->mrg_state = MAC_GROUP_STATE_UNINIT; 4538 group->mrg_mh = (mac_handle_t)mip; 4539 group->mrg_next = NULL; 4540 4541 /* 4542 * If there are ungrouped rings, allocate a continuous buffer for 4543 * remaining resources. 4544 */ 4545 if (ring_left != 0) { 4546 group->mrg_rings = NULL; 4547 group->mrg_cur_count = 0; 4548 mac_init_group(mip, group, ring_left, cap_rings); 4549 4550 /* The current group size should be equal to ring_left */ 4551 ASSERT(group->mrg_cur_count == ring_left); 4552 4553 ring_left = 0; 4554 4555 /* Update this group's status */ 4556 mac_set_group_state(group, MAC_GROUP_STATE_REGISTERED); 4557 } else { 4558 group->mrg_rings = NULL; 4559 } 4560 4561 ASSERT(ring_left == 0); 4562 4563 bail: 4564 4565 /* Cache other important information to finalize the initialization */ 4566 switch (rtype) { 4567 case MAC_RING_TYPE_RX: 4568 mip->mi_rx_group_type = cap_rings->mr_group_type; 4569 mip->mi_rx_group_count = cap_rings->mr_gnum; 4570 mip->mi_rx_groups = groups; 4571 mip->mi_rx_donor_grp = groups; 4572 if (mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) { 4573 /* 4574 * The default ring is reserved since it is 4575 * used for sending the broadcast etc. packets. 4576 */ 4577 mip->mi_rxrings_avail = 4578 mip->mi_rx_groups->mrg_cur_count - 1; 4579 mip->mi_rxrings_rsvd = 1; 4580 } 4581 /* 4582 * The default group cannot be reserved. It is used by 4583 * all the clients that do not have an exclusive group. 4584 */ 4585 mip->mi_rxhwclnt_avail = mip->mi_rx_group_count - 1; 4586 mip->mi_rxhwclnt_used = 1; 4587 break; 4588 case MAC_RING_TYPE_TX: 4589 mip->mi_tx_group_type = pseudo_txgrp ? MAC_GROUP_TYPE_DYNAMIC : 4590 cap_rings->mr_group_type; 4591 mip->mi_tx_group_count = grpcnt; 4592 mip->mi_tx_group_free = group_free; 4593 mip->mi_tx_groups = groups; 4594 4595 group = groups + grpcnt; 4596 ring = group->mrg_rings; 4597 /* 4598 * The ring can be NULL in the case of aggr. Aggr will 4599 * have an empty Tx group which will get populated 4600 * later when pseudo Tx rings are added after 4601 * mac_register() is done. 4602 */ 4603 if (ring == NULL) { 4604 ASSERT(mip->mi_state_flags & MIS_IS_AGGR); 4605 /* 4606 * pass the group to aggr so it can add Tx 4607 * rings to the group later. 4608 */ 4609 cap_rings->mr_gget(mip->mi_driver, rtype, 0, NULL, 4610 (mac_group_handle_t)group); 4611 /* 4612 * Even though there are no rings at this time 4613 * (rings will come later), set the group 4614 * state to registered. 4615 */ 4616 group->mrg_state = MAC_GROUP_STATE_REGISTERED; 4617 } else { 4618 /* 4619 * Ring 0 is used as the default one and it could be 4620 * assigned to a client as well. 4621 */ 4622 while ((ring->mr_index != 0) && (ring->mr_next != NULL)) 4623 ring = ring->mr_next; 4624 ASSERT(ring->mr_index == 0); 4625 mip->mi_default_tx_ring = (mac_ring_handle_t)ring; 4626 } 4627 if (mip->mi_tx_group_type == MAC_GROUP_TYPE_DYNAMIC) { 4628 mip->mi_txrings_avail = group->mrg_cur_count - 1; 4629 /* 4630 * The default ring cannot be reserved. 4631 */ 4632 mip->mi_txrings_rsvd = 1; 4633 } 4634 /* 4635 * The default group cannot be reserved. It will be shared 4636 * by clients that do not have an exclusive group. 4637 */ 4638 mip->mi_txhwclnt_avail = mip->mi_tx_group_count; 4639 mip->mi_txhwclnt_used = 1; 4640 break; 4641 default: 4642 ASSERT(B_FALSE); 4643 } 4644 4645 if (err != 0) 4646 mac_free_rings(mip, rtype); 4647 4648 return (err); 4649 } 4650 4651 /* 4652 * The ddi interrupt handle could be shared amoung rings. If so, compare 4653 * the new ring's ddi handle with the existing ones and set ddi_shared 4654 * flag. 4655 */ 4656 void 4657 mac_compare_ddi_handle(mac_group_t *groups, uint_t grpcnt, mac_ring_t *cring) 4658 { 4659 mac_group_t *group; 4660 mac_ring_t *ring; 4661 ddi_intr_handle_t ddi_handle; 4662 int g; 4663 4664 ddi_handle = cring->mr_info.mri_intr.mi_ddi_handle; 4665 for (g = 0; g < grpcnt; g++) { 4666 group = groups + g; 4667 for (ring = group->mrg_rings; ring != NULL; 4668 ring = ring->mr_next) { 4669 if (ring == cring) 4670 continue; 4671 if (ring->mr_info.mri_intr.mi_ddi_handle == 4672 ddi_handle) { 4673 if (cring->mr_type == MAC_RING_TYPE_RX && 4674 ring->mr_index == 0 && 4675 !ring->mr_info.mri_intr.mi_ddi_shared) { 4676 ring->mr_info.mri_intr.mi_ddi_shared = 4677 B_TRUE; 4678 } else { 4679 cring->mr_info.mri_intr.mi_ddi_shared = 4680 B_TRUE; 4681 } 4682 return; 4683 } 4684 } 4685 } 4686 } 4687 4688 /* 4689 * Called to free all groups of particular type (RX or TX). It's assumed that 4690 * no clients are using these groups. 4691 */ 4692 void 4693 mac_free_rings(mac_impl_t *mip, mac_ring_type_t rtype) 4694 { 4695 mac_group_t *group, *groups; 4696 uint_t group_count; 4697 4698 switch (rtype) { 4699 case MAC_RING_TYPE_RX: 4700 if (mip->mi_rx_groups == NULL) 4701 return; 4702 4703 groups = mip->mi_rx_groups; 4704 group_count = mip->mi_rx_group_count; 4705 4706 mip->mi_rx_groups = NULL; 4707 mip->mi_rx_donor_grp = NULL; 4708 mip->mi_rx_group_count = 0; 4709 break; 4710 case MAC_RING_TYPE_TX: 4711 ASSERT(mip->mi_tx_group_count == mip->mi_tx_group_free); 4712 4713 if (mip->mi_tx_groups == NULL) 4714 return; 4715 4716 groups = mip->mi_tx_groups; 4717 group_count = mip->mi_tx_group_count; 4718 4719 mip->mi_tx_groups = NULL; 4720 mip->mi_tx_group_count = 0; 4721 mip->mi_tx_group_free = 0; 4722 mip->mi_default_tx_ring = NULL; 4723 break; 4724 default: 4725 ASSERT(B_FALSE); 4726 } 4727 4728 for (group = groups; group != NULL; group = group->mrg_next) { 4729 mac_ring_t *ring; 4730 4731 if (group->mrg_cur_count == 0) 4732 continue; 4733 4734 ASSERT(group->mrg_rings != NULL); 4735 4736 while ((ring = group->mrg_rings) != NULL) { 4737 group->mrg_rings = ring->mr_next; 4738 mac_ring_free(mip, ring); 4739 } 4740 } 4741 4742 /* Free all the cached rings */ 4743 mac_ring_freeall(mip); 4744 /* Free the block of group data strutures */ 4745 kmem_free(groups, sizeof (mac_group_t) * (group_count + 1)); 4746 } 4747 4748 /* 4749 * Associate the VLAN filter to the receive group. 4750 */ 4751 int 4752 mac_group_addvlan(mac_group_t *group, uint16_t vlan) 4753 { 4754 VERIFY3S(group->mrg_type, ==, MAC_RING_TYPE_RX); 4755 VERIFY3P(group->mrg_info.mgi_addvlan, !=, NULL); 4756 4757 if (vlan > VLAN_ID_MAX) 4758 return (EINVAL); 4759 4760 vlan = MAC_VLAN_UNTAGGED_VID(vlan); 4761 return (group->mrg_info.mgi_addvlan(group->mrg_info.mgi_driver, vlan)); 4762 } 4763 4764 /* 4765 * Dissociate the VLAN from the receive group. 4766 */ 4767 int 4768 mac_group_remvlan(mac_group_t *group, uint16_t vlan) 4769 { 4770 VERIFY3S(group->mrg_type, ==, MAC_RING_TYPE_RX); 4771 VERIFY3P(group->mrg_info.mgi_remvlan, !=, NULL); 4772 4773 if (vlan > VLAN_ID_MAX) 4774 return (EINVAL); 4775 4776 vlan = MAC_VLAN_UNTAGGED_VID(vlan); 4777 return (group->mrg_info.mgi_remvlan(group->mrg_info.mgi_driver, vlan)); 4778 } 4779 4780 /* 4781 * Associate a MAC address with a receive group. 4782 * 4783 * The return value of this function should always be checked properly, because 4784 * any type of failure could cause unexpected results. A group can be added 4785 * or removed with a MAC address only after it has been reserved. Ideally, 4786 * a successful reservation always leads to calling mac_group_addmac() to 4787 * steer desired traffic. Failure of adding an unicast MAC address doesn't 4788 * always imply that the group is functioning abnormally. 4789 * 4790 * Currently this function is called everywhere, and it reflects assumptions 4791 * about MAC addresses in the implementation. CR 6735196. 4792 */ 4793 int 4794 mac_group_addmac(mac_group_t *group, const uint8_t *addr) 4795 { 4796 VERIFY3S(group->mrg_type, ==, MAC_RING_TYPE_RX); 4797 VERIFY3P(group->mrg_info.mgi_addmac, !=, NULL); 4798 4799 return (group->mrg_info.mgi_addmac(group->mrg_info.mgi_driver, addr)); 4800 } 4801 4802 /* 4803 * Remove the association between MAC address and receive group. 4804 */ 4805 int 4806 mac_group_remmac(mac_group_t *group, const uint8_t *addr) 4807 { 4808 VERIFY3S(group->mrg_type, ==, MAC_RING_TYPE_RX); 4809 VERIFY3P(group->mrg_info.mgi_remmac, !=, NULL); 4810 4811 return (group->mrg_info.mgi_remmac(group->mrg_info.mgi_driver, addr)); 4812 } 4813 4814 /* 4815 * This is the entry point for packets transmitted through the bridge 4816 * code. If no bridge is in place, mac_ring_tx() transmits via the tx 4817 * ring. The 'rh' pointer may be NULL to select the default ring. 4818 */ 4819 mblk_t * 4820 mac_bridge_tx(mac_impl_t *mip, mac_ring_handle_t rh, mblk_t *mp) 4821 { 4822 mac_handle_t mh; 4823 4824 /* 4825 * Once we take a reference on the bridge link, the bridge 4826 * module itself can't unload, so the callback pointers are 4827 * stable. 4828 */ 4829 mutex_enter(&mip->mi_bridge_lock); 4830 if ((mh = mip->mi_bridge_link) != NULL) 4831 mac_bridge_ref_cb(mh, B_TRUE); 4832 mutex_exit(&mip->mi_bridge_lock); 4833 if (mh == NULL) { 4834 mp = mac_ring_tx((mac_handle_t)mip, rh, mp); 4835 } else { 4836 /* 4837 * The bridge may place this mblk on a provider's Tx 4838 * path, a mac's Rx path, or both. Since we don't have 4839 * enough information at this point, we can't be sure 4840 * that the destination(s) are capable of handling the 4841 * hardware offloads requested by the mblk. We emulate 4842 * them here as it is the safest choice. In the 4843 * future, if bridge performance becomes a priority, 4844 * we can elide the emulation here and leave the 4845 * choice up to bridge. 4846 * 4847 * We don't clear the DB_CKSUMFLAGS here because 4848 * HCK_IPV4_HDRCKSUM (Tx) and HCK_IPV4_HDRCKSUM_OK 4849 * (Rx) still have the same value. If the bridge 4850 * receives a packet from a HCKSUM_IPHDRCKSUM NIC then 4851 * the mac(s) it is forwarded on may calculate the 4852 * checksum again, but incorrectly (because the 4853 * checksum field is not zero). Until the 4854 * HCK_IPV4_HDRCKSUM/HCK_IPV4_HDRCKSUM_OK issue is 4855 * resovled, we leave the flag clearing in bridge 4856 * itself. 4857 */ 4858 if ((DB_CKSUMFLAGS(mp) & (HCK_TX_FLAGS | HW_LSO_FLAGS)) != 0) { 4859 mac_hw_emul(&mp, NULL, NULL, MAC_ALL_EMULS); 4860 } 4861 4862 mp = mac_bridge_tx_cb(mh, rh, mp); 4863 mac_bridge_ref_cb(mh, B_FALSE); 4864 } 4865 4866 return (mp); 4867 } 4868 4869 /* 4870 * Find a ring from its index. 4871 */ 4872 mac_ring_handle_t 4873 mac_find_ring(mac_group_handle_t gh, int index) 4874 { 4875 mac_group_t *group = (mac_group_t *)gh; 4876 mac_ring_t *ring = group->mrg_rings; 4877 4878 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) 4879 if (ring->mr_index == index) 4880 break; 4881 4882 return ((mac_ring_handle_t)ring); 4883 } 4884 /* 4885 * Add a ring to an existing group. 4886 * 4887 * The ring must be either passed directly (for example if the ring 4888 * movement is initiated by the framework), or specified through a driver 4889 * index (for example when the ring is added by the driver. 4890 * 4891 * The caller needs to call mac_perim_enter() before calling this function. 4892 */ 4893 int 4894 i_mac_group_add_ring(mac_group_t *group, mac_ring_t *ring, int index) 4895 { 4896 mac_impl_t *mip = (mac_impl_t *)group->mrg_mh; 4897 mac_capab_rings_t *cap_rings; 4898 boolean_t driver_call = (ring == NULL); 4899 mac_group_type_t group_type; 4900 int ret = 0; 4901 flow_entry_t *flent; 4902 4903 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 4904 4905 switch (group->mrg_type) { 4906 case MAC_RING_TYPE_RX: 4907 cap_rings = &mip->mi_rx_rings_cap; 4908 group_type = mip->mi_rx_group_type; 4909 break; 4910 case MAC_RING_TYPE_TX: 4911 cap_rings = &mip->mi_tx_rings_cap; 4912 group_type = mip->mi_tx_group_type; 4913 break; 4914 default: 4915 ASSERT(B_FALSE); 4916 } 4917 4918 /* 4919 * There should be no ring with the same ring index in the target 4920 * group. 4921 */ 4922 ASSERT(mac_find_ring((mac_group_handle_t)group, 4923 driver_call ? index : ring->mr_index) == NULL); 4924 4925 if (driver_call) { 4926 /* 4927 * The function is called as a result of a request from 4928 * a driver to add a ring to an existing group, for example 4929 * from the aggregation driver. Allocate a new mac_ring_t 4930 * for that ring. 4931 */ 4932 ring = mac_init_ring(mip, group, index, cap_rings); 4933 ASSERT(group->mrg_state > MAC_GROUP_STATE_UNINIT); 4934 } else { 4935 /* 4936 * The function is called as a result of a MAC layer request 4937 * to add a ring to an existing group. In this case the 4938 * ring is being moved between groups, which requires 4939 * the underlying driver to support dynamic grouping, 4940 * and the mac_ring_t already exists. 4941 */ 4942 ASSERT(group_type == MAC_GROUP_TYPE_DYNAMIC); 4943 ASSERT(group->mrg_driver == NULL || 4944 cap_rings->mr_gaddring != NULL); 4945 ASSERT(ring->mr_gh == NULL); 4946 } 4947 4948 /* 4949 * At this point the ring should not be in use, and it should be 4950 * of the right for the target group. 4951 */ 4952 ASSERT(ring->mr_state < MR_INUSE); 4953 ASSERT(ring->mr_srs == NULL); 4954 ASSERT(ring->mr_type == group->mrg_type); 4955 4956 if (!driver_call) { 4957 /* 4958 * Add the driver level hardware ring if the process was not 4959 * initiated by the driver, and the target group is not the 4960 * group. 4961 */ 4962 if (group->mrg_driver != NULL) { 4963 cap_rings->mr_gaddring(group->mrg_driver, 4964 ring->mr_driver, ring->mr_type); 4965 } 4966 4967 /* 4968 * Insert the ring ahead existing rings. 4969 */ 4970 ring->mr_next = group->mrg_rings; 4971 group->mrg_rings = ring; 4972 ring->mr_gh = (mac_group_handle_t)group; 4973 group->mrg_cur_count++; 4974 } 4975 4976 /* 4977 * If the group has not been actively used, we're done. 4978 */ 4979 if (group->mrg_index != -1 && 4980 group->mrg_state < MAC_GROUP_STATE_RESERVED) 4981 return (0); 4982 4983 /* 4984 * Start the ring if needed. Failure causes to undo the grouping action. 4985 */ 4986 if (ring->mr_state != MR_INUSE) { 4987 if ((ret = mac_start_ring(ring)) != 0) { 4988 if (!driver_call) { 4989 cap_rings->mr_gremring(group->mrg_driver, 4990 ring->mr_driver, ring->mr_type); 4991 } 4992 group->mrg_cur_count--; 4993 group->mrg_rings = ring->mr_next; 4994 4995 ring->mr_gh = NULL; 4996 4997 if (driver_call) 4998 mac_ring_free(mip, ring); 4999 5000 return (ret); 5001 } 5002 } 5003 5004 /* 5005 * Set up SRS/SR according to the ring type. 5006 */ 5007 switch (ring->mr_type) { 5008 case MAC_RING_TYPE_RX: 5009 /* 5010 * Setup an SRS on top of the new ring if the group is 5011 * reserved for someone's exclusive use. 5012 */ 5013 if (group->mrg_state == MAC_GROUP_STATE_RESERVED) { 5014 mac_client_impl_t *mcip = MAC_GROUP_ONLY_CLIENT(group); 5015 5016 VERIFY3P(mcip, !=, NULL); 5017 flent = mcip->mci_flent; 5018 VERIFY3S(flent->fe_rx_srs_cnt, >, 0); 5019 mac_rx_srs_group_setup(mcip, flent, SRST_LINK); 5020 mac_fanout_setup(mcip, flent, MCIP_RESOURCE_PROPS(mcip), 5021 mac_rx_deliver, mcip, NULL); 5022 } else { 5023 ring->mr_classify_type = MAC_SW_CLASSIFIER; 5024 } 5025 break; 5026 case MAC_RING_TYPE_TX: 5027 { 5028 mac_grp_client_t *mgcp = group->mrg_clients; 5029 mac_client_impl_t *mcip; 5030 mac_soft_ring_set_t *mac_srs; 5031 mac_srs_tx_t *tx; 5032 5033 if (MAC_GROUP_NO_CLIENT(group)) { 5034 if (ring->mr_state == MR_INUSE) 5035 mac_stop_ring(ring); 5036 ring->mr_flag = 0; 5037 break; 5038 } 5039 /* 5040 * If the rings are being moved to a group that has 5041 * clients using it, then add the new rings to the 5042 * clients SRS. 5043 */ 5044 while (mgcp != NULL) { 5045 boolean_t is_aggr; 5046 5047 mcip = mgcp->mgc_client; 5048 flent = mcip->mci_flent; 5049 is_aggr = (mcip->mci_state_flags & MCIS_IS_AGGR_CLIENT); 5050 mac_srs = MCIP_TX_SRS(mcip); 5051 tx = &mac_srs->srs_tx; 5052 mac_tx_client_quiesce((mac_client_handle_t)mcip); 5053 /* 5054 * If we are growing from 1 to multiple rings. 5055 */ 5056 if (tx->st_mode == SRS_TX_BW || 5057 tx->st_mode == SRS_TX_SERIALIZE || 5058 tx->st_mode == SRS_TX_DEFAULT) { 5059 mac_ring_t *tx_ring = tx->st_arg2; 5060 5061 tx->st_arg2 = NULL; 5062 mac_tx_srs_stat_recreate(mac_srs, B_TRUE); 5063 mac_tx_srs_add_ring(mac_srs, tx_ring); 5064 if (mac_srs->srs_type & SRST_BW_CONTROL) { 5065 tx->st_mode = is_aggr ? SRS_TX_BW_AGGR : 5066 SRS_TX_BW_FANOUT; 5067 } else { 5068 tx->st_mode = is_aggr ? SRS_TX_AGGR : 5069 SRS_TX_FANOUT; 5070 } 5071 tx->st_func = mac_tx_get_func(tx->st_mode); 5072 } 5073 mac_tx_srs_add_ring(mac_srs, ring); 5074 mac_fanout_setup(mcip, flent, MCIP_RESOURCE_PROPS(mcip), 5075 mac_rx_deliver, mcip, NULL); 5076 mac_tx_client_restart((mac_client_handle_t)mcip); 5077 mgcp = mgcp->mgc_next; 5078 } 5079 break; 5080 } 5081 default: 5082 ASSERT(B_FALSE); 5083 } 5084 /* 5085 * For aggr, the default ring will be NULL to begin with. If it 5086 * is NULL, then pick the first ring that gets added as the 5087 * default ring. Any ring in an aggregation can be removed at 5088 * any time (by the user action of removing a link) and if the 5089 * current default ring gets removed, then a new one gets 5090 * picked (see i_mac_group_rem_ring()). 5091 */ 5092 if (mip->mi_state_flags & MIS_IS_AGGR && 5093 mip->mi_default_tx_ring == NULL && 5094 ring->mr_type == MAC_RING_TYPE_TX) { 5095 mip->mi_default_tx_ring = (mac_ring_handle_t)ring; 5096 } 5097 5098 MAC_RING_UNMARK(ring, MR_INCIPIENT); 5099 return (0); 5100 } 5101 5102 static void 5103 i_mac_group_aggr_remove_tx_ring(mac_group_t *group, mac_impl_t *mip, 5104 mac_ring_t *ring) 5105 { 5106 if (mip->mi_state_flags & MIS_IS_AGGR && 5107 mip->mi_default_tx_ring == (mac_ring_handle_t)ring) { 5108 /* pick a new default Tx ring */ 5109 mac_ring_t *new_default = group->mrg_rings; 5110 5111 while (new_default == ring) 5112 new_default = new_default->mr_next; 5113 5114 /* Yes, this can be NULL. */ 5115 mip->mi_default_tx_ring = (mac_ring_handle_t)new_default; 5116 } 5117 5118 /* 5119 * If the ring-group isn't at least reserved, don't bother as there 5120 * won't be unquiesced rings. 5121 */ 5122 if (group->mrg_state < MAC_GROUP_STATE_RESERVED) 5123 return; 5124 5125 /* 5126 * The two remaining states: RESERVED and SHARED, mean we need to 5127 * alert all/any upper clients! 5128 */ 5129 for (mac_grp_client_t *mgc = group->mrg_clients; mgc != NULL; 5130 mgc = mgc->mgc_next) { 5131 mac_soft_ring_t *sringp; 5132 mac_client_impl_t *mcip; 5133 mac_soft_ring_set_t *mac_srs; 5134 mac_srs_tx_t *srs_tx; 5135 5136 mcip = mgc->mgc_client; 5137 VERIFY(mcip->mci_state_flags & MCIS_IS_AGGR_CLIENT); 5138 mac_srs = MCIP_TX_SRS(mcip); 5139 ASSERT(mac_srs->srs_tx.st_mode == SRS_TX_AGGR || 5140 mac_srs->srs_tx.st_mode == SRS_TX_BW_AGGR); 5141 srs_tx = &mac_srs->srs_tx; 5142 /* 5143 * Wakeup any callers blocked on this Tx ring due to flow 5144 * control. 5145 */ 5146 sringp = srs_tx->st_soft_rings[ring->mr_index]; 5147 VERIFY(sringp != NULL); 5148 mac_tx_client_quiesce((mac_client_handle_t)mcip); 5149 mac_tx_invoke_callbacks(mcip, (mac_tx_cookie_t)sringp); 5150 mac_tx_srs_del_ring(mac_srs, ring); 5151 mac_tx_client_restart((mac_client_handle_t)mcip); 5152 } 5153 } 5154 5155 /* 5156 * Remove a ring from it's current group. MAC internal function for dynamic 5157 * grouping. 5158 * 5159 * The caller needs to call mac_perim_enter() before calling this function. 5160 */ 5161 void 5162 i_mac_group_rem_ring(mac_group_t *group, mac_ring_t *ring, 5163 boolean_t driver_call) 5164 { 5165 mac_impl_t *mip = (mac_impl_t *)group->mrg_mh; 5166 mac_capab_rings_t *cap_rings = NULL; 5167 mac_group_type_t group_type; 5168 5169 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 5170 5171 ASSERT(mac_find_ring((mac_group_handle_t)group, 5172 ring->mr_index) == (mac_ring_handle_t)ring); 5173 ASSERT((mac_group_t *)ring->mr_gh == group); 5174 ASSERT(ring->mr_type == group->mrg_type); 5175 5176 if (ring->mr_state == MR_INUSE) 5177 mac_stop_ring(ring); 5178 switch (ring->mr_type) { 5179 case MAC_RING_TYPE_RX: 5180 group_type = mip->mi_rx_group_type; 5181 cap_rings = &mip->mi_rx_rings_cap; 5182 5183 /* 5184 * Only hardware classified packets hold a reference to the 5185 * ring all the way up the Rx path. mac_rx_srs_remove() 5186 * will take care of quiescing the Rx path and removing the 5187 * SRS. The software classified path neither holds a reference 5188 * nor any association with the ring in mac_rx. 5189 */ 5190 if (ring->mr_srs != NULL) { 5191 mac_rx_srs_remove(ring->mr_srs); 5192 ring->mr_srs = NULL; 5193 } 5194 5195 break; 5196 case MAC_RING_TYPE_TX: 5197 { 5198 mac_grp_client_t *mgcp; 5199 mac_group_t *defgrp; 5200 5201 /* 5202 * For TX this function is invoked in three cases: 5203 * 5204 * 1) In the case of a failure during the initial creation of 5205 * a group when a share is associated with a MAC client. So 5206 * the SRS is not yet setup, and will be setup later after the 5207 * group has been reserved and populated. 5208 * 5209 * 2) From mac_release_tx_group() when freeing a TX SRS. 5210 * 5211 * 3) In the case of aggr, when a port gets removed, the 5212 * pseudo Tx rings that it exposed gets removed. 5213 * 5214 * In the first two cases the SRS and its soft rings are 5215 * already quiesced, AND we are not being called by a driver 5216 * ioctl (driver_call). 5217 * 5218 * The third case is factored out to the 5219 * i_mac_group_aggr_remove_tx_ring() function above. 5220 */ 5221 if (driver_call) { 5222 i_mac_group_aggr_remove_tx_ring(group, mip, ring); 5223 break; /* Out of the MAC_RING_TYPE_TX case. */ 5224 } 5225 ASSERT(ring != (mac_ring_t *)mip->mi_default_tx_ring); 5226 group_type = mip->mi_tx_group_type; 5227 cap_rings = &mip->mi_tx_rings_cap; 5228 /* 5229 * See if we need to take it out of the MAC clients using 5230 * this group 5231 */ 5232 if (MAC_GROUP_NO_CLIENT(group)) 5233 break; 5234 mgcp = group->mrg_clients; 5235 defgrp = MAC_DEFAULT_TX_GROUP(mip); 5236 while (mgcp != NULL) { 5237 mac_client_impl_t *mcip = mgcp->mgc_client; 5238 mac_soft_ring_set_t *mac_srs = MCIP_TX_SRS(mcip); 5239 mac_srs_tx_t *srs_tx = &mac_srs->srs_tx; 5240 5241 mac_tx_client_quiesce((mac_client_handle_t)mcip); 5242 /* 5243 * If we are here when removing rings from the default 5244 * group, mac_reserve_tx_ring would have already 5245 * deleted the ring from the MAC clients in the group. 5246 */ 5247 if (group != defgrp) { 5248 mac_tx_invoke_callbacks(mcip, 5249 (mac_tx_cookie_t) 5250 mac_tx_srs_get_soft_ring(mac_srs, ring)); 5251 mac_tx_srs_del_ring(mac_srs, ring); 5252 } 5253 /* 5254 * Additionally, if we are left with only 5255 * one ring in the group after this, we need 5256 * to modify the mode etc. to. (We haven't 5257 * yet taken the ring out, so we check with 2). 5258 */ 5259 if (group->mrg_cur_count == 2) { 5260 mac_ring_t *rem_ring; 5261 uint_t ring_info = 0; 5262 5263 if (ring->mr_next == NULL) 5264 rem_ring = group->mrg_rings; 5265 else 5266 rem_ring = ring->mr_next; 5267 mac_tx_invoke_callbacks(mcip, 5268 (mac_tx_cookie_t) 5269 mac_tx_srs_get_soft_ring(mac_srs, 5270 rem_ring)); 5271 mac_tx_srs_del_ring(mac_srs, rem_ring); 5272 if (rem_ring->mr_state != MR_INUSE) { 5273 (void) mac_start_ring(rem_ring); 5274 } 5275 srs_tx->st_arg2 = (void *)rem_ring; 5276 mac_tx_srs_stat_recreate(mac_srs, B_FALSE); 5277 ring_info = mac_hwring_getinfo( 5278 (mac_ring_handle_t)rem_ring); 5279 /* 5280 * We are shrinking from multiple 5281 * to 1 ring. 5282 */ 5283 if (mac_srs->srs_type & SRST_BW_CONTROL) { 5284 srs_tx->st_mode = SRS_TX_BW; 5285 } else if (mac_tx_serialize || 5286 (ring_info & MAC_RING_TX_SERIALIZE)) { 5287 srs_tx->st_mode = SRS_TX_SERIALIZE; 5288 } else { 5289 srs_tx->st_mode = SRS_TX_DEFAULT; 5290 } 5291 srs_tx->st_func = 5292 mac_tx_get_func(srs_tx->st_mode); 5293 } 5294 mac_tx_client_restart((mac_client_handle_t)mcip); 5295 mgcp = mgcp->mgc_next; 5296 } 5297 break; 5298 } 5299 default: 5300 ASSERT(B_FALSE); 5301 } 5302 5303 /* 5304 * Remove the ring from the group. 5305 */ 5306 if (ring == group->mrg_rings) 5307 group->mrg_rings = ring->mr_next; 5308 else { 5309 mac_ring_t *pre; 5310 5311 pre = group->mrg_rings; 5312 while (pre->mr_next != ring) 5313 pre = pre->mr_next; 5314 pre->mr_next = ring->mr_next; 5315 } 5316 group->mrg_cur_count--; 5317 5318 if (!driver_call) { 5319 ASSERT(group_type == MAC_GROUP_TYPE_DYNAMIC); 5320 ASSERT(group->mrg_driver == NULL || 5321 cap_rings->mr_gremring != NULL); 5322 5323 /* 5324 * Remove the driver level hardware ring. 5325 */ 5326 if (group->mrg_driver != NULL) { 5327 cap_rings->mr_gremring(group->mrg_driver, 5328 ring->mr_driver, ring->mr_type); 5329 } 5330 } 5331 5332 ring->mr_gh = NULL; 5333 if (driver_call) 5334 mac_ring_free(mip, ring); 5335 else 5336 ring->mr_flag = 0; 5337 } 5338 5339 /* 5340 * Move a ring to the target group. If needed, remove the ring from the group 5341 * that it currently belongs to. 5342 * 5343 * The caller need to enter MAC's perimeter by calling mac_perim_enter(). 5344 */ 5345 static int 5346 mac_group_mov_ring(mac_impl_t *mip, mac_group_t *d_group, mac_ring_t *ring) 5347 { 5348 mac_group_t *s_group = (mac_group_t *)ring->mr_gh; 5349 int rv; 5350 5351 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 5352 ASSERT(d_group != NULL); 5353 ASSERT(s_group == NULL || s_group->mrg_mh == d_group->mrg_mh); 5354 5355 if (s_group == d_group) 5356 return (0); 5357 5358 /* 5359 * Remove it from current group first. 5360 */ 5361 if (s_group != NULL) 5362 i_mac_group_rem_ring(s_group, ring, B_FALSE); 5363 5364 /* 5365 * Add it to the new group. 5366 */ 5367 rv = i_mac_group_add_ring(d_group, ring, 0); 5368 if (rv != 0) { 5369 /* 5370 * Failed to add ring back to source group. If 5371 * that fails, the ring is stuck in limbo, log message. 5372 */ 5373 if (i_mac_group_add_ring(s_group, ring, 0)) { 5374 cmn_err(CE_WARN, "%s: failed to move ring %p\n", 5375 mip->mi_name, (void *)ring); 5376 } 5377 } 5378 5379 return (rv); 5380 } 5381 5382 /* 5383 * Find a MAC address according to its value. 5384 */ 5385 mac_address_t * 5386 mac_find_macaddr(mac_impl_t *mip, uint8_t *mac_addr) 5387 { 5388 mac_address_t *map; 5389 5390 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 5391 5392 for (map = mip->mi_addresses; map != NULL; map = map->ma_next) { 5393 if (bcmp(mac_addr, map->ma_addr, map->ma_len) == 0) 5394 break; 5395 } 5396 5397 return (map); 5398 } 5399 5400 /* 5401 * Check whether the MAC address is shared by multiple clients. 5402 */ 5403 boolean_t 5404 mac_check_macaddr_shared(mac_address_t *map) 5405 { 5406 ASSERT(MAC_PERIM_HELD((mac_handle_t)map->ma_mip)); 5407 5408 return (map->ma_nusers > 1); 5409 } 5410 5411 /* 5412 * Remove the specified MAC address from the MAC address list and free it. 5413 */ 5414 static void 5415 mac_free_macaddr(mac_address_t *map) 5416 { 5417 mac_impl_t *mip = map->ma_mip; 5418 5419 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 5420 VERIFY3P(mip->mi_addresses, !=, NULL); 5421 5422 VERIFY3P(map, ==, mac_find_macaddr(mip, map->ma_addr)); 5423 VERIFY3P(map, !=, NULL); 5424 VERIFY3S(map->ma_nusers, ==, 0); 5425 VERIFY3P(map->ma_vlans, ==, NULL); 5426 5427 if (map == mip->mi_addresses) { 5428 mip->mi_addresses = map->ma_next; 5429 } else { 5430 mac_address_t *pre; 5431 5432 pre = mip->mi_addresses; 5433 while (pre->ma_next != map) 5434 pre = pre->ma_next; 5435 pre->ma_next = map->ma_next; 5436 } 5437 5438 kmem_free(map, sizeof (mac_address_t)); 5439 } 5440 5441 static mac_vlan_t * 5442 mac_find_vlan(mac_address_t *map, uint16_t vid) 5443 { 5444 mac_vlan_t *mvp; 5445 5446 for (mvp = map->ma_vlans; mvp != NULL; mvp = mvp->mv_next) { 5447 if (mvp->mv_vid == vid) 5448 return (mvp); 5449 } 5450 5451 return (NULL); 5452 } 5453 5454 static mac_vlan_t * 5455 mac_add_vlan(mac_address_t *map, uint16_t vid) 5456 { 5457 mac_vlan_t *mvp; 5458 5459 /* 5460 * We should never add the same {addr, VID} tuple more 5461 * than once, but let's be sure. 5462 */ 5463 for (mvp = map->ma_vlans; mvp != NULL; mvp = mvp->mv_next) 5464 VERIFY3U(mvp->mv_vid, !=, vid); 5465 5466 /* Add the VLAN to the head of the VLAN list. */ 5467 mvp = kmem_zalloc(sizeof (mac_vlan_t), KM_SLEEP); 5468 mvp->mv_vid = vid; 5469 mvp->mv_next = map->ma_vlans; 5470 map->ma_vlans = mvp; 5471 5472 return (mvp); 5473 } 5474 5475 static void 5476 mac_rem_vlan(mac_address_t *map, mac_vlan_t *mvp) 5477 { 5478 mac_vlan_t *pre; 5479 5480 if (map->ma_vlans == mvp) { 5481 map->ma_vlans = mvp->mv_next; 5482 } else { 5483 pre = map->ma_vlans; 5484 while (pre->mv_next != mvp) { 5485 pre = pre->mv_next; 5486 5487 /* 5488 * We've reached the end of the list without 5489 * finding mvp. 5490 */ 5491 VERIFY3P(pre, !=, NULL); 5492 } 5493 pre->mv_next = mvp->mv_next; 5494 } 5495 5496 kmem_free(mvp, sizeof (mac_vlan_t)); 5497 } 5498 5499 /* 5500 * Create a new mac_address_t if this is the first use of the address 5501 * or add a VID to an existing address. In either case, the 5502 * mac_address_t acts as a list of {addr, VID} tuples where each tuple 5503 * shares the same addr. If group is non-NULL then attempt to program 5504 * the MAC's HW filters for this group. Otherwise, if group is NULL, 5505 * then the MAC has no rings and there is nothing to program. 5506 */ 5507 int 5508 mac_add_macaddr_vlan(mac_impl_t *mip, mac_group_t *group, uint8_t *addr, 5509 uint16_t vid, boolean_t use_hw) 5510 { 5511 mac_address_t *map; 5512 mac_vlan_t *mvp; 5513 int err = 0; 5514 boolean_t allocated_map = B_FALSE; 5515 boolean_t hw_mac = B_FALSE; 5516 boolean_t hw_vlan = B_FALSE; 5517 5518 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 5519 5520 map = mac_find_macaddr(mip, addr); 5521 5522 /* 5523 * If this is the first use of this MAC address then allocate 5524 * and initialize a new structure. 5525 */ 5526 if (map == NULL) { 5527 map = kmem_zalloc(sizeof (mac_address_t), KM_SLEEP); 5528 map->ma_len = mip->mi_type->mt_addr_length; 5529 bcopy(addr, map->ma_addr, map->ma_len); 5530 map->ma_nusers = 0; 5531 map->ma_group = group; 5532 map->ma_mip = mip; 5533 map->ma_untagged = B_FALSE; 5534 5535 /* Add the new MAC address to the head of the address list. */ 5536 map->ma_next = mip->mi_addresses; 5537 mip->mi_addresses = map; 5538 5539 allocated_map = B_TRUE; 5540 } 5541 5542 VERIFY(map->ma_group == NULL || map->ma_group == group); 5543 if (map->ma_group == NULL) 5544 map->ma_group = group; 5545 5546 if (vid == VLAN_ID_NONE) { 5547 map->ma_untagged = B_TRUE; 5548 mvp = NULL; 5549 } else { 5550 mvp = mac_add_vlan(map, vid); 5551 } 5552 5553 /* 5554 * Set the VLAN HW filter if: 5555 * 5556 * o the MAC's VLAN HW filtering is enabled, and 5557 * o the address does not currently rely on promisc mode. 5558 * 5559 * This is called even when the client specifies an untagged 5560 * address (VLAN_ID_NONE) because some MAC providers require 5561 * setting additional bits to accept untagged traffic when 5562 * VLAN HW filtering is enabled. 5563 */ 5564 if (MAC_GROUP_HW_VLAN(group) && 5565 map->ma_type != MAC_ADDRESS_TYPE_UNICAST_PROMISC) { 5566 if ((err = mac_group_addvlan(group, vid)) != 0) 5567 goto bail; 5568 5569 hw_vlan = B_TRUE; 5570 } 5571 5572 VERIFY3S(map->ma_nusers, >=, 0); 5573 map->ma_nusers++; 5574 5575 /* 5576 * If this MAC address already has a HW filter then simply 5577 * increment the counter. 5578 */ 5579 if (map->ma_nusers > 1) 5580 return (0); 5581 5582 /* 5583 * All logic from here on out is executed during initial 5584 * creation only. 5585 */ 5586 VERIFY3S(map->ma_nusers, ==, 1); 5587 5588 /* 5589 * Activate this MAC address by adding it to the reserved group. 5590 */ 5591 if (group != NULL) { 5592 err = mac_group_addmac(group, (const uint8_t *)addr); 5593 5594 /* 5595 * If the driver is out of filters then we can 5596 * continue and use promisc mode. For any other error, 5597 * assume the driver is in a state where we can't 5598 * program the filters or use promisc mode; so we must 5599 * bail. 5600 */ 5601 if (err != 0 && err != ENOSPC) { 5602 map->ma_nusers--; 5603 goto bail; 5604 } 5605 5606 hw_mac = (err == 0); 5607 } 5608 5609 if (hw_mac) { 5610 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED; 5611 return (0); 5612 } 5613 5614 /* 5615 * The MAC address addition failed. If the client requires a 5616 * hardware classified MAC address, fail the operation. This 5617 * feature is only used by sun4v vsw. 5618 */ 5619 if (use_hw && !hw_mac) { 5620 err = ENOSPC; 5621 map->ma_nusers--; 5622 goto bail; 5623 } 5624 5625 /* 5626 * If we reach this point then either the MAC doesn't have 5627 * RINGS capability or we are out of MAC address HW filters. 5628 * In any case we must put the MAC into promiscuous mode. 5629 */ 5630 VERIFY(group == NULL || !hw_mac); 5631 5632 /* 5633 * The one exception is the primary address. A non-RINGS 5634 * driver filters the primary address by default; promisc mode 5635 * is not needed. 5636 */ 5637 if ((group == NULL) && 5638 (bcmp(map->ma_addr, mip->mi_addr, map->ma_len) == 0)) { 5639 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED; 5640 return (0); 5641 } 5642 5643 /* 5644 * Enable promiscuous mode in order to receive traffic to the 5645 * new MAC address. All existing HW filters still send their 5646 * traffic to their respective group/SRSes. But with promisc 5647 * enabled all unknown traffic is delivered to the default 5648 * group where it is SW classified via mac_rx_classify(). 5649 */ 5650 if ((err = i_mac_promisc_set(mip, B_TRUE)) == 0) { 5651 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_PROMISC; 5652 return (0); 5653 } 5654 5655 /* 5656 * We failed to set promisc mode and we are about to free 'map'. 5657 */ 5658 map->ma_nusers = 0; 5659 5660 bail: 5661 if (hw_vlan) { 5662 int err2 = mac_group_remvlan(group, vid); 5663 5664 if (err2 != 0) { 5665 cmn_err(CE_WARN, "Failed to remove VLAN %u from group" 5666 " %d on MAC %s: %d.", vid, group->mrg_index, 5667 mip->mi_name, err2); 5668 } 5669 } 5670 5671 if (mvp != NULL) 5672 mac_rem_vlan(map, mvp); 5673 5674 if (allocated_map) 5675 mac_free_macaddr(map); 5676 5677 return (err); 5678 } 5679 5680 int 5681 mac_remove_macaddr_vlan(mac_address_t *map, uint16_t vid) 5682 { 5683 mac_vlan_t *mvp; 5684 mac_impl_t *mip = map->ma_mip; 5685 mac_group_t *group = map->ma_group; 5686 int err = 0; 5687 5688 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 5689 VERIFY3P(map, ==, mac_find_macaddr(mip, map->ma_addr)); 5690 5691 if (vid == VLAN_ID_NONE) { 5692 map->ma_untagged = B_FALSE; 5693 mvp = NULL; 5694 } else { 5695 mvp = mac_find_vlan(map, vid); 5696 VERIFY3P(mvp, !=, NULL); 5697 } 5698 5699 if (MAC_GROUP_HW_VLAN(group) && 5700 map->ma_type == MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED && 5701 ((err = mac_group_remvlan(group, vid)) != 0)) 5702 return (err); 5703 5704 if (mvp != NULL) 5705 mac_rem_vlan(map, mvp); 5706 5707 /* 5708 * If it's not the last client using this MAC address, only update 5709 * the MAC clients count. 5710 */ 5711 map->ma_nusers--; 5712 if (map->ma_nusers > 0) 5713 return (0); 5714 5715 VERIFY3S(map->ma_nusers, ==, 0); 5716 5717 /* 5718 * The MAC address is no longer used by any MAC client, so 5719 * remove it from its associated group. Turn off promiscuous 5720 * mode if this is the last address relying on it. 5721 */ 5722 switch (map->ma_type) { 5723 case MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED: 5724 /* 5725 * Don't free the preset primary address for drivers that 5726 * don't advertise RINGS capability. 5727 */ 5728 if (group == NULL) 5729 return (0); 5730 5731 if ((err = mac_group_remmac(group, map->ma_addr)) != 0) { 5732 if (vid == VLAN_ID_NONE) 5733 map->ma_untagged = B_TRUE; 5734 else 5735 (void) mac_add_vlan(map, vid); 5736 5737 /* 5738 * If we fail to remove the MAC address HW 5739 * filter but then also fail to re-add the 5740 * VLAN HW filter then we are in a busted 5741 * state. We do our best by logging a warning 5742 * and returning the original 'err' that got 5743 * us here. At this point, traffic for this 5744 * address + VLAN combination will be dropped 5745 * until the user reboots the system. In the 5746 * future, it would be nice to have a system 5747 * that can compare the state of expected 5748 * classification according to mac to the 5749 * actual state of the provider, and report 5750 * and fix any inconsistencies. 5751 */ 5752 if (MAC_GROUP_HW_VLAN(group)) { 5753 int err2; 5754 5755 err2 = mac_group_addvlan(group, vid); 5756 if (err2 != 0) { 5757 cmn_err(CE_WARN, "Failed to readd VLAN" 5758 " %u to group %d on MAC %s: %d.", 5759 vid, group->mrg_index, mip->mi_name, 5760 err2); 5761 } 5762 } 5763 5764 map->ma_nusers = 1; 5765 return (err); 5766 } 5767 5768 map->ma_group = NULL; 5769 break; 5770 case MAC_ADDRESS_TYPE_UNICAST_PROMISC: 5771 err = i_mac_promisc_set(mip, B_FALSE); 5772 break; 5773 default: 5774 panic("Unexpected ma_type 0x%x, file: %s, line %d", 5775 map->ma_type, __FILE__, __LINE__); 5776 } 5777 5778 if (err != 0) { 5779 map->ma_nusers = 1; 5780 return (err); 5781 } 5782 5783 /* 5784 * We created MAC address for the primary one at registration, so we 5785 * won't free it here. mac_fini_macaddr() will take care of it. 5786 */ 5787 if (bcmp(map->ma_addr, mip->mi_addr, map->ma_len) != 0) 5788 mac_free_macaddr(map); 5789 5790 return (0); 5791 } 5792 5793 /* 5794 * Update an existing MAC address. The caller need to make sure that the new 5795 * value has not been used. 5796 */ 5797 int 5798 mac_update_macaddr(mac_address_t *map, uint8_t *mac_addr) 5799 { 5800 mac_impl_t *mip = map->ma_mip; 5801 int err = 0; 5802 5803 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 5804 ASSERT(mac_find_macaddr(mip, mac_addr) == NULL); 5805 5806 switch (map->ma_type) { 5807 case MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED: 5808 /* 5809 * Update the primary address for drivers that are not 5810 * RINGS capable. 5811 */ 5812 if (mip->mi_rx_groups == NULL) { 5813 err = mip->mi_unicst(mip->mi_driver, (const uint8_t *) 5814 mac_addr); 5815 if (err != 0) 5816 return (err); 5817 break; 5818 } 5819 5820 /* 5821 * If this MAC address is not currently in use, 5822 * simply break out and update the value. 5823 */ 5824 if (map->ma_nusers == 0) 5825 break; 5826 5827 /* 5828 * Need to replace the MAC address associated with a group. 5829 */ 5830 err = mac_group_remmac(map->ma_group, map->ma_addr); 5831 if (err != 0) 5832 return (err); 5833 5834 err = mac_group_addmac(map->ma_group, mac_addr); 5835 5836 /* 5837 * Failure hints hardware error. The MAC layer needs to 5838 * have error notification facility to handle this. 5839 * Now, simply try to restore the value. 5840 */ 5841 if (err != 0) 5842 (void) mac_group_addmac(map->ma_group, map->ma_addr); 5843 5844 break; 5845 case MAC_ADDRESS_TYPE_UNICAST_PROMISC: 5846 /* 5847 * Need to do nothing more if in promiscuous mode. 5848 */ 5849 break; 5850 default: 5851 ASSERT(B_FALSE); 5852 } 5853 5854 /* 5855 * Successfully replaced the MAC address. 5856 */ 5857 if (err == 0) 5858 bcopy(mac_addr, map->ma_addr, map->ma_len); 5859 5860 return (err); 5861 } 5862 5863 /* 5864 * Freshen the MAC address with new value. Its caller must have updated the 5865 * hardware MAC address before calling this function. 5866 * This funcitons is supposed to be used to handle the MAC address change 5867 * notification from underlying drivers. 5868 */ 5869 void 5870 mac_freshen_macaddr(mac_address_t *map, uint8_t *mac_addr) 5871 { 5872 mac_impl_t *mip = map->ma_mip; 5873 5874 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 5875 ASSERT(mac_find_macaddr(mip, mac_addr) == NULL); 5876 5877 /* 5878 * Freshen the MAC address with new value. 5879 */ 5880 bcopy(mac_addr, map->ma_addr, map->ma_len); 5881 bcopy(mac_addr, mip->mi_addr, map->ma_len); 5882 5883 /* 5884 * Update all MAC clients that share this MAC address. 5885 */ 5886 mac_unicast_update_clients(mip, map); 5887 } 5888 5889 /* 5890 * Set up the primary MAC address. 5891 */ 5892 void 5893 mac_init_macaddr(mac_impl_t *mip) 5894 { 5895 mac_address_t *map; 5896 5897 /* 5898 * The reference count is initialized to zero, until it's really 5899 * activated. 5900 */ 5901 map = kmem_zalloc(sizeof (mac_address_t), KM_SLEEP); 5902 map->ma_len = mip->mi_type->mt_addr_length; 5903 bcopy(mip->mi_addr, map->ma_addr, map->ma_len); 5904 5905 /* 5906 * If driver advertises RINGS capability, it shouldn't have initialized 5907 * its primary MAC address. For other drivers, including VNIC, the 5908 * primary address must work after registration. 5909 */ 5910 if (mip->mi_rx_groups == NULL) 5911 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED; 5912 5913 map->ma_mip = mip; 5914 5915 mip->mi_addresses = map; 5916 } 5917 5918 /* 5919 * Clean up the primary MAC address. Note, only one primary MAC address 5920 * is allowed. All other MAC addresses must have been freed appropriately. 5921 */ 5922 void 5923 mac_fini_macaddr(mac_impl_t *mip) 5924 { 5925 mac_address_t *map = mip->mi_addresses; 5926 5927 if (map == NULL) 5928 return; 5929 5930 /* 5931 * If mi_addresses is initialized, there should be exactly one 5932 * entry left on the list with no users. 5933 */ 5934 VERIFY3S(map->ma_nusers, ==, 0); 5935 VERIFY3P(map->ma_next, ==, NULL); 5936 VERIFY3P(map->ma_vlans, ==, NULL); 5937 5938 kmem_free(map, sizeof (mac_address_t)); 5939 mip->mi_addresses = NULL; 5940 } 5941 5942 /* 5943 * Logging related functions. 5944 * 5945 * Note that Kernel statistics have been extended to maintain fine 5946 * granularity of statistics viz. hardware lane, software lane, fanout 5947 * stats etc. However, extended accounting continues to support only 5948 * aggregate statistics like before. 5949 */ 5950 5951 /* Write the flow description to a netinfo_t record */ 5952 static netinfo_t * 5953 mac_write_flow_desc(flow_entry_t *flent, mac_client_impl_t *mcip) 5954 { 5955 netinfo_t *ninfo; 5956 net_desc_t *ndesc; 5957 flow_desc_t *fdesc; 5958 mac_resource_props_t *mrp; 5959 5960 ninfo = kmem_zalloc(sizeof (netinfo_t), KM_NOSLEEP); 5961 if (ninfo == NULL) 5962 return (NULL); 5963 ndesc = kmem_zalloc(sizeof (net_desc_t), KM_NOSLEEP); 5964 if (ndesc == NULL) { 5965 kmem_free(ninfo, sizeof (netinfo_t)); 5966 return (NULL); 5967 } 5968 5969 /* 5970 * Grab the fe_lock to see a self-consistent fe_flow_desc. 5971 * Updates to the fe_flow_desc are done under the fe_lock 5972 */ 5973 mutex_enter(&flent->fe_lock); 5974 fdesc = &flent->fe_flow_desc; 5975 mrp = &flent->fe_resource_props; 5976 5977 ndesc->nd_name = flent->fe_flow_name; 5978 ndesc->nd_devname = mcip->mci_name; 5979 bcopy(fdesc->fd_src_mac, ndesc->nd_ehost, ETHERADDRL); 5980 bcopy(fdesc->fd_dst_mac, ndesc->nd_edest, ETHERADDRL); 5981 ndesc->nd_sap = htonl(fdesc->fd_sap); 5982 ndesc->nd_isv4 = (uint8_t)fdesc->fd_ipversion == IPV4_VERSION; 5983 ndesc->nd_bw_limit = mrp->mrp_maxbw; 5984 if (ndesc->nd_isv4) { 5985 ndesc->nd_saddr[3] = htonl(fdesc->fd_local_addr.s6_addr32[3]); 5986 ndesc->nd_daddr[3] = htonl(fdesc->fd_remote_addr.s6_addr32[3]); 5987 } else { 5988 bcopy(&fdesc->fd_local_addr, ndesc->nd_saddr, IPV6_ADDR_LEN); 5989 bcopy(&fdesc->fd_remote_addr, ndesc->nd_daddr, IPV6_ADDR_LEN); 5990 } 5991 ndesc->nd_sport = htons(fdesc->fd_local_port); 5992 ndesc->nd_dport = htons(fdesc->fd_remote_port); 5993 ndesc->nd_protocol = (uint8_t)fdesc->fd_protocol; 5994 mutex_exit(&flent->fe_lock); 5995 5996 ninfo->ni_record = ndesc; 5997 ninfo->ni_size = sizeof (net_desc_t); 5998 ninfo->ni_type = EX_NET_FLDESC_REC; 5999 6000 return (ninfo); 6001 } 6002 6003 /* Write the flow statistics to a netinfo_t record */ 6004 static netinfo_t * 6005 mac_write_flow_stats(flow_entry_t *flent) 6006 { 6007 netinfo_t *ninfo; 6008 net_stat_t *nstat; 6009 mac_soft_ring_set_t *mac_srs; 6010 mac_rx_stats_t *mac_rx_stat; 6011 mac_tx_stats_t *mac_tx_stat; 6012 int i; 6013 6014 ninfo = kmem_zalloc(sizeof (netinfo_t), KM_NOSLEEP); 6015 if (ninfo == NULL) 6016 return (NULL); 6017 nstat = kmem_zalloc(sizeof (net_stat_t), KM_NOSLEEP); 6018 if (nstat == NULL) { 6019 kmem_free(ninfo, sizeof (netinfo_t)); 6020 return (NULL); 6021 } 6022 6023 nstat->ns_name = flent->fe_flow_name; 6024 for (i = 0; i < flent->fe_rx_srs_cnt; i++) { 6025 mac_srs = (mac_soft_ring_set_t *)flent->fe_rx_srs[i]; 6026 mac_rx_stat = &mac_srs->srs_rx.sr_stat; 6027 6028 nstat->ns_ibytes += mac_rx_stat->mrs_intrbytes + 6029 mac_rx_stat->mrs_pollbytes + mac_rx_stat->mrs_lclbytes; 6030 nstat->ns_ipackets += mac_rx_stat->mrs_intrcnt + 6031 mac_rx_stat->mrs_pollcnt + mac_rx_stat->mrs_lclcnt; 6032 nstat->ns_oerrors += mac_rx_stat->mrs_ierrors; 6033 } 6034 6035 mac_srs = (mac_soft_ring_set_t *)(flent->fe_tx_srs); 6036 if (mac_srs != NULL) { 6037 mac_tx_stat = &mac_srs->srs_tx.st_stat; 6038 6039 nstat->ns_obytes = mac_tx_stat->mts_obytes; 6040 nstat->ns_opackets = mac_tx_stat->mts_opackets; 6041 nstat->ns_oerrors = mac_tx_stat->mts_oerrors; 6042 } 6043 6044 ninfo->ni_record = nstat; 6045 ninfo->ni_size = sizeof (net_stat_t); 6046 ninfo->ni_type = EX_NET_FLSTAT_REC; 6047 6048 return (ninfo); 6049 } 6050 6051 /* Write the link description to a netinfo_t record */ 6052 static netinfo_t * 6053 mac_write_link_desc(mac_client_impl_t *mcip) 6054 { 6055 netinfo_t *ninfo; 6056 net_desc_t *ndesc; 6057 flow_entry_t *flent = mcip->mci_flent; 6058 6059 ninfo = kmem_zalloc(sizeof (netinfo_t), KM_NOSLEEP); 6060 if (ninfo == NULL) 6061 return (NULL); 6062 ndesc = kmem_zalloc(sizeof (net_desc_t), KM_NOSLEEP); 6063 if (ndesc == NULL) { 6064 kmem_free(ninfo, sizeof (netinfo_t)); 6065 return (NULL); 6066 } 6067 6068 ndesc->nd_name = mcip->mci_name; 6069 ndesc->nd_devname = mcip->mci_name; 6070 ndesc->nd_isv4 = B_TRUE; 6071 /* 6072 * Grab the fe_lock to see a self-consistent fe_flow_desc. 6073 * Updates to the fe_flow_desc are done under the fe_lock 6074 * after removing the flent from the flow table. 6075 */ 6076 mutex_enter(&flent->fe_lock); 6077 bcopy(flent->fe_flow_desc.fd_src_mac, ndesc->nd_ehost, ETHERADDRL); 6078 mutex_exit(&flent->fe_lock); 6079 6080 ninfo->ni_record = ndesc; 6081 ninfo->ni_size = sizeof (net_desc_t); 6082 ninfo->ni_type = EX_NET_LNDESC_REC; 6083 6084 return (ninfo); 6085 } 6086 6087 /* Write the link statistics to a netinfo_t record */ 6088 static netinfo_t * 6089 mac_write_link_stats(mac_client_impl_t *mcip) 6090 { 6091 netinfo_t *ninfo; 6092 net_stat_t *nstat; 6093 flow_entry_t *flent; 6094 mac_soft_ring_set_t *mac_srs; 6095 mac_rx_stats_t *mac_rx_stat; 6096 mac_tx_stats_t *mac_tx_stat; 6097 int i; 6098 6099 ninfo = kmem_zalloc(sizeof (netinfo_t), KM_NOSLEEP); 6100 if (ninfo == NULL) 6101 return (NULL); 6102 nstat = kmem_zalloc(sizeof (net_stat_t), KM_NOSLEEP); 6103 if (nstat == NULL) { 6104 kmem_free(ninfo, sizeof (netinfo_t)); 6105 return (NULL); 6106 } 6107 6108 nstat->ns_name = mcip->mci_name; 6109 flent = mcip->mci_flent; 6110 if (flent != NULL) { 6111 for (i = 0; i < flent->fe_rx_srs_cnt; i++) { 6112 mac_srs = (mac_soft_ring_set_t *)flent->fe_rx_srs[i]; 6113 mac_rx_stat = &mac_srs->srs_rx.sr_stat; 6114 6115 nstat->ns_ibytes += mac_rx_stat->mrs_intrbytes + 6116 mac_rx_stat->mrs_pollbytes + 6117 mac_rx_stat->mrs_lclbytes; 6118 nstat->ns_ipackets += mac_rx_stat->mrs_intrcnt + 6119 mac_rx_stat->mrs_pollcnt + mac_rx_stat->mrs_lclcnt; 6120 nstat->ns_oerrors += mac_rx_stat->mrs_ierrors; 6121 } 6122 } 6123 6124 mac_srs = (mac_soft_ring_set_t *)(mcip->mci_flent->fe_tx_srs); 6125 if (mac_srs != NULL) { 6126 mac_tx_stat = &mac_srs->srs_tx.st_stat; 6127 6128 nstat->ns_obytes = mac_tx_stat->mts_obytes; 6129 nstat->ns_opackets = mac_tx_stat->mts_opackets; 6130 nstat->ns_oerrors = mac_tx_stat->mts_oerrors; 6131 } 6132 6133 ninfo->ni_record = nstat; 6134 ninfo->ni_size = sizeof (net_stat_t); 6135 ninfo->ni_type = EX_NET_LNSTAT_REC; 6136 6137 return (ninfo); 6138 } 6139 6140 typedef struct i_mac_log_state_s { 6141 boolean_t mi_last; 6142 int mi_fenable; 6143 int mi_lenable; 6144 list_t *mi_list; 6145 } i_mac_log_state_t; 6146 6147 /* 6148 * For a given flow, if the description has not been logged before, do it now. 6149 * If it is a VNIC, then we have collected information about it from the MAC 6150 * table, so skip it. 6151 * 6152 * Called through mac_flow_walk_nolock() 6153 * 6154 * Return 0 if successful. 6155 */ 6156 static int 6157 mac_log_flowinfo(flow_entry_t *flent, void *arg) 6158 { 6159 mac_client_impl_t *mcip = flent->fe_mcip; 6160 i_mac_log_state_t *lstate = arg; 6161 netinfo_t *ninfo; 6162 6163 if (mcip == NULL) 6164 return (0); 6165 6166 /* 6167 * If the name starts with "vnic", and fe_user_generated is true (to 6168 * exclude the mcast and active flow entries created implicitly for 6169 * a vnic, it is a VNIC flow. i.e. vnic1 is a vnic flow, 6170 * vnic/bge1/mcast1 is not and neither is vnic/bge1/active. 6171 */ 6172 if (strncasecmp(flent->fe_flow_name, "vnic", 4) == 0 && 6173 (flent->fe_type & FLOW_USER) != 0) { 6174 return (0); 6175 } 6176 6177 if (!flent->fe_desc_logged) { 6178 /* 6179 * We don't return error because we want to continue the 6180 * walk in case this is the last walk which means we 6181 * need to reset fe_desc_logged in all the flows. 6182 */ 6183 if ((ninfo = mac_write_flow_desc(flent, mcip)) == NULL) 6184 return (0); 6185 list_insert_tail(lstate->mi_list, ninfo); 6186 flent->fe_desc_logged = B_TRUE; 6187 } 6188 6189 /* 6190 * Regardless of the error, we want to proceed in case we have to 6191 * reset fe_desc_logged. 6192 */ 6193 ninfo = mac_write_flow_stats(flent); 6194 if (ninfo == NULL) 6195 return (-1); 6196 6197 list_insert_tail(lstate->mi_list, ninfo); 6198 6199 if (mcip != NULL && !(mcip->mci_state_flags & MCIS_DESC_LOGGED)) 6200 flent->fe_desc_logged = B_FALSE; 6201 6202 return (0); 6203 } 6204 6205 /* 6206 * Log the description for each mac client of this mac_impl_t, if it 6207 * hasn't already been done. Additionally, log statistics for the link as 6208 * well. Walk the flow table and log information for each flow as well. 6209 * If it is the last walk (mci_last), then we turn off mci_desc_logged (and 6210 * also fe_desc_logged, if flow logging is on) since we want to log the 6211 * description if and when logging is restarted. 6212 * 6213 * Return 0 upon success or -1 upon failure 6214 */ 6215 static int 6216 i_mac_impl_log(mac_impl_t *mip, i_mac_log_state_t *lstate) 6217 { 6218 mac_client_impl_t *mcip; 6219 netinfo_t *ninfo; 6220 6221 i_mac_perim_enter(mip); 6222 /* 6223 * Only walk the client list for NIC and etherstub 6224 */ 6225 if ((mip->mi_state_flags & MIS_DISABLED) || 6226 ((mip->mi_state_flags & MIS_IS_VNIC) && 6227 (mac_get_lower_mac_handle((mac_handle_t)mip) != NULL))) { 6228 i_mac_perim_exit(mip); 6229 return (0); 6230 } 6231 6232 for (mcip = mip->mi_clients_list; mcip != NULL; 6233 mcip = mcip->mci_client_next) { 6234 if (!MCIP_DATAPATH_SETUP(mcip)) 6235 continue; 6236 if (lstate->mi_lenable) { 6237 if (!(mcip->mci_state_flags & MCIS_DESC_LOGGED)) { 6238 ninfo = mac_write_link_desc(mcip); 6239 if (ninfo == NULL) { 6240 /* 6241 * We can't terminate it if this is the last 6242 * walk, else there might be some links with 6243 * mi_desc_logged set to true, which means 6244 * their description won't be logged the next 6245 * time logging is started (similarly for the 6246 * flows within such links). We can continue 6247 * without walking the flow table (i.e. to 6248 * set fe_desc_logged to false) because we 6249 * won't have written any flow stuff for this 6250 * link as we haven't logged the link itself. 6251 */ 6252 i_mac_perim_exit(mip); 6253 if (lstate->mi_last) 6254 return (0); 6255 else 6256 return (-1); 6257 } 6258 mcip->mci_state_flags |= MCIS_DESC_LOGGED; 6259 list_insert_tail(lstate->mi_list, ninfo); 6260 } 6261 } 6262 6263 ninfo = mac_write_link_stats(mcip); 6264 if (ninfo == NULL && !lstate->mi_last) { 6265 i_mac_perim_exit(mip); 6266 return (-1); 6267 } 6268 list_insert_tail(lstate->mi_list, ninfo); 6269 6270 if (lstate->mi_last) 6271 mcip->mci_state_flags &= ~MCIS_DESC_LOGGED; 6272 6273 if (lstate->mi_fenable) { 6274 if (mcip->mci_subflow_tab != NULL) { 6275 (void) mac_flow_walk_nolock( 6276 mcip->mci_subflow_tab, mac_log_flowinfo, 6277 lstate); 6278 } 6279 } 6280 } 6281 i_mac_perim_exit(mip); 6282 return (0); 6283 } 6284 6285 /* 6286 * modhash walker function to add a mac_impl_t to a list 6287 */ 6288 /*ARGSUSED*/ 6289 static uint_t 6290 i_mac_impl_list_walker(mod_hash_key_t key, mod_hash_val_t *val, void *arg) 6291 { 6292 list_t *list = (list_t *)arg; 6293 mac_impl_t *mip = (mac_impl_t *)val; 6294 6295 if ((mip->mi_state_flags & MIS_DISABLED) == 0) { 6296 list_insert_tail(list, mip); 6297 mip->mi_ref++; 6298 } 6299 6300 return (MH_WALK_CONTINUE); 6301 } 6302 6303 void 6304 i_mac_log_info(list_t *net_log_list, i_mac_log_state_t *lstate) 6305 { 6306 list_t mac_impl_list; 6307 mac_impl_t *mip; 6308 netinfo_t *ninfo; 6309 6310 /* Create list of mac_impls */ 6311 ASSERT(RW_LOCK_HELD(&i_mac_impl_lock)); 6312 list_create(&mac_impl_list, sizeof (mac_impl_t), offsetof(mac_impl_t, 6313 mi_node)); 6314 mod_hash_walk(i_mac_impl_hash, i_mac_impl_list_walker, &mac_impl_list); 6315 rw_exit(&i_mac_impl_lock); 6316 6317 /* Create log entries for each mac_impl */ 6318 for (mip = list_head(&mac_impl_list); mip != NULL; 6319 mip = list_next(&mac_impl_list, mip)) { 6320 if (i_mac_impl_log(mip, lstate) != 0) 6321 continue; 6322 } 6323 6324 /* Remove elements and destroy list of mac_impls */ 6325 rw_enter(&i_mac_impl_lock, RW_WRITER); 6326 while ((mip = list_remove_tail(&mac_impl_list)) != NULL) { 6327 mip->mi_ref--; 6328 } 6329 rw_exit(&i_mac_impl_lock); 6330 list_destroy(&mac_impl_list); 6331 6332 /* 6333 * Write log entries to files outside of locks, free associated 6334 * structures, and remove entries from the list. 6335 */ 6336 while ((ninfo = list_head(net_log_list)) != NULL) { 6337 (void) exacct_commit_netinfo(ninfo->ni_record, ninfo->ni_type); 6338 list_remove(net_log_list, ninfo); 6339 kmem_free(ninfo->ni_record, ninfo->ni_size); 6340 kmem_free(ninfo, sizeof (*ninfo)); 6341 } 6342 list_destroy(net_log_list); 6343 } 6344 6345 /* 6346 * The timer thread that runs every mac_logging_interval seconds and logs 6347 * link and/or flow information. 6348 */ 6349 /* ARGSUSED */ 6350 void 6351 mac_log_linkinfo(void *arg) 6352 { 6353 i_mac_log_state_t lstate; 6354 list_t net_log_list; 6355 6356 list_create(&net_log_list, sizeof (netinfo_t), 6357 offsetof(netinfo_t, ni_link)); 6358 6359 rw_enter(&i_mac_impl_lock, RW_READER); 6360 if (!mac_flow_log_enable && !mac_link_log_enable) { 6361 rw_exit(&i_mac_impl_lock); 6362 return; 6363 } 6364 lstate.mi_fenable = mac_flow_log_enable; 6365 lstate.mi_lenable = mac_link_log_enable; 6366 lstate.mi_last = B_FALSE; 6367 lstate.mi_list = &net_log_list; 6368 6369 /* Write log entries for each mac_impl in the list */ 6370 i_mac_log_info(&net_log_list, &lstate); 6371 6372 if (mac_flow_log_enable || mac_link_log_enable) { 6373 mac_logging_timer = timeout(mac_log_linkinfo, NULL, 6374 SEC_TO_TICK(mac_logging_interval)); 6375 } 6376 } 6377 6378 typedef struct i_mac_fastpath_state_s { 6379 boolean_t mf_disable; 6380 int mf_err; 6381 } i_mac_fastpath_state_t; 6382 6383 /* modhash walker function to enable or disable fastpath */ 6384 /*ARGSUSED*/ 6385 static uint_t 6386 i_mac_fastpath_walker(mod_hash_key_t key, mod_hash_val_t *val, 6387 void *arg) 6388 { 6389 i_mac_fastpath_state_t *state = arg; 6390 mac_handle_t mh = (mac_handle_t)val; 6391 6392 if (state->mf_disable) 6393 state->mf_err = mac_fastpath_disable(mh); 6394 else 6395 mac_fastpath_enable(mh); 6396 6397 return (state->mf_err == 0 ? MH_WALK_CONTINUE : MH_WALK_TERMINATE); 6398 } 6399 6400 /* 6401 * Start the logging timer. 6402 */ 6403 int 6404 mac_start_logusage(mac_logtype_t type, uint_t interval) 6405 { 6406 i_mac_fastpath_state_t dstate = {B_TRUE, 0}; 6407 i_mac_fastpath_state_t estate = {B_FALSE, 0}; 6408 int err; 6409 6410 rw_enter(&i_mac_impl_lock, RW_WRITER); 6411 switch (type) { 6412 case MAC_LOGTYPE_FLOW: 6413 if (mac_flow_log_enable) { 6414 rw_exit(&i_mac_impl_lock); 6415 return (0); 6416 } 6417 /* FALLTHRU */ 6418 case MAC_LOGTYPE_LINK: 6419 if (mac_link_log_enable) { 6420 rw_exit(&i_mac_impl_lock); 6421 return (0); 6422 } 6423 break; 6424 default: 6425 ASSERT(0); 6426 } 6427 6428 /* Disable fastpath */ 6429 mod_hash_walk(i_mac_impl_hash, i_mac_fastpath_walker, &dstate); 6430 if ((err = dstate.mf_err) != 0) { 6431 /* Reenable fastpath */ 6432 mod_hash_walk(i_mac_impl_hash, i_mac_fastpath_walker, &estate); 6433 rw_exit(&i_mac_impl_lock); 6434 return (err); 6435 } 6436 6437 switch (type) { 6438 case MAC_LOGTYPE_FLOW: 6439 mac_flow_log_enable = B_TRUE; 6440 /* FALLTHRU */ 6441 case MAC_LOGTYPE_LINK: 6442 mac_link_log_enable = B_TRUE; 6443 break; 6444 } 6445 6446 mac_logging_interval = interval; 6447 rw_exit(&i_mac_impl_lock); 6448 mac_log_linkinfo(NULL); 6449 return (0); 6450 } 6451 6452 /* 6453 * Stop the logging timer if both link and flow logging are turned off. 6454 */ 6455 void 6456 mac_stop_logusage(mac_logtype_t type) 6457 { 6458 i_mac_log_state_t lstate; 6459 i_mac_fastpath_state_t estate = {B_FALSE, 0}; 6460 list_t net_log_list; 6461 6462 list_create(&net_log_list, sizeof (netinfo_t), 6463 offsetof(netinfo_t, ni_link)); 6464 6465 rw_enter(&i_mac_impl_lock, RW_WRITER); 6466 6467 lstate.mi_fenable = mac_flow_log_enable; 6468 lstate.mi_lenable = mac_link_log_enable; 6469 lstate.mi_list = &net_log_list; 6470 6471 /* Last walk */ 6472 lstate.mi_last = B_TRUE; 6473 6474 switch (type) { 6475 case MAC_LOGTYPE_FLOW: 6476 if (lstate.mi_fenable) { 6477 ASSERT(mac_link_log_enable); 6478 mac_flow_log_enable = B_FALSE; 6479 mac_link_log_enable = B_FALSE; 6480 break; 6481 } 6482 /* FALLTHRU */ 6483 case MAC_LOGTYPE_LINK: 6484 if (!lstate.mi_lenable || mac_flow_log_enable) { 6485 rw_exit(&i_mac_impl_lock); 6486 return; 6487 } 6488 mac_link_log_enable = B_FALSE; 6489 break; 6490 default: 6491 ASSERT(0); 6492 } 6493 6494 /* Reenable fastpath */ 6495 mod_hash_walk(i_mac_impl_hash, i_mac_fastpath_walker, &estate); 6496 6497 (void) untimeout(mac_logging_timer); 6498 mac_logging_timer = NULL; 6499 6500 /* Write log entries for each mac_impl in the list */ 6501 i_mac_log_info(&net_log_list, &lstate); 6502 } 6503 6504 /* 6505 * Walk the rx and tx SRS/SRs for a flow and update the priority value. 6506 */ 6507 void 6508 mac_flow_update_priority(mac_client_impl_t *mcip, flow_entry_t *flent) 6509 { 6510 pri_t pri; 6511 int count; 6512 mac_soft_ring_set_t *mac_srs; 6513 6514 if (flent->fe_rx_srs_cnt <= 0) 6515 return; 6516 6517 if (((mac_soft_ring_set_t *)flent->fe_rx_srs[0])->srs_type == 6518 SRST_FLOW) { 6519 pri = FLOW_PRIORITY(mcip->mci_min_pri, 6520 mcip->mci_max_pri, 6521 flent->fe_resource_props.mrp_priority); 6522 } else { 6523 pri = mcip->mci_max_pri; 6524 } 6525 6526 for (count = 0; count < flent->fe_rx_srs_cnt; count++) { 6527 mac_srs = flent->fe_rx_srs[count]; 6528 mac_update_srs_priority(mac_srs, pri); 6529 } 6530 /* 6531 * If we have a Tx SRS, we need to modify all the threads associated 6532 * with it. 6533 */ 6534 if (flent->fe_tx_srs != NULL) 6535 mac_update_srs_priority(flent->fe_tx_srs, pri); 6536 } 6537 6538 /* 6539 * RX and TX rings are reserved according to different semantics depending 6540 * on the requests from the MAC clients and type of rings: 6541 * 6542 * On the Tx side, by default we reserve individual rings, independently from 6543 * the groups. 6544 * 6545 * On the Rx side, the reservation is at the granularity of the group 6546 * of rings, and used for v12n level 1 only. It has a special case for the 6547 * primary client. 6548 * 6549 * If a share is allocated to a MAC client, we allocate a TX group and an 6550 * RX group to the client, and assign TX rings and RX rings to these 6551 * groups according to information gathered from the driver through 6552 * the share capability. 6553 * 6554 * The foreseable evolution of Rx rings will handle v12n level 2 and higher 6555 * to allocate individual rings out of a group and program the hw classifier 6556 * based on IP address or higher level criteria. 6557 */ 6558 6559 /* 6560 * mac_reserve_tx_ring() 6561 * Reserve a unused ring by marking it with MR_INUSE state. 6562 * As reserved, the ring is ready to function. 6563 * 6564 * Notes for Hybrid I/O: 6565 * 6566 * If a specific ring is needed, it is specified through the desired_ring 6567 * argument. Otherwise that argument is set to NULL. 6568 * If the desired ring was previous allocated to another client, this 6569 * function swaps it with a new ring from the group of unassigned rings. 6570 */ 6571 mac_ring_t * 6572 mac_reserve_tx_ring(mac_impl_t *mip, mac_ring_t *desired_ring) 6573 { 6574 mac_group_t *group; 6575 mac_grp_client_t *mgcp; 6576 mac_client_impl_t *mcip; 6577 mac_soft_ring_set_t *srs; 6578 6579 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 6580 6581 /* 6582 * Find an available ring and start it before changing its status. 6583 * The unassigned rings are at the end of the mi_tx_groups 6584 * array. 6585 */ 6586 group = MAC_DEFAULT_TX_GROUP(mip); 6587 6588 /* Can't take the default ring out of the default group */ 6589 ASSERT(desired_ring != (mac_ring_t *)mip->mi_default_tx_ring); 6590 6591 if (desired_ring->mr_state == MR_FREE) { 6592 ASSERT(MAC_GROUP_NO_CLIENT(group)); 6593 if (mac_start_ring(desired_ring) != 0) 6594 return (NULL); 6595 return (desired_ring); 6596 } 6597 /* 6598 * There are clients using this ring, so let's move the clients 6599 * away from using this ring. 6600 */ 6601 for (mgcp = group->mrg_clients; mgcp != NULL; mgcp = mgcp->mgc_next) { 6602 mcip = mgcp->mgc_client; 6603 mac_tx_client_quiesce((mac_client_handle_t)mcip); 6604 srs = MCIP_TX_SRS(mcip); 6605 ASSERT(mac_tx_srs_ring_present(srs, desired_ring)); 6606 mac_tx_invoke_callbacks(mcip, 6607 (mac_tx_cookie_t)mac_tx_srs_get_soft_ring(srs, 6608 desired_ring)); 6609 mac_tx_srs_del_ring(srs, desired_ring); 6610 mac_tx_client_restart((mac_client_handle_t)mcip); 6611 } 6612 return (desired_ring); 6613 } 6614 6615 /* 6616 * For a non-default group with multiple clients, return the primary client. 6617 */ 6618 static mac_client_impl_t * 6619 mac_get_grp_primary(mac_group_t *grp) 6620 { 6621 mac_grp_client_t *mgcp = grp->mrg_clients; 6622 mac_client_impl_t *mcip; 6623 6624 while (mgcp != NULL) { 6625 mcip = mgcp->mgc_client; 6626 if (mcip->mci_flent->fe_type & FLOW_PRIMARY_MAC) 6627 return (mcip); 6628 mgcp = mgcp->mgc_next; 6629 } 6630 return (NULL); 6631 } 6632 6633 /* 6634 * Hybrid I/O specifies the ring that should be given to a share. 6635 * If the ring is already used by clients, then we need to release 6636 * the ring back to the default group so that we can give it to 6637 * the share. This means the clients using this ring now get a 6638 * replacement ring. If there aren't any replacement rings, this 6639 * function returns a failure. 6640 */ 6641 static int 6642 mac_reclaim_ring_from_grp(mac_impl_t *mip, mac_ring_type_t ring_type, 6643 mac_ring_t *ring, mac_ring_t **rings, int nrings) 6644 { 6645 mac_group_t *group = (mac_group_t *)ring->mr_gh; 6646 mac_resource_props_t *mrp; 6647 mac_client_impl_t *mcip; 6648 mac_group_t *defgrp; 6649 mac_ring_t *tring; 6650 mac_group_t *tgrp; 6651 int i; 6652 int j; 6653 6654 mcip = MAC_GROUP_ONLY_CLIENT(group); 6655 if (mcip == NULL) 6656 mcip = mac_get_grp_primary(group); 6657 ASSERT(mcip != NULL); 6658 ASSERT(mcip->mci_share == 0); 6659 6660 mrp = MCIP_RESOURCE_PROPS(mcip); 6661 if (ring_type == MAC_RING_TYPE_RX) { 6662 defgrp = mip->mi_rx_donor_grp; 6663 if ((mrp->mrp_mask & MRP_RX_RINGS) == 0) { 6664 /* Need to put this mac client in the default group */ 6665 if (mac_rx_switch_group(mcip, group, defgrp) != 0) 6666 return (ENOSPC); 6667 } else { 6668 /* 6669 * Switch this ring with some other ring from 6670 * the default group. 6671 */ 6672 for (tring = defgrp->mrg_rings; tring != NULL; 6673 tring = tring->mr_next) { 6674 if (tring->mr_index == 0) 6675 continue; 6676 for (j = 0; j < nrings; j++) { 6677 if (rings[j] == tring) 6678 break; 6679 } 6680 if (j >= nrings) 6681 break; 6682 } 6683 if (tring == NULL) 6684 return (ENOSPC); 6685 if (mac_group_mov_ring(mip, group, tring) != 0) 6686 return (ENOSPC); 6687 if (mac_group_mov_ring(mip, defgrp, ring) != 0) { 6688 (void) mac_group_mov_ring(mip, defgrp, tring); 6689 return (ENOSPC); 6690 } 6691 } 6692 ASSERT(ring->mr_gh == (mac_group_handle_t)defgrp); 6693 return (0); 6694 } 6695 6696 defgrp = MAC_DEFAULT_TX_GROUP(mip); 6697 if (ring == (mac_ring_t *)mip->mi_default_tx_ring) { 6698 /* 6699 * See if we can get a spare ring to replace the default 6700 * ring. 6701 */ 6702 if (defgrp->mrg_cur_count == 1) { 6703 /* 6704 * Need to get a ring from another client, see if 6705 * there are any clients that can be moved to 6706 * the default group, thereby freeing some rings. 6707 */ 6708 for (i = 0; i < mip->mi_tx_group_count; i++) { 6709 tgrp = &mip->mi_tx_groups[i]; 6710 if (tgrp->mrg_state == 6711 MAC_GROUP_STATE_REGISTERED) { 6712 continue; 6713 } 6714 mcip = MAC_GROUP_ONLY_CLIENT(tgrp); 6715 if (mcip == NULL) 6716 mcip = mac_get_grp_primary(tgrp); 6717 ASSERT(mcip != NULL); 6718 mrp = MCIP_RESOURCE_PROPS(mcip); 6719 if ((mrp->mrp_mask & MRP_TX_RINGS) == 0) { 6720 ASSERT(tgrp->mrg_cur_count == 1); 6721 /* 6722 * If this ring is part of the 6723 * rings asked by the share we cannot 6724 * use it as the default ring. 6725 */ 6726 for (j = 0; j < nrings; j++) { 6727 if (rings[j] == tgrp->mrg_rings) 6728 break; 6729 } 6730 if (j < nrings) 6731 continue; 6732 mac_tx_client_quiesce( 6733 (mac_client_handle_t)mcip); 6734 mac_tx_switch_group(mcip, tgrp, 6735 defgrp); 6736 mac_tx_client_restart( 6737 (mac_client_handle_t)mcip); 6738 break; 6739 } 6740 } 6741 /* 6742 * All the rings are reserved, can't give up the 6743 * default ring. 6744 */ 6745 if (defgrp->mrg_cur_count <= 1) 6746 return (ENOSPC); 6747 } 6748 /* 6749 * Swap the default ring with another. 6750 */ 6751 for (tring = defgrp->mrg_rings; tring != NULL; 6752 tring = tring->mr_next) { 6753 /* 6754 * If this ring is part of the rings asked by the 6755 * share we cannot use it as the default ring. 6756 */ 6757 for (j = 0; j < nrings; j++) { 6758 if (rings[j] == tring) 6759 break; 6760 } 6761 if (j >= nrings) 6762 break; 6763 } 6764 ASSERT(tring != NULL); 6765 mip->mi_default_tx_ring = (mac_ring_handle_t)tring; 6766 return (0); 6767 } 6768 /* 6769 * The Tx ring is with a group reserved by a MAC client. See if 6770 * we can swap it. 6771 */ 6772 ASSERT(group->mrg_state == MAC_GROUP_STATE_RESERVED); 6773 mcip = MAC_GROUP_ONLY_CLIENT(group); 6774 if (mcip == NULL) 6775 mcip = mac_get_grp_primary(group); 6776 ASSERT(mcip != NULL); 6777 mrp = MCIP_RESOURCE_PROPS(mcip); 6778 mac_tx_client_quiesce((mac_client_handle_t)mcip); 6779 if ((mrp->mrp_mask & MRP_TX_RINGS) == 0) { 6780 ASSERT(group->mrg_cur_count == 1); 6781 /* Put this mac client in the default group */ 6782 mac_tx_switch_group(mcip, group, defgrp); 6783 } else { 6784 /* 6785 * Switch this ring with some other ring from 6786 * the default group. 6787 */ 6788 for (tring = defgrp->mrg_rings; tring != NULL; 6789 tring = tring->mr_next) { 6790 if (tring == (mac_ring_t *)mip->mi_default_tx_ring) 6791 continue; 6792 /* 6793 * If this ring is part of the rings asked by the 6794 * share we cannot use it for swapping. 6795 */ 6796 for (j = 0; j < nrings; j++) { 6797 if (rings[j] == tring) 6798 break; 6799 } 6800 if (j >= nrings) 6801 break; 6802 } 6803 if (tring == NULL) { 6804 mac_tx_client_restart((mac_client_handle_t)mcip); 6805 return (ENOSPC); 6806 } 6807 if (mac_group_mov_ring(mip, group, tring) != 0) { 6808 mac_tx_client_restart((mac_client_handle_t)mcip); 6809 return (ENOSPC); 6810 } 6811 if (mac_group_mov_ring(mip, defgrp, ring) != 0) { 6812 (void) mac_group_mov_ring(mip, defgrp, tring); 6813 mac_tx_client_restart((mac_client_handle_t)mcip); 6814 return (ENOSPC); 6815 } 6816 } 6817 mac_tx_client_restart((mac_client_handle_t)mcip); 6818 ASSERT(ring->mr_gh == (mac_group_handle_t)defgrp); 6819 return (0); 6820 } 6821 6822 /* 6823 * Populate a zero-ring group with rings. If the share is non-NULL, 6824 * the rings are chosen according to that share. 6825 * Invoked after allocating a new RX or TX group through 6826 * mac_reserve_rx_group() or mac_reserve_tx_group(), respectively. 6827 * Returns zero on success, an errno otherwise. 6828 */ 6829 int 6830 i_mac_group_allocate_rings(mac_impl_t *mip, mac_ring_type_t ring_type, 6831 mac_group_t *src_group, mac_group_t *new_group, mac_share_handle_t share, 6832 uint32_t ringcnt) 6833 { 6834 mac_ring_t **rings, *ring; 6835 uint_t nrings; 6836 int rv = 0, i = 0, j; 6837 6838 ASSERT((ring_type == MAC_RING_TYPE_RX && 6839 mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) || 6840 (ring_type == MAC_RING_TYPE_TX && 6841 mip->mi_tx_group_type == MAC_GROUP_TYPE_DYNAMIC)); 6842 6843 /* 6844 * First find the rings to allocate to the group. 6845 */ 6846 if (share != 0) { 6847 /* get rings through ms_squery() */ 6848 mip->mi_share_capab.ms_squery(share, ring_type, NULL, &nrings); 6849 ASSERT(nrings != 0); 6850 rings = kmem_alloc(nrings * sizeof (mac_ring_handle_t), 6851 KM_SLEEP); 6852 mip->mi_share_capab.ms_squery(share, ring_type, 6853 (mac_ring_handle_t *)rings, &nrings); 6854 for (i = 0; i < nrings; i++) { 6855 /* 6856 * If we have given this ring to a non-default 6857 * group, we need to check if we can get this 6858 * ring. 6859 */ 6860 ring = rings[i]; 6861 if (ring->mr_gh != (mac_group_handle_t)src_group || 6862 ring == (mac_ring_t *)mip->mi_default_tx_ring) { 6863 if (mac_reclaim_ring_from_grp(mip, ring_type, 6864 ring, rings, nrings) != 0) { 6865 rv = ENOSPC; 6866 goto bail; 6867 } 6868 } 6869 } 6870 } else { 6871 /* 6872 * Pick one ring from default group. 6873 * 6874 * for now pick the second ring which requires the first ring 6875 * at index 0 to stay in the default group, since it is the 6876 * ring which carries the multicast traffic. 6877 * We need a better way for a driver to indicate this, 6878 * for example a per-ring flag. 6879 */ 6880 rings = kmem_alloc(ringcnt * sizeof (mac_ring_handle_t), 6881 KM_SLEEP); 6882 for (ring = src_group->mrg_rings; ring != NULL; 6883 ring = ring->mr_next) { 6884 if (ring_type == MAC_RING_TYPE_RX && 6885 ring->mr_index == 0) { 6886 continue; 6887 } 6888 if (ring_type == MAC_RING_TYPE_TX && 6889 ring == (mac_ring_t *)mip->mi_default_tx_ring) { 6890 continue; 6891 } 6892 rings[i++] = ring; 6893 if (i == ringcnt) 6894 break; 6895 } 6896 ASSERT(ring != NULL); 6897 nrings = i; 6898 /* Not enough rings as required */ 6899 if (nrings != ringcnt) { 6900 rv = ENOSPC; 6901 goto bail; 6902 } 6903 } 6904 6905 switch (ring_type) { 6906 case MAC_RING_TYPE_RX: 6907 if (src_group->mrg_cur_count - nrings < 1) { 6908 /* we ran out of rings */ 6909 rv = ENOSPC; 6910 goto bail; 6911 } 6912 6913 /* move receive rings to new group */ 6914 for (i = 0; i < nrings; i++) { 6915 rv = mac_group_mov_ring(mip, new_group, rings[i]); 6916 if (rv != 0) { 6917 /* move rings back on failure */ 6918 for (j = 0; j < i; j++) { 6919 (void) mac_group_mov_ring(mip, 6920 src_group, rings[j]); 6921 } 6922 goto bail; 6923 } 6924 } 6925 break; 6926 6927 case MAC_RING_TYPE_TX: { 6928 mac_ring_t *tmp_ring; 6929 6930 /* move the TX rings to the new group */ 6931 for (i = 0; i < nrings; i++) { 6932 /* get the desired ring */ 6933 tmp_ring = mac_reserve_tx_ring(mip, rings[i]); 6934 if (tmp_ring == NULL) { 6935 rv = ENOSPC; 6936 goto bail; 6937 } 6938 ASSERT(tmp_ring == rings[i]); 6939 rv = mac_group_mov_ring(mip, new_group, rings[i]); 6940 if (rv != 0) { 6941 /* cleanup on failure */ 6942 for (j = 0; j < i; j++) { 6943 (void) mac_group_mov_ring(mip, 6944 MAC_DEFAULT_TX_GROUP(mip), 6945 rings[j]); 6946 } 6947 goto bail; 6948 } 6949 } 6950 break; 6951 } 6952 } 6953 6954 /* add group to share */ 6955 if (share != 0) 6956 mip->mi_share_capab.ms_sadd(share, new_group->mrg_driver); 6957 6958 bail: 6959 /* free temporary array of rings */ 6960 kmem_free(rings, nrings * sizeof (mac_ring_handle_t)); 6961 6962 return (rv); 6963 } 6964 6965 void 6966 mac_group_add_client(mac_group_t *grp, mac_client_impl_t *mcip) 6967 { 6968 mac_grp_client_t *mgcp; 6969 6970 for (mgcp = grp->mrg_clients; mgcp != NULL; mgcp = mgcp->mgc_next) { 6971 if (mgcp->mgc_client == mcip) 6972 break; 6973 } 6974 6975 ASSERT(mgcp == NULL); 6976 6977 mgcp = kmem_zalloc(sizeof (mac_grp_client_t), KM_SLEEP); 6978 mgcp->mgc_client = mcip; 6979 mgcp->mgc_next = grp->mrg_clients; 6980 grp->mrg_clients = mgcp; 6981 } 6982 6983 void 6984 mac_group_remove_client(mac_group_t *grp, mac_client_impl_t *mcip) 6985 { 6986 mac_grp_client_t *mgcp, **pprev; 6987 6988 for (pprev = &grp->mrg_clients, mgcp = *pprev; mgcp != NULL; 6989 pprev = &mgcp->mgc_next, mgcp = *pprev) { 6990 if (mgcp->mgc_client == mcip) 6991 break; 6992 } 6993 6994 ASSERT(mgcp != NULL); 6995 6996 *pprev = mgcp->mgc_next; 6997 kmem_free(mgcp, sizeof (mac_grp_client_t)); 6998 } 6999 7000 /* 7001 * Return true if any client on this group explicitly asked for HW 7002 * rings (of type mask) or have a bound share. 7003 */ 7004 static boolean_t 7005 i_mac_clients_hw(mac_group_t *grp, uint32_t mask) 7006 { 7007 mac_grp_client_t *mgcip; 7008 mac_client_impl_t *mcip; 7009 mac_resource_props_t *mrp; 7010 7011 for (mgcip = grp->mrg_clients; mgcip != NULL; mgcip = mgcip->mgc_next) { 7012 mcip = mgcip->mgc_client; 7013 mrp = MCIP_RESOURCE_PROPS(mcip); 7014 if (mcip->mci_share != 0 || (mrp->mrp_mask & mask) != 0) 7015 return (B_TRUE); 7016 } 7017 7018 return (B_FALSE); 7019 } 7020 7021 /* 7022 * Finds an available group and exclusively reserves it for a client. 7023 * The group is chosen to suit the flow's resource controls (bandwidth and 7024 * fanout requirements) and the address type. 7025 * If the requestor is the pimary MAC then return the group with the 7026 * largest number of rings, otherwise the default ring when available. 7027 */ 7028 mac_group_t * 7029 mac_reserve_rx_group(mac_client_impl_t *mcip, uint8_t *mac_addr, boolean_t move) 7030 { 7031 mac_share_handle_t share = mcip->mci_share; 7032 mac_impl_t *mip = mcip->mci_mip; 7033 mac_group_t *grp = NULL; 7034 int i; 7035 int err = 0; 7036 mac_address_t *map; 7037 mac_resource_props_t *mrp = MCIP_RESOURCE_PROPS(mcip); 7038 int nrings; 7039 int donor_grp_rcnt; 7040 boolean_t need_exclgrp = B_FALSE; 7041 int need_rings = 0; 7042 mac_group_t *candidate_grp = NULL; 7043 mac_client_impl_t *gclient; 7044 mac_group_t *donorgrp = NULL; 7045 boolean_t rxhw = mrp->mrp_mask & MRP_RX_RINGS; 7046 boolean_t unspec = mrp->mrp_mask & MRP_RXRINGS_UNSPEC; 7047 boolean_t isprimary; 7048 7049 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 7050 7051 isprimary = mcip->mci_flent->fe_type & FLOW_PRIMARY_MAC; 7052 7053 /* 7054 * Check if a group already has this MAC address (case of VLANs) 7055 * unless we are moving this MAC client from one group to another. 7056 */ 7057 if (!move && (map = mac_find_macaddr(mip, mac_addr)) != NULL) { 7058 if (map->ma_group != NULL) 7059 return (map->ma_group); 7060 } 7061 7062 if (mip->mi_rx_groups == NULL || mip->mi_rx_group_count == 0) 7063 return (NULL); 7064 7065 /* 7066 * If this client is requesting exclusive MAC access then 7067 * return NULL to ensure the client uses the default group. 7068 */ 7069 if (mcip->mci_state_flags & MCIS_EXCLUSIVE) 7070 return (NULL); 7071 7072 /* For dynamic groups default unspecified to 1 */ 7073 if (rxhw && unspec && 7074 mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) { 7075 mrp->mrp_nrxrings = 1; 7076 } 7077 7078 /* 7079 * For static grouping we allow only specifying rings=0 and 7080 * unspecified 7081 */ 7082 if (rxhw && mrp->mrp_nrxrings > 0 && 7083 mip->mi_rx_group_type == MAC_GROUP_TYPE_STATIC) { 7084 return (NULL); 7085 } 7086 7087 if (rxhw) { 7088 /* 7089 * We have explicitly asked for a group (with nrxrings, 7090 * if unspec). 7091 */ 7092 if (unspec || mrp->mrp_nrxrings > 0) { 7093 need_exclgrp = B_TRUE; 7094 need_rings = mrp->mrp_nrxrings; 7095 } else if (mrp->mrp_nrxrings == 0) { 7096 /* 7097 * We have asked for a software group. 7098 */ 7099 return (NULL); 7100 } 7101 } else if (isprimary && mip->mi_nactiveclients == 1 && 7102 mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) { 7103 /* 7104 * If the primary is the only active client on this 7105 * mip and we have not asked for any rings, we give 7106 * it the default group so that the primary gets to 7107 * use all the rings. 7108 */ 7109 return (NULL); 7110 } 7111 7112 /* The group that can donate rings */ 7113 donorgrp = mip->mi_rx_donor_grp; 7114 7115 /* 7116 * The number of rings that the default group can donate. 7117 * We need to leave at least one ring. 7118 */ 7119 donor_grp_rcnt = donorgrp->mrg_cur_count - 1; 7120 7121 /* 7122 * Try to exclusively reserve a RX group. 7123 * 7124 * For flows requiring HW_DEFAULT_RING (unicast flow of the primary 7125 * client), try to reserve the a non-default RX group and give 7126 * it all the rings from the donor group, except the default ring 7127 * 7128 * For flows requiring HW_RING (unicast flow of other clients), try 7129 * to reserve non-default RX group with the specified number of 7130 * rings, if available. 7131 * 7132 * For flows that have not asked for software or hardware ring, 7133 * try to reserve a non-default group with 1 ring, if available. 7134 */ 7135 for (i = 1; i < mip->mi_rx_group_count; i++) { 7136 grp = &mip->mi_rx_groups[i]; 7137 7138 DTRACE_PROBE3(rx__group__trying, char *, mip->mi_name, 7139 int, grp->mrg_index, mac_group_state_t, grp->mrg_state); 7140 7141 /* 7142 * Check if this group could be a candidate group for 7143 * eviction if we need a group for this MAC client, 7144 * but there aren't any. A candidate group is one 7145 * that didn't ask for an exclusive group, but got 7146 * one and it has enough rings (combined with what 7147 * the donor group can donate) for the new MAC 7148 * client. 7149 */ 7150 if (grp->mrg_state >= MAC_GROUP_STATE_RESERVED) { 7151 /* 7152 * If the donor group is not the default 7153 * group, don't bother looking for a candidate 7154 * group. If we don't have enough rings we 7155 * will check if the primary group can be 7156 * vacated. 7157 */ 7158 if (candidate_grp == NULL && 7159 donorgrp == MAC_DEFAULT_RX_GROUP(mip)) { 7160 if (!i_mac_clients_hw(grp, MRP_RX_RINGS) && 7161 (unspec || 7162 (grp->mrg_cur_count + donor_grp_rcnt >= 7163 need_rings))) { 7164 candidate_grp = grp; 7165 } 7166 } 7167 continue; 7168 } 7169 /* 7170 * This group could already be SHARED by other multicast 7171 * flows on this client. In that case, the group would 7172 * be shared and has already been started. 7173 */ 7174 ASSERT(grp->mrg_state != MAC_GROUP_STATE_UNINIT); 7175 7176 if ((grp->mrg_state == MAC_GROUP_STATE_REGISTERED) && 7177 (mac_start_group(grp) != 0)) { 7178 continue; 7179 } 7180 7181 if (mip->mi_rx_group_type != MAC_GROUP_TYPE_DYNAMIC) 7182 break; 7183 ASSERT(grp->mrg_cur_count == 0); 7184 7185 /* 7186 * Populate the group. Rings should be taken 7187 * from the donor group. 7188 */ 7189 nrings = rxhw ? need_rings : isprimary ? donor_grp_rcnt: 1; 7190 7191 /* 7192 * If the donor group can't donate, let's just walk and 7193 * see if someone can vacate a group, so that we have 7194 * enough rings for this, unless we already have 7195 * identified a candiate group.. 7196 */ 7197 if (nrings <= donor_grp_rcnt) { 7198 err = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_RX, 7199 donorgrp, grp, share, nrings); 7200 if (err == 0) { 7201 /* 7202 * For a share i_mac_group_allocate_rings gets 7203 * the rings from the driver, let's populate 7204 * the property for the client now. 7205 */ 7206 if (share != 0) { 7207 mac_client_set_rings( 7208 (mac_client_handle_t)mcip, 7209 grp->mrg_cur_count, -1); 7210 } 7211 if (mac_is_primary_client(mcip) && !rxhw) 7212 mip->mi_rx_donor_grp = grp; 7213 break; 7214 } 7215 } 7216 7217 DTRACE_PROBE3(rx__group__reserve__alloc__rings, char *, 7218 mip->mi_name, int, grp->mrg_index, int, err); 7219 7220 /* 7221 * It's a dynamic group but the grouping operation 7222 * failed. 7223 */ 7224 mac_stop_group(grp); 7225 } 7226 7227 /* We didn't find an exclusive group for this MAC client */ 7228 if (i >= mip->mi_rx_group_count) { 7229 7230 if (!need_exclgrp) 7231 return (NULL); 7232 7233 /* 7234 * If we found a candidate group then move the 7235 * existing MAC client from the candidate_group to the 7236 * default group and give the candidate_group to the 7237 * new MAC client. If we didn't find a candidate 7238 * group, then check if the primary is in its own 7239 * group and if it can make way for this MAC client. 7240 */ 7241 if (candidate_grp == NULL && 7242 donorgrp != MAC_DEFAULT_RX_GROUP(mip) && 7243 donorgrp->mrg_cur_count >= need_rings) { 7244 candidate_grp = donorgrp; 7245 } 7246 if (candidate_grp != NULL) { 7247 boolean_t prim_grp = B_FALSE; 7248 7249 /* 7250 * Switch the existing MAC client from the 7251 * candidate group to the default group. If 7252 * the candidate group is the donor group, 7253 * then after the switch we need to update the 7254 * donor group too. 7255 */ 7256 grp = candidate_grp; 7257 gclient = grp->mrg_clients->mgc_client; 7258 VERIFY3P(gclient, !=, NULL); 7259 if (grp == mip->mi_rx_donor_grp) 7260 prim_grp = B_TRUE; 7261 if (mac_rx_switch_group(gclient, grp, 7262 MAC_DEFAULT_RX_GROUP(mip)) != 0) { 7263 return (NULL); 7264 } 7265 if (prim_grp) { 7266 mip->mi_rx_donor_grp = 7267 MAC_DEFAULT_RX_GROUP(mip); 7268 donorgrp = MAC_DEFAULT_RX_GROUP(mip); 7269 } 7270 7271 /* 7272 * Now give this group with the required rings 7273 * to this MAC client. 7274 */ 7275 ASSERT(grp->mrg_state == MAC_GROUP_STATE_REGISTERED); 7276 if (mac_start_group(grp) != 0) 7277 return (NULL); 7278 7279 if (mip->mi_rx_group_type != MAC_GROUP_TYPE_DYNAMIC) 7280 return (grp); 7281 7282 donor_grp_rcnt = donorgrp->mrg_cur_count - 1; 7283 ASSERT(grp->mrg_cur_count == 0); 7284 ASSERT(donor_grp_rcnt >= need_rings); 7285 err = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_RX, 7286 donorgrp, grp, share, need_rings); 7287 if (err == 0) { 7288 /* 7289 * For a share i_mac_group_allocate_rings gets 7290 * the rings from the driver, let's populate 7291 * the property for the client now. 7292 */ 7293 if (share != 0) { 7294 mac_client_set_rings( 7295 (mac_client_handle_t)mcip, 7296 grp->mrg_cur_count, -1); 7297 } 7298 DTRACE_PROBE2(rx__group__reserved, 7299 char *, mip->mi_name, int, grp->mrg_index); 7300 return (grp); 7301 } 7302 DTRACE_PROBE3(rx__group__reserve__alloc__rings, char *, 7303 mip->mi_name, int, grp->mrg_index, int, err); 7304 mac_stop_group(grp); 7305 } 7306 return (NULL); 7307 } 7308 ASSERT(grp != NULL); 7309 7310 DTRACE_PROBE2(rx__group__reserved, 7311 char *, mip->mi_name, int, grp->mrg_index); 7312 return (grp); 7313 } 7314 7315 /* 7316 * mac_rx_release_group() 7317 * 7318 * Release the group when it has no remaining clients. The group is 7319 * stopped and its shares are removed and all rings are assigned back 7320 * to default group. This should never be called against the default 7321 * group. 7322 */ 7323 void 7324 mac_release_rx_group(mac_client_impl_t *mcip, mac_group_t *group) 7325 { 7326 mac_impl_t *mip = mcip->mci_mip; 7327 mac_ring_t *ring; 7328 7329 ASSERT(group != MAC_DEFAULT_RX_GROUP(mip)); 7330 ASSERT(MAC_GROUP_NO_CLIENT(group) == B_TRUE); 7331 7332 if (mip->mi_rx_donor_grp == group) 7333 mip->mi_rx_donor_grp = MAC_DEFAULT_RX_GROUP(mip); 7334 7335 /* 7336 * This is the case where there are no clients left. Any 7337 * SRS etc on this group have also be quiesced. 7338 */ 7339 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) { 7340 if (ring->mr_classify_type == MAC_HW_CLASSIFIER) { 7341 ASSERT(group->mrg_state == MAC_GROUP_STATE_RESERVED); 7342 /* 7343 * Remove the SRS associated with the HW ring. 7344 * As a result, polling will be disabled. 7345 */ 7346 ring->mr_srs = NULL; 7347 } 7348 ASSERT(group->mrg_state < MAC_GROUP_STATE_RESERVED || 7349 ring->mr_state == MR_INUSE); 7350 if (ring->mr_state == MR_INUSE) { 7351 mac_stop_ring(ring); 7352 ring->mr_flag = 0; 7353 } 7354 } 7355 7356 /* remove group from share */ 7357 if (mcip->mci_share != 0) { 7358 mip->mi_share_capab.ms_sremove(mcip->mci_share, 7359 group->mrg_driver); 7360 } 7361 7362 if (mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) { 7363 mac_ring_t *ring; 7364 7365 /* 7366 * Rings were dynamically allocated to group. 7367 * Move rings back to default group. 7368 */ 7369 while ((ring = group->mrg_rings) != NULL) { 7370 (void) mac_group_mov_ring(mip, mip->mi_rx_donor_grp, 7371 ring); 7372 } 7373 } 7374 mac_stop_group(group); 7375 /* 7376 * Possible improvement: See if we can assign the group just released 7377 * to a another client of the mip 7378 */ 7379 } 7380 7381 /* 7382 * Move the MAC address from fgrp to tgrp. 7383 */ 7384 static int 7385 mac_rx_move_macaddr(mac_client_impl_t *mcip, mac_group_t *fgrp, 7386 mac_group_t *tgrp) 7387 { 7388 mac_impl_t *mip = mcip->mci_mip; 7389 uint8_t maddr[MAXMACADDRLEN]; 7390 int err = 0; 7391 uint16_t vid; 7392 mac_unicast_impl_t *muip; 7393 boolean_t use_hw; 7394 7395 mac_rx_client_quiesce((mac_client_handle_t)mcip); 7396 VERIFY3P(mcip->mci_unicast, !=, NULL); 7397 bcopy(mcip->mci_unicast->ma_addr, maddr, mcip->mci_unicast->ma_len); 7398 7399 /* 7400 * Does the client require MAC address hardware classifiction? 7401 */ 7402 use_hw = (mcip->mci_state_flags & MCIS_UNICAST_HW) != 0; 7403 vid = i_mac_flow_vid(mcip->mci_flent); 7404 7405 /* 7406 * You can never move an address that is shared by multiple 7407 * clients. mac_datapath_setup() ensures that clients sharing 7408 * an address are placed on the default group. This guarantees 7409 * that a non-default group will only ever have one client and 7410 * thus make full use of HW filters. 7411 */ 7412 if (mac_check_macaddr_shared(mcip->mci_unicast)) 7413 return (EINVAL); 7414 7415 err = mac_remove_macaddr_vlan(mcip->mci_unicast, vid); 7416 7417 if (err != 0) { 7418 mac_rx_client_restart((mac_client_handle_t)mcip); 7419 return (err); 7420 } 7421 7422 /* 7423 * If this isn't the primary MAC address then the 7424 * mac_address_t has been freed by the last call to 7425 * mac_remove_macaddr_vlan(). In any case, NULL the reference 7426 * to avoid a dangling pointer. 7427 */ 7428 mcip->mci_unicast = NULL; 7429 7430 /* 7431 * We also have to NULL all the mui_map references -- sun4v 7432 * strikes again! 7433 */ 7434 rw_enter(&mcip->mci_rw_lock, RW_WRITER); 7435 for (muip = mcip->mci_unicast_list; muip != NULL; muip = muip->mui_next) 7436 muip->mui_map = NULL; 7437 rw_exit(&mcip->mci_rw_lock); 7438 7439 /* 7440 * Program the H/W Classifier first, if this fails we need not 7441 * proceed with the other stuff. 7442 */ 7443 if ((err = mac_add_macaddr_vlan(mip, tgrp, maddr, vid, use_hw)) != 0) { 7444 int err2; 7445 7446 /* Revert back the H/W Classifier */ 7447 err2 = mac_add_macaddr_vlan(mip, fgrp, maddr, vid, use_hw); 7448 7449 if (err2 != 0) { 7450 cmn_err(CE_WARN, "Failed to revert HW classification" 7451 " on MAC %s, for client %s: %d.", mip->mi_name, 7452 mcip->mci_name, err2); 7453 } 7454 7455 mac_rx_client_restart((mac_client_handle_t)mcip); 7456 return (err); 7457 } 7458 7459 /* 7460 * Get a reference to the new mac_address_t and update the 7461 * client's reference. Then restart the client and add the 7462 * other clients of this MAC addr (if they exsit). 7463 */ 7464 mcip->mci_unicast = mac_find_macaddr(mip, maddr); 7465 rw_enter(&mcip->mci_rw_lock, RW_WRITER); 7466 for (muip = mcip->mci_unicast_list; muip != NULL; muip = muip->mui_next) 7467 muip->mui_map = mcip->mci_unicast; 7468 rw_exit(&mcip->mci_rw_lock); 7469 mac_rx_client_restart((mac_client_handle_t)mcip); 7470 return (0); 7471 } 7472 7473 /* 7474 * Switch the MAC client from one group to another. This means we need 7475 * to remove the MAC address from the group, remove the MAC client, 7476 * teardown the SRSs and revert the group state. Then, we add the client 7477 * to the destination group, set the SRSs, and add the MAC address to the 7478 * group. 7479 */ 7480 int 7481 mac_rx_switch_group(mac_client_impl_t *mcip, mac_group_t *fgrp, 7482 mac_group_t *tgrp) 7483 { 7484 int err; 7485 mac_group_state_t next_state; 7486 mac_client_impl_t *group_only_mcip; 7487 mac_client_impl_t *gmcip; 7488 mac_impl_t *mip = mcip->mci_mip; 7489 mac_grp_client_t *mgcp; 7490 7491 VERIFY3P(fgrp, ==, mcip->mci_flent->fe_rx_ring_group); 7492 7493 if ((err = mac_rx_move_macaddr(mcip, fgrp, tgrp)) != 0) 7494 return (err); 7495 7496 /* 7497 * If the group is marked as reserved and in use by a single 7498 * client, then there is an SRS to teardown. 7499 */ 7500 if (fgrp->mrg_state == MAC_GROUP_STATE_RESERVED && 7501 MAC_GROUP_ONLY_CLIENT(fgrp) != NULL) { 7502 mac_rx_srs_group_teardown(mcip->mci_flent, B_TRUE); 7503 } 7504 7505 /* 7506 * If we are moving the client from a non-default group, then 7507 * we know that any additional clients on this group share the 7508 * same MAC address. Since we moved the MAC address filter, we 7509 * need to move these clients too. 7510 * 7511 * If we are moving the client from the default group and its 7512 * MAC address has VLAN clients, then we must move those 7513 * clients as well. 7514 * 7515 * In both cases the idea is the same: we moved the MAC 7516 * address filter to the tgrp, so we must move all clients 7517 * using that MAC address to tgrp as well. 7518 */ 7519 if (fgrp != MAC_DEFAULT_RX_GROUP(mip)) { 7520 mgcp = fgrp->mrg_clients; 7521 while (mgcp != NULL) { 7522 gmcip = mgcp->mgc_client; 7523 mgcp = mgcp->mgc_next; 7524 mac_group_remove_client(fgrp, gmcip); 7525 mac_group_add_client(tgrp, gmcip); 7526 gmcip->mci_flent->fe_rx_ring_group = tgrp; 7527 } 7528 mac_release_rx_group(mcip, fgrp); 7529 VERIFY3B(MAC_GROUP_NO_CLIENT(fgrp), ==, B_TRUE); 7530 mac_set_group_state(fgrp, MAC_GROUP_STATE_REGISTERED); 7531 } else { 7532 mac_group_remove_client(fgrp, mcip); 7533 mac_group_add_client(tgrp, mcip); 7534 mcip->mci_flent->fe_rx_ring_group = tgrp; 7535 7536 /* 7537 * If there are other clients (VLANs) sharing this address 7538 * then move them too. 7539 */ 7540 if (mac_check_macaddr_shared(mcip->mci_unicast)) { 7541 /* 7542 * We need to move all the clients that are using 7543 * this MAC address. 7544 */ 7545 mgcp = fgrp->mrg_clients; 7546 while (mgcp != NULL) { 7547 gmcip = mgcp->mgc_client; 7548 mgcp = mgcp->mgc_next; 7549 if (mcip->mci_unicast == gmcip->mci_unicast) { 7550 mac_group_remove_client(fgrp, gmcip); 7551 mac_group_add_client(tgrp, gmcip); 7552 gmcip->mci_flent->fe_rx_ring_group = 7553 tgrp; 7554 } 7555 } 7556 } 7557 7558 /* 7559 * The default group still handles multicast and 7560 * broadcast traffic; it won't transition to 7561 * MAC_GROUP_STATE_REGISTERED. 7562 */ 7563 if (fgrp->mrg_state == MAC_GROUP_STATE_RESERVED) 7564 mac_rx_group_unmark(fgrp, MR_CONDEMNED); 7565 mac_set_group_state(fgrp, MAC_GROUP_STATE_SHARED); 7566 } 7567 7568 next_state = mac_group_next_state(tgrp, &group_only_mcip, 7569 MAC_DEFAULT_RX_GROUP(mip), B_TRUE); 7570 mac_set_group_state(tgrp, next_state); 7571 7572 /* 7573 * If the destination group is reserved, then setup the SRSes. 7574 * Otherwise make sure to use SW classification. 7575 */ 7576 if (tgrp->mrg_state == MAC_GROUP_STATE_RESERVED) { 7577 mac_rx_srs_group_setup(mcip, mcip->mci_flent, SRST_LINK); 7578 mac_fanout_setup(mcip, mcip->mci_flent, 7579 MCIP_RESOURCE_PROPS(mcip), mac_rx_deliver, mcip, NULL); 7580 mac_rx_group_unmark(tgrp, MR_INCIPIENT); 7581 } else { 7582 mac_rx_switch_grp_to_sw(tgrp); 7583 } 7584 7585 return (0); 7586 } 7587 7588 /* 7589 * Reserves a TX group for the specified share. Invoked by mac_tx_srs_setup() 7590 * when a share was allocated to the client. 7591 */ 7592 mac_group_t * 7593 mac_reserve_tx_group(mac_client_impl_t *mcip, boolean_t move) 7594 { 7595 mac_impl_t *mip = mcip->mci_mip; 7596 mac_group_t *grp = NULL; 7597 int rv; 7598 int i; 7599 int err; 7600 mac_group_t *defgrp; 7601 mac_share_handle_t share = mcip->mci_share; 7602 mac_resource_props_t *mrp = MCIP_RESOURCE_PROPS(mcip); 7603 int nrings; 7604 int defnrings; 7605 boolean_t need_exclgrp = B_FALSE; 7606 int need_rings = 0; 7607 mac_group_t *candidate_grp = NULL; 7608 mac_client_impl_t *gclient; 7609 mac_resource_props_t *gmrp; 7610 boolean_t txhw = mrp->mrp_mask & MRP_TX_RINGS; 7611 boolean_t unspec = mrp->mrp_mask & MRP_TXRINGS_UNSPEC; 7612 boolean_t isprimary; 7613 7614 isprimary = mcip->mci_flent->fe_type & FLOW_PRIMARY_MAC; 7615 7616 /* 7617 * When we come here for a VLAN on the primary (dladm create-vlan), 7618 * we need to pair it along with the primary (to keep it consistent 7619 * with the RX side). So, we check if the primary is already assigned 7620 * to a group and return the group if so. The other way is also 7621 * true, i.e. the VLAN is already created and now we are plumbing 7622 * the primary. 7623 */ 7624 if (!move && isprimary) { 7625 for (gclient = mip->mi_clients_list; gclient != NULL; 7626 gclient = gclient->mci_client_next) { 7627 if (gclient->mci_flent->fe_type & FLOW_PRIMARY_MAC && 7628 gclient->mci_flent->fe_tx_ring_group != NULL) { 7629 return (gclient->mci_flent->fe_tx_ring_group); 7630 } 7631 } 7632 } 7633 7634 if (mip->mi_tx_groups == NULL || mip->mi_tx_group_count == 0) 7635 return (NULL); 7636 7637 /* For dynamic groups, default unspec to 1 */ 7638 if (txhw && unspec && 7639 mip->mi_tx_group_type == MAC_GROUP_TYPE_DYNAMIC) { 7640 mrp->mrp_ntxrings = 1; 7641 } 7642 /* 7643 * For static grouping we allow only specifying rings=0 and 7644 * unspecified 7645 */ 7646 if (txhw && mrp->mrp_ntxrings > 0 && 7647 mip->mi_tx_group_type == MAC_GROUP_TYPE_STATIC) { 7648 return (NULL); 7649 } 7650 7651 if (txhw) { 7652 /* 7653 * We have explicitly asked for a group (with ntxrings, 7654 * if unspec). 7655 */ 7656 if (unspec || mrp->mrp_ntxrings > 0) { 7657 need_exclgrp = B_TRUE; 7658 need_rings = mrp->mrp_ntxrings; 7659 } else if (mrp->mrp_ntxrings == 0) { 7660 /* 7661 * We have asked for a software group. 7662 */ 7663 return (NULL); 7664 } 7665 } 7666 defgrp = MAC_DEFAULT_TX_GROUP(mip); 7667 /* 7668 * The number of rings that the default group can donate. 7669 * We need to leave at least one ring - the default ring - in 7670 * this group. 7671 */ 7672 defnrings = defgrp->mrg_cur_count - 1; 7673 7674 /* 7675 * Primary gets default group unless explicitly told not 7676 * to (i.e. rings > 0). 7677 */ 7678 if (isprimary && !need_exclgrp) 7679 return (NULL); 7680 7681 nrings = (mrp->mrp_mask & MRP_TX_RINGS) != 0 ? mrp->mrp_ntxrings : 1; 7682 for (i = 0; i < mip->mi_tx_group_count; i++) { 7683 grp = &mip->mi_tx_groups[i]; 7684 if ((grp->mrg_state == MAC_GROUP_STATE_RESERVED) || 7685 (grp->mrg_state == MAC_GROUP_STATE_UNINIT)) { 7686 /* 7687 * Select a candidate for replacement if we don't 7688 * get an exclusive group. A candidate group is one 7689 * that didn't ask for an exclusive group, but got 7690 * one and it has enough rings (combined with what 7691 * the default group can donate) for the new MAC 7692 * client. 7693 */ 7694 if (grp->mrg_state == MAC_GROUP_STATE_RESERVED && 7695 candidate_grp == NULL) { 7696 gclient = MAC_GROUP_ONLY_CLIENT(grp); 7697 VERIFY3P(gclient, !=, NULL); 7698 gmrp = MCIP_RESOURCE_PROPS(gclient); 7699 if (gclient->mci_share == 0 && 7700 (gmrp->mrp_mask & MRP_TX_RINGS) == 0 && 7701 (unspec || 7702 (grp->mrg_cur_count + defnrings) >= 7703 need_rings)) { 7704 candidate_grp = grp; 7705 } 7706 } 7707 continue; 7708 } 7709 /* 7710 * If the default can't donate let's just walk and 7711 * see if someone can vacate a group, so that we have 7712 * enough rings for this. 7713 */ 7714 if (mip->mi_tx_group_type != MAC_GROUP_TYPE_DYNAMIC || 7715 nrings <= defnrings) { 7716 if (grp->mrg_state == MAC_GROUP_STATE_REGISTERED) { 7717 rv = mac_start_group(grp); 7718 ASSERT(rv == 0); 7719 } 7720 break; 7721 } 7722 } 7723 7724 /* The default group */ 7725 if (i >= mip->mi_tx_group_count) { 7726 /* 7727 * If we need an exclusive group and have identified a 7728 * candidate group we switch the MAC client from the 7729 * candidate group to the default group and give the 7730 * candidate group to this client. 7731 */ 7732 if (need_exclgrp && candidate_grp != NULL) { 7733 /* 7734 * Switch the MAC client from the candidate 7735 * group to the default group. We know the 7736 * candidate_grp came from a reserved group 7737 * and thus only has one client. 7738 */ 7739 grp = candidate_grp; 7740 gclient = MAC_GROUP_ONLY_CLIENT(grp); 7741 VERIFY3P(gclient, !=, NULL); 7742 mac_tx_client_quiesce((mac_client_handle_t)gclient); 7743 mac_tx_switch_group(gclient, grp, defgrp); 7744 mac_tx_client_restart((mac_client_handle_t)gclient); 7745 7746 /* 7747 * Give the candidate group with the specified number 7748 * of rings to this MAC client. 7749 */ 7750 ASSERT(grp->mrg_state == MAC_GROUP_STATE_REGISTERED); 7751 rv = mac_start_group(grp); 7752 ASSERT(rv == 0); 7753 7754 if (mip->mi_tx_group_type != MAC_GROUP_TYPE_DYNAMIC) 7755 return (grp); 7756 7757 ASSERT(grp->mrg_cur_count == 0); 7758 ASSERT(defgrp->mrg_cur_count > need_rings); 7759 7760 err = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_TX, 7761 defgrp, grp, share, need_rings); 7762 if (err == 0) { 7763 /* 7764 * For a share i_mac_group_allocate_rings gets 7765 * the rings from the driver, let's populate 7766 * the property for the client now. 7767 */ 7768 if (share != 0) { 7769 mac_client_set_rings( 7770 (mac_client_handle_t)mcip, -1, 7771 grp->mrg_cur_count); 7772 } 7773 mip->mi_tx_group_free--; 7774 return (grp); 7775 } 7776 DTRACE_PROBE3(tx__group__reserve__alloc__rings, char *, 7777 mip->mi_name, int, grp->mrg_index, int, err); 7778 mac_stop_group(grp); 7779 } 7780 return (NULL); 7781 } 7782 /* 7783 * We got an exclusive group, but it is not dynamic. 7784 */ 7785 if (mip->mi_tx_group_type != MAC_GROUP_TYPE_DYNAMIC) { 7786 mip->mi_tx_group_free--; 7787 return (grp); 7788 } 7789 7790 rv = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_TX, defgrp, grp, 7791 share, nrings); 7792 if (rv != 0) { 7793 DTRACE_PROBE3(tx__group__reserve__alloc__rings, 7794 char *, mip->mi_name, int, grp->mrg_index, int, rv); 7795 mac_stop_group(grp); 7796 return (NULL); 7797 } 7798 /* 7799 * For a share i_mac_group_allocate_rings gets the rings from the 7800 * driver, let's populate the property for the client now. 7801 */ 7802 if (share != 0) { 7803 mac_client_set_rings((mac_client_handle_t)mcip, -1, 7804 grp->mrg_cur_count); 7805 } 7806 mip->mi_tx_group_free--; 7807 return (grp); 7808 } 7809 7810 void 7811 mac_release_tx_group(mac_client_impl_t *mcip, mac_group_t *grp) 7812 { 7813 mac_impl_t *mip = mcip->mci_mip; 7814 mac_share_handle_t share = mcip->mci_share; 7815 mac_ring_t *ring; 7816 mac_soft_ring_set_t *srs = MCIP_TX_SRS(mcip); 7817 mac_group_t *defgrp; 7818 7819 defgrp = MAC_DEFAULT_TX_GROUP(mip); 7820 if (srs != NULL) { 7821 if (srs->srs_soft_ring_count > 0) { 7822 for (ring = grp->mrg_rings; ring != NULL; 7823 ring = ring->mr_next) { 7824 ASSERT(mac_tx_srs_ring_present(srs, ring)); 7825 mac_tx_invoke_callbacks(mcip, 7826 (mac_tx_cookie_t) 7827 mac_tx_srs_get_soft_ring(srs, ring)); 7828 mac_tx_srs_del_ring(srs, ring); 7829 } 7830 } else { 7831 ASSERT(srs->srs_tx.st_arg2 != NULL); 7832 srs->srs_tx.st_arg2 = NULL; 7833 mac_srs_stat_delete(srs); 7834 } 7835 } 7836 if (share != 0) 7837 mip->mi_share_capab.ms_sremove(share, grp->mrg_driver); 7838 7839 /* move the ring back to the pool */ 7840 if (mip->mi_tx_group_type == MAC_GROUP_TYPE_DYNAMIC) { 7841 while ((ring = grp->mrg_rings) != NULL) 7842 (void) mac_group_mov_ring(mip, defgrp, ring); 7843 } 7844 mac_stop_group(grp); 7845 mip->mi_tx_group_free++; 7846 } 7847 7848 /* 7849 * Disassociate a MAC client from a group, i.e go through the rings in the 7850 * group and delete all the soft rings tied to them. 7851 */ 7852 static void 7853 mac_tx_dismantle_soft_rings(mac_group_t *fgrp, flow_entry_t *flent) 7854 { 7855 mac_client_impl_t *mcip = flent->fe_mcip; 7856 mac_soft_ring_set_t *tx_srs; 7857 mac_srs_tx_t *tx; 7858 mac_ring_t *ring; 7859 7860 tx_srs = flent->fe_tx_srs; 7861 tx = &tx_srs->srs_tx; 7862 7863 /* Single ring case we haven't created any soft rings */ 7864 if (tx->st_mode == SRS_TX_BW || tx->st_mode == SRS_TX_SERIALIZE || 7865 tx->st_mode == SRS_TX_DEFAULT) { 7866 tx->st_arg2 = NULL; 7867 mac_srs_stat_delete(tx_srs); 7868 /* Fanout case, where we have to dismantle the soft rings */ 7869 } else { 7870 for (ring = fgrp->mrg_rings; ring != NULL; 7871 ring = ring->mr_next) { 7872 ASSERT(mac_tx_srs_ring_present(tx_srs, ring)); 7873 mac_tx_invoke_callbacks(mcip, 7874 (mac_tx_cookie_t)mac_tx_srs_get_soft_ring(tx_srs, 7875 ring)); 7876 mac_tx_srs_del_ring(tx_srs, ring); 7877 } 7878 ASSERT(tx->st_arg2 == NULL); 7879 } 7880 } 7881 7882 /* 7883 * Switch the MAC client from one group to another. This means we need 7884 * to remove the MAC client, teardown the SRSs and revert the group state. 7885 * Then, we add the client to the destination roup, set the SRSs etc. 7886 */ 7887 void 7888 mac_tx_switch_group(mac_client_impl_t *mcip, mac_group_t *fgrp, 7889 mac_group_t *tgrp) 7890 { 7891 mac_client_impl_t *group_only_mcip; 7892 mac_impl_t *mip = mcip->mci_mip; 7893 flow_entry_t *flent = mcip->mci_flent; 7894 mac_group_t *defgrp; 7895 mac_grp_client_t *mgcp; 7896 mac_client_impl_t *gmcip; 7897 flow_entry_t *gflent; 7898 7899 defgrp = MAC_DEFAULT_TX_GROUP(mip); 7900 ASSERT(fgrp == flent->fe_tx_ring_group); 7901 7902 if (fgrp == defgrp) { 7903 /* 7904 * If this is the primary we need to find any VLANs on 7905 * the primary and move them too. 7906 */ 7907 mac_group_remove_client(fgrp, mcip); 7908 mac_tx_dismantle_soft_rings(fgrp, flent); 7909 if (mac_check_macaddr_shared(mcip->mci_unicast)) { 7910 mgcp = fgrp->mrg_clients; 7911 while (mgcp != NULL) { 7912 gmcip = mgcp->mgc_client; 7913 mgcp = mgcp->mgc_next; 7914 if (mcip->mci_unicast != gmcip->mci_unicast) 7915 continue; 7916 mac_tx_client_quiesce( 7917 (mac_client_handle_t)gmcip); 7918 7919 gflent = gmcip->mci_flent; 7920 mac_group_remove_client(fgrp, gmcip); 7921 mac_tx_dismantle_soft_rings(fgrp, gflent); 7922 7923 mac_group_add_client(tgrp, gmcip); 7924 gflent->fe_tx_ring_group = tgrp; 7925 /* We could directly set this to SHARED */ 7926 tgrp->mrg_state = mac_group_next_state(tgrp, 7927 &group_only_mcip, defgrp, B_FALSE); 7928 7929 mac_tx_srs_group_setup(gmcip, gflent, 7930 SRST_LINK); 7931 mac_fanout_setup(gmcip, gflent, 7932 MCIP_RESOURCE_PROPS(gmcip), mac_rx_deliver, 7933 gmcip, NULL); 7934 7935 mac_tx_client_restart( 7936 (mac_client_handle_t)gmcip); 7937 } 7938 } 7939 if (MAC_GROUP_NO_CLIENT(fgrp)) { 7940 mac_ring_t *ring; 7941 int cnt; 7942 int ringcnt; 7943 7944 fgrp->mrg_state = MAC_GROUP_STATE_REGISTERED; 7945 /* 7946 * Additionally, we also need to stop all 7947 * the rings in the default group, except 7948 * the default ring. The reason being 7949 * this group won't be released since it is 7950 * the default group, so the rings won't 7951 * be stopped otherwise. 7952 */ 7953 ringcnt = fgrp->mrg_cur_count; 7954 ring = fgrp->mrg_rings; 7955 for (cnt = 0; cnt < ringcnt; cnt++) { 7956 if (ring->mr_state == MR_INUSE && 7957 ring != 7958 (mac_ring_t *)mip->mi_default_tx_ring) { 7959 mac_stop_ring(ring); 7960 ring->mr_flag = 0; 7961 } 7962 ring = ring->mr_next; 7963 } 7964 } else if (MAC_GROUP_ONLY_CLIENT(fgrp) != NULL) { 7965 fgrp->mrg_state = MAC_GROUP_STATE_RESERVED; 7966 } else { 7967 ASSERT(fgrp->mrg_state == MAC_GROUP_STATE_SHARED); 7968 } 7969 } else { 7970 /* 7971 * We could have VLANs sharing the non-default group with 7972 * the primary. 7973 */ 7974 mgcp = fgrp->mrg_clients; 7975 while (mgcp != NULL) { 7976 gmcip = mgcp->mgc_client; 7977 mgcp = mgcp->mgc_next; 7978 if (gmcip == mcip) 7979 continue; 7980 mac_tx_client_quiesce((mac_client_handle_t)gmcip); 7981 gflent = gmcip->mci_flent; 7982 7983 mac_group_remove_client(fgrp, gmcip); 7984 mac_tx_dismantle_soft_rings(fgrp, gflent); 7985 7986 mac_group_add_client(tgrp, gmcip); 7987 gflent->fe_tx_ring_group = tgrp; 7988 /* We could directly set this to SHARED */ 7989 tgrp->mrg_state = mac_group_next_state(tgrp, 7990 &group_only_mcip, defgrp, B_FALSE); 7991 mac_tx_srs_group_setup(gmcip, gflent, SRST_LINK); 7992 mac_fanout_setup(gmcip, gflent, 7993 MCIP_RESOURCE_PROPS(gmcip), mac_rx_deliver, 7994 gmcip, NULL); 7995 7996 mac_tx_client_restart((mac_client_handle_t)gmcip); 7997 } 7998 mac_group_remove_client(fgrp, mcip); 7999 mac_release_tx_group(mcip, fgrp); 8000 fgrp->mrg_state = MAC_GROUP_STATE_REGISTERED; 8001 } 8002 8003 /* Add it to the tgroup */ 8004 mac_group_add_client(tgrp, mcip); 8005 flent->fe_tx_ring_group = tgrp; 8006 tgrp->mrg_state = mac_group_next_state(tgrp, &group_only_mcip, 8007 defgrp, B_FALSE); 8008 8009 mac_tx_srs_group_setup(mcip, flent, SRST_LINK); 8010 mac_fanout_setup(mcip, flent, MCIP_RESOURCE_PROPS(mcip), 8011 mac_rx_deliver, mcip, NULL); 8012 } 8013 8014 /* 8015 * This is a 1-time control path activity initiated by the client (IP). 8016 * The mac perimeter protects against other simultaneous control activities, 8017 * for example an ioctl that attempts to change the degree of fanout and 8018 * increase or decrease the number of softrings associated with this Tx SRS. 8019 */ 8020 static mac_tx_notify_cb_t * 8021 mac_client_tx_notify_add(mac_client_impl_t *mcip, 8022 mac_tx_notify_t notify, void *arg) 8023 { 8024 mac_cb_info_t *mcbi; 8025 mac_tx_notify_cb_t *mtnfp; 8026 8027 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 8028 8029 mtnfp = kmem_zalloc(sizeof (mac_tx_notify_cb_t), KM_SLEEP); 8030 mtnfp->mtnf_fn = notify; 8031 mtnfp->mtnf_arg = arg; 8032 mtnfp->mtnf_link.mcb_objp = mtnfp; 8033 mtnfp->mtnf_link.mcb_objsize = sizeof (mac_tx_notify_cb_t); 8034 mtnfp->mtnf_link.mcb_flags = MCB_TX_NOTIFY_CB_T; 8035 8036 mcbi = &mcip->mci_tx_notify_cb_info; 8037 mutex_enter(mcbi->mcbi_lockp); 8038 mac_callback_add(mcbi, &mcip->mci_tx_notify_cb_list, &mtnfp->mtnf_link); 8039 mutex_exit(mcbi->mcbi_lockp); 8040 return (mtnfp); 8041 } 8042 8043 static void 8044 mac_client_tx_notify_remove(mac_client_impl_t *mcip, mac_tx_notify_cb_t *mtnfp) 8045 { 8046 mac_cb_info_t *mcbi; 8047 mac_cb_t **cblist; 8048 8049 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 8050 8051 if (!mac_callback_find(&mcip->mci_tx_notify_cb_info, 8052 &mcip->mci_tx_notify_cb_list, &mtnfp->mtnf_link)) { 8053 cmn_err(CE_WARN, 8054 "mac_client_tx_notify_remove: callback not " 8055 "found, mcip 0x%p mtnfp 0x%p", (void *)mcip, (void *)mtnfp); 8056 return; 8057 } 8058 8059 mcbi = &mcip->mci_tx_notify_cb_info; 8060 cblist = &mcip->mci_tx_notify_cb_list; 8061 mutex_enter(mcbi->mcbi_lockp); 8062 if (mac_callback_remove(mcbi, cblist, &mtnfp->mtnf_link)) 8063 kmem_free(mtnfp, sizeof (mac_tx_notify_cb_t)); 8064 else 8065 mac_callback_remove_wait(&mcip->mci_tx_notify_cb_info); 8066 mutex_exit(mcbi->mcbi_lockp); 8067 } 8068 8069 /* 8070 * mac_client_tx_notify(): 8071 * call to add and remove flow control callback routine. 8072 */ 8073 mac_tx_notify_handle_t 8074 mac_client_tx_notify(mac_client_handle_t mch, mac_tx_notify_t callb_func, 8075 void *ptr) 8076 { 8077 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 8078 mac_tx_notify_cb_t *mtnfp = NULL; 8079 8080 i_mac_perim_enter(mcip->mci_mip); 8081 8082 if (callb_func != NULL) { 8083 /* Add a notify callback */ 8084 mtnfp = mac_client_tx_notify_add(mcip, callb_func, ptr); 8085 } else { 8086 mac_client_tx_notify_remove(mcip, (mac_tx_notify_cb_t *)ptr); 8087 } 8088 i_mac_perim_exit(mcip->mci_mip); 8089 8090 return ((mac_tx_notify_handle_t)mtnfp); 8091 } 8092 8093 void 8094 mac_bridge_vectors(mac_bridge_tx_t txf, mac_bridge_rx_t rxf, 8095 mac_bridge_ref_t reff, mac_bridge_ls_t lsf) 8096 { 8097 mac_bridge_tx_cb = txf; 8098 mac_bridge_rx_cb = rxf; 8099 mac_bridge_ref_cb = reff; 8100 mac_bridge_ls_cb = lsf; 8101 } 8102 8103 int 8104 mac_bridge_set(mac_handle_t mh, mac_handle_t link) 8105 { 8106 mac_impl_t *mip = (mac_impl_t *)mh; 8107 int retv; 8108 8109 mutex_enter(&mip->mi_bridge_lock); 8110 if (mip->mi_bridge_link == NULL) { 8111 mip->mi_bridge_link = link; 8112 retv = 0; 8113 } else { 8114 retv = EBUSY; 8115 } 8116 mutex_exit(&mip->mi_bridge_lock); 8117 if (retv == 0) { 8118 mac_poll_state_change(mh, B_FALSE); 8119 mac_capab_update(mh); 8120 } 8121 return (retv); 8122 } 8123 8124 /* 8125 * Disable bridging on the indicated link. 8126 */ 8127 void 8128 mac_bridge_clear(mac_handle_t mh, mac_handle_t link) 8129 { 8130 mac_impl_t *mip = (mac_impl_t *)mh; 8131 8132 mutex_enter(&mip->mi_bridge_lock); 8133 ASSERT(mip->mi_bridge_link == link); 8134 mip->mi_bridge_link = NULL; 8135 mutex_exit(&mip->mi_bridge_lock); 8136 mac_poll_state_change(mh, B_TRUE); 8137 mac_capab_update(mh); 8138 } 8139 8140 void 8141 mac_no_active(mac_handle_t mh) 8142 { 8143 mac_impl_t *mip = (mac_impl_t *)mh; 8144 8145 i_mac_perim_enter(mip); 8146 mip->mi_state_flags |= MIS_NO_ACTIVE; 8147 i_mac_perim_exit(mip); 8148 } 8149 8150 /* 8151 * Walk the primary VLAN clients whenever the primary's rings property 8152 * changes and update the mac_resource_props_t for the VLAN's client. 8153 * We need to do this since we don't support setting these properties 8154 * on the primary's VLAN clients, but the VLAN clients have to 8155 * follow the primary w.r.t the rings property. 8156 */ 8157 void 8158 mac_set_prim_vlan_rings(mac_impl_t *mip, mac_resource_props_t *mrp) 8159 { 8160 mac_client_impl_t *vmcip; 8161 mac_resource_props_t *vmrp; 8162 8163 for (vmcip = mip->mi_clients_list; vmcip != NULL; 8164 vmcip = vmcip->mci_client_next) { 8165 if (!(vmcip->mci_flent->fe_type & FLOW_PRIMARY_MAC) || 8166 mac_client_vid((mac_client_handle_t)vmcip) == 8167 VLAN_ID_NONE) { 8168 continue; 8169 } 8170 vmrp = MCIP_RESOURCE_PROPS(vmcip); 8171 8172 vmrp->mrp_nrxrings = mrp->mrp_nrxrings; 8173 if (mrp->mrp_mask & MRP_RX_RINGS) 8174 vmrp->mrp_mask |= MRP_RX_RINGS; 8175 else if (vmrp->mrp_mask & MRP_RX_RINGS) 8176 vmrp->mrp_mask &= ~MRP_RX_RINGS; 8177 8178 vmrp->mrp_ntxrings = mrp->mrp_ntxrings; 8179 if (mrp->mrp_mask & MRP_TX_RINGS) 8180 vmrp->mrp_mask |= MRP_TX_RINGS; 8181 else if (vmrp->mrp_mask & MRP_TX_RINGS) 8182 vmrp->mrp_mask &= ~MRP_TX_RINGS; 8183 8184 if (mrp->mrp_mask & MRP_RXRINGS_UNSPEC) 8185 vmrp->mrp_mask |= MRP_RXRINGS_UNSPEC; 8186 else 8187 vmrp->mrp_mask &= ~MRP_RXRINGS_UNSPEC; 8188 8189 if (mrp->mrp_mask & MRP_TXRINGS_UNSPEC) 8190 vmrp->mrp_mask |= MRP_TXRINGS_UNSPEC; 8191 else 8192 vmrp->mrp_mask &= ~MRP_TXRINGS_UNSPEC; 8193 } 8194 } 8195 8196 /* 8197 * We are adding or removing ring(s) from a group. The source for taking 8198 * rings is the default group. The destination for giving rings back is 8199 * the default group. 8200 */ 8201 int 8202 mac_group_ring_modify(mac_client_impl_t *mcip, mac_group_t *group, 8203 mac_group_t *defgrp) 8204 { 8205 mac_resource_props_t *mrp = MCIP_RESOURCE_PROPS(mcip); 8206 uint_t modify; 8207 int count; 8208 mac_ring_t *ring; 8209 mac_ring_t *next; 8210 mac_impl_t *mip = mcip->mci_mip; 8211 mac_ring_t **rings; 8212 uint_t ringcnt; 8213 int i = 0; 8214 boolean_t rx_group = group->mrg_type == MAC_RING_TYPE_RX; 8215 int start; 8216 int end; 8217 mac_group_t *tgrp; 8218 int j; 8219 int rv = 0; 8220 8221 /* 8222 * If we are asked for just a group, we give 1 ring, else 8223 * the specified number of rings. 8224 */ 8225 if (rx_group) { 8226 ringcnt = (mrp->mrp_mask & MRP_RXRINGS_UNSPEC) ? 1: 8227 mrp->mrp_nrxrings; 8228 } else { 8229 ringcnt = (mrp->mrp_mask & MRP_TXRINGS_UNSPEC) ? 1: 8230 mrp->mrp_ntxrings; 8231 } 8232 8233 /* don't allow modifying rings for a share for now. */ 8234 ASSERT(mcip->mci_share == 0); 8235 8236 if (ringcnt == group->mrg_cur_count) 8237 return (0); 8238 8239 if (group->mrg_cur_count > ringcnt) { 8240 modify = group->mrg_cur_count - ringcnt; 8241 if (rx_group) { 8242 if (mip->mi_rx_donor_grp == group) { 8243 ASSERT(mac_is_primary_client(mcip)); 8244 mip->mi_rx_donor_grp = defgrp; 8245 } else { 8246 defgrp = mip->mi_rx_donor_grp; 8247 } 8248 } 8249 ring = group->mrg_rings; 8250 rings = kmem_alloc(modify * sizeof (mac_ring_handle_t), 8251 KM_SLEEP); 8252 j = 0; 8253 for (count = 0; count < modify; count++) { 8254 next = ring->mr_next; 8255 rv = mac_group_mov_ring(mip, defgrp, ring); 8256 if (rv != 0) { 8257 /* cleanup on failure */ 8258 for (j = 0; j < count; j++) { 8259 (void) mac_group_mov_ring(mip, group, 8260 rings[j]); 8261 } 8262 break; 8263 } 8264 rings[j++] = ring; 8265 ring = next; 8266 } 8267 kmem_free(rings, modify * sizeof (mac_ring_handle_t)); 8268 return (rv); 8269 } 8270 if (ringcnt >= MAX_RINGS_PER_GROUP) 8271 return (EINVAL); 8272 8273 modify = ringcnt - group->mrg_cur_count; 8274 8275 if (rx_group) { 8276 if (group != mip->mi_rx_donor_grp) 8277 defgrp = mip->mi_rx_donor_grp; 8278 else 8279 /* 8280 * This is the donor group with all the remaining 8281 * rings. Default group now gets to be the donor 8282 */ 8283 mip->mi_rx_donor_grp = defgrp; 8284 start = 1; 8285 end = mip->mi_rx_group_count; 8286 } else { 8287 start = 0; 8288 end = mip->mi_tx_group_count - 1; 8289 } 8290 /* 8291 * If the default doesn't have any rings, lets see if we can 8292 * take rings given to an h/w client that doesn't need it. 8293 * For now, we just see if there is any one client that can donate 8294 * all the required rings. 8295 */ 8296 if (defgrp->mrg_cur_count < (modify + 1)) { 8297 for (i = start; i < end; i++) { 8298 if (rx_group) { 8299 tgrp = &mip->mi_rx_groups[i]; 8300 if (tgrp == group || tgrp->mrg_state < 8301 MAC_GROUP_STATE_RESERVED) { 8302 continue; 8303 } 8304 if (i_mac_clients_hw(tgrp, MRP_RX_RINGS)) 8305 continue; 8306 mcip = tgrp->mrg_clients->mgc_client; 8307 VERIFY3P(mcip, !=, NULL); 8308 if ((tgrp->mrg_cur_count + 8309 defgrp->mrg_cur_count) < (modify + 1)) { 8310 continue; 8311 } 8312 if (mac_rx_switch_group(mcip, tgrp, 8313 defgrp) != 0) { 8314 return (ENOSPC); 8315 } 8316 } else { 8317 tgrp = &mip->mi_tx_groups[i]; 8318 if (tgrp == group || tgrp->mrg_state < 8319 MAC_GROUP_STATE_RESERVED) { 8320 continue; 8321 } 8322 if (i_mac_clients_hw(tgrp, MRP_TX_RINGS)) 8323 continue; 8324 mcip = tgrp->mrg_clients->mgc_client; 8325 VERIFY3P(mcip, !=, NULL); 8326 if ((tgrp->mrg_cur_count + 8327 defgrp->mrg_cur_count) < (modify + 1)) { 8328 continue; 8329 } 8330 /* OK, we can switch this to s/w */ 8331 mac_tx_client_quiesce( 8332 (mac_client_handle_t)mcip); 8333 mac_tx_switch_group(mcip, tgrp, defgrp); 8334 mac_tx_client_restart( 8335 (mac_client_handle_t)mcip); 8336 } 8337 } 8338 if (defgrp->mrg_cur_count < (modify + 1)) 8339 return (ENOSPC); 8340 } 8341 if ((rv = i_mac_group_allocate_rings(mip, group->mrg_type, defgrp, 8342 group, mcip->mci_share, modify)) != 0) { 8343 return (rv); 8344 } 8345 return (0); 8346 } 8347 8348 /* 8349 * Given the poolname in mac_resource_props, find the cpupart 8350 * that is associated with this pool. The cpupart will be used 8351 * later for finding the cpus to be bound to the networking threads. 8352 * 8353 * use_default is set B_TRUE if pools are enabled and pool_default 8354 * is returned. This avoids a 2nd lookup to set the poolname 8355 * for pool-effective. 8356 * 8357 * returns: 8358 * 8359 * NULL - pools are disabled or if the 'cpus' property is set. 8360 * cpupart of pool_default - pools are enabled and the pool 8361 * is not available or poolname is blank 8362 * cpupart of named pool - pools are enabled and the pool 8363 * is available. 8364 */ 8365 cpupart_t * 8366 mac_pset_find(mac_resource_props_t *mrp, boolean_t *use_default) 8367 { 8368 pool_t *pool; 8369 cpupart_t *cpupart; 8370 8371 *use_default = B_FALSE; 8372 8373 /* CPUs property is set */ 8374 if (mrp->mrp_mask & MRP_CPUS) 8375 return (NULL); 8376 8377 ASSERT(pool_lock_held()); 8378 8379 /* Pools are disabled, no pset */ 8380 if (pool_state == POOL_DISABLED) 8381 return (NULL); 8382 8383 /* Pools property is set */ 8384 if (mrp->mrp_mask & MRP_POOL) { 8385 if ((pool = pool_lookup_pool_by_name(mrp->mrp_pool)) == NULL) { 8386 /* Pool not found */ 8387 DTRACE_PROBE1(mac_pset_find_no_pool, char *, 8388 mrp->mrp_pool); 8389 *use_default = B_TRUE; 8390 pool = pool_default; 8391 } 8392 /* Pools property is not set */ 8393 } else { 8394 *use_default = B_TRUE; 8395 pool = pool_default; 8396 } 8397 8398 /* Find the CPU pset that corresponds to the pool */ 8399 mutex_enter(&cpu_lock); 8400 if ((cpupart = cpupart_find(pool->pool_pset->pset_id)) == NULL) { 8401 DTRACE_PROBE1(mac_find_pset_no_pset, psetid_t, 8402 pool->pool_pset->pset_id); 8403 } 8404 mutex_exit(&cpu_lock); 8405 8406 return (cpupart); 8407 } 8408 8409 void 8410 mac_set_pool_effective(boolean_t use_default, cpupart_t *cpupart, 8411 mac_resource_props_t *mrp, mac_resource_props_t *emrp) 8412 { 8413 ASSERT(pool_lock_held()); 8414 8415 if (cpupart != NULL) { 8416 emrp->mrp_mask |= MRP_POOL; 8417 if (use_default) { 8418 (void) strcpy(emrp->mrp_pool, 8419 "pool_default"); 8420 } else { 8421 ASSERT(strlen(mrp->mrp_pool) != 0); 8422 (void) strcpy(emrp->mrp_pool, 8423 mrp->mrp_pool); 8424 } 8425 } else { 8426 emrp->mrp_mask &= ~MRP_POOL; 8427 bzero(emrp->mrp_pool, MAXPATHLEN); 8428 } 8429 } 8430 8431 struct mac_pool_arg { 8432 char mpa_poolname[MAXPATHLEN]; 8433 pool_event_t mpa_what; 8434 }; 8435 8436 /*ARGSUSED*/ 8437 static uint_t 8438 mac_pool_link_update(mod_hash_key_t key, mod_hash_val_t *val, void *arg) 8439 { 8440 struct mac_pool_arg *mpa = arg; 8441 mac_impl_t *mip = (mac_impl_t *)val; 8442 mac_client_impl_t *mcip; 8443 mac_resource_props_t *mrp, *emrp; 8444 boolean_t pool_update = B_FALSE; 8445 boolean_t pool_clear = B_FALSE; 8446 boolean_t use_default = B_FALSE; 8447 cpupart_t *cpupart = NULL; 8448 8449 mrp = kmem_zalloc(sizeof (*mrp), KM_SLEEP); 8450 i_mac_perim_enter(mip); 8451 for (mcip = mip->mi_clients_list; mcip != NULL; 8452 mcip = mcip->mci_client_next) { 8453 pool_update = B_FALSE; 8454 pool_clear = B_FALSE; 8455 use_default = B_FALSE; 8456 mac_client_get_resources((mac_client_handle_t)mcip, mrp); 8457 emrp = MCIP_EFFECTIVE_PROPS(mcip); 8458 8459 /* 8460 * When pools are enabled 8461 */ 8462 if ((mpa->mpa_what == POOL_E_ENABLE) && 8463 ((mrp->mrp_mask & MRP_CPUS) == 0)) { 8464 mrp->mrp_mask |= MRP_POOL; 8465 pool_update = B_TRUE; 8466 } 8467 8468 /* 8469 * When pools are disabled 8470 */ 8471 if ((mpa->mpa_what == POOL_E_DISABLE) && 8472 ((mrp->mrp_mask & MRP_CPUS) == 0)) { 8473 mrp->mrp_mask |= MRP_POOL; 8474 pool_clear = B_TRUE; 8475 } 8476 8477 /* 8478 * Look for links with the pool property set and the poolname 8479 * matching the one which is changing. 8480 */ 8481 if (strcmp(mrp->mrp_pool, mpa->mpa_poolname) == 0) { 8482 /* 8483 * The pool associated with the link has changed. 8484 */ 8485 if (mpa->mpa_what == POOL_E_CHANGE) { 8486 mrp->mrp_mask |= MRP_POOL; 8487 pool_update = B_TRUE; 8488 } 8489 } 8490 8491 /* 8492 * This link is associated with pool_default and 8493 * pool_default has changed. 8494 */ 8495 if ((mpa->mpa_what == POOL_E_CHANGE) && 8496 (strcmp(emrp->mrp_pool, "pool_default") == 0) && 8497 (strcmp(mpa->mpa_poolname, "pool_default") == 0)) { 8498 mrp->mrp_mask |= MRP_POOL; 8499 pool_update = B_TRUE; 8500 } 8501 8502 /* 8503 * Get new list of cpus for the pool, bind network 8504 * threads to new list of cpus and update resources. 8505 */ 8506 if (pool_update) { 8507 if (MCIP_DATAPATH_SETUP(mcip)) { 8508 pool_lock(); 8509 cpupart = mac_pset_find(mrp, &use_default); 8510 mac_fanout_setup(mcip, mcip->mci_flent, mrp, 8511 mac_rx_deliver, mcip, cpupart); 8512 mac_set_pool_effective(use_default, cpupart, 8513 mrp, emrp); 8514 pool_unlock(); 8515 } 8516 mac_update_resources(mrp, MCIP_RESOURCE_PROPS(mcip), 8517 B_FALSE); 8518 } 8519 8520 /* 8521 * Clear the effective pool and bind network threads 8522 * to any available CPU. 8523 */ 8524 if (pool_clear) { 8525 if (MCIP_DATAPATH_SETUP(mcip)) { 8526 emrp->mrp_mask &= ~MRP_POOL; 8527 bzero(emrp->mrp_pool, MAXPATHLEN); 8528 mac_fanout_setup(mcip, mcip->mci_flent, mrp, 8529 mac_rx_deliver, mcip, NULL); 8530 } 8531 mac_update_resources(mrp, MCIP_RESOURCE_PROPS(mcip), 8532 B_FALSE); 8533 } 8534 } 8535 i_mac_perim_exit(mip); 8536 kmem_free(mrp, sizeof (*mrp)); 8537 return (MH_WALK_CONTINUE); 8538 } 8539 8540 static void 8541 mac_pool_update(void *arg) 8542 { 8543 mod_hash_walk(i_mac_impl_hash, mac_pool_link_update, arg); 8544 kmem_free(arg, sizeof (struct mac_pool_arg)); 8545 } 8546 8547 /* 8548 * Callback function to be executed when a noteworthy pool event 8549 * takes place. 8550 */ 8551 /* ARGSUSED */ 8552 static void 8553 mac_pool_event_cb(pool_event_t what, poolid_t id, void *arg) 8554 { 8555 pool_t *pool; 8556 char *poolname = NULL; 8557 struct mac_pool_arg *mpa; 8558 8559 pool_lock(); 8560 mpa = kmem_zalloc(sizeof (struct mac_pool_arg), KM_SLEEP); 8561 8562 switch (what) { 8563 case POOL_E_ENABLE: 8564 case POOL_E_DISABLE: 8565 break; 8566 8567 case POOL_E_CHANGE: 8568 pool = pool_lookup_pool_by_id(id); 8569 if (pool == NULL) { 8570 kmem_free(mpa, sizeof (struct mac_pool_arg)); 8571 pool_unlock(); 8572 return; 8573 } 8574 pool_get_name(pool, &poolname); 8575 (void) strlcpy(mpa->mpa_poolname, poolname, 8576 sizeof (mpa->mpa_poolname)); 8577 break; 8578 8579 default: 8580 kmem_free(mpa, sizeof (struct mac_pool_arg)); 8581 pool_unlock(); 8582 return; 8583 } 8584 pool_unlock(); 8585 8586 mpa->mpa_what = what; 8587 8588 mac_pool_update(mpa); 8589 } 8590 8591 /* 8592 * Set effective rings property. This could be called from datapath_setup/ 8593 * datapath_teardown or set-linkprop. 8594 * If the group is reserved we just go ahead and set the effective rings. 8595 * Additionally, for TX this could mean the default group has lost/gained 8596 * some rings, so if the default group is reserved, we need to adjust the 8597 * effective rings for the default group clients. For RX, if we are working 8598 * with the non-default group, we just need to reset the effective props 8599 * for the default group clients. 8600 */ 8601 void 8602 mac_set_rings_effective(mac_client_impl_t *mcip) 8603 { 8604 mac_impl_t *mip = mcip->mci_mip; 8605 mac_group_t *grp; 8606 mac_group_t *defgrp; 8607 flow_entry_t *flent = mcip->mci_flent; 8608 mac_resource_props_t *emrp = MCIP_EFFECTIVE_PROPS(mcip); 8609 mac_grp_client_t *mgcp; 8610 mac_client_impl_t *gmcip; 8611 8612 grp = flent->fe_rx_ring_group; 8613 if (grp != NULL) { 8614 defgrp = MAC_DEFAULT_RX_GROUP(mip); 8615 /* 8616 * If we have reserved a group, set the effective rings 8617 * to the ring count in the group. 8618 */ 8619 if (grp->mrg_state == MAC_GROUP_STATE_RESERVED) { 8620 emrp->mrp_mask |= MRP_RX_RINGS; 8621 emrp->mrp_nrxrings = grp->mrg_cur_count; 8622 } 8623 8624 /* 8625 * We go through the clients in the shared group and 8626 * reset the effective properties. It is possible this 8627 * might have already been done for some client (i.e. 8628 * if some client is being moved to a group that is 8629 * already shared). The case where the default group is 8630 * RESERVED is taken care of above (note in the RX side if 8631 * there is a non-default group, the default group is always 8632 * SHARED). 8633 */ 8634 if (grp != defgrp || grp->mrg_state == MAC_GROUP_STATE_SHARED) { 8635 if (grp->mrg_state == MAC_GROUP_STATE_SHARED) 8636 mgcp = grp->mrg_clients; 8637 else 8638 mgcp = defgrp->mrg_clients; 8639 while (mgcp != NULL) { 8640 gmcip = mgcp->mgc_client; 8641 emrp = MCIP_EFFECTIVE_PROPS(gmcip); 8642 if (emrp->mrp_mask & MRP_RX_RINGS) { 8643 emrp->mrp_mask &= ~MRP_RX_RINGS; 8644 emrp->mrp_nrxrings = 0; 8645 } 8646 mgcp = mgcp->mgc_next; 8647 } 8648 } 8649 } 8650 8651 /* Now the TX side */ 8652 grp = flent->fe_tx_ring_group; 8653 if (grp != NULL) { 8654 defgrp = MAC_DEFAULT_TX_GROUP(mip); 8655 8656 if (grp->mrg_state == MAC_GROUP_STATE_RESERVED) { 8657 emrp->mrp_mask |= MRP_TX_RINGS; 8658 emrp->mrp_ntxrings = grp->mrg_cur_count; 8659 } else if (grp->mrg_state == MAC_GROUP_STATE_SHARED) { 8660 mgcp = grp->mrg_clients; 8661 while (mgcp != NULL) { 8662 gmcip = mgcp->mgc_client; 8663 emrp = MCIP_EFFECTIVE_PROPS(gmcip); 8664 if (emrp->mrp_mask & MRP_TX_RINGS) { 8665 emrp->mrp_mask &= ~MRP_TX_RINGS; 8666 emrp->mrp_ntxrings = 0; 8667 } 8668 mgcp = mgcp->mgc_next; 8669 } 8670 } 8671 8672 /* 8673 * If the group is not the default group and the default 8674 * group is reserved, the ring count in the default group 8675 * might have changed, update it. 8676 */ 8677 if (grp != defgrp && 8678 defgrp->mrg_state == MAC_GROUP_STATE_RESERVED) { 8679 gmcip = MAC_GROUP_ONLY_CLIENT(defgrp); 8680 emrp = MCIP_EFFECTIVE_PROPS(gmcip); 8681 emrp->mrp_ntxrings = defgrp->mrg_cur_count; 8682 } 8683 } 8684 emrp = MCIP_EFFECTIVE_PROPS(mcip); 8685 } 8686 8687 /* 8688 * Check if the primary is in the default group. If so, see if we 8689 * can give it a an exclusive group now that another client is 8690 * being configured. We take the primary out of the default group 8691 * because the multicast/broadcast packets for the all the clients 8692 * will land in the default ring in the default group which means 8693 * any client in the default group, even if it is the only on in 8694 * the group, will lose exclusive access to the rings, hence 8695 * polling. 8696 */ 8697 mac_client_impl_t * 8698 mac_check_primary_relocation(mac_client_impl_t *mcip, boolean_t rxhw) 8699 { 8700 mac_impl_t *mip = mcip->mci_mip; 8701 mac_group_t *defgrp = MAC_DEFAULT_RX_GROUP(mip); 8702 flow_entry_t *flent = mcip->mci_flent; 8703 mac_resource_props_t *mrp = MCIP_RESOURCE_PROPS(mcip); 8704 uint8_t *mac_addr; 8705 mac_group_t *ngrp; 8706 8707 /* 8708 * Check if the primary is in the default group, if not 8709 * or if it is explicitly configured to be in the default 8710 * group OR set the RX rings property, return. 8711 */ 8712 if (flent->fe_rx_ring_group != defgrp || mrp->mrp_mask & MRP_RX_RINGS) 8713 return (NULL); 8714 8715 /* 8716 * If the new client needs an exclusive group and we 8717 * don't have another for the primary, return. 8718 */ 8719 if (rxhw && mip->mi_rxhwclnt_avail < 2) 8720 return (NULL); 8721 8722 mac_addr = flent->fe_flow_desc.fd_dst_mac; 8723 /* 8724 * We call this when we are setting up the datapath for 8725 * the first non-primary. 8726 */ 8727 ASSERT(mip->mi_nactiveclients == 2); 8728 8729 /* 8730 * OK, now we have the primary that needs to be relocated. 8731 */ 8732 ngrp = mac_reserve_rx_group(mcip, mac_addr, B_TRUE); 8733 if (ngrp == NULL) 8734 return (NULL); 8735 if (mac_rx_switch_group(mcip, defgrp, ngrp) != 0) { 8736 mac_stop_group(ngrp); 8737 return (NULL); 8738 } 8739 return (mcip); 8740 } 8741 8742 void 8743 mac_transceiver_init(mac_impl_t *mip) 8744 { 8745 if (mac_capab_get((mac_handle_t)mip, MAC_CAPAB_TRANSCEIVER, 8746 &mip->mi_transceiver)) { 8747 /* 8748 * The driver set a flag that we don't know about. In this case, 8749 * we need to warn about that case and ignore this capability. 8750 */ 8751 if (mip->mi_transceiver.mct_flags != 0) { 8752 dev_err(mip->mi_dip, CE_WARN, "driver set transceiver " 8753 "flags to invalid value: 0x%x, ignoring " 8754 "capability", mip->mi_transceiver.mct_flags); 8755 bzero(&mip->mi_transceiver, 8756 sizeof (mac_capab_transceiver_t)); 8757 } 8758 } else { 8759 bzero(&mip->mi_transceiver, 8760 sizeof (mac_capab_transceiver_t)); 8761 } 8762 } 8763 8764 int 8765 mac_transceiver_count(mac_handle_t mh, uint_t *countp) 8766 { 8767 mac_impl_t *mip = (mac_impl_t *)mh; 8768 8769 ASSERT(MAC_PERIM_HELD(mh)); 8770 8771 if (mip->mi_transceiver.mct_ntransceivers == 0) 8772 return (ENOTSUP); 8773 8774 *countp = mip->mi_transceiver.mct_ntransceivers; 8775 return (0); 8776 } 8777 8778 int 8779 mac_transceiver_info(mac_handle_t mh, uint_t tranid, boolean_t *present, 8780 boolean_t *usable) 8781 { 8782 int ret; 8783 mac_transceiver_info_t info; 8784 8785 mac_impl_t *mip = (mac_impl_t *)mh; 8786 8787 ASSERT(MAC_PERIM_HELD(mh)); 8788 8789 if (mip->mi_transceiver.mct_info == NULL || 8790 mip->mi_transceiver.mct_ntransceivers == 0) 8791 return (ENOTSUP); 8792 8793 if (tranid >= mip->mi_transceiver.mct_ntransceivers) 8794 return (EINVAL); 8795 8796 bzero(&info, sizeof (mac_transceiver_info_t)); 8797 if ((ret = mip->mi_transceiver.mct_info(mip->mi_driver, tranid, 8798 &info)) != 0) { 8799 return (ret); 8800 } 8801 8802 *present = info.mti_present; 8803 *usable = info.mti_usable; 8804 return (0); 8805 } 8806 8807 int 8808 mac_transceiver_read(mac_handle_t mh, uint_t tranid, uint_t page, void *buf, 8809 size_t nbytes, off_t offset, size_t *nread) 8810 { 8811 int ret; 8812 size_t nr; 8813 mac_impl_t *mip = (mac_impl_t *)mh; 8814 8815 ASSERT(MAC_PERIM_HELD(mh)); 8816 8817 if (mip->mi_transceiver.mct_read == NULL) 8818 return (ENOTSUP); 8819 8820 if (tranid >= mip->mi_transceiver.mct_ntransceivers) 8821 return (EINVAL); 8822 8823 /* 8824 * All supported pages today are 256 bytes wide. Make sure offset + 8825 * nbytes never exceeds that. 8826 */ 8827 if (offset < 0 || offset >= 256 || nbytes > 256 || 8828 offset + nbytes > 256) 8829 return (EINVAL); 8830 8831 if (nread == NULL) 8832 nread = &nr; 8833 ret = mip->mi_transceiver.mct_read(mip->mi_driver, tranid, page, buf, 8834 nbytes, offset, nread); 8835 if (ret == 0 && *nread > nbytes) { 8836 dev_err(mip->mi_dip, CE_PANIC, "driver wrote %lu bytes into " 8837 "%lu byte sized buffer, possible memory corruption", 8838 *nread, nbytes); 8839 } 8840 8841 return (ret); 8842 } 8843 8844 void 8845 mac_led_init(mac_impl_t *mip) 8846 { 8847 mip->mi_led_modes = MAC_LED_DEFAULT; 8848 8849 if (!mac_capab_get((mac_handle_t)mip, MAC_CAPAB_LED, &mip->mi_led)) { 8850 bzero(&mip->mi_led, sizeof (mac_capab_led_t)); 8851 return; 8852 } 8853 8854 if (mip->mi_led.mcl_flags != 0) { 8855 dev_err(mip->mi_dip, CE_WARN, "driver set led capability " 8856 "flags to invalid value: 0x%x, ignoring " 8857 "capability", mip->mi_transceiver.mct_flags); 8858 bzero(&mip->mi_led, sizeof (mac_capab_led_t)); 8859 return; 8860 } 8861 8862 if ((mip->mi_led.mcl_modes & ~MAC_LED_ALL) != 0) { 8863 dev_err(mip->mi_dip, CE_WARN, "driver set led capability " 8864 "supported modes to invalid value: 0x%x, ignoring " 8865 "capability", mip->mi_transceiver.mct_flags); 8866 bzero(&mip->mi_led, sizeof (mac_capab_led_t)); 8867 return; 8868 } 8869 } 8870 8871 int 8872 mac_led_get(mac_handle_t mh, mac_led_mode_t *supported, mac_led_mode_t *active) 8873 { 8874 mac_impl_t *mip = (mac_impl_t *)mh; 8875 8876 ASSERT(MAC_PERIM_HELD(mh)); 8877 8878 if (mip->mi_led.mcl_set == NULL) 8879 return (ENOTSUP); 8880 8881 *supported = mip->mi_led.mcl_modes; 8882 *active = mip->mi_led_modes; 8883 8884 return (0); 8885 } 8886 8887 /* 8888 * Update and multiplex the various LED requests. We only ever send one LED to 8889 * the underlying driver at a time. As such, we end up multiplexing all 8890 * requested states and picking one to send down to the driver. 8891 */ 8892 int 8893 mac_led_set(mac_handle_t mh, mac_led_mode_t desired) 8894 { 8895 int ret; 8896 mac_led_mode_t driver; 8897 8898 mac_impl_t *mip = (mac_impl_t *)mh; 8899 8900 ASSERT(MAC_PERIM_HELD(mh)); 8901 8902 /* 8903 * If we've been passed a desired value of zero, that indicates that 8904 * we're basically resetting to the value of zero, which is our default 8905 * value. 8906 */ 8907 if (desired == 0) 8908 desired = MAC_LED_DEFAULT; 8909 8910 if (mip->mi_led.mcl_set == NULL) 8911 return (ENOTSUP); 8912 8913 /* 8914 * Catch both values that we don't know about and those that the driver 8915 * doesn't support. 8916 */ 8917 if ((desired & ~MAC_LED_ALL) != 0) 8918 return (EINVAL); 8919 8920 if ((desired & ~mip->mi_led.mcl_modes) != 0) 8921 return (ENOTSUP); 8922 8923 /* 8924 * If we have the same value, then there is nothing to do. 8925 */ 8926 if (desired == mip->mi_led_modes) 8927 return (0); 8928 8929 /* 8930 * Based on the desired value, determine what to send to the driver. We 8931 * only will send a single bit to the driver at any given time. IDENT 8932 * takes priority over OFF or ON. We also let OFF take priority over the 8933 * rest. 8934 */ 8935 if (desired & MAC_LED_IDENT) { 8936 driver = MAC_LED_IDENT; 8937 } else if (desired & MAC_LED_OFF) { 8938 driver = MAC_LED_OFF; 8939 } else if (desired & MAC_LED_ON) { 8940 driver = MAC_LED_ON; 8941 } else { 8942 driver = MAC_LED_DEFAULT; 8943 } 8944 8945 if ((ret = mip->mi_led.mcl_set(mip->mi_driver, driver, 0)) == 0) { 8946 mip->mi_led_modes = desired; 8947 } 8948 8949 return (ret); 8950 } 8951 8952 /* 8953 * Send packets through the Tx ring ('mrh') or through the default 8954 * handler if no ring is specified. Before passing the packet down to 8955 * the MAC provider, emulate any hardware offloads which have been 8956 * requested but are not supported by the provider. 8957 */ 8958 mblk_t * 8959 mac_ring_tx(mac_handle_t mh, mac_ring_handle_t mrh, mblk_t *mp) 8960 { 8961 mac_impl_t *mip = (mac_impl_t *)mh; 8962 8963 if (mrh == NULL) 8964 mrh = mip->mi_default_tx_ring; 8965 8966 if (mrh == NULL) 8967 return (mip->mi_tx(mip->mi_driver, mp)); 8968 else 8969 return (mac_hwring_tx(mrh, mp)); 8970 } 8971 8972 /* 8973 * This is the final stop before reaching the underlying MAC provider. 8974 * This is also where the bridging hook is inserted. Packets that are 8975 * bridged will return through mac_bridge_tx(), with rh nulled out if 8976 * the bridge chooses to send output on a different link due to 8977 * forwarding. 8978 */ 8979 mblk_t * 8980 mac_provider_tx(mac_impl_t *mip, mac_ring_handle_t rh, mblk_t *mp, 8981 mac_client_impl_t *mcip) 8982 { 8983 /* 8984 * If there is a bound Hybrid I/O share, send packets through 8985 * the default tx ring. When there's a bound Hybrid I/O share, 8986 * the tx rings of this client are mapped in the guest domain 8987 * and not accessible from here. 8988 */ 8989 if (mcip->mci_state_flags & MCIS_SHARE_BOUND) 8990 rh = mip->mi_default_tx_ring; 8991 8992 if (mip->mi_promisc_list != NULL) 8993 mac_promisc_dispatch(mip, mp, mcip, B_FALSE); 8994 8995 if (mip->mi_bridge_link == NULL) 8996 return (mac_ring_tx((mac_handle_t)mip, rh, mp)); 8997 else 8998 return (mac_bridge_tx(mip, rh, mp)); 8999 } 9000