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 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * MAC Services Module 29 * 30 * The GLDv3 framework locking - The MAC layer 31 * -------------------------------------------- 32 * 33 * The MAC layer is central to the GLD framework and can provide the locking 34 * framework needed for itself and for the use of MAC clients. MAC end points 35 * are fairly disjoint and don't share a lot of state. So a coarse grained 36 * multi-threading scheme is to single thread all create/modify/delete or set 37 * type of control operations on a per mac end point while allowing data threads 38 * concurrently. 39 * 40 * Control operations (set) that modify a mac end point are always serialized on 41 * a per mac end point basis, We have at most 1 such thread per mac end point 42 * at a time. 43 * 44 * All other operations that are not serialized are essentially multi-threaded. 45 * For example a control operation (get) like getting statistics which may not 46 * care about reading values atomically or data threads sending or receiving 47 * data. Mostly these type of operations don't modify the control state. Any 48 * state these operations care about are protected using traditional locks. 49 * 50 * The perimeter only serializes serial operations. It does not imply there 51 * aren't any other concurrent operations. However a serialized operation may 52 * sometimes need to make sure it is the only thread. In this case it needs 53 * to use reference counting mechanisms to cv_wait until any current data 54 * threads are done. 55 * 56 * The mac layer itself does not hold any locks across a call to another layer. 57 * The perimeter is however held across a down call to the driver to make the 58 * whole control operation atomic with respect to other control operations. 59 * Also the data path and get type control operations may proceed concurrently. 60 * These operations synchronize with the single serial operation on a given mac 61 * end point using regular locks. The perimeter ensures that conflicting 62 * operations like say a mac_multicast_add and a mac_multicast_remove on the 63 * same mac end point don't interfere with each other and also ensures that the 64 * changes in the mac layer and the call to the underlying driver to say add a 65 * multicast address are done atomically without interference from a thread 66 * trying to delete the same address. 67 * 68 * For example, consider 69 * mac_multicst_add() 70 * { 71 * mac_perimeter_enter(); serialize all control operations 72 * 73 * grab list lock protect against access by data threads 74 * add to list 75 * drop list lock 76 * 77 * call driver's mi_multicst 78 * 79 * mac_perimeter_exit(); 80 * } 81 * 82 * To lessen the number of serialization locks and simplify the lock hierarchy, 83 * we serialize all the control operations on a per mac end point by using a 84 * single serialization lock called the perimeter. We allow recursive entry into 85 * the perimeter to facilitate use of this mechanism by both the mac client and 86 * the MAC layer itself. 87 * 88 * MAC client means an entity that does an operation on a mac handle 89 * obtained from a mac_open/mac_client_open. Similarly MAC driver means 90 * an entity that does an operation on a mac handle obtained from a 91 * mac_register. An entity could be both client and driver but on different 92 * handles eg. aggr. and should only make the corresponding mac interface calls 93 * i.e. mac driver interface or mac client interface as appropriate for that 94 * mac handle. 95 * 96 * General rules. 97 * ------------- 98 * 99 * R1. The lock order of upcall threads is natually opposite to downcall 100 * threads. Hence upcalls must not hold any locks across layers for fear of 101 * recursive lock enter and lock order violation. This applies to all layers. 102 * 103 * R2. The perimeter is just another lock. Since it is held in the down 104 * direction, acquiring the perimeter in an upcall is prohibited as it would 105 * cause a deadlock. This applies to all layers. 106 * 107 * Note that upcalls that need to grab the mac perimeter (for example 108 * mac_notify upcalls) can still achieve that by posting the request to a 109 * thread, which can then grab all the required perimeters and locks in the 110 * right global order. Note that in the above example the mac layer iself 111 * won't grab the mac perimeter in the mac_notify upcall, instead the upcall 112 * to the client must do that. Please see the aggr code for an example. 113 * 114 * MAC client rules 115 * ---------------- 116 * 117 * R3. A MAC client may use the MAC provided perimeter facility to serialize 118 * control operations on a per mac end point. It does this by by acquring 119 * and holding the perimeter across a sequence of calls to the mac layer. 120 * This ensures atomicity across the entire block of mac calls. In this 121 * model the MAC client must not hold any client locks across the calls to 122 * the mac layer. This model is the preferred solution. 123 * 124 * R4. However if a MAC client has a lot of global state across all mac end 125 * points the per mac end point serialization may not be sufficient. In this 126 * case the client may choose to use global locks or use its own serialization. 127 * To avoid deadlocks, these client layer locks held across the mac calls 128 * in the control path must never be acquired by the data path for the reason 129 * mentioned below. 130 * 131 * (Assume that a control operation that holds a client lock blocks in the 132 * mac layer waiting for upcall reference counts to drop to zero. If an upcall 133 * data thread that holds this reference count, tries to acquire the same 134 * client lock subsequently it will deadlock). 135 * 136 * A MAC client may follow either the R3 model or the R4 model, but can't 137 * mix both. In the former, the hierarchy is Perim -> client locks, but in 138 * the latter it is client locks -> Perim. 139 * 140 * R5. MAC clients must make MAC calls (excluding data calls) in a cv_wait'able 141 * context since they may block while trying to acquire the perimeter. 142 * In addition some calls may block waiting for upcall refcnts to come down to 143 * zero. 144 * 145 * R6. MAC clients must make sure that they are single threaded and all threads 146 * from the top (in particular data threads) have finished before calling 147 * mac_client_close. The MAC framework does not track the number of client 148 * threads using the mac client handle. Also mac clients must make sure 149 * they have undone all the control operations before calling mac_client_close. 150 * For example mac_unicast_remove/mac_multicast_remove to undo the corresponding 151 * mac_unicast_add/mac_multicast_add. 152 * 153 * MAC framework rules 154 * ------------------- 155 * 156 * R7. The mac layer itself must not hold any mac layer locks (except the mac 157 * perimeter) across a call to any other layer from the mac layer. The call to 158 * any other layer could be via mi_* entry points, classifier entry points into 159 * the driver or via upcall pointers into layers above. The mac perimeter may 160 * be acquired or held only in the down direction, for e.g. when calling into 161 * a mi_* driver enty point to provide atomicity of the operation. 162 * 163 * R8. Since it is not guaranteed (see R14) that drivers won't hold locks across 164 * mac driver interfaces, the MAC layer must provide a cut out for control 165 * interfaces like upcall notifications and start them in a separate thread. 166 * 167 * R9. Note that locking order also implies a plumbing order. For example 168 * VNICs are allowed to be created over aggrs, but not vice-versa. An attempt 169 * to plumb in any other order must be failed at mac_open time, otherwise it 170 * could lead to deadlocks due to inverse locking order. 171 * 172 * R10. MAC driver interfaces must not block since the driver could call them 173 * in interrupt context. 174 * 175 * R11. Walkers must preferably not hold any locks while calling walker 176 * callbacks. Instead these can operate on reference counts. In simple 177 * callbacks it may be ok to hold a lock and call the callbacks, but this is 178 * harder to maintain in the general case of arbitrary callbacks. 179 * 180 * R12. The MAC layer must protect upcall notification callbacks using reference 181 * counts rather than holding locks across the callbacks. 182 * 183 * R13. Given the variety of drivers, it is preferable if the MAC layer can make 184 * sure that any pointers (such as mac ring pointers) it passes to the driver 185 * remain valid until mac unregister time. Currently the mac layer achieves 186 * this by using generation numbers for rings and freeing the mac rings only 187 * at unregister time. The MAC layer must provide a layer of indirection and 188 * must not expose underlying driver rings or driver data structures/pointers 189 * directly to MAC clients. 190 * 191 * MAC driver rules 192 * ---------------- 193 * 194 * R14. It would be preferable if MAC drivers don't hold any locks across any 195 * mac call. However at a minimum they must not hold any locks across data 196 * upcalls. They must also make sure that all references to mac data structures 197 * are cleaned up and that it is single threaded at mac_unregister time. 198 * 199 * R15. MAC driver interfaces don't block and so the action may be done 200 * asynchronously in a separate thread as for example handling notifications. 201 * The driver must not assume that the action is complete when the call 202 * returns. 203 * 204 * R16. Drivers must maintain a generation number per Rx ring, and pass it 205 * back to mac_rx_ring(); They are expected to increment the generation 206 * number whenever the ring's stop routine is invoked. 207 * See comments in mac_rx_ring(); 208 * 209 * R17 Similarly mi_stop is another synchronization point and the driver must 210 * ensure that all upcalls are done and there won't be any future upcall 211 * before returning from mi_stop. 212 * 213 * R18. The driver may assume that all set/modify control operations via 214 * the mi_* entry points are single threaded on a per mac end point. 215 * 216 * Lock and Perimeter hierarchy scenarios 217 * --------------------------------------- 218 * 219 * i_mac_impl_lock -> mi_rw_lock -> srs_lock -> s_ring_lock[i_mac_tx_srs_notify] 220 * 221 * ft_lock -> fe_lock [mac_flow_lookup] 222 * 223 * mi_rw_lock -> fe_lock [mac_bcast_send] 224 * 225 * srs_lock -> mac_bw_lock [mac_rx_srs_drain_bw] 226 * 227 * cpu_lock -> mac_srs_g_lock -> srs_lock -> s_ring_lock [mac_walk_srs_and_bind] 228 * 229 * i_dls_devnet_lock -> mac layer locks [dls_devnet_rename] 230 * 231 * Perimeters are ordered P1 -> P2 -> P3 from top to bottom in order of mac 232 * client to driver. In the case of clients that explictly use the mac provided 233 * perimeter mechanism for its serialization, the hierarchy is 234 * Perimeter -> mac layer locks, since the client never holds any locks across 235 * the mac calls. In the case of clients that use its own locks the hierarchy 236 * is Client locks -> Mac Perim -> Mac layer locks. The client never explicitly 237 * calls mac_perim_enter/exit in this case. 238 * 239 * Subflow creation rules 240 * --------------------------- 241 * o In case of a user specified cpulist present on underlying link and flows, 242 * the flows cpulist must be a subset of the underlying link. 243 * o In case of a user specified fanout mode present on link and flow, the 244 * subflow fanout count has to be less than or equal to that of the 245 * underlying link. The cpu-bindings for the subflows will be a subset of 246 * the underlying link. 247 * o In case if no cpulist specified on both underlying link and flow, the 248 * underlying link relies on a MAC tunable to provide out of box fanout. 249 * The subflow will have no cpulist (the subflow will be unbound) 250 * o In case if no cpulist is specified on the underlying link, a subflow can 251 * carry either a user-specified cpulist or fanout count. The cpu-bindings 252 * for the subflow will not adhere to restriction that they need to be subset 253 * of the underlying link. 254 * o In case where the underlying link is carrying either a user specified 255 * cpulist or fanout mode and for a unspecified subflow, the subflow will be 256 * created unbound. 257 * o While creating unbound subflows, bandwidth mode changes attempt to 258 * figure a right fanout count. In such cases the fanout count will override 259 * the unbound cpu-binding behavior. 260 * o In addition to this, while cycling between flow and link properties, we 261 * impose a restriction that if a link property has a subflow with 262 * user-specified attributes, we will not allow changing the link property. 263 * The administrator needs to reset all the user specified properties for the 264 * subflows before attempting a link property change. 265 * Some of the above rules can be overridden by specifying additional command 266 * line options while creating or modifying link or subflow properties. 267 */ 268 269 #include <sys/types.h> 270 #include <sys/conf.h> 271 #include <sys/id_space.h> 272 #include <sys/esunddi.h> 273 #include <sys/stat.h> 274 #include <sys/mkdev.h> 275 #include <sys/stream.h> 276 #include <sys/strsun.h> 277 #include <sys/strsubr.h> 278 #include <sys/dlpi.h> 279 #include <sys/modhash.h> 280 #include <sys/mac_provider.h> 281 #include <sys/mac_client_impl.h> 282 #include <sys/mac_soft_ring.h> 283 #include <sys/mac_impl.h> 284 #include <sys/mac.h> 285 #include <sys/dls.h> 286 #include <sys/dld.h> 287 #include <sys/modctl.h> 288 #include <sys/fs/dv_node.h> 289 #include <sys/thread.h> 290 #include <sys/proc.h> 291 #include <sys/callb.h> 292 #include <sys/cpuvar.h> 293 #include <sys/atomic.h> 294 #include <sys/bitmap.h> 295 #include <sys/sdt.h> 296 #include <sys/mac_flow.h> 297 #include <sys/ddi_intr_impl.h> 298 #include <sys/disp.h> 299 #include <sys/sdt.h> 300 #include <sys/vnic.h> 301 #include <sys/vnic_impl.h> 302 #include <sys/vlan.h> 303 #include <inet/ip.h> 304 #include <inet/ip6.h> 305 #include <sys/exacct.h> 306 #include <sys/exacct_impl.h> 307 #include <inet/nd.h> 308 #include <sys/ethernet.h> 309 310 #define IMPL_HASHSZ 67 /* prime */ 311 312 kmem_cache_t *i_mac_impl_cachep; 313 mod_hash_t *i_mac_impl_hash; 314 krwlock_t i_mac_impl_lock; 315 uint_t i_mac_impl_count; 316 static kmem_cache_t *mac_ring_cache; 317 static id_space_t *minor_ids; 318 static uint32_t minor_count; 319 320 /* 321 * Logging stuff. Perhaps mac_logging_interval could be broken into 322 * mac_flow_log_interval and mac_link_log_interval if we want to be 323 * able to schedule them differently. 324 */ 325 uint_t mac_logging_interval; 326 boolean_t mac_flow_log_enable; 327 boolean_t mac_link_log_enable; 328 timeout_id_t mac_logging_timer; 329 330 /* for debugging, see MAC_DBG_PRT() in mac_impl.h */ 331 int mac_dbg = 0; 332 333 #define MACTYPE_KMODDIR "mac" 334 #define MACTYPE_HASHSZ 67 335 static mod_hash_t *i_mactype_hash; 336 /* 337 * i_mactype_lock synchronizes threads that obtain references to mactype_t 338 * structures through i_mactype_getplugin(). 339 */ 340 static kmutex_t i_mactype_lock; 341 342 /* 343 * mac_tx_percpu_cnt 344 * 345 * Number of per cpu locks per mac_client_impl_t. Used by the transmit side 346 * in mac_tx to reduce lock contention. This is sized at boot time in mac_init. 347 * mac_tx_percpu_cnt_max is settable in /etc/system and must be a power of 2. 348 * Per cpu locks may be disabled by setting mac_tx_percpu_cnt_max to 1. 349 */ 350 int mac_tx_percpu_cnt; 351 int mac_tx_percpu_cnt_max = 128; 352 353 static int i_mac_constructor(void *, void *, int); 354 static void i_mac_destructor(void *, void *); 355 static int i_mac_ring_ctor(void *, void *, int); 356 static void i_mac_ring_dtor(void *, void *); 357 static mblk_t *mac_rx_classify(mac_impl_t *, mac_resource_handle_t, mblk_t *); 358 void mac_tx_client_flush(mac_client_impl_t *); 359 void mac_tx_client_block(mac_client_impl_t *); 360 static void mac_rx_ring_quiesce(mac_ring_t *, uint_t); 361 static int mac_start_group_and_rings(mac_group_t *); 362 static void mac_stop_group_and_rings(mac_group_t *); 363 364 /* 365 * Module initialization functions. 366 */ 367 368 void 369 mac_init(void) 370 { 371 mac_tx_percpu_cnt = ((boot_max_ncpus == -1) ? max_ncpus : 372 boot_max_ncpus); 373 374 /* Upper bound is mac_tx_percpu_cnt_max */ 375 if (mac_tx_percpu_cnt > mac_tx_percpu_cnt_max) 376 mac_tx_percpu_cnt = mac_tx_percpu_cnt_max; 377 378 if (mac_tx_percpu_cnt < 1) { 379 /* Someone set max_tx_percpu_cnt_max to 0 or less */ 380 mac_tx_percpu_cnt = 1; 381 } 382 383 ASSERT(mac_tx_percpu_cnt >= 1); 384 mac_tx_percpu_cnt = (1 << highbit(mac_tx_percpu_cnt - 1)); 385 /* 386 * Make it of the form 2**N - 1 in the range 387 * [0 .. mac_tx_percpu_cnt_max - 1] 388 */ 389 mac_tx_percpu_cnt--; 390 391 i_mac_impl_cachep = kmem_cache_create("mac_impl_cache", 392 sizeof (mac_impl_t), 0, i_mac_constructor, i_mac_destructor, 393 NULL, NULL, NULL, 0); 394 ASSERT(i_mac_impl_cachep != NULL); 395 396 mac_ring_cache = kmem_cache_create("mac_ring_cache", 397 sizeof (mac_ring_t), 0, i_mac_ring_ctor, i_mac_ring_dtor, NULL, 398 NULL, NULL, 0); 399 ASSERT(mac_ring_cache != NULL); 400 401 i_mac_impl_hash = mod_hash_create_extended("mac_impl_hash", 402 IMPL_HASHSZ, mod_hash_null_keydtor, mod_hash_null_valdtor, 403 mod_hash_bystr, NULL, mod_hash_strkey_cmp, KM_SLEEP); 404 rw_init(&i_mac_impl_lock, NULL, RW_DEFAULT, NULL); 405 406 mac_flow_init(); 407 mac_soft_ring_init(); 408 mac_bcast_init(); 409 mac_client_init(); 410 411 i_mac_impl_count = 0; 412 413 i_mactype_hash = mod_hash_create_extended("mactype_hash", 414 MACTYPE_HASHSZ, 415 mod_hash_null_keydtor, mod_hash_null_valdtor, 416 mod_hash_bystr, NULL, mod_hash_strkey_cmp, KM_SLEEP); 417 418 /* 419 * Allocate an id space to manage minor numbers. The range of the 420 * space will be from MAC_MAX_MINOR+1 to MAXMIN32 (maximum legal 421 * minor number is MAXMIN, but id_t is type of integer and does not 422 * allow MAXMIN). 423 */ 424 minor_ids = id_space_create("mac_minor_ids", MAC_MAX_MINOR+1, MAXMIN32); 425 ASSERT(minor_ids != NULL); 426 minor_count = 0; 427 428 /* Let's default to 20 seconds */ 429 mac_logging_interval = 20; 430 mac_flow_log_enable = B_FALSE; 431 mac_link_log_enable = B_FALSE; 432 mac_logging_timer = 0; 433 } 434 435 int 436 mac_fini(void) 437 { 438 if (i_mac_impl_count > 0 || minor_count > 0) 439 return (EBUSY); 440 441 id_space_destroy(minor_ids); 442 mac_flow_fini(); 443 444 mod_hash_destroy_hash(i_mac_impl_hash); 445 rw_destroy(&i_mac_impl_lock); 446 447 mac_client_fini(); 448 kmem_cache_destroy(mac_ring_cache); 449 450 mod_hash_destroy_hash(i_mactype_hash); 451 mac_soft_ring_finish(); 452 return (0); 453 } 454 455 void 456 mac_init_ops(struct dev_ops *ops, const char *name) 457 { 458 dld_init_ops(ops, name); 459 } 460 461 void 462 mac_fini_ops(struct dev_ops *ops) 463 { 464 dld_fini_ops(ops); 465 } 466 467 /*ARGSUSED*/ 468 static int 469 i_mac_constructor(void *buf, void *arg, int kmflag) 470 { 471 mac_impl_t *mip = buf; 472 473 bzero(buf, sizeof (mac_impl_t)); 474 475 mip->mi_linkstate = LINK_STATE_UNKNOWN; 476 mip->mi_nclients = 0; 477 478 mutex_init(&mip->mi_lock, NULL, MUTEX_DRIVER, NULL); 479 rw_init(&mip->mi_rw_lock, NULL, RW_DRIVER, NULL); 480 mutex_init(&mip->mi_notify_lock, NULL, MUTEX_DRIVER, NULL); 481 mutex_init(&mip->mi_promisc_lock, NULL, MUTEX_DRIVER, NULL); 482 mutex_init(&mip->mi_ring_lock, NULL, MUTEX_DEFAULT, NULL); 483 484 mip->mi_notify_cb_info.mcbi_lockp = &mip->mi_notify_lock; 485 cv_init(&mip->mi_notify_cb_info.mcbi_cv, NULL, CV_DRIVER, NULL); 486 mip->mi_promisc_cb_info.mcbi_lockp = &mip->mi_promisc_lock; 487 cv_init(&mip->mi_promisc_cb_info.mcbi_cv, NULL, CV_DRIVER, NULL); 488 return (0); 489 } 490 491 /*ARGSUSED*/ 492 static void 493 i_mac_destructor(void *buf, void *arg) 494 { 495 mac_impl_t *mip = buf; 496 mac_cb_info_t *mcbi; 497 498 ASSERT(mip->mi_ref == 0); 499 ASSERT(mip->mi_active == 0); 500 ASSERT(mip->mi_linkstate == LINK_STATE_UNKNOWN); 501 ASSERT(mip->mi_devpromisc == 0); 502 ASSERT(mip->mi_ksp == NULL); 503 ASSERT(mip->mi_kstat_count == 0); 504 ASSERT(mip->mi_nclients == 0); 505 ASSERT(mip->mi_nactiveclients == 0); 506 ASSERT(mip->mi_single_active_client == NULL); 507 ASSERT(mip->mi_state_flags == 0); 508 ASSERT(mip->mi_factory_addr == NULL); 509 ASSERT(mip->mi_factory_addr_num == 0); 510 ASSERT(mip->mi_default_tx_ring == NULL); 511 512 mcbi = &mip->mi_notify_cb_info; 513 ASSERT(mcbi->mcbi_del_cnt == 0 && mcbi->mcbi_walker_cnt == 0); 514 ASSERT(mip->mi_notify_bits == 0); 515 ASSERT(mip->mi_notify_thread == NULL); 516 ASSERT(mcbi->mcbi_lockp == &mip->mi_notify_lock); 517 mcbi->mcbi_lockp = NULL; 518 519 mcbi = &mip->mi_promisc_cb_info; 520 ASSERT(mcbi->mcbi_del_cnt == 0 && mip->mi_promisc_list == NULL); 521 ASSERT(mip->mi_promisc_list == NULL); 522 ASSERT(mcbi->mcbi_lockp == &mip->mi_promisc_lock); 523 mcbi->mcbi_lockp = NULL; 524 525 ASSERT(mip->mi_bcast_ngrps == 0 && mip->mi_bcast_grp == NULL); 526 ASSERT(mip->mi_perim_owner == NULL && mip->mi_perim_ocnt == 0); 527 528 mutex_destroy(&mip->mi_lock); 529 rw_destroy(&mip->mi_rw_lock); 530 531 mutex_destroy(&mip->mi_promisc_lock); 532 cv_destroy(&mip->mi_promisc_cb_info.mcbi_cv); 533 mutex_destroy(&mip->mi_notify_lock); 534 cv_destroy(&mip->mi_notify_cb_info.mcbi_cv); 535 mutex_destroy(&mip->mi_ring_lock); 536 } 537 538 /* ARGSUSED */ 539 static int 540 i_mac_ring_ctor(void *buf, void *arg, int kmflag) 541 { 542 mac_ring_t *ring = (mac_ring_t *)buf; 543 544 bzero(ring, sizeof (mac_ring_t)); 545 cv_init(&ring->mr_cv, NULL, CV_DEFAULT, NULL); 546 mutex_init(&ring->mr_lock, NULL, MUTEX_DEFAULT, NULL); 547 ring->mr_state = MR_FREE; 548 return (0); 549 } 550 551 /* ARGSUSED */ 552 static void 553 i_mac_ring_dtor(void *buf, void *arg) 554 { 555 mac_ring_t *ring = (mac_ring_t *)buf; 556 557 cv_destroy(&ring->mr_cv); 558 mutex_destroy(&ring->mr_lock); 559 } 560 561 /* 562 * Common functions to do mac callback addition and deletion. Currently this is 563 * used by promisc callbacks and notify callbacks. List addition and deletion 564 * need to take care of list walkers. List walkers in general, can't hold list 565 * locks and make upcall callbacks due to potential lock order and recursive 566 * reentry issues. Instead list walkers increment the list walker count to mark 567 * the presence of a walker thread. Addition can be carefully done to ensure 568 * that the list walker always sees either the old list or the new list. 569 * However the deletion can't be done while the walker is active, instead the 570 * deleting thread simply marks the entry as logically deleted. The last walker 571 * physically deletes and frees up the logically deleted entries when the walk 572 * is complete. 573 */ 574 void 575 mac_callback_add(mac_cb_info_t *mcbi, mac_cb_t **mcb_head, 576 mac_cb_t *mcb_elem) 577 { 578 mac_cb_t *p; 579 mac_cb_t **pp; 580 581 /* Verify it is not already in the list */ 582 for (pp = mcb_head; (p = *pp) != NULL; pp = &p->mcb_nextp) { 583 if (p == mcb_elem) 584 break; 585 } 586 VERIFY(p == NULL); 587 588 /* 589 * Add it to the head of the callback list. The membar ensures that 590 * the following list pointer manipulations reach global visibility 591 * in exactly the program order below. 592 */ 593 ASSERT(MUTEX_HELD(mcbi->mcbi_lockp)); 594 595 mcb_elem->mcb_nextp = *mcb_head; 596 membar_producer(); 597 *mcb_head = mcb_elem; 598 } 599 600 /* 601 * Mark the entry as logically deleted. If there aren't any walkers unlink 602 * from the list. In either case return the corresponding status. 603 */ 604 boolean_t 605 mac_callback_remove(mac_cb_info_t *mcbi, mac_cb_t **mcb_head, 606 mac_cb_t *mcb_elem) 607 { 608 mac_cb_t *p; 609 mac_cb_t **pp; 610 611 ASSERT(MUTEX_HELD(mcbi->mcbi_lockp)); 612 /* 613 * Search the callback list for the entry to be removed 614 */ 615 for (pp = mcb_head; (p = *pp) != NULL; pp = &p->mcb_nextp) { 616 if (p == mcb_elem) 617 break; 618 } 619 VERIFY(p != NULL); 620 621 /* 622 * If there are walkers just mark it as deleted and the last walker 623 * will remove from the list and free it. 624 */ 625 if (mcbi->mcbi_walker_cnt != 0) { 626 p->mcb_flags |= MCB_CONDEMNED; 627 mcbi->mcbi_del_cnt++; 628 return (B_FALSE); 629 } 630 631 ASSERT(mcbi->mcbi_del_cnt == 0); 632 *pp = p->mcb_nextp; 633 p->mcb_nextp = NULL; 634 return (B_TRUE); 635 } 636 637 /* 638 * Wait for all pending callback removals to be completed 639 */ 640 void 641 mac_callback_remove_wait(mac_cb_info_t *mcbi) 642 { 643 ASSERT(MUTEX_HELD(mcbi->mcbi_lockp)); 644 while (mcbi->mcbi_del_cnt != 0) { 645 DTRACE_PROBE1(need_wait, mac_cb_info_t *, mcbi); 646 cv_wait(&mcbi->mcbi_cv, mcbi->mcbi_lockp); 647 } 648 } 649 650 /* 651 * The last mac callback walker does the cleanup. Walk the list and unlik 652 * all the logically deleted entries and construct a temporary list of 653 * removed entries. Return the list of removed entries to the caller. 654 */ 655 mac_cb_t * 656 mac_callback_walker_cleanup(mac_cb_info_t *mcbi, mac_cb_t **mcb_head) 657 { 658 mac_cb_t *p; 659 mac_cb_t **pp; 660 mac_cb_t *rmlist = NULL; /* List of removed elements */ 661 int cnt = 0; 662 663 ASSERT(MUTEX_HELD(mcbi->mcbi_lockp)); 664 ASSERT(mcbi->mcbi_del_cnt != 0 && mcbi->mcbi_walker_cnt == 0); 665 666 pp = mcb_head; 667 while (*pp != NULL) { 668 if ((*pp)->mcb_flags & MCB_CONDEMNED) { 669 p = *pp; 670 *pp = p->mcb_nextp; 671 p->mcb_nextp = rmlist; 672 rmlist = p; 673 cnt++; 674 continue; 675 } 676 pp = &(*pp)->mcb_nextp; 677 } 678 679 ASSERT(mcbi->mcbi_del_cnt == cnt); 680 mcbi->mcbi_del_cnt = 0; 681 return (rmlist); 682 } 683 684 boolean_t 685 mac_callback_lookup(mac_cb_t **mcb_headp, mac_cb_t *mcb_elem) 686 { 687 mac_cb_t *mcb; 688 689 /* Verify it is not already in the list */ 690 for (mcb = *mcb_headp; mcb != NULL; mcb = mcb->mcb_nextp) { 691 if (mcb == mcb_elem) 692 return (B_TRUE); 693 } 694 695 return (B_FALSE); 696 } 697 698 boolean_t 699 mac_callback_find(mac_cb_info_t *mcbi, mac_cb_t **mcb_headp, mac_cb_t *mcb_elem) 700 { 701 boolean_t found; 702 703 mutex_enter(mcbi->mcbi_lockp); 704 found = mac_callback_lookup(mcb_headp, mcb_elem); 705 mutex_exit(mcbi->mcbi_lockp); 706 707 return (found); 708 } 709 710 /* Free the list of removed callbacks */ 711 void 712 mac_callback_free(mac_cb_t *rmlist) 713 { 714 mac_cb_t *mcb; 715 mac_cb_t *mcb_next; 716 717 for (mcb = rmlist; mcb != NULL; mcb = mcb_next) { 718 mcb_next = mcb->mcb_nextp; 719 kmem_free(mcb->mcb_objp, mcb->mcb_objsize); 720 } 721 } 722 723 /* 724 * The promisc callbacks are in 2 lists, one off the 'mip' and another off the 725 * 'mcip' threaded by mpi_mi_link and mpi_mci_link respectively. However there 726 * is only a single shared total walker count, and an entry can't be physically 727 * unlinked if a walker is active on either list. The last walker does this 728 * cleanup of logically deleted entries. 729 */ 730 void 731 i_mac_promisc_walker_cleanup(mac_impl_t *mip) 732 { 733 mac_cb_t *rmlist; 734 mac_cb_t *mcb; 735 mac_cb_t *mcb_next; 736 mac_promisc_impl_t *mpip; 737 738 /* 739 * Construct a temporary list of deleted callbacks by walking the 740 * the mi_promisc_list. Then for each entry in the temporary list, 741 * remove it from the mci_promisc_list and free the entry. 742 */ 743 rmlist = mac_callback_walker_cleanup(&mip->mi_promisc_cb_info, 744 &mip->mi_promisc_list); 745 746 for (mcb = rmlist; mcb != NULL; mcb = mcb_next) { 747 mcb_next = mcb->mcb_nextp; 748 mpip = (mac_promisc_impl_t *)mcb->mcb_objp; 749 VERIFY(mac_callback_remove(&mip->mi_promisc_cb_info, 750 &mpip->mpi_mcip->mci_promisc_list, &mpip->mpi_mci_link)); 751 mcb->mcb_flags = 0; 752 mcb->mcb_nextp = NULL; 753 kmem_cache_free(mac_promisc_impl_cache, mpip); 754 } 755 } 756 757 void 758 i_mac_notify(mac_impl_t *mip, mac_notify_type_t type) 759 { 760 mac_cb_info_t *mcbi; 761 762 /* 763 * Signal the notify thread even after mi_ref has become zero and 764 * mi_disabled is set. The synchronization with the notify thread 765 * happens in mac_unregister and that implies the driver must make 766 * sure it is single-threaded (with respect to mac calls) and that 767 * all pending mac calls have returned before it calls mac_unregister 768 */ 769 rw_enter(&i_mac_impl_lock, RW_READER); 770 if (mip->mi_state_flags & MIS_DISABLED) 771 goto exit; 772 773 /* 774 * Guard against incorrect notifications. (Running a newer 775 * mac client against an older implementation?) 776 */ 777 if (type >= MAC_NNOTE) 778 goto exit; 779 780 mcbi = &mip->mi_notify_cb_info; 781 mutex_enter(mcbi->mcbi_lockp); 782 mip->mi_notify_bits |= (1 << type); 783 cv_broadcast(&mcbi->mcbi_cv); 784 mutex_exit(mcbi->mcbi_lockp); 785 786 exit: 787 rw_exit(&i_mac_impl_lock); 788 } 789 790 /* 791 * Mac serialization primitives. Please see the block comment at the 792 * top of the file. 793 */ 794 void 795 i_mac_perim_enter(mac_impl_t *mip) 796 { 797 mac_client_impl_t *mcip; 798 799 if (mip->mi_state_flags & MIS_IS_VNIC) { 800 /* 801 * This is a VNIC. Return the lower mac since that is what 802 * we want to serialize on. 803 */ 804 mcip = mac_vnic_lower(mip); 805 mip = mcip->mci_mip; 806 } 807 808 mutex_enter(&mip->mi_perim_lock); 809 if (mip->mi_perim_owner == curthread) { 810 mip->mi_perim_ocnt++; 811 mutex_exit(&mip->mi_perim_lock); 812 return; 813 } 814 815 while (mip->mi_perim_owner != NULL) 816 cv_wait(&mip->mi_perim_cv, &mip->mi_perim_lock); 817 818 mip->mi_perim_owner = curthread; 819 ASSERT(mip->mi_perim_ocnt == 0); 820 mip->mi_perim_ocnt++; 821 #ifdef DEBUG 822 mip->mi_perim_stack_depth = getpcstack(mip->mi_perim_stack, 823 MAC_PERIM_STACK_DEPTH); 824 #endif 825 mutex_exit(&mip->mi_perim_lock); 826 } 827 828 int 829 i_mac_perim_enter_nowait(mac_impl_t *mip) 830 { 831 /* 832 * The vnic is a special case, since the serialization is done based 833 * on the lower mac. If the lower mac is busy, it does not imply the 834 * vnic can't be unregistered. But in the case of other drivers, 835 * a busy perimeter or open mac handles implies that the mac is busy 836 * and can't be unregistered. 837 */ 838 if (mip->mi_state_flags & MIS_IS_VNIC) { 839 i_mac_perim_enter(mip); 840 return (0); 841 } 842 843 mutex_enter(&mip->mi_perim_lock); 844 if (mip->mi_perim_owner != NULL) { 845 mutex_exit(&mip->mi_perim_lock); 846 return (EBUSY); 847 } 848 ASSERT(mip->mi_perim_ocnt == 0); 849 mip->mi_perim_owner = curthread; 850 mip->mi_perim_ocnt++; 851 mutex_exit(&mip->mi_perim_lock); 852 853 return (0); 854 } 855 856 void 857 i_mac_perim_exit(mac_impl_t *mip) 858 { 859 mac_client_impl_t *mcip; 860 861 if (mip->mi_state_flags & MIS_IS_VNIC) { 862 /* 863 * This is a VNIC. Return the lower mac since that is what 864 * we want to serialize on. 865 */ 866 mcip = mac_vnic_lower(mip); 867 mip = mcip->mci_mip; 868 } 869 870 ASSERT(mip->mi_perim_owner == curthread && mip->mi_perim_ocnt != 0); 871 872 mutex_enter(&mip->mi_perim_lock); 873 if (--mip->mi_perim_ocnt == 0) { 874 mip->mi_perim_owner = NULL; 875 cv_signal(&mip->mi_perim_cv); 876 } 877 mutex_exit(&mip->mi_perim_lock); 878 } 879 880 /* 881 * Returns whether the current thread holds the mac perimeter. Used in making 882 * assertions. 883 */ 884 boolean_t 885 mac_perim_held(mac_handle_t mh) 886 { 887 mac_impl_t *mip = (mac_impl_t *)mh; 888 mac_client_impl_t *mcip; 889 890 if (mip->mi_state_flags & MIS_IS_VNIC) { 891 /* 892 * This is a VNIC. Return the lower mac since that is what 893 * we want to serialize on. 894 */ 895 mcip = mac_vnic_lower(mip); 896 mip = mcip->mci_mip; 897 } 898 return (mip->mi_perim_owner == curthread); 899 } 900 901 /* 902 * mac client interfaces to enter the mac perimeter of a mac end point, given 903 * its mac handle, or macname or linkid. 904 */ 905 void 906 mac_perim_enter_by_mh(mac_handle_t mh, mac_perim_handle_t *mphp) 907 { 908 mac_impl_t *mip = (mac_impl_t *)mh; 909 910 i_mac_perim_enter(mip); 911 /* 912 * The mac_perim_handle_t returned encodes the 'mip' and whether a 913 * mac_open has been done internally while entering the perimeter. 914 * This information is used in mac_perim_exit 915 */ 916 MAC_ENCODE_MPH(*mphp, mip, 0); 917 } 918 919 int 920 mac_perim_enter_by_macname(const char *name, mac_perim_handle_t *mphp) 921 { 922 int err; 923 mac_handle_t mh; 924 925 if ((err = mac_open(name, &mh)) != 0) 926 return (err); 927 928 mac_perim_enter_by_mh(mh, mphp); 929 MAC_ENCODE_MPH(*mphp, mh, 1); 930 return (0); 931 } 932 933 int 934 mac_perim_enter_by_linkid(datalink_id_t linkid, mac_perim_handle_t *mphp) 935 { 936 int err; 937 mac_handle_t mh; 938 939 if ((err = mac_open_by_linkid(linkid, &mh)) != 0) 940 return (err); 941 942 mac_perim_enter_by_mh(mh, mphp); 943 MAC_ENCODE_MPH(*mphp, mh, 1); 944 return (0); 945 } 946 947 void 948 mac_perim_exit(mac_perim_handle_t mph) 949 { 950 mac_impl_t *mip; 951 boolean_t need_close; 952 953 MAC_DECODE_MPH(mph, mip, need_close); 954 i_mac_perim_exit(mip); 955 if (need_close) 956 mac_close((mac_handle_t)mip); 957 } 958 959 int 960 mac_hold(const char *macname, mac_impl_t **pmip) 961 { 962 mac_impl_t *mip; 963 int err; 964 965 /* 966 * Check the device name length to make sure it won't overflow our 967 * buffer. 968 */ 969 if (strlen(macname) >= MAXNAMELEN) 970 return (EINVAL); 971 972 /* 973 * Look up its entry in the global hash table. 974 */ 975 rw_enter(&i_mac_impl_lock, RW_WRITER); 976 err = mod_hash_find(i_mac_impl_hash, (mod_hash_key_t)macname, 977 (mod_hash_val_t *)&mip); 978 979 if (err != 0) { 980 rw_exit(&i_mac_impl_lock); 981 return (ENOENT); 982 } 983 984 if (mip->mi_state_flags & MIS_DISABLED) { 985 rw_exit(&i_mac_impl_lock); 986 return (ENOENT); 987 } 988 989 if (mip->mi_state_flags & MIS_EXCLUSIVE_HELD) { 990 rw_exit(&i_mac_impl_lock); 991 return (EBUSY); 992 } 993 994 mip->mi_ref++; 995 rw_exit(&i_mac_impl_lock); 996 997 *pmip = mip; 998 return (0); 999 } 1000 1001 void 1002 mac_rele(mac_impl_t *mip) 1003 { 1004 rw_enter(&i_mac_impl_lock, RW_WRITER); 1005 ASSERT(mip->mi_ref != 0); 1006 if (--mip->mi_ref == 0) { 1007 ASSERT(mip->mi_nactiveclients == 0 && 1008 !(mip->mi_state_flags & MIS_EXCLUSIVE)); 1009 } 1010 rw_exit(&i_mac_impl_lock); 1011 } 1012 1013 /* 1014 * Private GLDv3 function to start a MAC instance. 1015 */ 1016 int 1017 mac_start(mac_handle_t mh) 1018 { 1019 mac_impl_t *mip = (mac_impl_t *)mh; 1020 int err = 0; 1021 1022 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 1023 ASSERT(mip->mi_start != NULL); 1024 1025 /* 1026 * Check whether the device is already started. 1027 */ 1028 if (mip->mi_active++ == 0) { 1029 mac_ring_t *ring = NULL; 1030 1031 /* 1032 * Start the device. 1033 */ 1034 err = mip->mi_start(mip->mi_driver); 1035 if (err != 0) { 1036 mip->mi_active--; 1037 return (err); 1038 } 1039 1040 /* 1041 * Start the default tx ring. 1042 */ 1043 if (mip->mi_default_tx_ring != NULL) { 1044 1045 ring = (mac_ring_t *)mip->mi_default_tx_ring; 1046 err = mac_start_ring(ring); 1047 if (err != 0) { 1048 mip->mi_active--; 1049 return (err); 1050 } 1051 ring->mr_state = MR_INUSE; 1052 } 1053 1054 if (mip->mi_rx_groups != NULL) { 1055 /* 1056 * Start the default ring, since it will be needed 1057 * to receive broadcast and multicast traffic for 1058 * both primary and non-primary MAC clients. 1059 */ 1060 mac_group_t *grp = &mip->mi_rx_groups[0]; 1061 1062 ASSERT(grp->mrg_state == MAC_GROUP_STATE_REGISTERED); 1063 err = mac_start_group_and_rings(grp); 1064 if (err != 0) { 1065 mip->mi_active--; 1066 if (ring != NULL) { 1067 mac_stop_ring(ring); 1068 ring->mr_state = MR_FREE; 1069 } 1070 return (err); 1071 } 1072 mac_set_rx_group_state(grp, MAC_GROUP_STATE_SHARED); 1073 } 1074 } 1075 1076 return (err); 1077 } 1078 1079 /* 1080 * Private GLDv3 function to stop a MAC instance. 1081 */ 1082 void 1083 mac_stop(mac_handle_t mh) 1084 { 1085 mac_impl_t *mip = (mac_impl_t *)mh; 1086 1087 ASSERT(mip->mi_stop != NULL); 1088 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 1089 1090 /* 1091 * Check whether the device is still needed. 1092 */ 1093 ASSERT(mip->mi_active != 0); 1094 if (--mip->mi_active == 0) { 1095 if (mip->mi_rx_groups != NULL) { 1096 /* 1097 * There should be no more active clients since the 1098 * MAC is being stopped. Stop the default RX group 1099 * and transition it back to registered state. 1100 */ 1101 mac_group_t *grp = &mip->mi_rx_groups[0]; 1102 1103 /* 1104 * When clients are torn down, the groups 1105 * are release via mac_release_rx_group which 1106 * knows the the default group is always in 1107 * started mode since broadcast uses it. So 1108 * we can assert that their are no clients 1109 * (since mac_bcast_add doesn't register itself 1110 * as a client) and group is in SHARED state. 1111 */ 1112 ASSERT(grp->mrg_state == MAC_GROUP_STATE_SHARED); 1113 ASSERT(MAC_RX_GROUP_NO_CLIENT(grp) && 1114 mip->mi_nactiveclients == 0); 1115 mac_stop_group_and_rings(grp); 1116 mac_set_rx_group_state(grp, MAC_GROUP_STATE_REGISTERED); 1117 } 1118 1119 if (mip->mi_default_tx_ring != NULL) { 1120 mac_ring_t *ring; 1121 1122 ring = (mac_ring_t *)mip->mi_default_tx_ring; 1123 mac_stop_ring(ring); 1124 ring->mr_state = MR_FREE; 1125 } 1126 1127 /* 1128 * Stop the device. 1129 */ 1130 mip->mi_stop(mip->mi_driver); 1131 } 1132 } 1133 1134 int 1135 i_mac_promisc_set(mac_impl_t *mip, boolean_t on) 1136 { 1137 int err = 0; 1138 1139 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 1140 ASSERT(mip->mi_setpromisc != NULL); 1141 1142 if (on) { 1143 /* 1144 * Enable promiscuous mode on the device if not yet enabled. 1145 */ 1146 if (mip->mi_devpromisc++ == 0) { 1147 err = mip->mi_setpromisc(mip->mi_driver, B_TRUE); 1148 if (err != 0) { 1149 mip->mi_devpromisc--; 1150 return (err); 1151 } 1152 i_mac_notify(mip, MAC_NOTE_DEVPROMISC); 1153 } 1154 } else { 1155 if (mip->mi_devpromisc == 0) 1156 return (EPROTO); 1157 1158 /* 1159 * Disable promiscuous mode on the device if this is the last 1160 * enabling. 1161 */ 1162 if (--mip->mi_devpromisc == 0) { 1163 err = mip->mi_setpromisc(mip->mi_driver, B_FALSE); 1164 if (err != 0) { 1165 mip->mi_devpromisc++; 1166 return (err); 1167 } 1168 i_mac_notify(mip, MAC_NOTE_DEVPROMISC); 1169 } 1170 } 1171 1172 return (0); 1173 } 1174 1175 /* 1176 * The promiscuity state can change any time. If the caller needs to take 1177 * actions that are atomic with the promiscuity state, then the caller needs 1178 * to bracket the entire sequence with mac_perim_enter/exit 1179 */ 1180 boolean_t 1181 mac_promisc_get(mac_handle_t mh) 1182 { 1183 mac_impl_t *mip = (mac_impl_t *)mh; 1184 1185 /* 1186 * Return the current promiscuity. 1187 */ 1188 return (mip->mi_devpromisc != 0); 1189 } 1190 1191 /* 1192 * Invoked at MAC instance attach time to initialize the list 1193 * of factory MAC addresses supported by a MAC instance. This function 1194 * builds a local cache in the mac_impl_t for the MAC addresses 1195 * supported by the underlying hardware. The MAC clients themselves 1196 * use the mac_addr_factory*() functions to query and reserve 1197 * factory MAC addresses. 1198 */ 1199 void 1200 mac_addr_factory_init(mac_impl_t *mip) 1201 { 1202 mac_capab_multifactaddr_t capab; 1203 uint8_t *addr; 1204 int i; 1205 1206 /* 1207 * First round to see how many factory MAC addresses are available. 1208 */ 1209 bzero(&capab, sizeof (capab)); 1210 if (!i_mac_capab_get((mac_handle_t)mip, MAC_CAPAB_MULTIFACTADDR, 1211 &capab) || (capab.mcm_naddr == 0)) { 1212 /* 1213 * The MAC instance doesn't support multiple factory 1214 * MAC addresses, we're done here. 1215 */ 1216 return; 1217 } 1218 1219 /* 1220 * Allocate the space and get all the factory addresses. 1221 */ 1222 addr = kmem_alloc(capab.mcm_naddr * MAXMACADDRLEN, KM_SLEEP); 1223 capab.mcm_getaddr(mip->mi_driver, capab.mcm_naddr, addr); 1224 1225 mip->mi_factory_addr_num = capab.mcm_naddr; 1226 mip->mi_factory_addr = kmem_zalloc(mip->mi_factory_addr_num * 1227 sizeof (mac_factory_addr_t), KM_SLEEP); 1228 1229 for (i = 0; i < capab.mcm_naddr; i++) { 1230 bcopy(addr + i * MAXMACADDRLEN, 1231 mip->mi_factory_addr[i].mfa_addr, 1232 mip->mi_type->mt_addr_length); 1233 mip->mi_factory_addr[i].mfa_in_use = B_FALSE; 1234 } 1235 1236 kmem_free(addr, capab.mcm_naddr * MAXMACADDRLEN); 1237 } 1238 1239 void 1240 mac_addr_factory_fini(mac_impl_t *mip) 1241 { 1242 if (mip->mi_factory_addr == NULL) { 1243 ASSERT(mip->mi_factory_addr_num == 0); 1244 return; 1245 } 1246 1247 kmem_free(mip->mi_factory_addr, mip->mi_factory_addr_num * 1248 sizeof (mac_factory_addr_t)); 1249 1250 mip->mi_factory_addr = NULL; 1251 mip->mi_factory_addr_num = 0; 1252 } 1253 1254 /* 1255 * Reserve a factory MAC address. If *slot is set to -1, the function 1256 * attempts to reserve any of the available factory MAC addresses and 1257 * returns the reserved slot id. If no slots are available, the function 1258 * returns ENOSPC. If *slot is not set to -1, the function reserves 1259 * the specified slot if it is available, or returns EBUSY is the slot 1260 * is already used. Returns ENOTSUP if the underlying MAC does not 1261 * support multiple factory addresses. If the slot number is not -1 but 1262 * is invalid, returns EINVAL. 1263 */ 1264 int 1265 mac_addr_factory_reserve(mac_client_handle_t mch, int *slot) 1266 { 1267 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1268 mac_impl_t *mip = mcip->mci_mip; 1269 int i, ret = 0; 1270 1271 i_mac_perim_enter(mip); 1272 /* 1273 * Protect against concurrent readers that may need a self-consistent 1274 * view of the factory addresses 1275 */ 1276 rw_enter(&mip->mi_rw_lock, RW_WRITER); 1277 1278 if (mip->mi_factory_addr_num == 0) { 1279 ret = ENOTSUP; 1280 goto bail; 1281 } 1282 1283 if (*slot != -1) { 1284 /* check the specified slot */ 1285 if (*slot < 1 || *slot > mip->mi_factory_addr_num) { 1286 ret = EINVAL; 1287 goto bail; 1288 } 1289 if (mip->mi_factory_addr[*slot-1].mfa_in_use) { 1290 ret = EBUSY; 1291 goto bail; 1292 } 1293 } else { 1294 /* pick the next available slot */ 1295 for (i = 0; i < mip->mi_factory_addr_num; i++) { 1296 if (!mip->mi_factory_addr[i].mfa_in_use) 1297 break; 1298 } 1299 1300 if (i == mip->mi_factory_addr_num) { 1301 ret = ENOSPC; 1302 goto bail; 1303 } 1304 *slot = i+1; 1305 } 1306 1307 mip->mi_factory_addr[*slot-1].mfa_in_use = B_TRUE; 1308 mip->mi_factory_addr[*slot-1].mfa_client = mcip; 1309 1310 bail: 1311 rw_exit(&mip->mi_rw_lock); 1312 i_mac_perim_exit(mip); 1313 return (ret); 1314 } 1315 1316 /* 1317 * Release the specified factory MAC address slot. 1318 */ 1319 void 1320 mac_addr_factory_release(mac_client_handle_t mch, uint_t slot) 1321 { 1322 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1323 mac_impl_t *mip = mcip->mci_mip; 1324 1325 i_mac_perim_enter(mip); 1326 /* 1327 * Protect against concurrent readers that may need a self-consistent 1328 * view of the factory addresses 1329 */ 1330 rw_enter(&mip->mi_rw_lock, RW_WRITER); 1331 1332 ASSERT(slot > 0 && slot <= mip->mi_factory_addr_num); 1333 ASSERT(mip->mi_factory_addr[slot-1].mfa_in_use); 1334 1335 mip->mi_factory_addr[slot-1].mfa_in_use = B_FALSE; 1336 1337 rw_exit(&mip->mi_rw_lock); 1338 i_mac_perim_exit(mip); 1339 } 1340 1341 /* 1342 * Stores in mac_addr the value of the specified MAC address. Returns 1343 * 0 on success, or EINVAL if the slot number is not valid for the MAC. 1344 * The caller must provide a string of at least MAXNAMELEN bytes. 1345 */ 1346 void 1347 mac_addr_factory_value(mac_handle_t mh, int slot, uchar_t *mac_addr, 1348 uint_t *addr_len, char *client_name, boolean_t *in_use_arg) 1349 { 1350 mac_impl_t *mip = (mac_impl_t *)mh; 1351 boolean_t in_use; 1352 1353 ASSERT(slot > 0 && slot <= mip->mi_factory_addr_num); 1354 1355 /* 1356 * Readers need to hold mi_rw_lock. Writers need to hold mac perimeter 1357 * and mi_rw_lock 1358 */ 1359 rw_enter(&mip->mi_rw_lock, RW_READER); 1360 bcopy(mip->mi_factory_addr[slot-1].mfa_addr, mac_addr, MAXMACADDRLEN); 1361 *addr_len = mip->mi_type->mt_addr_length; 1362 in_use = mip->mi_factory_addr[slot-1].mfa_in_use; 1363 if (in_use && client_name != NULL) { 1364 bcopy(mip->mi_factory_addr[slot-1].mfa_client->mci_name, 1365 client_name, MAXNAMELEN); 1366 } 1367 if (in_use_arg != NULL) 1368 *in_use_arg = in_use; 1369 rw_exit(&mip->mi_rw_lock); 1370 } 1371 1372 /* 1373 * Returns the number of factory MAC addresses (in addition to the 1374 * primary MAC address), 0 if the underlying MAC doesn't support 1375 * that feature. 1376 */ 1377 uint_t 1378 mac_addr_factory_num(mac_handle_t mh) 1379 { 1380 mac_impl_t *mip = (mac_impl_t *)mh; 1381 1382 return (mip->mi_factory_addr_num); 1383 } 1384 1385 1386 void 1387 mac_rx_group_unmark(mac_group_t *grp, uint_t flag) 1388 { 1389 mac_ring_t *ring; 1390 1391 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next) 1392 ring->mr_flag &= ~flag; 1393 } 1394 1395 /* 1396 * The following mac_hwrings_xxx() functions are private mac client functions 1397 * used by the aggr driver to access and control the underlying HW Rx group 1398 * and rings. In this case, the aggr driver has exclusive control of the 1399 * underlying HW Rx group/rings, it calls the following functions to 1400 * start/stop the HW Rx rings, disable/enable polling, add/remove mac' 1401 * addresses, or set up the Rx callback. 1402 */ 1403 /* ARGSUSED */ 1404 static void 1405 mac_hwrings_rx_process(void *arg, mac_resource_handle_t srs, 1406 mblk_t *mp_chain, boolean_t loopback) 1407 { 1408 mac_soft_ring_set_t *mac_srs = (mac_soft_ring_set_t *)srs; 1409 mac_srs_rx_t *srs_rx = &mac_srs->srs_rx; 1410 mac_direct_rx_t proc; 1411 void *arg1; 1412 mac_resource_handle_t arg2; 1413 1414 proc = srs_rx->sr_func; 1415 arg1 = srs_rx->sr_arg1; 1416 arg2 = mac_srs->srs_mrh; 1417 1418 proc(arg1, arg2, mp_chain, NULL); 1419 } 1420 1421 /* 1422 * This function is called to get the list of HW rings that are reserved by 1423 * an exclusive mac client. 1424 * 1425 * Return value: the number of HW rings. 1426 */ 1427 int 1428 mac_hwrings_get(mac_client_handle_t mch, mac_group_handle_t *hwgh, 1429 mac_ring_handle_t *hwrh) 1430 { 1431 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1432 flow_entry_t *flent = mcip->mci_flent; 1433 mac_group_t *grp = flent->fe_rx_ring_group; 1434 mac_ring_t *ring; 1435 int cnt = 0; 1436 1437 /* 1438 * The mac client did not reserve any RX group, return directly. 1439 * This is probably because the underlying MAC does not support 1440 * any RX groups. 1441 */ 1442 *hwgh = NULL; 1443 if (grp == NULL) 1444 return (0); 1445 1446 /* 1447 * This RX group must be reserved by this mac client. 1448 */ 1449 ASSERT((grp->mrg_state == MAC_GROUP_STATE_RESERVED) && 1450 (mch == (mac_client_handle_t)(MAC_RX_GROUP_ONLY_CLIENT(grp)))); 1451 1452 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next) { 1453 ASSERT(cnt < MAX_RINGS_PER_GROUP); 1454 hwrh[cnt++] = (mac_ring_handle_t)ring; 1455 } 1456 *hwgh = (mac_group_handle_t)grp; 1457 return (cnt); 1458 } 1459 1460 /* 1461 * Setup the RX callback of the mac client which exclusively controls HW ring. 1462 */ 1463 void 1464 mac_hwring_setup(mac_ring_handle_t hwrh, mac_resource_handle_t prh) 1465 { 1466 mac_ring_t *hw_ring = (mac_ring_t *)hwrh; 1467 mac_soft_ring_set_t *mac_srs = hw_ring->mr_srs; 1468 1469 mac_srs->srs_mrh = prh; 1470 mac_srs->srs_rx.sr_lower_proc = mac_hwrings_rx_process; 1471 } 1472 1473 void 1474 mac_hwring_teardown(mac_ring_handle_t hwrh) 1475 { 1476 mac_ring_t *hw_ring = (mac_ring_t *)hwrh; 1477 mac_soft_ring_set_t *mac_srs = hw_ring->mr_srs; 1478 1479 mac_srs->srs_rx.sr_lower_proc = mac_rx_srs_process; 1480 mac_srs->srs_mrh = NULL; 1481 } 1482 1483 int 1484 mac_hwring_disable_intr(mac_ring_handle_t rh) 1485 { 1486 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1487 mac_intr_t *intr = &rr_ring->mr_info.mri_intr; 1488 1489 return (intr->mi_disable(intr->mi_handle)); 1490 } 1491 1492 int 1493 mac_hwring_enable_intr(mac_ring_handle_t rh) 1494 { 1495 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1496 mac_intr_t *intr = &rr_ring->mr_info.mri_intr; 1497 1498 return (intr->mi_enable(intr->mi_handle)); 1499 } 1500 1501 int 1502 mac_hwring_start(mac_ring_handle_t rh) 1503 { 1504 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1505 1506 MAC_RING_UNMARK(rr_ring, MR_QUIESCE); 1507 return (0); 1508 } 1509 1510 void 1511 mac_hwring_stop(mac_ring_handle_t rh) 1512 { 1513 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1514 1515 mac_rx_ring_quiesce(rr_ring, MR_QUIESCE); 1516 } 1517 1518 mblk_t * 1519 mac_hwring_poll(mac_ring_handle_t rh, int bytes_to_pickup) 1520 { 1521 mac_ring_t *rr_ring = (mac_ring_t *)rh; 1522 mac_ring_info_t *info = &rr_ring->mr_info; 1523 1524 return (info->mri_poll(info->mri_driver, bytes_to_pickup)); 1525 } 1526 1527 int 1528 mac_hwgroup_addmac(mac_group_handle_t gh, const uint8_t *addr) 1529 { 1530 mac_group_t *group = (mac_group_t *)gh; 1531 1532 return (mac_group_addmac(group, addr)); 1533 } 1534 1535 int 1536 mac_hwgroup_remmac(mac_group_handle_t gh, const uint8_t *addr) 1537 { 1538 mac_group_t *group = (mac_group_t *)gh; 1539 1540 return (mac_group_remmac(group, addr)); 1541 } 1542 1543 /* 1544 * Set the RX group to be shared/reserved. Note that the group must be 1545 * started/stopped outside of this function. 1546 */ 1547 void 1548 mac_set_rx_group_state(mac_group_t *grp, mac_group_state_t state) 1549 { 1550 /* 1551 * If there is no change in the group state, just return. 1552 */ 1553 if (grp->mrg_state == state) 1554 return; 1555 1556 switch (state) { 1557 case MAC_GROUP_STATE_RESERVED: 1558 /* 1559 * Successfully reserved the group. 1560 * 1561 * Given that there is an exclusive client controlling this 1562 * group, we enable the group level polling when available, 1563 * so that SRSs get to turn on/off individual rings they's 1564 * assigned to. 1565 */ 1566 ASSERT(MAC_PERIM_HELD(grp->mrg_mh)); 1567 1568 if (GROUP_INTR_DISABLE_FUNC(grp) != NULL) 1569 GROUP_INTR_DISABLE_FUNC(grp)(GROUP_INTR_HANDLE(grp)); 1570 1571 break; 1572 1573 case MAC_GROUP_STATE_SHARED: 1574 /* 1575 * Set all rings of this group to software classified. 1576 * If the group has an overriding interrupt, then re-enable it. 1577 */ 1578 ASSERT(MAC_PERIM_HELD(grp->mrg_mh)); 1579 1580 if (GROUP_INTR_ENABLE_FUNC(grp) != NULL) 1581 GROUP_INTR_ENABLE_FUNC(grp)(GROUP_INTR_HANDLE(grp)); 1582 1583 /* The ring is not available for reservations any more */ 1584 break; 1585 1586 case MAC_GROUP_STATE_REGISTERED: 1587 /* Also callable from mac_register, perim is not held */ 1588 break; 1589 1590 default: 1591 ASSERT(B_FALSE); 1592 break; 1593 } 1594 1595 grp->mrg_state = state; 1596 } 1597 1598 /* 1599 * Quiesce future hardware classified packets for the specified Rx ring 1600 */ 1601 static void 1602 mac_rx_ring_quiesce(mac_ring_t *rx_ring, uint_t ring_flag) 1603 { 1604 ASSERT(rx_ring->mr_classify_type == MAC_HW_CLASSIFIER); 1605 ASSERT(ring_flag == MR_CONDEMNED || ring_flag == MR_QUIESCE); 1606 1607 mutex_enter(&rx_ring->mr_lock); 1608 rx_ring->mr_flag |= ring_flag; 1609 while (rx_ring->mr_refcnt != 0) 1610 cv_wait(&rx_ring->mr_cv, &rx_ring->mr_lock); 1611 mutex_exit(&rx_ring->mr_lock); 1612 } 1613 1614 /* 1615 * Please see mac_tx for details about the per cpu locking scheme 1616 */ 1617 static void 1618 mac_tx_lock_all(mac_client_impl_t *mcip) 1619 { 1620 int i; 1621 1622 for (i = 0; i <= mac_tx_percpu_cnt; i++) 1623 mutex_enter(&mcip->mci_tx_pcpu[i].pcpu_tx_lock); 1624 } 1625 1626 static void 1627 mac_tx_unlock_all(mac_client_impl_t *mcip) 1628 { 1629 int i; 1630 1631 for (i = mac_tx_percpu_cnt; i >= 0; i--) 1632 mutex_exit(&mcip->mci_tx_pcpu[i].pcpu_tx_lock); 1633 } 1634 1635 static void 1636 mac_tx_unlock_allbutzero(mac_client_impl_t *mcip) 1637 { 1638 int i; 1639 1640 for (i = mac_tx_percpu_cnt; i > 0; i--) 1641 mutex_exit(&mcip->mci_tx_pcpu[i].pcpu_tx_lock); 1642 } 1643 1644 static int 1645 mac_tx_sum_refcnt(mac_client_impl_t *mcip) 1646 { 1647 int i; 1648 int refcnt = 0; 1649 1650 for (i = 0; i <= mac_tx_percpu_cnt; i++) 1651 refcnt += mcip->mci_tx_pcpu[i].pcpu_tx_refcnt; 1652 1653 return (refcnt); 1654 } 1655 1656 /* 1657 * Stop future Tx packets coming down from the client in preparation for 1658 * quiescing the Tx side. This is needed for dynamic reclaim and reassignment 1659 * of rings between clients 1660 */ 1661 void 1662 mac_tx_client_block(mac_client_impl_t *mcip) 1663 { 1664 mac_tx_lock_all(mcip); 1665 mcip->mci_tx_flag |= MCI_TX_QUIESCE; 1666 while (mac_tx_sum_refcnt(mcip) != 0) { 1667 mac_tx_unlock_allbutzero(mcip); 1668 cv_wait(&mcip->mci_tx_cv, &mcip->mci_tx_pcpu[0].pcpu_tx_lock); 1669 mutex_exit(&mcip->mci_tx_pcpu[0].pcpu_tx_lock); 1670 mac_tx_lock_all(mcip); 1671 } 1672 mac_tx_unlock_all(mcip); 1673 } 1674 1675 void 1676 mac_tx_client_unblock(mac_client_impl_t *mcip) 1677 { 1678 mac_tx_lock_all(mcip); 1679 mcip->mci_tx_flag &= ~MCI_TX_QUIESCE; 1680 mac_tx_unlock_all(mcip); 1681 /* 1682 * We may fail to disable flow control for the last MAC_NOTE_TX 1683 * notification because the MAC client is quiesced. Send the 1684 * notification again. 1685 */ 1686 i_mac_notify(mcip->mci_mip, MAC_NOTE_TX); 1687 } 1688 1689 /* 1690 * Wait for an SRS to quiesce. The SRS worker will signal us when the 1691 * quiesce is done. 1692 */ 1693 static void 1694 mac_srs_quiesce_wait(mac_soft_ring_set_t *srs, uint_t srs_flag) 1695 { 1696 mutex_enter(&srs->srs_lock); 1697 while (!(srs->srs_state & srs_flag)) 1698 cv_wait(&srs->srs_quiesce_done_cv, &srs->srs_lock); 1699 mutex_exit(&srs->srs_lock); 1700 } 1701 1702 /* 1703 * Quiescing an Rx SRS is achieved by the following sequence. The protocol 1704 * works bottom up by cutting off packet flow from the bottommost point in the 1705 * mac, then the SRS, and then the soft rings. There are 2 use cases of this 1706 * mechanism. One is a temporary quiesce of the SRS, such as say while changing 1707 * the Rx callbacks. Another use case is Rx SRS teardown. In the former case 1708 * the QUIESCE prefix/suffix is used and in the latter the CONDEMNED is used 1709 * for the SRS and MR flags. In the former case the threads pause waiting for 1710 * a restart, while in the latter case the threads exit. The Tx SRS teardown 1711 * is also mostly similar to the above. 1712 * 1713 * 1. Stop future hardware classified packets at the lowest level in the mac. 1714 * Remove any hardware classification rule (CONDEMNED case) and mark the 1715 * rings as CONDEMNED or QUIESCE as appropriate. This prevents the mr_refcnt 1716 * from increasing. Upcalls from the driver that come through hardware 1717 * classification will be dropped in mac_rx from now on. Then we wait for 1718 * the mr_refcnt to drop to zero. When the mr_refcnt reaches zero we are 1719 * sure there aren't any upcall threads from the driver through hardware 1720 * classification. In the case of SRS teardown we also remove the 1721 * classification rule in the driver. 1722 * 1723 * 2. Stop future software classified packets by marking the flow entry with 1724 * FE_QUIESCE or FE_CONDEMNED as appropriate which prevents the refcnt from 1725 * increasing. We also remove the flow entry from the table in the latter 1726 * case. Then wait for the fe_refcnt to reach an appropriate quiescent value 1727 * that indicates there aren't any active threads using that flow entry. 1728 * 1729 * 3. Quiesce the SRS and softrings by signaling the SRS. The SRS poll thread, 1730 * SRS worker thread, and the soft ring threads are quiesced in sequence 1731 * with the SRS worker thread serving as a master controller. This 1732 * mechansim is explained in mac_srs_worker_quiesce(). 1733 * 1734 * The restart mechanism to reactivate the SRS and softrings is explained 1735 * in mac_srs_worker_restart(). Here we just signal the SRS worker to start the 1736 * restart sequence. 1737 */ 1738 void 1739 mac_rx_srs_quiesce(mac_soft_ring_set_t *srs, uint_t srs_quiesce_flag) 1740 { 1741 flow_entry_t *flent = srs->srs_flent; 1742 uint_t mr_flag, srs_done_flag; 1743 1744 ASSERT(MAC_PERIM_HELD((mac_handle_t)FLENT_TO_MIP(flent))); 1745 ASSERT(!(srs->srs_type & SRST_TX)); 1746 1747 if (srs_quiesce_flag == SRS_CONDEMNED) { 1748 mr_flag = MR_CONDEMNED; 1749 srs_done_flag = SRS_CONDEMNED_DONE; 1750 if (srs->srs_type & SRST_CLIENT_POLL_ENABLED) 1751 mac_srs_client_poll_disable(srs->srs_mcip, srs); 1752 } else { 1753 ASSERT(srs_quiesce_flag == SRS_QUIESCE); 1754 mr_flag = MR_QUIESCE; 1755 srs_done_flag = SRS_QUIESCE_DONE; 1756 if (srs->srs_type & SRST_CLIENT_POLL_ENABLED) 1757 mac_srs_client_poll_quiesce(srs->srs_mcip, srs); 1758 } 1759 1760 if (srs->srs_ring != NULL) { 1761 mac_rx_ring_quiesce(srs->srs_ring, mr_flag); 1762 } else { 1763 /* 1764 * SRS is driven by software classification. In case 1765 * of CONDEMNED, the top level teardown functions will 1766 * deal with flow removal. 1767 */ 1768 if (srs_quiesce_flag != SRS_CONDEMNED) { 1769 FLOW_MARK(flent, FE_QUIESCE); 1770 mac_flow_wait(flent, FLOW_DRIVER_UPCALL); 1771 } 1772 } 1773 1774 /* 1775 * Signal the SRS to quiesce itself, and then cv_wait for the 1776 * SRS quiesce to complete. The SRS worker thread will wake us 1777 * up when the quiesce is complete 1778 */ 1779 mac_srs_signal(srs, srs_quiesce_flag); 1780 mac_srs_quiesce_wait(srs, srs_done_flag); 1781 } 1782 1783 /* 1784 * Remove an SRS. 1785 */ 1786 void 1787 mac_rx_srs_remove(mac_soft_ring_set_t *srs) 1788 { 1789 flow_entry_t *flent = srs->srs_flent; 1790 int i; 1791 1792 mac_rx_srs_quiesce(srs, SRS_CONDEMNED); 1793 /* 1794 * Locate and remove our entry in the fe_rx_srs[] array, and 1795 * adjust the fe_rx_srs array entries and array count by 1796 * moving the last entry into the vacated spot. 1797 */ 1798 mutex_enter(&flent->fe_lock); 1799 for (i = 0; i < flent->fe_rx_srs_cnt; i++) { 1800 if (flent->fe_rx_srs[i] == srs) 1801 break; 1802 } 1803 1804 ASSERT(i != 0 && i < flent->fe_rx_srs_cnt); 1805 if (i != flent->fe_rx_srs_cnt - 1) { 1806 flent->fe_rx_srs[i] = 1807 flent->fe_rx_srs[flent->fe_rx_srs_cnt - 1]; 1808 i = flent->fe_rx_srs_cnt - 1; 1809 } 1810 1811 flent->fe_rx_srs[i] = NULL; 1812 flent->fe_rx_srs_cnt--; 1813 mutex_exit(&flent->fe_lock); 1814 1815 mac_srs_free(srs); 1816 } 1817 1818 static void 1819 mac_srs_clear_flag(mac_soft_ring_set_t *srs, uint_t flag) 1820 { 1821 mutex_enter(&srs->srs_lock); 1822 srs->srs_state &= ~flag; 1823 mutex_exit(&srs->srs_lock); 1824 } 1825 1826 void 1827 mac_rx_srs_restart(mac_soft_ring_set_t *srs) 1828 { 1829 flow_entry_t *flent = srs->srs_flent; 1830 mac_ring_t *mr; 1831 1832 ASSERT(MAC_PERIM_HELD((mac_handle_t)FLENT_TO_MIP(flent))); 1833 ASSERT((srs->srs_type & SRST_TX) == 0); 1834 1835 /* 1836 * This handles a change in the number of SRSs between the quiesce and 1837 * and restart operation of a flow. 1838 */ 1839 if (!SRS_QUIESCED(srs)) 1840 return; 1841 1842 /* 1843 * Signal the SRS to restart itself. Wait for the restart to complete 1844 * Note that we only restart the SRS if it is not marked as 1845 * permanently quiesced. 1846 */ 1847 if (!SRS_QUIESCED_PERMANENT(srs)) { 1848 mac_srs_signal(srs, SRS_RESTART); 1849 mac_srs_quiesce_wait(srs, SRS_RESTART_DONE); 1850 mac_srs_clear_flag(srs, SRS_RESTART_DONE); 1851 1852 mac_srs_client_poll_restart(srs->srs_mcip, srs); 1853 } 1854 1855 /* Finally clear the flags to let the packets in */ 1856 mr = srs->srs_ring; 1857 if (mr != NULL) { 1858 MAC_RING_UNMARK(mr, MR_QUIESCE); 1859 /* In case the ring was stopped, safely restart it */ 1860 (void) mac_start_ring(mr); 1861 } else { 1862 FLOW_UNMARK(flent, FE_QUIESCE); 1863 } 1864 } 1865 1866 /* 1867 * Temporary quiesce of a flow and associated Rx SRS. 1868 * Please see block comment above mac_rx_classify_flow_rem. 1869 */ 1870 /* ARGSUSED */ 1871 int 1872 mac_rx_classify_flow_quiesce(flow_entry_t *flent, void *arg) 1873 { 1874 int i; 1875 1876 for (i = 0; i < flent->fe_rx_srs_cnt; i++) { 1877 mac_rx_srs_quiesce((mac_soft_ring_set_t *)flent->fe_rx_srs[i], 1878 SRS_QUIESCE); 1879 } 1880 return (0); 1881 } 1882 1883 /* 1884 * Restart a flow and associated Rx SRS that has been quiesced temporarily 1885 * Please see block comment above mac_rx_classify_flow_rem 1886 */ 1887 /* ARGSUSED */ 1888 int 1889 mac_rx_classify_flow_restart(flow_entry_t *flent, void *arg) 1890 { 1891 int i; 1892 1893 for (i = 0; i < flent->fe_rx_srs_cnt; i++) 1894 mac_rx_srs_restart((mac_soft_ring_set_t *)flent->fe_rx_srs[i]); 1895 1896 return (0); 1897 } 1898 1899 void 1900 mac_srs_perm_quiesce(mac_client_handle_t mch, boolean_t on) 1901 { 1902 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1903 flow_entry_t *flent = mcip->mci_flent; 1904 mac_impl_t *mip = mcip->mci_mip; 1905 mac_soft_ring_set_t *mac_srs; 1906 int i; 1907 1908 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 1909 1910 if (flent == NULL) 1911 return; 1912 1913 for (i = 0; i < flent->fe_rx_srs_cnt; i++) { 1914 mac_srs = flent->fe_rx_srs[i]; 1915 mutex_enter(&mac_srs->srs_lock); 1916 if (on) 1917 mac_srs->srs_state |= SRS_QUIESCE_PERM; 1918 else 1919 mac_srs->srs_state &= ~SRS_QUIESCE_PERM; 1920 mutex_exit(&mac_srs->srs_lock); 1921 } 1922 } 1923 1924 void 1925 mac_rx_client_quiesce(mac_client_handle_t mch) 1926 { 1927 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1928 mac_impl_t *mip = mcip->mci_mip; 1929 1930 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 1931 1932 if (MCIP_DATAPATH_SETUP(mcip)) { 1933 (void) mac_rx_classify_flow_quiesce(mcip->mci_flent, 1934 NULL); 1935 (void) mac_flow_walk_nolock(mcip->mci_subflow_tab, 1936 mac_rx_classify_flow_quiesce, NULL); 1937 } 1938 } 1939 1940 void 1941 mac_rx_client_restart(mac_client_handle_t mch) 1942 { 1943 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 1944 mac_impl_t *mip = mcip->mci_mip; 1945 1946 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 1947 1948 if (MCIP_DATAPATH_SETUP(mcip)) { 1949 (void) mac_rx_classify_flow_restart(mcip->mci_flent, NULL); 1950 (void) mac_flow_walk_nolock(mcip->mci_subflow_tab, 1951 mac_rx_classify_flow_restart, NULL); 1952 } 1953 } 1954 1955 /* 1956 * This function only quiesces the Tx SRS and softring worker threads. Callers 1957 * need to make sure that there aren't any mac client threads doing current or 1958 * future transmits in the mac before calling this function. 1959 */ 1960 void 1961 mac_tx_srs_quiesce(mac_soft_ring_set_t *srs, uint_t srs_quiesce_flag) 1962 { 1963 mac_client_impl_t *mcip = srs->srs_mcip; 1964 1965 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 1966 1967 ASSERT(srs->srs_type & SRST_TX); 1968 ASSERT(srs_quiesce_flag == SRS_CONDEMNED || 1969 srs_quiesce_flag == SRS_QUIESCE); 1970 1971 /* 1972 * Signal the SRS to quiesce itself, and then cv_wait for the 1973 * SRS quiesce to complete. The SRS worker thread will wake us 1974 * up when the quiesce is complete 1975 */ 1976 mac_srs_signal(srs, srs_quiesce_flag); 1977 mac_srs_quiesce_wait(srs, srs_quiesce_flag == SRS_QUIESCE ? 1978 SRS_QUIESCE_DONE : SRS_CONDEMNED_DONE); 1979 } 1980 1981 void 1982 mac_tx_srs_restart(mac_soft_ring_set_t *srs) 1983 { 1984 /* 1985 * Resizing the fanout could result in creation of new SRSs. 1986 * They may not necessarily be in the quiesced state in which 1987 * case it need be restarted 1988 */ 1989 if (!SRS_QUIESCED(srs)) 1990 return; 1991 1992 mac_srs_signal(srs, SRS_RESTART); 1993 mac_srs_quiesce_wait(srs, SRS_RESTART_DONE); 1994 mac_srs_clear_flag(srs, SRS_RESTART_DONE); 1995 } 1996 1997 /* 1998 * Temporary quiesce of a flow and associated Rx SRS. 1999 * Please see block comment above mac_rx_srs_quiesce 2000 */ 2001 /* ARGSUSED */ 2002 int 2003 mac_tx_flow_quiesce(flow_entry_t *flent, void *arg) 2004 { 2005 /* 2006 * The fe_tx_srs is null for a subflow on an interface that is 2007 * not plumbed 2008 */ 2009 if (flent->fe_tx_srs != NULL) 2010 mac_tx_srs_quiesce(flent->fe_tx_srs, SRS_QUIESCE); 2011 return (0); 2012 } 2013 2014 /* ARGSUSED */ 2015 int 2016 mac_tx_flow_restart(flow_entry_t *flent, void *arg) 2017 { 2018 /* 2019 * The fe_tx_srs is null for a subflow on an interface that is 2020 * not plumbed 2021 */ 2022 if (flent->fe_tx_srs != NULL) 2023 mac_tx_srs_restart(flent->fe_tx_srs); 2024 return (0); 2025 } 2026 2027 void 2028 mac_tx_client_quiesce(mac_client_impl_t *mcip, uint_t srs_quiesce_flag) 2029 { 2030 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 2031 2032 mac_tx_client_block(mcip); 2033 if (MCIP_TX_SRS(mcip) != NULL) { 2034 mac_tx_srs_quiesce(MCIP_TX_SRS(mcip), srs_quiesce_flag); 2035 (void) mac_flow_walk_nolock(mcip->mci_subflow_tab, 2036 mac_tx_flow_quiesce, NULL); 2037 } 2038 } 2039 2040 void 2041 mac_tx_client_restart(mac_client_impl_t *mcip) 2042 { 2043 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 2044 2045 mac_tx_client_unblock(mcip); 2046 if (MCIP_TX_SRS(mcip) != NULL) { 2047 mac_tx_srs_restart(MCIP_TX_SRS(mcip)); 2048 (void) mac_flow_walk_nolock(mcip->mci_subflow_tab, 2049 mac_tx_flow_restart, NULL); 2050 } 2051 } 2052 2053 void 2054 mac_tx_client_flush(mac_client_impl_t *mcip) 2055 { 2056 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 2057 2058 mac_tx_client_quiesce(mcip, SRS_QUIESCE); 2059 mac_tx_client_restart(mcip); 2060 } 2061 2062 void 2063 mac_client_quiesce(mac_client_impl_t *mcip) 2064 { 2065 mac_rx_client_quiesce((mac_client_handle_t)mcip); 2066 mac_tx_client_quiesce(mcip, SRS_QUIESCE); 2067 } 2068 2069 void 2070 mac_client_restart(mac_client_impl_t *mcip) 2071 { 2072 mac_rx_client_restart((mac_client_handle_t)mcip); 2073 mac_tx_client_restart(mcip); 2074 } 2075 2076 /* 2077 * Allocate a minor number. 2078 */ 2079 minor_t 2080 mac_minor_hold(boolean_t sleep) 2081 { 2082 minor_t minor; 2083 2084 /* 2085 * Grab a value from the arena. 2086 */ 2087 atomic_add_32(&minor_count, 1); 2088 2089 if (sleep) 2090 minor = (uint_t)id_alloc(minor_ids); 2091 else 2092 minor = (uint_t)id_alloc_nosleep(minor_ids); 2093 2094 if (minor == 0) { 2095 atomic_add_32(&minor_count, -1); 2096 return (0); 2097 } 2098 2099 return (minor); 2100 } 2101 2102 /* 2103 * Release a previously allocated minor number. 2104 */ 2105 void 2106 mac_minor_rele(minor_t minor) 2107 { 2108 /* 2109 * Return the value to the arena. 2110 */ 2111 id_free(minor_ids, minor); 2112 atomic_add_32(&minor_count, -1); 2113 } 2114 2115 uint32_t 2116 mac_no_notification(mac_handle_t mh) 2117 { 2118 mac_impl_t *mip = (mac_impl_t *)mh; 2119 2120 return (((mip->mi_state_flags & MIS_LEGACY) != 0) ? 2121 mip->mi_capab_legacy.ml_unsup_note : 0); 2122 } 2123 2124 /* 2125 * Prevent any new opens of this mac in preparation for unregister 2126 */ 2127 int 2128 i_mac_disable(mac_impl_t *mip) 2129 { 2130 mac_client_impl_t *mcip; 2131 2132 rw_enter(&i_mac_impl_lock, RW_WRITER); 2133 if (mip->mi_state_flags & MIS_DISABLED) { 2134 /* Already disabled, return success */ 2135 rw_exit(&i_mac_impl_lock); 2136 return (0); 2137 } 2138 /* 2139 * See if there are any other references to this mac_t (e.g., VLAN's). 2140 * If so return failure. If all the other checks below pass, then 2141 * set mi_disabled atomically under the i_mac_impl_lock to prevent 2142 * any new VLAN's from being created or new mac client opens of this 2143 * mac end point. 2144 */ 2145 if (mip->mi_ref > 0) { 2146 rw_exit(&i_mac_impl_lock); 2147 return (EBUSY); 2148 } 2149 2150 /* 2151 * mac clients must delete all multicast groups they join before 2152 * closing. bcast groups are reference counted, the last client 2153 * to delete the group will wait till the group is physically 2154 * deleted. Since all clients have closed this mac end point 2155 * mi_bcast_ngrps must be zero at this point 2156 */ 2157 ASSERT(mip->mi_bcast_ngrps == 0); 2158 2159 /* 2160 * Don't let go of this if it has some flows. 2161 * All other code guarantees no flows are added to a disabled 2162 * mac, therefore it is sufficient to check for the flow table 2163 * only here. 2164 */ 2165 mcip = mac_primary_client_handle(mip); 2166 if ((mcip != NULL) && mac_link_has_flows((mac_client_handle_t)mcip)) { 2167 rw_exit(&i_mac_impl_lock); 2168 return (ENOTEMPTY); 2169 } 2170 2171 mip->mi_state_flags |= MIS_DISABLED; 2172 rw_exit(&i_mac_impl_lock); 2173 return (0); 2174 } 2175 2176 int 2177 mac_disable_nowait(mac_handle_t mh) 2178 { 2179 mac_impl_t *mip = (mac_impl_t *)mh; 2180 int err; 2181 2182 if ((err = i_mac_perim_enter_nowait(mip)) != 0) 2183 return (err); 2184 err = i_mac_disable(mip); 2185 i_mac_perim_exit(mip); 2186 return (err); 2187 } 2188 2189 int 2190 mac_disable(mac_handle_t mh) 2191 { 2192 mac_impl_t *mip = (mac_impl_t *)mh; 2193 int err; 2194 2195 i_mac_perim_enter(mip); 2196 err = i_mac_disable(mip); 2197 i_mac_perim_exit(mip); 2198 2199 /* 2200 * Clean up notification thread and wait for it to exit. 2201 */ 2202 if (err == 0) 2203 i_mac_notify_exit(mip); 2204 2205 return (err); 2206 } 2207 2208 /* 2209 * Called when the MAC instance has a non empty flow table, to de-multiplex 2210 * incoming packets to the right flow. 2211 * The MAC's rw lock is assumed held as a READER. 2212 */ 2213 /* ARGSUSED */ 2214 static mblk_t * 2215 mac_rx_classify(mac_impl_t *mip, mac_resource_handle_t mrh, mblk_t *mp) 2216 { 2217 flow_entry_t *flent = NULL; 2218 uint_t flags = FLOW_INBOUND; 2219 int err; 2220 2221 /* 2222 * If the mac is a port of an aggregation, pass FLOW_IGNORE_VLAN 2223 * to mac_flow_lookup() so that the VLAN packets can be successfully 2224 * passed to the non-VLAN aggregation flows. 2225 * 2226 * Note that there is possibly a race between this and 2227 * mac_unicast_remove/add() and VLAN packets could be incorrectly 2228 * classified to non-VLAN flows of non-aggregation mac clients. These 2229 * VLAN packets will be then filtered out by the mac module. 2230 */ 2231 if ((mip->mi_state_flags & MIS_EXCLUSIVE) != 0) 2232 flags |= FLOW_IGNORE_VLAN; 2233 2234 err = mac_flow_lookup(mip->mi_flow_tab, mp, flags, &flent); 2235 if (err != 0) { 2236 /* no registered receive function */ 2237 return (mp); 2238 } else { 2239 mac_client_impl_t *mcip; 2240 2241 /* 2242 * This flent might just be an additional one on the MAC client, 2243 * i.e. for classification purposes (different fdesc), however 2244 * the resources, SRS et. al., are in the mci_flent, so if 2245 * this isn't the mci_flent, we need to get it. 2246 */ 2247 if ((mcip = flent->fe_mcip) != NULL && 2248 mcip->mci_flent != flent) { 2249 FLOW_REFRELE(flent); 2250 flent = mcip->mci_flent; 2251 FLOW_TRY_REFHOLD(flent, err); 2252 if (err != 0) 2253 return (mp); 2254 } 2255 (flent->fe_cb_fn)(flent->fe_cb_arg1, flent->fe_cb_arg2, mp, 2256 B_FALSE); 2257 FLOW_REFRELE(flent); 2258 } 2259 return (NULL); 2260 } 2261 2262 mblk_t * 2263 mac_rx_flow(mac_handle_t mh, mac_resource_handle_t mrh, mblk_t *mp_chain) 2264 { 2265 mac_impl_t *mip = (mac_impl_t *)mh; 2266 mblk_t *bp, *bp1, **bpp, *list = NULL; 2267 2268 /* 2269 * We walk the chain and attempt to classify each packet. 2270 * The packets that couldn't be classified will be returned 2271 * back to the caller. 2272 */ 2273 bp = mp_chain; 2274 bpp = &list; 2275 while (bp != NULL) { 2276 bp1 = bp; 2277 bp = bp->b_next; 2278 bp1->b_next = NULL; 2279 2280 if (mac_rx_classify(mip, mrh, bp1) != NULL) { 2281 *bpp = bp1; 2282 bpp = &bp1->b_next; 2283 } 2284 } 2285 return (list); 2286 } 2287 2288 static int 2289 mac_tx_flow_srs_wakeup(flow_entry_t *flent, void *arg) 2290 { 2291 mac_ring_handle_t ring = arg; 2292 2293 if (flent->fe_tx_srs) 2294 mac_tx_srs_wakeup(flent->fe_tx_srs, ring); 2295 return (0); 2296 } 2297 2298 void 2299 i_mac_tx_srs_notify(mac_impl_t *mip, mac_ring_handle_t ring) 2300 { 2301 mac_client_impl_t *cclient; 2302 mac_soft_ring_set_t *mac_srs; 2303 2304 /* 2305 * After grabbing the mi_rw_lock, the list of clients can't change. 2306 * If there are any clients mi_disabled must be B_FALSE and can't 2307 * get set since there are clients. If there aren't any clients we 2308 * don't do anything. In any case the mip has to be valid. The driver 2309 * must make sure that it goes single threaded (with respect to mac 2310 * calls) and wait for all pending mac calls to finish before calling 2311 * mac_unregister. 2312 */ 2313 rw_enter(&i_mac_impl_lock, RW_READER); 2314 if (mip->mi_state_flags & MIS_DISABLED) { 2315 rw_exit(&i_mac_impl_lock); 2316 return; 2317 } 2318 2319 /* 2320 * Get MAC tx srs from walking mac_client_handle list. 2321 */ 2322 rw_enter(&mip->mi_rw_lock, RW_READER); 2323 for (cclient = mip->mi_clients_list; cclient != NULL; 2324 cclient = cclient->mci_client_next) { 2325 if ((mac_srs = MCIP_TX_SRS(cclient)) != NULL) 2326 mac_tx_srs_wakeup(mac_srs, ring); 2327 (void) mac_flow_walk(cclient->mci_subflow_tab, 2328 mac_tx_flow_srs_wakeup, ring); 2329 } 2330 rw_exit(&mip->mi_rw_lock); 2331 rw_exit(&i_mac_impl_lock); 2332 } 2333 2334 /* ARGSUSED */ 2335 void 2336 mac_multicast_refresh(mac_handle_t mh, mac_multicst_t refresh, void *arg, 2337 boolean_t add) 2338 { 2339 mac_impl_t *mip = (mac_impl_t *)mh; 2340 2341 i_mac_perim_enter((mac_impl_t *)mh); 2342 /* 2343 * If no specific refresh function was given then default to the 2344 * driver's m_multicst entry point. 2345 */ 2346 if (refresh == NULL) { 2347 refresh = mip->mi_multicst; 2348 arg = mip->mi_driver; 2349 } 2350 2351 mac_bcast_refresh(mip, refresh, arg, add); 2352 i_mac_perim_exit((mac_impl_t *)mh); 2353 } 2354 2355 void 2356 mac_promisc_refresh(mac_handle_t mh, mac_setpromisc_t refresh, void *arg) 2357 { 2358 mac_impl_t *mip = (mac_impl_t *)mh; 2359 2360 /* 2361 * If no specific refresh function was given then default to the 2362 * driver's m_promisc entry point. 2363 */ 2364 if (refresh == NULL) { 2365 refresh = mip->mi_setpromisc; 2366 arg = mip->mi_driver; 2367 } 2368 ASSERT(refresh != NULL); 2369 2370 /* 2371 * Call the refresh function with the current promiscuity. 2372 */ 2373 refresh(arg, (mip->mi_devpromisc != 0)); 2374 } 2375 2376 /* 2377 * The mac client requests that the mac not to change its margin size to 2378 * be less than the specified value. If "current" is B_TRUE, then the client 2379 * requests the mac not to change its margin size to be smaller than the 2380 * current size. Further, return the current margin size value in this case. 2381 * 2382 * We keep every requested size in an ordered list from largest to smallest. 2383 */ 2384 int 2385 mac_margin_add(mac_handle_t mh, uint32_t *marginp, boolean_t current) 2386 { 2387 mac_impl_t *mip = (mac_impl_t *)mh; 2388 mac_margin_req_t **pp, *p; 2389 int err = 0; 2390 2391 rw_enter(&(mip->mi_rw_lock), RW_WRITER); 2392 if (current) 2393 *marginp = mip->mi_margin; 2394 2395 /* 2396 * If the current margin value cannot satisfy the margin requested, 2397 * return ENOTSUP directly. 2398 */ 2399 if (*marginp > mip->mi_margin) { 2400 err = ENOTSUP; 2401 goto done; 2402 } 2403 2404 /* 2405 * Check whether the given margin is already in the list. If so, 2406 * bump the reference count. 2407 */ 2408 for (pp = &mip->mi_mmrp; (p = *pp) != NULL; pp = &p->mmr_nextp) { 2409 if (p->mmr_margin == *marginp) { 2410 /* 2411 * The margin requested is already in the list, 2412 * so just bump the reference count. 2413 */ 2414 p->mmr_ref++; 2415 goto done; 2416 } 2417 if (p->mmr_margin < *marginp) 2418 break; 2419 } 2420 2421 2422 p = kmem_zalloc(sizeof (mac_margin_req_t), KM_SLEEP); 2423 p->mmr_margin = *marginp; 2424 p->mmr_ref++; 2425 p->mmr_nextp = *pp; 2426 *pp = p; 2427 2428 done: 2429 rw_exit(&(mip->mi_rw_lock)); 2430 return (err); 2431 } 2432 2433 /* 2434 * The mac client requests to cancel its previous mac_margin_add() request. 2435 * We remove the requested margin size from the list. 2436 */ 2437 int 2438 mac_margin_remove(mac_handle_t mh, uint32_t margin) 2439 { 2440 mac_impl_t *mip = (mac_impl_t *)mh; 2441 mac_margin_req_t **pp, *p; 2442 int err = 0; 2443 2444 rw_enter(&(mip->mi_rw_lock), RW_WRITER); 2445 /* 2446 * Find the entry in the list for the given margin. 2447 */ 2448 for (pp = &(mip->mi_mmrp); (p = *pp) != NULL; pp = &(p->mmr_nextp)) { 2449 if (p->mmr_margin == margin) { 2450 if (--p->mmr_ref == 0) 2451 break; 2452 2453 /* 2454 * There is still a reference to this address so 2455 * there's nothing more to do. 2456 */ 2457 goto done; 2458 } 2459 } 2460 2461 /* 2462 * We did not find an entry for the given margin. 2463 */ 2464 if (p == NULL) { 2465 err = ENOENT; 2466 goto done; 2467 } 2468 2469 ASSERT(p->mmr_ref == 0); 2470 2471 /* 2472 * Remove it from the list. 2473 */ 2474 *pp = p->mmr_nextp; 2475 kmem_free(p, sizeof (mac_margin_req_t)); 2476 done: 2477 rw_exit(&(mip->mi_rw_lock)); 2478 return (err); 2479 } 2480 2481 boolean_t 2482 mac_margin_update(mac_handle_t mh, uint32_t margin) 2483 { 2484 mac_impl_t *mip = (mac_impl_t *)mh; 2485 uint32_t margin_needed = 0; 2486 2487 rw_enter(&(mip->mi_rw_lock), RW_WRITER); 2488 2489 if (mip->mi_mmrp != NULL) 2490 margin_needed = mip->mi_mmrp->mmr_margin; 2491 2492 if (margin_needed <= margin) 2493 mip->mi_margin = margin; 2494 2495 rw_exit(&(mip->mi_rw_lock)); 2496 2497 if (margin_needed <= margin) 2498 i_mac_notify(mip, MAC_NOTE_MARGIN); 2499 2500 return (margin_needed <= margin); 2501 } 2502 2503 /* 2504 * MAC Type Plugin functions. 2505 */ 2506 2507 mactype_t * 2508 mactype_getplugin(const char *pname) 2509 { 2510 mactype_t *mtype = NULL; 2511 boolean_t tried_modload = B_FALSE; 2512 2513 mutex_enter(&i_mactype_lock); 2514 2515 find_registered_mactype: 2516 if (mod_hash_find(i_mactype_hash, (mod_hash_key_t)pname, 2517 (mod_hash_val_t *)&mtype) != 0) { 2518 if (!tried_modload) { 2519 /* 2520 * If the plugin has not yet been loaded, then 2521 * attempt to load it now. If modload() succeeds, 2522 * the plugin should have registered using 2523 * mactype_register(), in which case we can go back 2524 * and attempt to find it again. 2525 */ 2526 if (modload(MACTYPE_KMODDIR, (char *)pname) != -1) { 2527 tried_modload = B_TRUE; 2528 goto find_registered_mactype; 2529 } 2530 } 2531 } else { 2532 /* 2533 * Note that there's no danger that the plugin we've loaded 2534 * could be unloaded between the modload() step and the 2535 * reference count bump here, as we're holding 2536 * i_mactype_lock, which mactype_unregister() also holds. 2537 */ 2538 atomic_inc_32(&mtype->mt_ref); 2539 } 2540 2541 mutex_exit(&i_mactype_lock); 2542 return (mtype); 2543 } 2544 2545 mactype_register_t * 2546 mactype_alloc(uint_t mactype_version) 2547 { 2548 mactype_register_t *mtrp; 2549 2550 /* 2551 * Make sure there isn't a version mismatch between the plugin and 2552 * the framework. In the future, if multiple versions are 2553 * supported, this check could become more sophisticated. 2554 */ 2555 if (mactype_version != MACTYPE_VERSION) 2556 return (NULL); 2557 2558 mtrp = kmem_zalloc(sizeof (mactype_register_t), KM_SLEEP); 2559 mtrp->mtr_version = mactype_version; 2560 return (mtrp); 2561 } 2562 2563 void 2564 mactype_free(mactype_register_t *mtrp) 2565 { 2566 kmem_free(mtrp, sizeof (mactype_register_t)); 2567 } 2568 2569 int 2570 mactype_register(mactype_register_t *mtrp) 2571 { 2572 mactype_t *mtp; 2573 mactype_ops_t *ops = mtrp->mtr_ops; 2574 2575 /* Do some sanity checking before we register this MAC type. */ 2576 if (mtrp->mtr_ident == NULL || ops == NULL) 2577 return (EINVAL); 2578 2579 /* 2580 * Verify that all mandatory callbacks are set in the ops 2581 * vector. 2582 */ 2583 if (ops->mtops_unicst_verify == NULL || 2584 ops->mtops_multicst_verify == NULL || 2585 ops->mtops_sap_verify == NULL || 2586 ops->mtops_header == NULL || 2587 ops->mtops_header_info == NULL) { 2588 return (EINVAL); 2589 } 2590 2591 mtp = kmem_zalloc(sizeof (*mtp), KM_SLEEP); 2592 mtp->mt_ident = mtrp->mtr_ident; 2593 mtp->mt_ops = *ops; 2594 mtp->mt_type = mtrp->mtr_mactype; 2595 mtp->mt_nativetype = mtrp->mtr_nativetype; 2596 mtp->mt_addr_length = mtrp->mtr_addrlen; 2597 if (mtrp->mtr_brdcst_addr != NULL) { 2598 mtp->mt_brdcst_addr = kmem_alloc(mtrp->mtr_addrlen, KM_SLEEP); 2599 bcopy(mtrp->mtr_brdcst_addr, mtp->mt_brdcst_addr, 2600 mtrp->mtr_addrlen); 2601 } 2602 2603 mtp->mt_stats = mtrp->mtr_stats; 2604 mtp->mt_statcount = mtrp->mtr_statcount; 2605 2606 mtp->mt_mapping = mtrp->mtr_mapping; 2607 mtp->mt_mappingcount = mtrp->mtr_mappingcount; 2608 2609 if (mod_hash_insert(i_mactype_hash, 2610 (mod_hash_key_t)mtp->mt_ident, (mod_hash_val_t)mtp) != 0) { 2611 kmem_free(mtp->mt_brdcst_addr, mtp->mt_addr_length); 2612 kmem_free(mtp, sizeof (*mtp)); 2613 return (EEXIST); 2614 } 2615 return (0); 2616 } 2617 2618 int 2619 mactype_unregister(const char *ident) 2620 { 2621 mactype_t *mtp; 2622 mod_hash_val_t val; 2623 int err; 2624 2625 /* 2626 * Let's not allow MAC drivers to use this plugin while we're 2627 * trying to unregister it. Holding i_mactype_lock also prevents a 2628 * plugin from unregistering while a MAC driver is attempting to 2629 * hold a reference to it in i_mactype_getplugin(). 2630 */ 2631 mutex_enter(&i_mactype_lock); 2632 2633 if ((err = mod_hash_find(i_mactype_hash, (mod_hash_key_t)ident, 2634 (mod_hash_val_t *)&mtp)) != 0) { 2635 /* A plugin is trying to unregister, but it never registered. */ 2636 err = ENXIO; 2637 goto done; 2638 } 2639 2640 if (mtp->mt_ref != 0) { 2641 err = EBUSY; 2642 goto done; 2643 } 2644 2645 err = mod_hash_remove(i_mactype_hash, (mod_hash_key_t)ident, &val); 2646 ASSERT(err == 0); 2647 if (err != 0) { 2648 /* This should never happen, thus the ASSERT() above. */ 2649 err = EINVAL; 2650 goto done; 2651 } 2652 ASSERT(mtp == (mactype_t *)val); 2653 2654 kmem_free(mtp->mt_brdcst_addr, mtp->mt_addr_length); 2655 kmem_free(mtp, sizeof (mactype_t)); 2656 done: 2657 mutex_exit(&i_mactype_lock); 2658 return (err); 2659 } 2660 2661 /* 2662 * Returns TRUE when the specified property is intended for the MAC framework, 2663 * as opposed to driver defined properties. 2664 */ 2665 static boolean_t 2666 mac_is_macprop(mac_prop_t *macprop) 2667 { 2668 switch (macprop->mp_id) { 2669 case MAC_PROP_MAXBW: 2670 case MAC_PROP_PRIO: 2671 case MAC_PROP_BIND_CPU: 2672 return (B_TRUE); 2673 default: 2674 return (B_FALSE); 2675 } 2676 } 2677 2678 /* 2679 * mac_set_prop() sets mac or hardware driver properties: 2680 * mac properties include maxbw, priority, and cpu binding list. Driver 2681 * properties are private properties to the hardware, such as mtu, speed 2682 * etc. 2683 * If the property is a driver property, mac_set_prop() calls driver's callback 2684 * function to set it. 2685 * If the property is a mac property, mac_set_prop() invokes mac_set_resources() 2686 * which will cache the property value in mac_impl_t and may call 2687 * mac_client_set_resource() to update property value of the primary mac client, 2688 * if it exists. 2689 */ 2690 int 2691 mac_set_prop(mac_handle_t mh, mac_prop_t *macprop, void *val, uint_t valsize) 2692 { 2693 int err = ENOTSUP; 2694 mac_impl_t *mip = (mac_impl_t *)mh; 2695 2696 ASSERT(MAC_PERIM_HELD(mh)); 2697 2698 /* If it is mac property, call mac_set_resources() */ 2699 if (mac_is_macprop(macprop)) { 2700 mac_resource_props_t mrp; 2701 2702 if (valsize < sizeof (mac_resource_props_t)) 2703 return (EINVAL); 2704 bzero(&mrp, sizeof (mac_resource_props_t)); 2705 bcopy(val, &mrp, sizeof (mrp)); 2706 return (mac_set_resources(mh, &mrp)); 2707 } 2708 switch (macprop->mp_id) { 2709 case MAC_PROP_MTU: { 2710 uint32_t mtu; 2711 2712 if (valsize < sizeof (mtu)) 2713 return (EINVAL); 2714 bcopy(val, &mtu, sizeof (mtu)); 2715 err = mac_set_mtu(mh, mtu, NULL); 2716 break; 2717 } 2718 default: 2719 /* For other driver properties, call driver's callback */ 2720 if (mip->mi_callbacks->mc_callbacks & MC_SETPROP) { 2721 err = mip->mi_callbacks->mc_setprop(mip->mi_driver, 2722 macprop->mp_name, macprop->mp_id, valsize, val); 2723 } 2724 } 2725 return (err); 2726 } 2727 2728 /* 2729 * mac_get_prop() gets mac or hardware driver properties. 2730 * 2731 * If the property is a driver property, mac_get_prop() calls driver's callback 2732 * function to get it. 2733 * If the property is a mac property, mac_get_prop() invokes mac_get_resources() 2734 * which returns the cached value in mac_impl_t. 2735 */ 2736 int 2737 mac_get_prop(mac_handle_t mh, mac_prop_t *macprop, void *val, uint_t valsize, 2738 uint_t *perm) 2739 { 2740 int err = ENOTSUP; 2741 mac_impl_t *mip = (mac_impl_t *)mh; 2742 link_state_t link_state; 2743 boolean_t is_getprop, is_setprop; 2744 2745 is_getprop = (mip->mi_callbacks->mc_callbacks & MC_GETPROP); 2746 is_setprop = (mip->mi_callbacks->mc_callbacks & MC_SETPROP); 2747 2748 /* If mac property, read from cache */ 2749 if (mac_is_macprop(macprop)) { 2750 mac_resource_props_t mrp; 2751 2752 if (valsize < sizeof (mac_resource_props_t)) 2753 return (EINVAL); 2754 bzero(&mrp, sizeof (mac_resource_props_t)); 2755 mac_get_resources(mh, &mrp); 2756 bcopy(&mrp, val, sizeof (mac_resource_props_t)); 2757 return (0); 2758 } 2759 2760 switch (macprop->mp_id) { 2761 case MAC_PROP_MTU: { 2762 uint32_t sdu; 2763 mac_propval_range_t range; 2764 2765 if ((macprop->mp_flags & MAC_PROP_POSSIBLE) != 0) { 2766 if (valsize < sizeof (mac_propval_range_t)) 2767 return (EINVAL); 2768 if (is_getprop) { 2769 err = mip->mi_callbacks->mc_getprop(mip-> 2770 mi_driver, macprop->mp_name, macprop->mp_id, 2771 macprop->mp_flags, valsize, val, perm); 2772 } 2773 /* 2774 * If the driver doesn't have *_m_getprop defined or 2775 * if the driver doesn't support setting MTU then 2776 * return the CURRENT value as POSSIBLE value. 2777 */ 2778 if (!is_getprop || err == ENOTSUP) { 2779 mac_sdu_get(mh, NULL, &sdu); 2780 range.mpr_count = 1; 2781 range.mpr_type = MAC_PROPVAL_UINT32; 2782 range.range_uint32[0].mpur_min = 2783 range.range_uint32[0].mpur_max = sdu; 2784 bcopy(&range, val, sizeof (range)); 2785 err = 0; 2786 } 2787 return (err); 2788 } 2789 if (valsize < sizeof (sdu)) 2790 return (EINVAL); 2791 if ((macprop->mp_flags & MAC_PROP_DEFAULT) == 0) { 2792 mac_sdu_get(mh, NULL, &sdu); 2793 bcopy(&sdu, val, sizeof (sdu)); 2794 if (is_setprop && (mip->mi_callbacks->mc_setprop(mip-> 2795 mi_driver, macprop->mp_name, macprop->mp_id, 2796 valsize, val) == 0)) { 2797 *perm = MAC_PROP_PERM_RW; 2798 } else { 2799 *perm = MAC_PROP_PERM_READ; 2800 } 2801 return (0); 2802 } else { 2803 if (mip->mi_info.mi_media == DL_ETHER) { 2804 sdu = ETHERMTU; 2805 bcopy(&sdu, val, sizeof (sdu)); 2806 2807 return (0); 2808 } 2809 /* 2810 * ask driver for its default. 2811 */ 2812 break; 2813 } 2814 } 2815 case MAC_PROP_STATUS: 2816 if (valsize < sizeof (link_state)) 2817 return (EINVAL); 2818 *perm = MAC_PROP_PERM_READ; 2819 link_state = mac_link_get(mh); 2820 bcopy(&link_state, val, sizeof (link_state)); 2821 return (0); 2822 default: 2823 break; 2824 2825 } 2826 /* If driver property, request from driver */ 2827 if (is_getprop) { 2828 err = mip->mi_callbacks->mc_getprop(mip->mi_driver, 2829 macprop->mp_name, macprop->mp_id, macprop->mp_flags, 2830 valsize, val, perm); 2831 } 2832 return (err); 2833 } 2834 2835 int 2836 mac_fastpath_disable(mac_handle_t mh) 2837 { 2838 mac_impl_t *mip = (mac_impl_t *)mh; 2839 2840 if ((mip->mi_state_flags & MIS_LEGACY) == 0) 2841 return (0); 2842 2843 return (mip->mi_capab_legacy.ml_fastpath_disable(mip->mi_driver)); 2844 } 2845 2846 void 2847 mac_fastpath_enable(mac_handle_t mh) 2848 { 2849 mac_impl_t *mip = (mac_impl_t *)mh; 2850 2851 if ((mip->mi_state_flags & MIS_LEGACY) == 0) 2852 return; 2853 2854 mip->mi_capab_legacy.ml_fastpath_enable(mip->mi_driver); 2855 } 2856 2857 void 2858 mac_register_priv_prop(mac_impl_t *mip, mac_priv_prop_t *mpp, uint_t nprop) 2859 { 2860 mac_priv_prop_t *mpriv; 2861 2862 if (mpp == NULL) 2863 return; 2864 2865 mpriv = kmem_zalloc(nprop * sizeof (*mpriv), KM_SLEEP); 2866 (void) memcpy(mpriv, mpp, nprop * sizeof (*mpriv)); 2867 mip->mi_priv_prop = mpriv; 2868 mip->mi_priv_prop_count = nprop; 2869 } 2870 2871 void 2872 mac_unregister_priv_prop(mac_impl_t *mip) 2873 { 2874 mac_priv_prop_t *mpriv; 2875 2876 mpriv = mip->mi_priv_prop; 2877 if (mpriv != NULL) { 2878 kmem_free(mpriv, mip->mi_priv_prop_count * sizeof (*mpriv)); 2879 mip->mi_priv_prop = NULL; 2880 } 2881 mip->mi_priv_prop_count = 0; 2882 } 2883 2884 /* 2885 * mac_ring_t 'mr' macros. Some rogue drivers may access ring structure 2886 * (by invoking mac_rx()) even after processing mac_stop_ring(). In such 2887 * cases if MAC free's the ring structure after mac_stop_ring(), any 2888 * illegal access to the ring structure coming from the driver will panic 2889 * the system. In order to protect the system from such inadverent access, 2890 * we maintain a cache of rings in the mac_impl_t after they get free'd up. 2891 * When packets are received on free'd up rings, MAC (through the generation 2892 * count mechanism) will drop such packets. 2893 */ 2894 static mac_ring_t * 2895 mac_ring_alloc(mac_impl_t *mip, mac_capab_rings_t *cap_rings) 2896 { 2897 mac_ring_t *ring; 2898 2899 if (cap_rings->mr_type == MAC_RING_TYPE_RX) { 2900 mutex_enter(&mip->mi_ring_lock); 2901 if (mip->mi_ring_freelist != NULL) { 2902 ring = mip->mi_ring_freelist; 2903 mip->mi_ring_freelist = ring->mr_next; 2904 bzero(ring, sizeof (mac_ring_t)); 2905 } else { 2906 ring = kmem_cache_alloc(mac_ring_cache, KM_SLEEP); 2907 } 2908 mutex_exit(&mip->mi_ring_lock); 2909 } else { 2910 ring = kmem_zalloc(sizeof (mac_ring_t), KM_SLEEP); 2911 } 2912 ASSERT((ring != NULL) && (ring->mr_state == MR_FREE)); 2913 return (ring); 2914 } 2915 2916 static void 2917 mac_ring_free(mac_impl_t *mip, mac_ring_t *ring) 2918 { 2919 if (ring->mr_type == MAC_RING_TYPE_RX) { 2920 mutex_enter(&mip->mi_ring_lock); 2921 ring->mr_state = MR_FREE; 2922 ring->mr_flag = 0; 2923 ring->mr_next = mip->mi_ring_freelist; 2924 mip->mi_ring_freelist = ring; 2925 mutex_exit(&mip->mi_ring_lock); 2926 } else { 2927 kmem_free(ring, sizeof (mac_ring_t)); 2928 } 2929 } 2930 2931 static void 2932 mac_ring_freeall(mac_impl_t *mip) 2933 { 2934 mac_ring_t *ring_next; 2935 mutex_enter(&mip->mi_ring_lock); 2936 mac_ring_t *ring = mip->mi_ring_freelist; 2937 while (ring != NULL) { 2938 ring_next = ring->mr_next; 2939 kmem_cache_free(mac_ring_cache, ring); 2940 ring = ring_next; 2941 } 2942 mip->mi_ring_freelist = NULL; 2943 mutex_exit(&mip->mi_ring_lock); 2944 } 2945 2946 int 2947 mac_start_ring(mac_ring_t *ring) 2948 { 2949 int rv = 0; 2950 2951 if (ring->mr_start != NULL) 2952 rv = ring->mr_start(ring->mr_driver, ring->mr_gen_num); 2953 2954 return (rv); 2955 } 2956 2957 void 2958 mac_stop_ring(mac_ring_t *ring) 2959 { 2960 if (ring->mr_stop != NULL) 2961 ring->mr_stop(ring->mr_driver); 2962 2963 /* 2964 * Increment the ring generation number for this ring. 2965 */ 2966 ring->mr_gen_num++; 2967 } 2968 2969 int 2970 mac_start_group(mac_group_t *group) 2971 { 2972 int rv = 0; 2973 2974 if (group->mrg_start != NULL) 2975 rv = group->mrg_start(group->mrg_driver); 2976 2977 return (rv); 2978 } 2979 2980 void 2981 mac_stop_group(mac_group_t *group) 2982 { 2983 if (group->mrg_stop != NULL) 2984 group->mrg_stop(group->mrg_driver); 2985 } 2986 2987 /* 2988 * Called from mac_start() on the default Rx group. Broadcast and multicast 2989 * packets are received only on the default group. Hence the default group 2990 * needs to be up even if the primary client is not up, for the other groups 2991 * to be functional. We do this by calling this function at mac_start time 2992 * itself. However the broadcast packets that are received can't make their 2993 * way beyond mac_rx until a mac client creates a broadcast flow. 2994 */ 2995 static int 2996 mac_start_group_and_rings(mac_group_t *group) 2997 { 2998 mac_ring_t *ring; 2999 int rv = 0; 3000 3001 ASSERT(group->mrg_state == MAC_GROUP_STATE_REGISTERED); 3002 if ((rv = mac_start_group(group)) != 0) 3003 return (rv); 3004 3005 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) { 3006 ASSERT(ring->mr_state == MR_FREE); 3007 if ((rv = mac_start_ring(ring)) != 0) 3008 goto error; 3009 ring->mr_state = MR_INUSE; 3010 ring->mr_classify_type = MAC_SW_CLASSIFIER; 3011 } 3012 return (0); 3013 3014 error: 3015 mac_stop_group_and_rings(group); 3016 return (rv); 3017 } 3018 3019 /* Called from mac_stop on the default Rx group */ 3020 static void 3021 mac_stop_group_and_rings(mac_group_t *group) 3022 { 3023 mac_ring_t *ring; 3024 3025 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) { 3026 if (ring->mr_state != MR_FREE) { 3027 mac_stop_ring(ring); 3028 ring->mr_state = MR_FREE; 3029 ring->mr_flag = 0; 3030 ring->mr_classify_type = MAC_NO_CLASSIFIER; 3031 } 3032 } 3033 mac_stop_group(group); 3034 } 3035 3036 3037 static mac_ring_t * 3038 mac_init_ring(mac_impl_t *mip, mac_group_t *group, int index, 3039 mac_capab_rings_t *cap_rings) 3040 { 3041 mac_ring_t *ring; 3042 mac_ring_info_t ring_info; 3043 3044 ring = mac_ring_alloc(mip, cap_rings); 3045 3046 /* Prepare basic information of ring */ 3047 ring->mr_index = index; 3048 ring->mr_type = group->mrg_type; 3049 ring->mr_gh = (mac_group_handle_t)group; 3050 3051 /* Insert the new ring to the list. */ 3052 ring->mr_next = group->mrg_rings; 3053 group->mrg_rings = ring; 3054 3055 /* Zero to reuse the info data structure */ 3056 bzero(&ring_info, sizeof (ring_info)); 3057 3058 /* Query ring information from driver */ 3059 cap_rings->mr_rget(mip->mi_driver, group->mrg_type, group->mrg_index, 3060 index, &ring_info, (mac_ring_handle_t)ring); 3061 3062 ring->mr_info = ring_info; 3063 3064 /* Update ring's status */ 3065 ring->mr_state = MR_FREE; 3066 ring->mr_flag = 0; 3067 3068 /* Update the ring count of the group */ 3069 group->mrg_cur_count++; 3070 return (ring); 3071 } 3072 3073 /* 3074 * Rings are chained together for easy regrouping. 3075 */ 3076 static void 3077 mac_init_group(mac_impl_t *mip, mac_group_t *group, int size, 3078 mac_capab_rings_t *cap_rings) 3079 { 3080 int index; 3081 3082 /* 3083 * Initialize all ring members of this group. Size of zero will not 3084 * enter the loop, so it's safe for initializing an empty group. 3085 */ 3086 for (index = size - 1; index >= 0; index--) 3087 (void) mac_init_ring(mip, group, index, cap_rings); 3088 } 3089 3090 int 3091 mac_init_rings(mac_impl_t *mip, mac_ring_type_t rtype) 3092 { 3093 mac_capab_rings_t *cap_rings; 3094 mac_group_t *group, *groups; 3095 mac_group_info_t group_info; 3096 uint_t group_free = 0; 3097 uint_t ring_left; 3098 mac_ring_t *ring; 3099 int g, err = 0; 3100 3101 switch (rtype) { 3102 case MAC_RING_TYPE_RX: 3103 ASSERT(mip->mi_rx_groups == NULL); 3104 3105 cap_rings = &mip->mi_rx_rings_cap; 3106 cap_rings->mr_type = MAC_RING_TYPE_RX; 3107 break; 3108 case MAC_RING_TYPE_TX: 3109 ASSERT(mip->mi_tx_groups == NULL); 3110 3111 cap_rings = &mip->mi_tx_rings_cap; 3112 cap_rings->mr_type = MAC_RING_TYPE_TX; 3113 break; 3114 default: 3115 ASSERT(B_FALSE); 3116 } 3117 3118 if (!i_mac_capab_get((mac_handle_t)mip, MAC_CAPAB_RINGS, 3119 cap_rings)) 3120 return (0); 3121 3122 /* 3123 * Allocate a contiguous buffer for all groups. 3124 */ 3125 groups = kmem_zalloc(sizeof (mac_group_t) * (cap_rings->mr_gnum + 1), 3126 KM_SLEEP); 3127 3128 ring_left = cap_rings->mr_rnum; 3129 3130 /* 3131 * Get all ring groups if any, and get their ring members 3132 * if any. 3133 */ 3134 for (g = 0; g < cap_rings->mr_gnum; g++) { 3135 group = groups + g; 3136 3137 /* Prepare basic information of the group */ 3138 group->mrg_index = g; 3139 group->mrg_type = rtype; 3140 group->mrg_state = MAC_GROUP_STATE_UNINIT; 3141 group->mrg_mh = (mac_handle_t)mip; 3142 group->mrg_next = group + 1; 3143 3144 /* Zero to reuse the info data structure */ 3145 bzero(&group_info, sizeof (group_info)); 3146 3147 /* Query group information from driver */ 3148 cap_rings->mr_gget(mip->mi_driver, rtype, g, &group_info, 3149 (mac_group_handle_t)group); 3150 3151 switch (cap_rings->mr_group_type) { 3152 case MAC_GROUP_TYPE_DYNAMIC: 3153 if (cap_rings->mr_gaddring == NULL || 3154 cap_rings->mr_gremring == NULL) { 3155 DTRACE_PROBE3( 3156 mac__init__rings_no_addremring, 3157 char *, mip->mi_name, 3158 mac_group_add_ring_t, 3159 cap_rings->mr_gaddring, 3160 mac_group_add_ring_t, 3161 cap_rings->mr_gremring); 3162 err = EINVAL; 3163 goto bail; 3164 } 3165 3166 switch (rtype) { 3167 case MAC_RING_TYPE_RX: 3168 /* 3169 * The first RX group must have non-zero 3170 * rings, and the following groups must 3171 * have zero rings. 3172 */ 3173 if (g == 0 && group_info.mgi_count == 0) { 3174 DTRACE_PROBE1( 3175 mac__init__rings__rx__def__zero, 3176 char *, mip->mi_name); 3177 err = EINVAL; 3178 goto bail; 3179 } 3180 if (g > 0 && group_info.mgi_count != 0) { 3181 DTRACE_PROBE3( 3182 mac__init__rings__rx__nonzero, 3183 char *, mip->mi_name, 3184 int, g, int, group_info.mgi_count); 3185 err = EINVAL; 3186 goto bail; 3187 } 3188 break; 3189 case MAC_RING_TYPE_TX: 3190 /* 3191 * All TX ring groups must have zero rings. 3192 */ 3193 if (group_info.mgi_count != 0) { 3194 DTRACE_PROBE3( 3195 mac__init__rings__tx__nonzero, 3196 char *, mip->mi_name, 3197 int, g, int, group_info.mgi_count); 3198 err = EINVAL; 3199 goto bail; 3200 } 3201 break; 3202 } 3203 break; 3204 case MAC_GROUP_TYPE_STATIC: 3205 /* 3206 * Note that an empty group is allowed, e.g., an aggr 3207 * would start with an empty group. 3208 */ 3209 break; 3210 default: 3211 /* unknown group type */ 3212 DTRACE_PROBE2(mac__init__rings__unknown__type, 3213 char *, mip->mi_name, 3214 int, cap_rings->mr_group_type); 3215 err = EINVAL; 3216 goto bail; 3217 } 3218 3219 3220 /* 3221 * Driver must register group->mgi_addmac/remmac() for rx groups 3222 * to support multiple MAC addresses. 3223 */ 3224 if (rtype == MAC_RING_TYPE_RX) { 3225 if ((group_info.mgi_addmac == NULL) || 3226 (group_info.mgi_addmac == NULL)) 3227 goto bail; 3228 } 3229 3230 /* Cache driver-supplied information */ 3231 group->mrg_info = group_info; 3232 3233 /* Update the group's status and group count. */ 3234 mac_set_rx_group_state(group, MAC_GROUP_STATE_REGISTERED); 3235 group_free++; 3236 3237 group->mrg_rings = NULL; 3238 group->mrg_cur_count = 0; 3239 mac_init_group(mip, group, group_info.mgi_count, cap_rings); 3240 ring_left -= group_info.mgi_count; 3241 3242 /* The current group size should be equal to default value */ 3243 ASSERT(group->mrg_cur_count == group_info.mgi_count); 3244 } 3245 3246 /* Build up a dummy group for free resources as a pool */ 3247 group = groups + cap_rings->mr_gnum; 3248 3249 /* Prepare basic information of the group */ 3250 group->mrg_index = -1; 3251 group->mrg_type = rtype; 3252 group->mrg_state = MAC_GROUP_STATE_UNINIT; 3253 group->mrg_mh = (mac_handle_t)mip; 3254 group->mrg_next = NULL; 3255 3256 /* 3257 * If there are ungrouped rings, allocate a continuous buffer for 3258 * remaining resources. 3259 */ 3260 if (ring_left != 0) { 3261 group->mrg_rings = NULL; 3262 group->mrg_cur_count = 0; 3263 mac_init_group(mip, group, ring_left, cap_rings); 3264 3265 /* The current group size should be equal to ring_left */ 3266 ASSERT(group->mrg_cur_count == ring_left); 3267 3268 ring_left = 0; 3269 3270 /* Update this group's status */ 3271 mac_set_rx_group_state(group, MAC_GROUP_STATE_REGISTERED); 3272 } else 3273 group->mrg_rings = NULL; 3274 3275 ASSERT(ring_left == 0); 3276 3277 bail: 3278 /* Cache other important information to finalize the initialization */ 3279 switch (rtype) { 3280 case MAC_RING_TYPE_RX: 3281 mip->mi_rx_group_type = cap_rings->mr_group_type; 3282 mip->mi_rx_group_count = cap_rings->mr_gnum; 3283 mip->mi_rx_groups = groups; 3284 break; 3285 case MAC_RING_TYPE_TX: 3286 mip->mi_tx_group_type = cap_rings->mr_group_type; 3287 mip->mi_tx_group_count = cap_rings->mr_gnum; 3288 mip->mi_tx_group_free = group_free; 3289 mip->mi_tx_groups = groups; 3290 3291 /* 3292 * Ring 0 is used as the default one and it could be assigned 3293 * to a client as well. 3294 */ 3295 group = groups + cap_rings->mr_gnum; 3296 ring = group->mrg_rings; 3297 while ((ring->mr_index != 0) && (ring->mr_next != NULL)) 3298 ring = ring->mr_next; 3299 ASSERT(ring->mr_index == 0); 3300 mip->mi_default_tx_ring = (mac_ring_handle_t)ring; 3301 break; 3302 default: 3303 ASSERT(B_FALSE); 3304 } 3305 3306 if (err != 0) 3307 mac_free_rings(mip, rtype); 3308 3309 return (err); 3310 } 3311 3312 /* 3313 * Called to free all ring groups with particular type. It's supposed all groups 3314 * have been released by clinet. 3315 */ 3316 void 3317 mac_free_rings(mac_impl_t *mip, mac_ring_type_t rtype) 3318 { 3319 mac_group_t *group, *groups; 3320 uint_t group_count; 3321 3322 switch (rtype) { 3323 case MAC_RING_TYPE_RX: 3324 if (mip->mi_rx_groups == NULL) 3325 return; 3326 3327 groups = mip->mi_rx_groups; 3328 group_count = mip->mi_rx_group_count; 3329 3330 mip->mi_rx_groups = NULL; 3331 mip->mi_rx_group_count = 0; 3332 break; 3333 case MAC_RING_TYPE_TX: 3334 ASSERT(mip->mi_tx_group_count == mip->mi_tx_group_free); 3335 3336 if (mip->mi_tx_groups == NULL) 3337 return; 3338 3339 groups = mip->mi_tx_groups; 3340 group_count = mip->mi_tx_group_count; 3341 3342 mip->mi_tx_groups = NULL; 3343 mip->mi_tx_group_count = 0; 3344 mip->mi_tx_group_free = 0; 3345 mip->mi_default_tx_ring = NULL; 3346 break; 3347 default: 3348 ASSERT(B_FALSE); 3349 } 3350 3351 for (group = groups; group != NULL; group = group->mrg_next) { 3352 mac_ring_t *ring; 3353 3354 if (group->mrg_cur_count == 0) 3355 continue; 3356 3357 ASSERT(group->mrg_rings != NULL); 3358 3359 while ((ring = group->mrg_rings) != NULL) { 3360 group->mrg_rings = ring->mr_next; 3361 mac_ring_free(mip, ring); 3362 } 3363 } 3364 3365 /* Free all the cached rings */ 3366 mac_ring_freeall(mip); 3367 /* Free the block of group data strutures */ 3368 kmem_free(groups, sizeof (mac_group_t) * (group_count + 1)); 3369 } 3370 3371 /* 3372 * Associate a MAC address with a receive group. 3373 * 3374 * The return value of this function should always be checked properly, because 3375 * any type of failure could cause unexpected results. A group can be added 3376 * or removed with a MAC address only after it has been reserved. Ideally, 3377 * a successful reservation always leads to calling mac_group_addmac() to 3378 * steer desired traffic. Failure of adding an unicast MAC address doesn't 3379 * always imply that the group is functioning abnormally. 3380 * 3381 * Currently this function is called everywhere, and it reflects assumptions 3382 * about MAC addresses in the implementation. CR 6735196. 3383 */ 3384 int 3385 mac_group_addmac(mac_group_t *group, const uint8_t *addr) 3386 { 3387 ASSERT(group->mrg_type == MAC_RING_TYPE_RX); 3388 ASSERT(group->mrg_info.mgi_addmac != NULL); 3389 3390 return (group->mrg_info.mgi_addmac(group->mrg_info.mgi_driver, addr)); 3391 } 3392 3393 /* 3394 * Remove the association between MAC address and receive group. 3395 */ 3396 int 3397 mac_group_remmac(mac_group_t *group, const uint8_t *addr) 3398 { 3399 ASSERT(group->mrg_type == MAC_RING_TYPE_RX); 3400 ASSERT(group->mrg_info.mgi_remmac != NULL); 3401 3402 return (group->mrg_info.mgi_remmac(group->mrg_info.mgi_driver, addr)); 3403 } 3404 3405 /* 3406 * Release a ring in use by marking it MR_FREE. 3407 * Any other client may reserve it for its use. 3408 */ 3409 void 3410 mac_release_tx_ring(mac_ring_handle_t rh) 3411 { 3412 mac_ring_t *ring = (mac_ring_t *)rh; 3413 mac_group_t *group = (mac_group_t *)ring->mr_gh; 3414 mac_impl_t *mip = (mac_impl_t *)group->mrg_mh; 3415 3416 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 3417 ASSERT(ring->mr_state != MR_FREE); 3418 3419 /* 3420 * Default tx ring will be released by mac_stop(). 3421 */ 3422 if (rh == mip->mi_default_tx_ring) 3423 return; 3424 3425 mac_stop_ring(ring); 3426 3427 ring->mr_state = MR_FREE; 3428 ring->mr_flag = 0; 3429 } 3430 3431 /* 3432 * Send packets through a selected tx ring. 3433 */ 3434 mblk_t * 3435 mac_ring_tx(mac_ring_handle_t rh, mblk_t *mp) 3436 { 3437 mac_ring_t *ring = (mac_ring_t *)rh; 3438 mac_ring_info_t *info = &ring->mr_info; 3439 3440 ASSERT(ring->mr_type == MAC_RING_TYPE_TX); 3441 ASSERT(ring->mr_state >= MR_INUSE); 3442 ASSERT(info->mri_tx != NULL); 3443 3444 return (info->mri_tx(info->mri_driver, mp)); 3445 } 3446 3447 /* 3448 * Find a ring from its index. 3449 */ 3450 mac_ring_t * 3451 mac_find_ring(mac_group_t *group, int index) 3452 { 3453 mac_ring_t *ring = group->mrg_rings; 3454 3455 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) 3456 if (ring->mr_index == index) 3457 break; 3458 3459 return (ring); 3460 } 3461 /* 3462 * Add a ring to an existing group. 3463 * 3464 * The ring must be either passed directly (for example if the ring 3465 * movement is initiated by the framework), or specified through a driver 3466 * index (for example when the ring is added by the driver. 3467 * 3468 * The caller needs to call mac_perim_enter() before calling this function. 3469 */ 3470 int 3471 i_mac_group_add_ring(mac_group_t *group, mac_ring_t *ring, int index) 3472 { 3473 mac_impl_t *mip = (mac_impl_t *)group->mrg_mh; 3474 mac_capab_rings_t *cap_rings; 3475 boolean_t driver_call = (ring == NULL); 3476 mac_group_type_t group_type; 3477 int ret = 0; 3478 3479 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 3480 3481 switch (group->mrg_type) { 3482 case MAC_RING_TYPE_RX: 3483 cap_rings = &mip->mi_rx_rings_cap; 3484 group_type = mip->mi_rx_group_type; 3485 break; 3486 case MAC_RING_TYPE_TX: 3487 cap_rings = &mip->mi_tx_rings_cap; 3488 group_type = mip->mi_tx_group_type; 3489 break; 3490 default: 3491 ASSERT(B_FALSE); 3492 } 3493 3494 /* 3495 * There should be no ring with the same ring index in the target 3496 * group. 3497 */ 3498 ASSERT(mac_find_ring(group, driver_call ? index : ring->mr_index) == 3499 NULL); 3500 3501 if (driver_call) { 3502 /* 3503 * The function is called as a result of a request from 3504 * a driver to add a ring to an existing group, for example 3505 * from the aggregation driver. Allocate a new mac_ring_t 3506 * for that ring. 3507 */ 3508 ring = mac_init_ring(mip, group, index, cap_rings); 3509 ASSERT(group->mrg_state > MAC_GROUP_STATE_UNINIT); 3510 } else { 3511 /* 3512 * The function is called as a result of a MAC layer request 3513 * to add a ring to an existing group. In this case the 3514 * ring is being moved between groups, which requires 3515 * the underlying driver to support dynamic grouping, 3516 * and the mac_ring_t already exists. 3517 */ 3518 ASSERT(group_type == MAC_GROUP_TYPE_DYNAMIC); 3519 ASSERT(cap_rings->mr_gaddring != NULL); 3520 ASSERT(ring->mr_gh == NULL); 3521 } 3522 3523 /* 3524 * At this point the ring should not be in use, and it should be 3525 * of the right for the target group. 3526 */ 3527 ASSERT(ring->mr_state < MR_INUSE); 3528 ASSERT(ring->mr_srs == NULL); 3529 ASSERT(ring->mr_type == group->mrg_type); 3530 3531 if (!driver_call) { 3532 /* 3533 * Add the driver level hardware ring if the process was not 3534 * initiated by the driver, and the target group is not the 3535 * group. 3536 */ 3537 if (group->mrg_driver != NULL) { 3538 cap_rings->mr_gaddring(group->mrg_driver, 3539 ring->mr_driver, ring->mr_type); 3540 } 3541 3542 /* 3543 * Insert the ring ahead existing rings. 3544 */ 3545 ring->mr_next = group->mrg_rings; 3546 group->mrg_rings = ring; 3547 ring->mr_gh = (mac_group_handle_t)group; 3548 group->mrg_cur_count++; 3549 } 3550 3551 /* 3552 * If the group has not been actively used, we're done. 3553 */ 3554 if (group->mrg_index != -1 && 3555 group->mrg_state < MAC_GROUP_STATE_RESERVED) 3556 return (0); 3557 3558 /* 3559 * Set up SRS/SR according to the ring type. 3560 */ 3561 switch (ring->mr_type) { 3562 case MAC_RING_TYPE_RX: 3563 /* 3564 * Setup SRS on top of the new ring if the group is 3565 * reserved for someones exclusive use. 3566 */ 3567 if (group->mrg_state == MAC_GROUP_STATE_RESERVED) { 3568 flow_entry_t *flent; 3569 mac_client_impl_t *mcip; 3570 3571 mcip = MAC_RX_GROUP_ONLY_CLIENT(group); 3572 ASSERT(mcip != NULL); 3573 flent = mcip->mci_flent; 3574 ASSERT(flent->fe_rx_srs_cnt > 0); 3575 mac_srs_group_setup(mcip, flent, group, SRST_LINK); 3576 } 3577 break; 3578 case MAC_RING_TYPE_TX: 3579 /* 3580 * For TX this function is only invoked during the 3581 * initial creation of a group when a share is 3582 * associated with a MAC client. So the datapath is not 3583 * yet setup, and will be setup later after the 3584 * group has been reserved and populated. 3585 */ 3586 break; 3587 default: 3588 ASSERT(B_FALSE); 3589 } 3590 3591 /* 3592 * Start the ring if needed. Failure causes to undo the grouping action. 3593 */ 3594 if ((ret = mac_start_ring(ring)) != 0) { 3595 if (ring->mr_type == MAC_RING_TYPE_RX) { 3596 if (ring->mr_srs != NULL) { 3597 mac_rx_srs_remove(ring->mr_srs); 3598 ring->mr_srs = NULL; 3599 } 3600 } 3601 if (!driver_call) { 3602 cap_rings->mr_gremring(group->mrg_driver, 3603 ring->mr_driver, ring->mr_type); 3604 } 3605 group->mrg_cur_count--; 3606 group->mrg_rings = ring->mr_next; 3607 3608 ring->mr_gh = NULL; 3609 3610 if (driver_call) 3611 mac_ring_free(mip, ring); 3612 3613 return (ret); 3614 } 3615 3616 /* 3617 * Update the ring's state. 3618 */ 3619 ring->mr_state = MR_INUSE; 3620 MAC_RING_UNMARK(ring, MR_INCIPIENT); 3621 return (0); 3622 } 3623 3624 /* 3625 * Remove a ring from it's current group. MAC internal function for dynamic 3626 * grouping. 3627 * 3628 * The caller needs to call mac_perim_enter() before calling this function. 3629 */ 3630 void 3631 i_mac_group_rem_ring(mac_group_t *group, mac_ring_t *ring, 3632 boolean_t driver_call) 3633 { 3634 mac_impl_t *mip = (mac_impl_t *)group->mrg_mh; 3635 mac_capab_rings_t *cap_rings = NULL; 3636 mac_group_type_t group_type; 3637 3638 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 3639 3640 ASSERT(mac_find_ring(group, ring->mr_index) == ring); 3641 ASSERT((mac_group_t *)ring->mr_gh == group); 3642 ASSERT(ring->mr_type == group->mrg_type); 3643 3644 switch (ring->mr_type) { 3645 case MAC_RING_TYPE_RX: 3646 group_type = mip->mi_rx_group_type; 3647 cap_rings = &mip->mi_rx_rings_cap; 3648 3649 if (group->mrg_state >= MAC_GROUP_STATE_RESERVED) 3650 mac_stop_ring(ring); 3651 3652 /* 3653 * Only hardware classified packets hold a reference to the 3654 * ring all the way up the Rx path. mac_rx_srs_remove() 3655 * will take care of quiescing the Rx path and removing the 3656 * SRS. The software classified path neither holds a reference 3657 * nor any association with the ring in mac_rx. 3658 */ 3659 if (ring->mr_srs != NULL) { 3660 mac_rx_srs_remove(ring->mr_srs); 3661 ring->mr_srs = NULL; 3662 } 3663 ring->mr_state = MR_FREE; 3664 ring->mr_flag = 0; 3665 3666 break; 3667 case MAC_RING_TYPE_TX: 3668 /* 3669 * For TX this function is only invoked in two 3670 * cases: 3671 * 3672 * 1) In the case of a failure during the 3673 * initial creation of a group when a share is 3674 * associated with a MAC client. So the SRS is not 3675 * yet setup, and will be setup later after the 3676 * group has been reserved and populated. 3677 * 3678 * 2) From mac_release_tx_group() when freeing 3679 * a TX SRS. 3680 * 3681 * In both cases the SRS and its soft rings are 3682 * already quiesced. 3683 */ 3684 ASSERT(!driver_call); 3685 group_type = mip->mi_tx_group_type; 3686 cap_rings = &mip->mi_tx_rings_cap; 3687 break; 3688 default: 3689 ASSERT(B_FALSE); 3690 } 3691 3692 /* 3693 * Remove the ring from the group. 3694 */ 3695 if (ring == group->mrg_rings) 3696 group->mrg_rings = ring->mr_next; 3697 else { 3698 mac_ring_t *pre; 3699 3700 pre = group->mrg_rings; 3701 while (pre->mr_next != ring) 3702 pre = pre->mr_next; 3703 pre->mr_next = ring->mr_next; 3704 } 3705 group->mrg_cur_count--; 3706 3707 if (!driver_call) { 3708 ASSERT(group_type == MAC_GROUP_TYPE_DYNAMIC); 3709 ASSERT(cap_rings->mr_gremring != NULL); 3710 3711 /* 3712 * Remove the driver level hardware ring. 3713 */ 3714 if (group->mrg_driver != NULL) { 3715 cap_rings->mr_gremring(group->mrg_driver, 3716 ring->mr_driver, ring->mr_type); 3717 } 3718 } 3719 3720 ring->mr_gh = NULL; 3721 if (driver_call) { 3722 mac_ring_free(mip, ring); 3723 } else { 3724 ring->mr_state = MR_FREE; 3725 ring->mr_flag = 0; 3726 } 3727 } 3728 3729 /* 3730 * Move a ring to the target group. If needed, remove the ring from the group 3731 * that it currently belongs to. 3732 * 3733 * The caller need to enter MAC's perimeter by calling mac_perim_enter(). 3734 */ 3735 static int 3736 mac_group_mov_ring(mac_impl_t *mip, mac_group_t *d_group, mac_ring_t *ring) 3737 { 3738 mac_group_t *s_group = (mac_group_t *)ring->mr_gh; 3739 int rv; 3740 3741 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 3742 ASSERT(d_group != NULL); 3743 ASSERT(s_group->mrg_mh == d_group->mrg_mh); 3744 3745 if (s_group == d_group) 3746 return (0); 3747 3748 /* 3749 * Remove it from current group first. 3750 */ 3751 if (s_group != NULL) 3752 i_mac_group_rem_ring(s_group, ring, B_FALSE); 3753 3754 /* 3755 * Add it to the new group. 3756 */ 3757 rv = i_mac_group_add_ring(d_group, ring, 0); 3758 if (rv != 0) { 3759 /* 3760 * Failed to add ring back to source group. If 3761 * that fails, the ring is stuck in limbo, log message. 3762 */ 3763 if (i_mac_group_add_ring(s_group, ring, 0)) { 3764 cmn_err(CE_WARN, "%s: failed to move ring %p\n", 3765 mip->mi_name, (void *)ring); 3766 } 3767 } 3768 3769 return (rv); 3770 } 3771 3772 /* 3773 * Find a MAC address according to its value. 3774 */ 3775 mac_address_t * 3776 mac_find_macaddr(mac_impl_t *mip, uint8_t *mac_addr) 3777 { 3778 mac_address_t *map; 3779 3780 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 3781 3782 for (map = mip->mi_addresses; map != NULL; map = map->ma_next) { 3783 if (bcmp(mac_addr, map->ma_addr, map->ma_len) == 0) 3784 break; 3785 } 3786 3787 return (map); 3788 } 3789 3790 /* 3791 * Check whether the MAC address is shared by multiple clients. 3792 */ 3793 boolean_t 3794 mac_check_macaddr_shared(mac_address_t *map) 3795 { 3796 ASSERT(MAC_PERIM_HELD((mac_handle_t)map->ma_mip)); 3797 3798 return (map->ma_nusers > 1); 3799 } 3800 3801 /* 3802 * Remove the specified MAC address from the MAC address list and free it. 3803 */ 3804 static void 3805 mac_free_macaddr(mac_address_t *map) 3806 { 3807 mac_impl_t *mip = map->ma_mip; 3808 3809 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 3810 ASSERT(mip->mi_addresses != NULL); 3811 3812 map = mac_find_macaddr(mip, map->ma_addr); 3813 3814 ASSERT(map != NULL); 3815 ASSERT(map->ma_nusers == 0); 3816 3817 if (map == mip->mi_addresses) { 3818 mip->mi_addresses = map->ma_next; 3819 } else { 3820 mac_address_t *pre; 3821 3822 pre = mip->mi_addresses; 3823 while (pre->ma_next != map) 3824 pre = pre->ma_next; 3825 pre->ma_next = map->ma_next; 3826 } 3827 3828 kmem_free(map, sizeof (mac_address_t)); 3829 } 3830 3831 /* 3832 * Add a MAC address reference for a client. If the desired MAC address 3833 * exists, add a reference to it. Otherwise, add the new address by adding 3834 * it to a reserved group or setting promiscuous mode. Won't try different 3835 * group is the group is non-NULL, so the caller must explictly share 3836 * default group when needed. 3837 * 3838 * Note, the primary MAC address is initialized at registration time, so 3839 * to add it to default group only need to activate it if its reference 3840 * count is still zero. Also, some drivers may not have advertised RINGS 3841 * capability. 3842 */ 3843 int 3844 mac_add_macaddr(mac_impl_t *mip, mac_group_t *group, uint8_t *mac_addr, 3845 boolean_t use_hw) 3846 { 3847 mac_address_t *map; 3848 int err = 0; 3849 boolean_t allocated_map = B_FALSE; 3850 3851 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 3852 3853 map = mac_find_macaddr(mip, mac_addr); 3854 3855 /* 3856 * If the new MAC address has not been added. Allocate a new one 3857 * and set it up. 3858 */ 3859 if (map == NULL) { 3860 map = kmem_zalloc(sizeof (mac_address_t), KM_SLEEP); 3861 map->ma_len = mip->mi_type->mt_addr_length; 3862 bcopy(mac_addr, map->ma_addr, map->ma_len); 3863 map->ma_nusers = 0; 3864 map->ma_group = group; 3865 map->ma_mip = mip; 3866 3867 /* add the new MAC address to the head of the address list */ 3868 map->ma_next = mip->mi_addresses; 3869 mip->mi_addresses = map; 3870 3871 allocated_map = B_TRUE; 3872 } 3873 3874 ASSERT(map->ma_group == group); 3875 3876 /* 3877 * If the MAC address is already in use, simply account for the 3878 * new client. 3879 */ 3880 if (map->ma_nusers++ > 0) 3881 return (0); 3882 3883 /* 3884 * Activate this MAC address by adding it to the reserved group. 3885 */ 3886 if (group != NULL) { 3887 err = mac_group_addmac(group, (const uint8_t *)mac_addr); 3888 if (err == 0) { 3889 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED; 3890 return (0); 3891 } 3892 } 3893 3894 /* 3895 * The MAC address addition failed. If the client requires a 3896 * hardware classified MAC address, fail the operation. 3897 */ 3898 if (use_hw) { 3899 err = ENOSPC; 3900 goto bail; 3901 } 3902 3903 /* 3904 * Try promiscuous mode. 3905 * 3906 * For drivers that don't advertise RINGS capability, do 3907 * nothing for the primary address. 3908 */ 3909 if ((group == NULL) && 3910 (bcmp(map->ma_addr, mip->mi_addr, map->ma_len) == 0)) { 3911 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED; 3912 return (0); 3913 } 3914 3915 /* 3916 * Enable promiscuous mode in order to receive traffic 3917 * to the new MAC address. 3918 */ 3919 if ((err = i_mac_promisc_set(mip, B_TRUE)) == 0) { 3920 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_PROMISC; 3921 return (0); 3922 } 3923 3924 /* 3925 * Free the MAC address that could not be added. Don't free 3926 * a pre-existing address, it could have been the entry 3927 * for the primary MAC address which was pre-allocated by 3928 * mac_init_macaddr(), and which must remain on the list. 3929 */ 3930 bail: 3931 map->ma_nusers--; 3932 if (allocated_map) 3933 mac_free_macaddr(map); 3934 return (err); 3935 } 3936 3937 /* 3938 * Remove a reference to a MAC address. This may cause to remove the MAC 3939 * address from an associated group or to turn off promiscuous mode. 3940 * The caller needs to handle the failure properly. 3941 */ 3942 int 3943 mac_remove_macaddr(mac_address_t *map) 3944 { 3945 mac_impl_t *mip = map->ma_mip; 3946 int err = 0; 3947 3948 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 3949 3950 ASSERT(map == mac_find_macaddr(mip, map->ma_addr)); 3951 3952 /* 3953 * If it's not the last client using this MAC address, only update 3954 * the MAC clients count. 3955 */ 3956 if (--map->ma_nusers > 0) 3957 return (0); 3958 3959 /* 3960 * The MAC address is no longer used by any MAC client, so remove 3961 * it from its associated group, or turn off promiscuous mode 3962 * if it was enabled for the MAC address. 3963 */ 3964 switch (map->ma_type) { 3965 case MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED: 3966 /* 3967 * Don't free the preset primary address for drivers that 3968 * don't advertise RINGS capability. 3969 */ 3970 if (map->ma_group == NULL) 3971 return (0); 3972 3973 err = mac_group_remmac(map->ma_group, map->ma_addr); 3974 break; 3975 case MAC_ADDRESS_TYPE_UNICAST_PROMISC: 3976 err = i_mac_promisc_set(mip, B_FALSE); 3977 break; 3978 default: 3979 ASSERT(B_FALSE); 3980 } 3981 3982 if (err != 0) 3983 return (err); 3984 3985 /* 3986 * We created MAC address for the primary one at registration, so we 3987 * won't free it here. mac_fini_macaddr() will take care of it. 3988 */ 3989 if (bcmp(map->ma_addr, mip->mi_addr, map->ma_len) != 0) 3990 mac_free_macaddr(map); 3991 3992 return (0); 3993 } 3994 3995 /* 3996 * Update an existing MAC address. The caller need to make sure that the new 3997 * value has not been used. 3998 */ 3999 int 4000 mac_update_macaddr(mac_address_t *map, uint8_t *mac_addr) 4001 { 4002 mac_impl_t *mip = map->ma_mip; 4003 int err = 0; 4004 4005 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 4006 ASSERT(mac_find_macaddr(mip, mac_addr) == NULL); 4007 4008 switch (map->ma_type) { 4009 case MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED: 4010 /* 4011 * Update the primary address for drivers that are not 4012 * RINGS capable. 4013 */ 4014 if (map->ma_group == NULL) { 4015 err = mip->mi_unicst(mip->mi_driver, (const uint8_t *) 4016 mac_addr); 4017 if (err != 0) 4018 return (err); 4019 break; 4020 } 4021 4022 /* 4023 * If this MAC address is not currently in use, 4024 * simply break out and update the value. 4025 */ 4026 if (map->ma_nusers == 0) 4027 break; 4028 4029 /* 4030 * Need to replace the MAC address associated with a group. 4031 */ 4032 err = mac_group_remmac(map->ma_group, map->ma_addr); 4033 if (err != 0) 4034 return (err); 4035 4036 err = mac_group_addmac(map->ma_group, mac_addr); 4037 4038 /* 4039 * Failure hints hardware error. The MAC layer needs to 4040 * have error notification facility to handle this. 4041 * Now, simply try to restore the value. 4042 */ 4043 if (err != 0) 4044 (void) mac_group_addmac(map->ma_group, map->ma_addr); 4045 4046 break; 4047 case MAC_ADDRESS_TYPE_UNICAST_PROMISC: 4048 /* 4049 * Need to do nothing more if in promiscuous mode. 4050 */ 4051 break; 4052 default: 4053 ASSERT(B_FALSE); 4054 } 4055 4056 /* 4057 * Successfully replaced the MAC address. 4058 */ 4059 if (err == 0) 4060 bcopy(mac_addr, map->ma_addr, map->ma_len); 4061 4062 return (err); 4063 } 4064 4065 /* 4066 * Freshen the MAC address with new value. Its caller must have updated the 4067 * hardware MAC address before calling this function. 4068 * This funcitons is supposed to be used to handle the MAC address change 4069 * notification from underlying drivers. 4070 */ 4071 void 4072 mac_freshen_macaddr(mac_address_t *map, uint8_t *mac_addr) 4073 { 4074 mac_impl_t *mip = map->ma_mip; 4075 4076 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 4077 ASSERT(mac_find_macaddr(mip, mac_addr) == NULL); 4078 4079 /* 4080 * Freshen the MAC address with new value. 4081 */ 4082 bcopy(mac_addr, map->ma_addr, map->ma_len); 4083 bcopy(mac_addr, mip->mi_addr, map->ma_len); 4084 4085 /* 4086 * Update all MAC clients that share this MAC address. 4087 */ 4088 mac_unicast_update_clients(mip, map); 4089 } 4090 4091 /* 4092 * Set up the primary MAC address. 4093 */ 4094 void 4095 mac_init_macaddr(mac_impl_t *mip) 4096 { 4097 mac_address_t *map; 4098 4099 /* 4100 * The reference count is initialized to zero, until it's really 4101 * activated. 4102 */ 4103 map = kmem_zalloc(sizeof (mac_address_t), KM_SLEEP); 4104 map->ma_len = mip->mi_type->mt_addr_length; 4105 bcopy(mip->mi_addr, map->ma_addr, map->ma_len); 4106 4107 /* 4108 * If driver advertises RINGS capability, it shouldn't have initialized 4109 * its primary MAC address. For other drivers, including VNIC, the 4110 * primary address must work after registration. 4111 */ 4112 if (mip->mi_rx_groups == NULL) 4113 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED; 4114 4115 /* 4116 * The primary MAC address is reserved for default group according 4117 * to current design. 4118 */ 4119 map->ma_group = mip->mi_rx_groups; 4120 map->ma_mip = mip; 4121 4122 mip->mi_addresses = map; 4123 } 4124 4125 /* 4126 * Clean up the primary MAC address. Note, only one primary MAC address 4127 * is allowed. All other MAC addresses must have been freed appropriately. 4128 */ 4129 void 4130 mac_fini_macaddr(mac_impl_t *mip) 4131 { 4132 mac_address_t *map = mip->mi_addresses; 4133 4134 if (map == NULL) 4135 return; 4136 4137 /* 4138 * If mi_addresses is initialized, there should be exactly one 4139 * entry left on the list with no users. 4140 */ 4141 ASSERT(map->ma_nusers == 0); 4142 ASSERT(map->ma_next == NULL); 4143 4144 kmem_free(map, sizeof (mac_address_t)); 4145 mip->mi_addresses = NULL; 4146 } 4147 4148 /* 4149 * Logging related functions. 4150 */ 4151 4152 /* Write the Flow description to the log file */ 4153 int 4154 mac_write_flow_desc(flow_entry_t *flent, mac_client_impl_t *mcip) 4155 { 4156 flow_desc_t *fdesc; 4157 mac_resource_props_t *mrp; 4158 net_desc_t ndesc; 4159 4160 bzero(&ndesc, sizeof (net_desc_t)); 4161 4162 /* 4163 * Grab the fe_lock to see a self-consistent fe_flow_desc. 4164 * Updates to the fe_flow_desc are done under the fe_lock 4165 */ 4166 mutex_enter(&flent->fe_lock); 4167 fdesc = &flent->fe_flow_desc; 4168 mrp = &flent->fe_resource_props; 4169 4170 ndesc.nd_name = flent->fe_flow_name; 4171 ndesc.nd_devname = mcip->mci_name; 4172 bcopy(fdesc->fd_src_mac, ndesc.nd_ehost, ETHERADDRL); 4173 bcopy(fdesc->fd_dst_mac, ndesc.nd_edest, ETHERADDRL); 4174 ndesc.nd_sap = htonl(fdesc->fd_sap); 4175 ndesc.nd_isv4 = (uint8_t)fdesc->fd_ipversion == IPV4_VERSION; 4176 ndesc.nd_bw_limit = mrp->mrp_maxbw; 4177 if (ndesc.nd_isv4) { 4178 ndesc.nd_saddr[3] = htonl(fdesc->fd_local_addr.s6_addr32[3]); 4179 ndesc.nd_daddr[3] = htonl(fdesc->fd_remote_addr.s6_addr32[3]); 4180 } else { 4181 bcopy(&fdesc->fd_local_addr, ndesc.nd_saddr, IPV6_ADDR_LEN); 4182 bcopy(&fdesc->fd_remote_addr, ndesc.nd_daddr, IPV6_ADDR_LEN); 4183 } 4184 ndesc.nd_sport = htons(fdesc->fd_local_port); 4185 ndesc.nd_dport = htons(fdesc->fd_remote_port); 4186 ndesc.nd_protocol = (uint8_t)fdesc->fd_protocol; 4187 mutex_exit(&flent->fe_lock); 4188 4189 return (exacct_commit_netinfo((void *)&ndesc, EX_NET_FLDESC_REC)); 4190 } 4191 4192 /* Write the Flow statistics to the log file */ 4193 int 4194 mac_write_flow_stats(flow_entry_t *flent) 4195 { 4196 flow_stats_t *fl_stats; 4197 net_stat_t nstat; 4198 4199 fl_stats = &flent->fe_flowstats; 4200 nstat.ns_name = flent->fe_flow_name; 4201 nstat.ns_ibytes = fl_stats->fs_rbytes; 4202 nstat.ns_obytes = fl_stats->fs_obytes; 4203 nstat.ns_ipackets = fl_stats->fs_ipackets; 4204 nstat.ns_opackets = fl_stats->fs_opackets; 4205 nstat.ns_ierrors = fl_stats->fs_ierrors; 4206 nstat.ns_oerrors = fl_stats->fs_oerrors; 4207 4208 return (exacct_commit_netinfo((void *)&nstat, EX_NET_FLSTAT_REC)); 4209 } 4210 4211 /* Write the Link Description to the log file */ 4212 int 4213 mac_write_link_desc(mac_client_impl_t *mcip) 4214 { 4215 net_desc_t ndesc; 4216 flow_entry_t *flent = mcip->mci_flent; 4217 4218 bzero(&ndesc, sizeof (net_desc_t)); 4219 4220 ndesc.nd_name = mcip->mci_name; 4221 ndesc.nd_devname = mcip->mci_name; 4222 ndesc.nd_isv4 = B_TRUE; 4223 /* 4224 * Grab the fe_lock to see a self-consistent fe_flow_desc. 4225 * Updates to the fe_flow_desc are done under the fe_lock 4226 * after removing the flent from the flow table. 4227 */ 4228 mutex_enter(&flent->fe_lock); 4229 bcopy(flent->fe_flow_desc.fd_src_mac, ndesc.nd_ehost, ETHERADDRL); 4230 mutex_exit(&flent->fe_lock); 4231 4232 return (exacct_commit_netinfo((void *)&ndesc, EX_NET_LNDESC_REC)); 4233 } 4234 4235 /* Write the Link statistics to the log file */ 4236 int 4237 mac_write_link_stats(mac_client_impl_t *mcip) 4238 { 4239 net_stat_t nstat; 4240 4241 nstat.ns_name = mcip->mci_name; 4242 nstat.ns_ibytes = mcip->mci_stat_ibytes; 4243 nstat.ns_obytes = mcip->mci_stat_obytes; 4244 nstat.ns_ipackets = mcip->mci_stat_ipackets; 4245 nstat.ns_opackets = mcip->mci_stat_opackets; 4246 nstat.ns_ierrors = mcip->mci_stat_ierrors; 4247 nstat.ns_oerrors = mcip->mci_stat_oerrors; 4248 4249 return (exacct_commit_netinfo((void *)&nstat, EX_NET_LNSTAT_REC)); 4250 } 4251 4252 /* 4253 * For a given flow, if the descrition has not been logged before, do it now. 4254 * If it is a VNIC, then we have collected information about it from the MAC 4255 * table, so skip it. 4256 */ 4257 /*ARGSUSED*/ 4258 static int 4259 mac_log_flowinfo(flow_entry_t *flent, void *args) 4260 { 4261 mac_client_impl_t *mcip = flent->fe_mcip; 4262 4263 if (mcip == NULL) 4264 return (0); 4265 4266 /* 4267 * If the name starts with "vnic", and fe_user_generated is true (to 4268 * exclude the mcast and active flow entries created implicitly for 4269 * a vnic, it is a VNIC flow. i.e. vnic1 is a vnic flow, 4270 * vnic/bge1/mcast1 is not and neither is vnic/bge1/active. 4271 */ 4272 if (strncasecmp(flent->fe_flow_name, "vnic", 4) == 0 && 4273 (flent->fe_type & FLOW_USER) != 0) { 4274 return (0); 4275 } 4276 4277 if (!flent->fe_desc_logged) { 4278 /* 4279 * We don't return error because we want to continu the 4280 * walk in case this is the last walk which means we 4281 * need to reset fe_desc_logged in all the flows. 4282 */ 4283 if (mac_write_flow_desc(flent, mcip) != 0) 4284 return (0); 4285 flent->fe_desc_logged = B_TRUE; 4286 } 4287 4288 /* 4289 * Regardless of the error, we want to proceed in case we have to 4290 * reset fe_desc_logged. 4291 */ 4292 (void) mac_write_flow_stats(flent); 4293 4294 if (mcip != NULL && !(mcip->mci_state_flags & MCIS_DESC_LOGGED)) 4295 flent->fe_desc_logged = B_FALSE; 4296 4297 return (0); 4298 } 4299 4300 typedef struct i_mac_log_state_s { 4301 boolean_t mi_last; 4302 int mi_fenable; 4303 int mi_lenable; 4304 } i_mac_log_state_t; 4305 4306 /* 4307 * Walk the mac_impl_ts and log the description for each mac client of this mac, 4308 * if it hasn't already been done. Additionally, log statistics for the link as 4309 * well. Walk the flow table and log information for each flow as well. 4310 * If it is the last walk (mci_last), then we turn off mci_desc_logged (and 4311 * also fe_desc_logged, if flow logging is on) since we want to log the 4312 * description if and when logging is restarted. 4313 */ 4314 /*ARGSUSED*/ 4315 static uint_t 4316 i_mac_log_walker(mod_hash_key_t key, mod_hash_val_t *val, void *arg) 4317 { 4318 mac_impl_t *mip = (mac_impl_t *)val; 4319 i_mac_log_state_t *lstate = (i_mac_log_state_t *)arg; 4320 int ret; 4321 mac_client_impl_t *mcip; 4322 4323 /* 4324 * Only walk the client list for NIC and etherstub 4325 */ 4326 if ((mip->mi_state_flags & MIS_DISABLED) || 4327 ((mip->mi_state_flags & MIS_IS_VNIC) && 4328 (mac_get_lower_mac_handle((mac_handle_t)mip) != NULL))) 4329 return (MH_WALK_CONTINUE); 4330 4331 for (mcip = mip->mi_clients_list; mcip != NULL; 4332 mcip = mcip->mci_client_next) { 4333 if (!MCIP_DATAPATH_SETUP(mcip)) 4334 continue; 4335 if (lstate->mi_lenable) { 4336 if (!(mcip->mci_state_flags & MCIS_DESC_LOGGED)) { 4337 ret = mac_write_link_desc(mcip); 4338 if (ret != 0) { 4339 /* 4340 * We can't terminate it if this is the last 4341 * walk, else there might be some links with 4342 * mi_desc_logged set to true, which means 4343 * their description won't be logged the next 4344 * time logging is started (similarly for the 4345 * flows within such links). We can continue 4346 * without walking the flow table (i.e. to 4347 * set fe_desc_logged to false) because we 4348 * won't have written any flow stuff for this 4349 * link as we haven't logged the link itself. 4350 */ 4351 if (lstate->mi_last) 4352 return (MH_WALK_CONTINUE); 4353 else 4354 return (MH_WALK_TERMINATE); 4355 } 4356 mcip->mci_state_flags |= MCIS_DESC_LOGGED; 4357 } 4358 } 4359 4360 if (mac_write_link_stats(mcip) != 0 && !lstate->mi_last) 4361 return (MH_WALK_TERMINATE); 4362 4363 if (lstate->mi_last) 4364 mcip->mci_state_flags &= ~MCIS_DESC_LOGGED; 4365 4366 if (lstate->mi_fenable) { 4367 if (mcip->mci_subflow_tab != NULL) { 4368 (void) mac_flow_walk(mcip->mci_subflow_tab, 4369 mac_log_flowinfo, mip); 4370 } 4371 } 4372 } 4373 return (MH_WALK_CONTINUE); 4374 } 4375 4376 /* 4377 * The timer thread that runs every mac_logging_interval seconds and logs 4378 * link and/or flow information. 4379 */ 4380 /* ARGSUSED */ 4381 void 4382 mac_log_linkinfo(void *arg) 4383 { 4384 i_mac_log_state_t lstate; 4385 4386 rw_enter(&i_mac_impl_lock, RW_READER); 4387 if (!mac_flow_log_enable && !mac_link_log_enable) { 4388 rw_exit(&i_mac_impl_lock); 4389 return; 4390 } 4391 lstate.mi_fenable = mac_flow_log_enable; 4392 lstate.mi_lenable = mac_link_log_enable; 4393 lstate.mi_last = B_FALSE; 4394 rw_exit(&i_mac_impl_lock); 4395 4396 mod_hash_walk(i_mac_impl_hash, i_mac_log_walker, &lstate); 4397 4398 rw_enter(&i_mac_impl_lock, RW_WRITER); 4399 if (mac_flow_log_enable || mac_link_log_enable) { 4400 mac_logging_timer = timeout(mac_log_linkinfo, NULL, 4401 SEC_TO_TICK(mac_logging_interval)); 4402 } 4403 rw_exit(&i_mac_impl_lock); 4404 } 4405 4406 typedef struct i_mac_fastpath_state_s { 4407 boolean_t mf_disable; 4408 int mf_err; 4409 } i_mac_fastpath_state_t; 4410 4411 /*ARGSUSED*/ 4412 static uint_t 4413 i_mac_fastpath_disable_walker(mod_hash_key_t key, mod_hash_val_t *val, 4414 void *arg) 4415 { 4416 i_mac_fastpath_state_t *state = arg; 4417 mac_handle_t mh = (mac_handle_t)val; 4418 4419 if (state->mf_disable) 4420 state->mf_err = mac_fastpath_disable(mh); 4421 else 4422 mac_fastpath_enable(mh); 4423 4424 return (state->mf_err == 0 ? MH_WALK_CONTINUE : MH_WALK_TERMINATE); 4425 } 4426 4427 /* 4428 * Start the logging timer. 4429 */ 4430 int 4431 mac_start_logusage(mac_logtype_t type, uint_t interval) 4432 { 4433 i_mac_fastpath_state_t state = {B_TRUE, 0}; 4434 int err; 4435 4436 rw_enter(&i_mac_impl_lock, RW_WRITER); 4437 switch (type) { 4438 case MAC_LOGTYPE_FLOW: 4439 if (mac_flow_log_enable) { 4440 rw_exit(&i_mac_impl_lock); 4441 return (0); 4442 } 4443 /* FALLTHRU */ 4444 case MAC_LOGTYPE_LINK: 4445 if (mac_link_log_enable) { 4446 rw_exit(&i_mac_impl_lock); 4447 return (0); 4448 } 4449 break; 4450 default: 4451 ASSERT(0); 4452 } 4453 4454 /* Disable fastpath */ 4455 mod_hash_walk(i_mac_impl_hash, i_mac_fastpath_disable_walker, &state); 4456 if ((err = state.mf_err) != 0) { 4457 /* Reenable fastpath */ 4458 state.mf_disable = B_FALSE; 4459 state.mf_err = 0; 4460 mod_hash_walk(i_mac_impl_hash, 4461 i_mac_fastpath_disable_walker, &state); 4462 rw_exit(&i_mac_impl_lock); 4463 return (err); 4464 } 4465 4466 switch (type) { 4467 case MAC_LOGTYPE_FLOW: 4468 mac_flow_log_enable = B_TRUE; 4469 /* FALLTHRU */ 4470 case MAC_LOGTYPE_LINK: 4471 mac_link_log_enable = B_TRUE; 4472 break; 4473 } 4474 4475 mac_logging_interval = interval; 4476 rw_exit(&i_mac_impl_lock); 4477 mac_log_linkinfo(NULL); 4478 return (0); 4479 } 4480 4481 /* 4482 * Stop the logging timer if both Link and Flow logging are turned off. 4483 */ 4484 void 4485 mac_stop_logusage(mac_logtype_t type) 4486 { 4487 i_mac_log_state_t lstate; 4488 i_mac_fastpath_state_t state = {B_FALSE, 0}; 4489 4490 rw_enter(&i_mac_impl_lock, RW_WRITER); 4491 lstate.mi_fenable = mac_flow_log_enable; 4492 lstate.mi_lenable = mac_link_log_enable; 4493 4494 /* Last walk */ 4495 lstate.mi_last = B_TRUE; 4496 4497 switch (type) { 4498 case MAC_LOGTYPE_FLOW: 4499 if (lstate.mi_fenable) { 4500 ASSERT(mac_link_log_enable); 4501 mac_flow_log_enable = B_FALSE; 4502 mac_link_log_enable = B_FALSE; 4503 break; 4504 } 4505 /* FALLTHRU */ 4506 case MAC_LOGTYPE_LINK: 4507 if (!lstate.mi_lenable || mac_flow_log_enable) { 4508 rw_exit(&i_mac_impl_lock); 4509 return; 4510 } 4511 mac_link_log_enable = B_FALSE; 4512 break; 4513 default: 4514 ASSERT(0); 4515 } 4516 4517 /* Reenable fastpath */ 4518 mod_hash_walk(i_mac_impl_hash, i_mac_fastpath_disable_walker, &state); 4519 4520 rw_exit(&i_mac_impl_lock); 4521 (void) untimeout(mac_logging_timer); 4522 mac_logging_timer = 0; 4523 4524 /* Last walk */ 4525 mod_hash_walk(i_mac_impl_hash, i_mac_log_walker, &lstate); 4526 } 4527 4528 /* 4529 * Walk the rx and tx SRS/SRs for a flow and update the priority value. 4530 */ 4531 void 4532 mac_flow_update_priority(mac_client_impl_t *mcip, flow_entry_t *flent) 4533 { 4534 pri_t pri; 4535 int count; 4536 mac_soft_ring_set_t *mac_srs; 4537 4538 if (flent->fe_rx_srs_cnt <= 0) 4539 return; 4540 4541 if (((mac_soft_ring_set_t *)flent->fe_rx_srs[0])->srs_type == 4542 SRST_FLOW) { 4543 pri = FLOW_PRIORITY(mcip->mci_min_pri, 4544 mcip->mci_max_pri, 4545 flent->fe_resource_props.mrp_priority); 4546 } else { 4547 pri = mcip->mci_max_pri; 4548 } 4549 4550 for (count = 0; count < flent->fe_rx_srs_cnt; count++) { 4551 mac_srs = flent->fe_rx_srs[count]; 4552 mac_update_srs_priority(mac_srs, pri); 4553 } 4554 /* 4555 * If we have a Tx SRS, we need to modify all the threads associated 4556 * with it. 4557 */ 4558 if (flent->fe_tx_srs != NULL) 4559 mac_update_srs_priority(flent->fe_tx_srs, pri); 4560 } 4561 4562 /* 4563 * RX and TX rings are reserved according to different semantics depending 4564 * on the requests from the MAC clients and type of rings: 4565 * 4566 * On the Tx side, by default we reserve individual rings, independently from 4567 * the groups. 4568 * 4569 * On the Rx side, the reservation is at the granularity of the group 4570 * of rings, and used for v12n level 1 only. It has a special case for the 4571 * primary client. 4572 * 4573 * If a share is allocated to a MAC client, we allocate a TX group and an 4574 * RX group to the client, and assign TX rings and RX rings to these 4575 * groups according to information gathered from the driver through 4576 * the share capability. 4577 * 4578 * The foreseable evolution of Rx rings will handle v12n level 2 and higher 4579 * to allocate individual rings out of a group and program the hw classifier 4580 * based on IP address or higher level criteria. 4581 */ 4582 4583 /* 4584 * mac_reserve_tx_ring() 4585 * Reserve a unused ring by marking it with MR_INUSE state. 4586 * As reserved, the ring is ready to function. 4587 * 4588 * Notes for Hybrid I/O: 4589 * 4590 * If a specific ring is needed, it is specified through the desired_ring 4591 * argument. Otherwise that argument is set to NULL. 4592 * If the desired ring was previous allocated to another client, this 4593 * function swaps it with a new ring from the group of unassigned rings. 4594 */ 4595 mac_ring_t * 4596 mac_reserve_tx_ring(mac_impl_t *mip, mac_ring_t *desired_ring) 4597 { 4598 mac_group_t *group; 4599 mac_ring_t *ring; 4600 4601 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 4602 4603 if (mip->mi_tx_groups == NULL) 4604 return (NULL); 4605 4606 /* 4607 * Find an available ring and start it before changing its status. 4608 * The unassigned rings are at the end of the mi_tx_groups 4609 * array. 4610 */ 4611 group = mip->mi_tx_groups + mip->mi_tx_group_count; 4612 4613 for (ring = group->mrg_rings; ring != NULL; 4614 ring = ring->mr_next) { 4615 if (desired_ring == NULL) { 4616 if (ring->mr_state == MR_FREE) 4617 /* wanted any free ring and found one */ 4618 break; 4619 } else { 4620 mac_ring_t *sring; 4621 mac_client_impl_t *client; 4622 mac_soft_ring_set_t *srs; 4623 4624 if (ring != desired_ring) 4625 /* wants a desired ring but this one ain't it */ 4626 continue; 4627 4628 if (ring->mr_state == MR_FREE) 4629 break; 4630 4631 /* 4632 * Found the desired ring but it's already in use. 4633 * Swap it with a new ring. 4634 */ 4635 4636 /* find the client which owns that ring */ 4637 for (client = mip->mi_clients_list; client != NULL; 4638 client = client->mci_client_next) { 4639 srs = MCIP_TX_SRS(client); 4640 if (srs != NULL && mac_tx_srs_ring_present(srs, 4641 desired_ring)) { 4642 /* found our ring */ 4643 break; 4644 } 4645 } 4646 if (client == NULL) { 4647 /* 4648 * The TX ring is in use, but it's not 4649 * associated with any clients, so it 4650 * has to be the default ring. In that 4651 * case we can simply assign a new ring 4652 * as the default ring, and we're done. 4653 */ 4654 ASSERT(mip->mi_default_tx_ring == 4655 (mac_ring_handle_t)desired_ring); 4656 4657 /* 4658 * Quiesce all clients on top of 4659 * the NIC to make sure there are no 4660 * pending threads still relying on 4661 * that default ring, for example 4662 * the multicast path. 4663 */ 4664 for (client = mip->mi_clients_list; 4665 client != NULL; 4666 client = client->mci_client_next) { 4667 mac_tx_client_quiesce(client, 4668 SRS_QUIESCE); 4669 } 4670 4671 mip->mi_default_tx_ring = (mac_ring_handle_t) 4672 mac_reserve_tx_ring(mip, NULL); 4673 4674 /* resume the clients */ 4675 for (client = mip->mi_clients_list; 4676 client != NULL; 4677 client = client->mci_client_next) 4678 mac_tx_client_restart(client); 4679 4680 break; 4681 } 4682 4683 /* 4684 * Note that we cannot simply invoke the group 4685 * add/rem routines since the client doesn't have a 4686 * TX group. So we need to instead add/remove 4687 * the rings from the SRS. 4688 */ 4689 ASSERT(client->mci_share == NULL); 4690 4691 /* first quiece the client */ 4692 mac_tx_client_quiesce(client, SRS_QUIESCE); 4693 4694 /* give a new ring to the client... */ 4695 sring = mac_reserve_tx_ring(mip, NULL); 4696 if (sring != NULL) { 4697 /* 4698 * There are no other available ring 4699 * on that MAC instance. The client 4700 * will fallback to the shared TX 4701 * ring. 4702 */ 4703 mac_tx_srs_add_ring(srs, sring); 4704 } 4705 4706 /* ... in exchange for our desired ring */ 4707 mac_tx_srs_del_ring(srs, desired_ring); 4708 4709 /* restart the client */ 4710 mac_tx_client_restart(client); 4711 4712 if (mip->mi_default_tx_ring == 4713 (mac_ring_handle_t)desired_ring) { 4714 /* 4715 * The desired ring is the default ring, 4716 * and there are one or more clients 4717 * using that default ring directly. 4718 */ 4719 mip->mi_default_tx_ring = 4720 (mac_ring_handle_t)sring; 4721 /* 4722 * Find clients using default ring and 4723 * swap it with the new default ring. 4724 */ 4725 for (client = mip->mi_clients_list; 4726 client != NULL; 4727 client = client->mci_client_next) { 4728 srs = MCIP_TX_SRS(client); 4729 if (srs != NULL && 4730 mac_tx_srs_ring_present(srs, 4731 desired_ring)) { 4732 /* first quiece the client */ 4733 mac_tx_client_quiesce(client, 4734 SRS_QUIESCE); 4735 4736 /* 4737 * Give it the new default 4738 * ring, and remove the old 4739 * one. 4740 */ 4741 if (sring != NULL) { 4742 mac_tx_srs_add_ring(srs, 4743 sring); 4744 } 4745 mac_tx_srs_del_ring(srs, 4746 desired_ring); 4747 4748 /* restart the client */ 4749 mac_tx_client_restart(client); 4750 } 4751 } 4752 } 4753 break; 4754 } 4755 } 4756 4757 if (ring != NULL) { 4758 if (mac_start_ring(ring) != 0) 4759 return (NULL); 4760 ring->mr_state = MR_INUSE; 4761 } 4762 4763 return (ring); 4764 } 4765 4766 /* 4767 * Minimum number of rings to leave in the default TX group when allocating 4768 * rings to new clients. 4769 */ 4770 static uint_t mac_min_rx_default_rings = 1; 4771 4772 /* 4773 * Populate a zero-ring group with rings. If the share is non-NULL, 4774 * the rings are chosen according to that share. 4775 * Invoked after allocating a new RX or TX group through 4776 * mac_reserve_rx_group() or mac_reserve_tx_group(), respectively. 4777 * Returns zero on success, an errno otherwise. 4778 */ 4779 int 4780 i_mac_group_allocate_rings(mac_impl_t *mip, mac_ring_type_t ring_type, 4781 mac_group_t *src_group, mac_group_t *new_group, mac_share_handle_t share) 4782 { 4783 mac_ring_t **rings, *tmp_ring[1], *ring; 4784 uint_t nrings; 4785 int rv, i, j; 4786 4787 ASSERT(mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC && 4788 mip->mi_tx_group_type == MAC_GROUP_TYPE_DYNAMIC); 4789 ASSERT(new_group->mrg_cur_count == 0); 4790 4791 /* 4792 * First find the rings to allocate to the group. 4793 */ 4794 if (share != NULL) { 4795 /* get rings through ms_squery() */ 4796 mip->mi_share_capab.ms_squery(share, ring_type, NULL, &nrings); 4797 ASSERT(nrings != 0); 4798 rings = kmem_alloc(nrings * sizeof (mac_ring_handle_t), 4799 KM_SLEEP); 4800 mip->mi_share_capab.ms_squery(share, ring_type, 4801 (mac_ring_handle_t *)rings, &nrings); 4802 } else { 4803 /* this function is called for TX only with a share */ 4804 ASSERT(ring_type == MAC_RING_TYPE_RX); 4805 /* 4806 * Pick one ring from default group. 4807 * 4808 * for now pick the second ring which requires the first ring 4809 * at index 0 to stay in the default group, since it is the 4810 * ring which carries the multicast traffic. 4811 * We need a better way for a driver to indicate this, 4812 * for example a per-ring flag. 4813 */ 4814 for (ring = src_group->mrg_rings; ring != NULL; 4815 ring = ring->mr_next) { 4816 if (ring->mr_index != 0) 4817 break; 4818 } 4819 ASSERT(ring != NULL); 4820 nrings = 1; 4821 tmp_ring[0] = ring; 4822 rings = tmp_ring; 4823 } 4824 4825 switch (ring_type) { 4826 case MAC_RING_TYPE_RX: 4827 if (src_group->mrg_cur_count - nrings < 4828 mac_min_rx_default_rings) { 4829 /* we ran out of rings */ 4830 return (ENOSPC); 4831 } 4832 4833 /* move receive rings to new group */ 4834 for (i = 0; i < nrings; i++) { 4835 rv = mac_group_mov_ring(mip, new_group, rings[i]); 4836 if (rv != 0) { 4837 /* move rings back on failure */ 4838 for (j = 0; j < i; j++) { 4839 (void) mac_group_mov_ring(mip, 4840 src_group, rings[j]); 4841 } 4842 return (rv); 4843 } 4844 } 4845 break; 4846 4847 case MAC_RING_TYPE_TX: { 4848 mac_ring_t *tmp_ring; 4849 4850 /* move the TX rings to the new group */ 4851 ASSERT(src_group == NULL); 4852 for (i = 0; i < nrings; i++) { 4853 /* get the desired ring */ 4854 tmp_ring = mac_reserve_tx_ring(mip, rings[i]); 4855 ASSERT(tmp_ring == rings[i]); 4856 rv = mac_group_mov_ring(mip, new_group, rings[i]); 4857 if (rv != 0) { 4858 /* cleanup on failure */ 4859 for (j = 0; j < i; j++) { 4860 (void) mac_group_mov_ring(mip, 4861 mip->mi_tx_groups + 4862 mip->mi_tx_group_count, rings[j]); 4863 } 4864 } 4865 } 4866 break; 4867 } 4868 } 4869 4870 if (share != NULL) { 4871 /* add group to share */ 4872 mip->mi_share_capab.ms_sadd(share, new_group->mrg_driver); 4873 /* free temporary array of rings */ 4874 kmem_free(rings, nrings * sizeof (mac_ring_handle_t)); 4875 } 4876 4877 return (0); 4878 } 4879 4880 void 4881 mac_rx_group_add_client(mac_group_t *grp, mac_client_impl_t *mcip) 4882 { 4883 mac_grp_client_t *mgcp; 4884 4885 for (mgcp = grp->mrg_clients; mgcp != NULL; mgcp = mgcp->mgc_next) { 4886 if (mgcp->mgc_client == mcip) 4887 break; 4888 } 4889 4890 VERIFY(mgcp == NULL); 4891 4892 mgcp = kmem_zalloc(sizeof (mac_grp_client_t), KM_SLEEP); 4893 mgcp->mgc_client = mcip; 4894 mgcp->mgc_next = grp->mrg_clients; 4895 grp->mrg_clients = mgcp; 4896 4897 } 4898 4899 void 4900 mac_rx_group_remove_client(mac_group_t *grp, mac_client_impl_t *mcip) 4901 { 4902 mac_grp_client_t *mgcp, **pprev; 4903 4904 for (pprev = &grp->mrg_clients, mgcp = *pprev; mgcp != NULL; 4905 pprev = &mgcp->mgc_next, mgcp = *pprev) { 4906 if (mgcp->mgc_client == mcip) 4907 break; 4908 } 4909 4910 ASSERT(mgcp != NULL); 4911 4912 *pprev = mgcp->mgc_next; 4913 kmem_free(mgcp, sizeof (mac_grp_client_t)); 4914 } 4915 4916 /* 4917 * mac_reserve_rx_group() 4918 * 4919 * Finds an available group and exclusively reserves it for a client. 4920 * The group is chosen to suit the flow's resource controls (bandwidth and 4921 * fanout requirements) and the address type. 4922 * If the requestor is the pimary MAC then return the group with the 4923 * largest number of rings, otherwise the default ring when available. 4924 */ 4925 mac_group_t * 4926 mac_reserve_rx_group(mac_client_impl_t *mcip, uint8_t *mac_addr, 4927 mac_rx_group_reserve_type_t rtype) 4928 { 4929 mac_share_handle_t share = mcip->mci_share; 4930 mac_impl_t *mip = mcip->mci_mip; 4931 mac_group_t *grp = NULL; 4932 int i, start, loopcount; 4933 int err; 4934 mac_address_t *map; 4935 4936 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip)); 4937 4938 /* Check if a group already has this mac address (case of VLANs) */ 4939 if ((map = mac_find_macaddr(mip, mac_addr)) != NULL) 4940 return (map->ma_group); 4941 4942 if (mip->mi_rx_groups == NULL || mip->mi_rx_group_count == 0 || 4943 rtype == MAC_RX_NO_RESERVE) 4944 return (NULL); 4945 4946 /* 4947 * Try to exclusively reserve a RX group. 4948 * 4949 * For flows requires SW_RING it always goes to the default group 4950 * (Until we can explicitely call out default groups (CR 6695600), 4951 * we assume that the default group is always at position zero); 4952 * 4953 * For flows requires HW_DEFAULT_RING (unicast flow of the primary 4954 * client), try to reserve the default RX group only. 4955 * 4956 * For flows requires HW_RING (unicast flow of other clients), try 4957 * to reserve non-default RX group then the default group. 4958 */ 4959 switch (rtype) { 4960 case MAC_RX_RESERVE_DEFAULT: 4961 start = 0; 4962 loopcount = 1; 4963 break; 4964 case MAC_RX_RESERVE_NONDEFAULT: 4965 start = 1; 4966 loopcount = mip->mi_rx_group_count; 4967 } 4968 4969 for (i = start; i < start + loopcount; i++) { 4970 grp = &mip->mi_rx_groups[i % mip->mi_rx_group_count]; 4971 4972 DTRACE_PROBE3(rx__group__trying, char *, mip->mi_name, 4973 int, grp->mrg_index, mac_group_state_t, grp->mrg_state); 4974 4975 /* 4976 * Check to see whether this mac client is the only client 4977 * on this RX group. If not, we cannot exclusively reserve 4978 * this RX group. 4979 */ 4980 if (!MAC_RX_GROUP_NO_CLIENT(grp) && 4981 (MAC_RX_GROUP_ONLY_CLIENT(grp) != mcip)) { 4982 continue; 4983 } 4984 4985 /* 4986 * This group could already be SHARED by other multicast 4987 * flows on this client. In that case, the group would 4988 * be shared and has already been started. 4989 */ 4990 ASSERT(grp->mrg_state != MAC_GROUP_STATE_UNINIT); 4991 4992 if ((grp->mrg_state == MAC_GROUP_STATE_REGISTERED) && 4993 (mac_start_group(grp) != 0)) { 4994 continue; 4995 } 4996 4997 if ((i % mip->mi_rx_group_count) == 0 || 4998 mip->mi_rx_group_type != MAC_GROUP_TYPE_DYNAMIC) { 4999 break; 5000 } 5001 5002 ASSERT(grp->mrg_cur_count == 0); 5003 5004 /* 5005 * Populate the group. Rings should be taken 5006 * from the default group at position 0 for now. 5007 */ 5008 5009 err = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_RX, 5010 &mip->mi_rx_groups[0], grp, share); 5011 if (err == 0) 5012 break; 5013 5014 DTRACE_PROBE3(rx__group__reserve__alloc__rings, char *, 5015 mip->mi_name, int, grp->mrg_index, int, err); 5016 5017 /* 5018 * It's a dynamic group but the grouping operation failed. 5019 */ 5020 mac_stop_group(grp); 5021 } 5022 5023 if (i == start + loopcount) 5024 return (NULL); 5025 5026 ASSERT(grp != NULL); 5027 5028 DTRACE_PROBE2(rx__group__reserved, 5029 char *, mip->mi_name, int, grp->mrg_index); 5030 return (grp); 5031 } 5032 5033 /* 5034 * mac_rx_release_group() 5035 * 5036 * This is called when there are no clients left for the group. 5037 * The group is stopped and marked MAC_GROUP_STATE_REGISTERED, 5038 * and if it is a non default group, the shares are removed and 5039 * all rings are assigned back to default group. 5040 */ 5041 void 5042 mac_release_rx_group(mac_client_impl_t *mcip, mac_group_t *group) 5043 { 5044 mac_impl_t *mip = mcip->mci_mip; 5045 mac_ring_t *ring; 5046 5047 ASSERT(group != &mip->mi_rx_groups[0]); 5048 5049 /* 5050 * This is the case where there are no clients left. Any 5051 * SRS etc on this group have also be quiesced. 5052 */ 5053 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) { 5054 if (ring->mr_classify_type == MAC_HW_CLASSIFIER) { 5055 ASSERT(group->mrg_state == MAC_GROUP_STATE_RESERVED); 5056 /* 5057 * Remove the SRS associated with the HW ring. 5058 * As a result, polling will be disabled. 5059 */ 5060 ring->mr_srs = NULL; 5061 } 5062 ASSERT(ring->mr_state == MR_INUSE); 5063 mac_stop_ring(ring); 5064 ring->mr_state = MR_FREE; 5065 ring->mr_flag = 0; 5066 } 5067 5068 /* remove group from share */ 5069 if (mcip->mci_share != NULL) { 5070 mip->mi_share_capab.ms_sremove(mcip->mci_share, 5071 group->mrg_driver); 5072 } 5073 5074 if (mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) { 5075 mac_ring_t *ring; 5076 5077 /* 5078 * Rings were dynamically allocated to group. 5079 * Move rings back to default group. 5080 */ 5081 while ((ring = group->mrg_rings) != NULL) { 5082 (void) mac_group_mov_ring(mip, 5083 &mip->mi_rx_groups[0], ring); 5084 } 5085 } 5086 mac_stop_group(group); 5087 /* 5088 * Possible improvement: See if we can assign the group just released 5089 * to a another client of the mip 5090 */ 5091 } 5092 5093 /* 5094 * Reserves a TX group for the specified share. Invoked by mac_tx_srs_setup() 5095 * when a share was allocated to the client. 5096 */ 5097 mac_group_t * 5098 mac_reserve_tx_group(mac_impl_t *mip, mac_share_handle_t share) 5099 { 5100 mac_group_t *grp; 5101 int rv, i; 5102 5103 /* 5104 * TX groups are currently allocated only to MAC clients 5105 * which are associated with a share. Since we have a fixed 5106 * number of share and groups, and we already successfully 5107 * allocated a share, find an available TX group. 5108 */ 5109 ASSERT(share != NULL); 5110 ASSERT(mip->mi_tx_group_free > 0); 5111 5112 for (i = 0; i < mip->mi_tx_group_count; i++) { 5113 grp = &mip->mi_tx_groups[i]; 5114 5115 if ((grp->mrg_state == MAC_GROUP_STATE_RESERVED) || 5116 (grp->mrg_state == MAC_GROUP_STATE_UNINIT)) 5117 continue; 5118 5119 rv = mac_start_group(grp); 5120 ASSERT(rv == 0); 5121 5122 grp->mrg_state = MAC_GROUP_STATE_RESERVED; 5123 break; 5124 } 5125 5126 ASSERT(grp != NULL); 5127 5128 /* 5129 * Populate the group. Rings should be taken from the group 5130 * of unassigned rings, which is past the array of TX 5131 * groups adversized by the driver. 5132 */ 5133 rv = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_TX, NULL, 5134 grp, share); 5135 if (rv != 0) { 5136 DTRACE_PROBE3(tx__group__reserve__alloc__rings, 5137 char *, mip->mi_name, int, grp->mrg_index, int, rv); 5138 5139 mac_stop_group(grp); 5140 grp->mrg_state = MAC_GROUP_STATE_UNINIT; 5141 5142 return (NULL); 5143 } 5144 5145 mip->mi_tx_group_free--; 5146 5147 return (grp); 5148 } 5149 5150 void 5151 mac_release_tx_group(mac_impl_t *mip, mac_group_t *grp) 5152 { 5153 mac_client_impl_t *mcip = grp->mrg_tx_client; 5154 mac_share_handle_t share = mcip->mci_share; 5155 mac_ring_t *ring; 5156 5157 ASSERT(mip->mi_tx_group_type == MAC_GROUP_TYPE_DYNAMIC); 5158 ASSERT(share != NULL); 5159 ASSERT(grp->mrg_state == MAC_GROUP_STATE_RESERVED); 5160 5161 mip->mi_share_capab.ms_sremove(share, grp->mrg_driver); 5162 while ((ring = grp->mrg_rings) != NULL) { 5163 /* move the ring back to the pool */ 5164 (void) mac_group_mov_ring(mip, mip->mi_tx_groups + 5165 mip->mi_tx_group_count, ring); 5166 } 5167 mac_stop_group(grp); 5168 mac_set_rx_group_state(grp, MAC_GROUP_STATE_REGISTERED); 5169 grp->mrg_tx_client = NULL; 5170 mip->mi_tx_group_free++; 5171 } 5172 5173 /* 5174 * This is a 1-time control path activity initiated by the client (IP). 5175 * The mac perimeter protects against other simultaneous control activities, 5176 * for example an ioctl that attempts to change the degree of fanout and 5177 * increase or decrease the number of softrings associated with this Tx SRS. 5178 */ 5179 static mac_tx_notify_cb_t * 5180 mac_client_tx_notify_add(mac_client_impl_t *mcip, 5181 mac_tx_notify_t notify, void *arg) 5182 { 5183 mac_cb_info_t *mcbi; 5184 mac_tx_notify_cb_t *mtnfp; 5185 5186 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 5187 5188 mtnfp = kmem_zalloc(sizeof (mac_tx_notify_cb_t), KM_SLEEP); 5189 mtnfp->mtnf_fn = notify; 5190 mtnfp->mtnf_arg = arg; 5191 mtnfp->mtnf_link.mcb_objp = mtnfp; 5192 mtnfp->mtnf_link.mcb_objsize = sizeof (mac_tx_notify_cb_t); 5193 mtnfp->mtnf_link.mcb_flags = MCB_TX_NOTIFY_CB_T; 5194 5195 mcbi = &mcip->mci_tx_notify_cb_info; 5196 mutex_enter(mcbi->mcbi_lockp); 5197 mac_callback_add(mcbi, &mcip->mci_tx_notify_cb_list, &mtnfp->mtnf_link); 5198 mutex_exit(mcbi->mcbi_lockp); 5199 return (mtnfp); 5200 } 5201 5202 static void 5203 mac_client_tx_notify_remove(mac_client_impl_t *mcip, mac_tx_notify_cb_t *mtnfp) 5204 { 5205 mac_cb_info_t *mcbi; 5206 mac_cb_t **cblist; 5207 5208 ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip)); 5209 5210 if (!mac_callback_find(&mcip->mci_tx_notify_cb_info, 5211 &mcip->mci_tx_notify_cb_list, &mtnfp->mtnf_link)) { 5212 cmn_err(CE_WARN, 5213 "mac_client_tx_notify_remove: callback not " 5214 "found, mcip 0x%p mtnfp 0x%p", (void *)mcip, (void *)mtnfp); 5215 return; 5216 } 5217 5218 mcbi = &mcip->mci_tx_notify_cb_info; 5219 cblist = &mcip->mci_tx_notify_cb_list; 5220 mutex_enter(mcbi->mcbi_lockp); 5221 if (mac_callback_remove(mcbi, cblist, &mtnfp->mtnf_link)) 5222 kmem_free(mtnfp, sizeof (mac_tx_notify_cb_t)); 5223 else 5224 mac_callback_remove_wait(&mcip->mci_tx_notify_cb_info); 5225 mutex_exit(mcbi->mcbi_lockp); 5226 } 5227 5228 /* 5229 * mac_client_tx_notify(): 5230 * call to add and remove flow control callback routine. 5231 */ 5232 mac_tx_notify_handle_t 5233 mac_client_tx_notify(mac_client_handle_t mch, mac_tx_notify_t callb_func, 5234 void *ptr) 5235 { 5236 mac_client_impl_t *mcip = (mac_client_impl_t *)mch; 5237 mac_tx_notify_cb_t *mtnfp = NULL; 5238 5239 i_mac_perim_enter(mcip->mci_mip); 5240 5241 if (callb_func != NULL) { 5242 /* Add a notify callback */ 5243 mtnfp = mac_client_tx_notify_add(mcip, callb_func, ptr); 5244 } else { 5245 mac_client_tx_notify_remove(mcip, (mac_tx_notify_cb_t *)ptr); 5246 } 5247 i_mac_perim_exit(mcip->mci_mip); 5248 5249 return ((mac_tx_notify_handle_t)mtnfp); 5250 } 5251