443
444 i_mactype_hash = mod_hash_create_extended("mactype_hash",
445 MACTYPE_HASHSZ,
446 mod_hash_null_keydtor, mod_hash_null_valdtor,
447 mod_hash_bystr, NULL, mod_hash_strkey_cmp, KM_SLEEP);
448
449 /*
450 * Allocate an id space to manage minor numbers. The range of the
451 * space will be from MAC_MAX_MINOR+1 to MAC_PRIVATE_MINOR-1. This
452 * leaves half of the 32-bit minors available for driver private use.
453 */
454 minor_ids = id_space_create("mac_minor_ids", MAC_MAX_MINOR+1,
455 MAC_PRIVATE_MINOR-1);
456 ASSERT(minor_ids != NULL);
457 minor_count = 0;
458
459 /* Let's default to 20 seconds */
460 mac_logging_interval = 20;
461 mac_flow_log_enable = B_FALSE;
462 mac_link_log_enable = B_FALSE;
463 mac_logging_timer = 0;
464
465 /* Register to be notified of noteworthy pools events */
466 mac_pool_event_reg.pec_func = mac_pool_event_cb;
467 mac_pool_event_reg.pec_arg = NULL;
468 pool_event_cb_register(&mac_pool_event_reg);
469 }
470
471 int
472 mac_fini(void)
473 {
474
475 if (i_mac_impl_count > 0 || minor_count > 0)
476 return (EBUSY);
477
478 pool_event_cb_unregister(&mac_pool_event_reg);
479
480 id_space_destroy(minor_ids);
481 mac_flow_fini();
482
483 mod_hash_destroy_hash(i_mac_impl_hash);
1098 return (err);
1099 }
1100
1101 /*
1102 * Start the default tx ring.
1103 */
1104 if (mip->mi_default_tx_ring != NULL) {
1105
1106 ring = (mac_ring_t *)mip->mi_default_tx_ring;
1107 if (ring->mr_state != MR_INUSE) {
1108 err = mac_start_ring(ring);
1109 if (err != 0) {
1110 mip->mi_active--;
1111 return (err);
1112 }
1113 }
1114 }
1115
1116 if ((defgrp = MAC_DEFAULT_RX_GROUP(mip)) != NULL) {
1117 /*
1118 * Start the default ring, since it will be needed
1119 * to receive broadcast and multicast traffic for
1120 * both primary and non-primary MAC clients.
1121 */
1122 ASSERT(defgrp->mrg_state == MAC_GROUP_STATE_REGISTERED);
1123 err = mac_start_group_and_rings(defgrp);
1124 if (err != 0) {
1125 mip->mi_active--;
1126 if ((ring != NULL) &&
1127 (ring->mr_state == MR_INUSE))
1128 mac_stop_ring(ring);
1129 return (err);
1130 }
1131 mac_set_group_state(defgrp, MAC_GROUP_STATE_SHARED);
1132 }
1133 }
1134
1135 return (err);
1136 }
1137
1138 /*
1139 * Private GLDv3 function to stop a MAC instance.
1140 */
1713 mip->mi_default_tx_ring = rh;
1714 }
1715
1716 int
1717 mac_hwgroup_addmac(mac_group_handle_t gh, const uint8_t *addr)
1718 {
1719 mac_group_t *group = (mac_group_t *)gh;
1720
1721 return (mac_group_addmac(group, addr));
1722 }
1723
1724 int
1725 mac_hwgroup_remmac(mac_group_handle_t gh, const uint8_t *addr)
1726 {
1727 mac_group_t *group = (mac_group_t *)gh;
1728
1729 return (mac_group_remmac(group, addr));
1730 }
1731
1732 /*
1733 * Set the RX group to be shared/reserved. Note that the group must be
1734 * started/stopped outside of this function.
1735 */
1736 void
1737 mac_set_group_state(mac_group_t *grp, mac_group_state_t state)
1738 {
1739 /*
1740 * If there is no change in the group state, just return.
1741 */
1742 if (grp->mrg_state == state)
1743 return;
1744
1745 switch (state) {
1746 case MAC_GROUP_STATE_RESERVED:
1747 /*
1748 * Successfully reserved the group.
1749 *
1750 * Given that there is an exclusive client controlling this
1751 * group, we enable the group level polling when available,
1752 * so that SRSs get to turn on/off individual rings they's
2397 {
2398 mac_impl_t *mip = (mac_impl_t *)mh;
2399 int err;
2400
2401 i_mac_perim_enter(mip);
2402 err = i_mac_disable(mip);
2403 i_mac_perim_exit(mip);
2404
2405 /*
2406 * Clean up notification thread and wait for it to exit.
2407 */
2408 if (err == 0)
2409 i_mac_notify_exit(mip);
2410
2411 return (err);
2412 }
2413
2414 /*
2415 * Called when the MAC instance has a non empty flow table, to de-multiplex
2416 * incoming packets to the right flow.
2417 * The MAC's rw lock is assumed held as a READER.
2418 */
2419 /* ARGSUSED */
2420 static mblk_t *
2421 mac_rx_classify(mac_impl_t *mip, mac_resource_handle_t mrh, mblk_t *mp)
2422 {
2423 flow_entry_t *flent = NULL;
2424 uint_t flags = FLOW_INBOUND;
2425 int err;
2426
2427 /*
2428 * If the mac is a port of an aggregation, pass FLOW_IGNORE_VLAN
2429 * to mac_flow_lookup() so that the VLAN packets can be successfully
2430 * passed to the non-VLAN aggregation flows.
2431 *
2432 * Note that there is possibly a race between this and
2433 * mac_unicast_remove/add() and VLAN packets could be incorrectly
2434 * classified to non-VLAN flows of non-aggregation mac clients. These
2435 * VLAN packets will be then filtered out by the mac module.
2436 */
2437 if ((mip->mi_state_flags & MIS_EXCLUSIVE) != 0)
2438 flags |= FLOW_IGNORE_VLAN;
2439
2440 err = mac_flow_lookup(mip->mi_flow_tab, mp, flags, &flent);
2441 if (err != 0) {
2442 /* no registered receive function */
2443 return (mp);
2444 } else {
2445 mac_client_impl_t *mcip;
2446
2447 /*
2448 * This flent might just be an additional one on the MAC client,
2449 * i.e. for classification purposes (different fdesc), however
2450 * the resources, SRS et. al., are in the mci_flent, so if
2451 * this isn't the mci_flent, we need to get it.
2452 */
2453 if ((mcip = flent->fe_mcip) != NULL &&
2454 mcip->mci_flent != flent) {
2455 FLOW_REFRELE(flent);
4058 break;
4059 }
4060 break;
4061 case MAC_GROUP_TYPE_STATIC:
4062 /*
4063 * Note that an empty group is allowed, e.g., an aggr
4064 * would start with an empty group.
4065 */
4066 break;
4067 default:
4068 /* unknown group type */
4069 DTRACE_PROBE2(mac__init__rings__unknown__type,
4070 char *, mip->mi_name,
4071 int, cap_rings->mr_group_type);
4072 err = EINVAL;
4073 goto bail;
4074 }
4075
4076
4077 /*
4078 * Driver must register group->mgi_addmac/remmac() for rx groups
4079 * to support multiple MAC addresses.
4080 */
4081 if (rtype == MAC_RING_TYPE_RX &&
4082 ((group_info.mgi_addmac == NULL) ||
4083 (group_info.mgi_remmac == NULL))) {
4084 err = EINVAL;
4085 goto bail;
4086 }
4087
4088 /* Cache driver-supplied information */
4089 group->mrg_info = group_info;
4090
4091 /* Update the group's status and group count. */
4092 mac_set_group_state(group, MAC_GROUP_STATE_REGISTERED);
4093 group_free++;
4094
4095 group->mrg_rings = NULL;
4096 group->mrg_cur_count = 0;
4097 mac_init_group(mip, group, group_info.mgi_count, cap_rings);
4098 ring_left -= group_info.mgi_count;
4099
4100 /* The current group size should be equal to default value */
4101 ASSERT(group->mrg_cur_count == group_info.mgi_count);
4102 }
4103
4110 group->mrg_state = MAC_GROUP_STATE_UNINIT;
4111 group->mrg_mh = (mac_handle_t)mip;
4112 group->mrg_next = NULL;
4113
4114 /*
4115 * If there are ungrouped rings, allocate a continuous buffer for
4116 * remaining resources.
4117 */
4118 if (ring_left != 0) {
4119 group->mrg_rings = NULL;
4120 group->mrg_cur_count = 0;
4121 mac_init_group(mip, group, ring_left, cap_rings);
4122
4123 /* The current group size should be equal to ring_left */
4124 ASSERT(group->mrg_cur_count == ring_left);
4125
4126 ring_left = 0;
4127
4128 /* Update this group's status */
4129 mac_set_group_state(group, MAC_GROUP_STATE_REGISTERED);
4130 } else
4131 group->mrg_rings = NULL;
4132
4133 ASSERT(ring_left == 0);
4134
4135 bail:
4136
4137 /* Cache other important information to finalize the initialization */
4138 switch (rtype) {
4139 case MAC_RING_TYPE_RX:
4140 mip->mi_rx_group_type = cap_rings->mr_group_type;
4141 mip->mi_rx_group_count = cap_rings->mr_gnum;
4142 mip->mi_rx_groups = groups;
4143 mip->mi_rx_donor_grp = groups;
4144 if (mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) {
4145 /*
4146 * The default ring is reserved since it is
4147 * used for sending the broadcast etc. packets.
4148 */
4149 mip->mi_rxrings_avail =
4150 mip->mi_rx_groups->mrg_cur_count - 1;
4151 mip->mi_rxrings_rsvd = 1;
4301 mac_ring_t *ring;
4302
4303 if (group->mrg_cur_count == 0)
4304 continue;
4305
4306 ASSERT(group->mrg_rings != NULL);
4307
4308 while ((ring = group->mrg_rings) != NULL) {
4309 group->mrg_rings = ring->mr_next;
4310 mac_ring_free(mip, ring);
4311 }
4312 }
4313
4314 /* Free all the cached rings */
4315 mac_ring_freeall(mip);
4316 /* Free the block of group data strutures */
4317 kmem_free(groups, sizeof (mac_group_t) * (group_count + 1));
4318 }
4319
4320 /*
4321 * Associate a MAC address with a receive group.
4322 *
4323 * The return value of this function should always be checked properly, because
4324 * any type of failure could cause unexpected results. A group can be added
4325 * or removed with a MAC address only after it has been reserved. Ideally,
4326 * a successful reservation always leads to calling mac_group_addmac() to
4327 * steer desired traffic. Failure of adding an unicast MAC address doesn't
4328 * always imply that the group is functioning abnormally.
4329 *
4330 * Currently this function is called everywhere, and it reflects assumptions
4331 * about MAC addresses in the implementation. CR 6735196.
4332 */
4333 int
4334 mac_group_addmac(mac_group_t *group, const uint8_t *addr)
4335 {
4336 ASSERT(group->mrg_type == MAC_RING_TYPE_RX);
4337 ASSERT(group->mrg_info.mgi_addmac != NULL);
4338
4339 return (group->mrg_info.mgi_addmac(group->mrg_info.mgi_driver, addr));
4340 }
4341
4342 /*
4343 * Remove the association between MAC address and receive group.
4344 */
4345 int
4346 mac_group_remmac(mac_group_t *group, const uint8_t *addr)
4347 {
4348 ASSERT(group->mrg_type == MAC_RING_TYPE_RX);
4349 ASSERT(group->mrg_info.mgi_remmac != NULL);
4350
4351 return (group->mrg_info.mgi_remmac(group->mrg_info.mgi_driver, addr));
4352 }
4353
4354 /*
4355 * This is the entry point for packets transmitted through the bridging code.
4356 * If no bridge is in place, MAC_RING_TX transmits using tx ring. The 'rh'
4357 * pointer may be NULL to select the default ring.
4358 */
4359 mblk_t *
4360 mac_bridge_tx(mac_impl_t *mip, mac_ring_handle_t rh, mblk_t *mp)
4361 {
4362 mac_handle_t mh;
4363
4364 /*
4365 * Once we take a reference on the bridge link, the bridge
4366 * module itself can't unload, so the callback pointers are
4367 * stable.
4368 */
4369 mutex_enter(&mip->mi_bridge_lock);
4504 ring->mr_driver, ring->mr_type);
4505 }
4506 group->mrg_cur_count--;
4507 group->mrg_rings = ring->mr_next;
4508
4509 ring->mr_gh = NULL;
4510
4511 if (driver_call)
4512 mac_ring_free(mip, ring);
4513
4514 return (ret);
4515 }
4516 }
4517
4518 /*
4519 * Set up SRS/SR according to the ring type.
4520 */
4521 switch (ring->mr_type) {
4522 case MAC_RING_TYPE_RX:
4523 /*
4524 * Setup SRS on top of the new ring if the group is
4525 * reserved for someones exclusive use.
4526 */
4527 if (group->mrg_state == MAC_GROUP_STATE_RESERVED) {
4528 mac_client_impl_t *mcip;
4529
4530 mcip = MAC_GROUP_ONLY_CLIENT(group);
4531 /*
4532 * Even though this group is reserved we migth still
4533 * have multiple clients, i.e a VLAN shares the
4534 * group with the primary mac client.
4535 */
4536 if (mcip != NULL) {
4537 flent = mcip->mci_flent;
4538 ASSERT(flent->fe_rx_srs_cnt > 0);
4539 mac_rx_srs_group_setup(mcip, flent, SRST_LINK);
4540 mac_fanout_setup(mcip, flent,
4541 MCIP_RESOURCE_PROPS(mcip), mac_rx_deliver,
4542 mcip, NULL, NULL);
4543 } else {
4544 ring->mr_classify_type = MAC_SW_CLASSIFIER;
4545 }
4546 }
4547 break;
4548 case MAC_RING_TYPE_TX:
4549 {
4550 mac_grp_client_t *mgcp = group->mrg_clients;
4551 mac_client_impl_t *mcip;
4552 mac_soft_ring_set_t *mac_srs;
4553 mac_srs_tx_t *tx;
4554
4555 if (MAC_GROUP_NO_CLIENT(group)) {
4556 if (ring->mr_state == MR_INUSE)
4557 mac_stop_ring(ring);
4558 ring->mr_flag = 0;
4559 break;
4560 }
4561 /*
4562 * If the rings are being moved to a group that has
4563 * clients using it, then add the new rings to the
4564 * clients SRS.
4565 */
4566 while (mgcp != NULL) {
4567 boolean_t is_aggr;
4568
4569 mcip = mgcp->mgc_client;
4570 flent = mcip->mci_flent;
4571 is_aggr = (mcip->mci_state_flags & MCIS_IS_AGGR);
4572 mac_srs = MCIP_TX_SRS(mcip);
4573 tx = &mac_srs->srs_tx;
4574 mac_tx_client_quiesce((mac_client_handle_t)mcip);
4575 /*
4576 * If we are growing from 1 to multiple rings.
4577 */
4578 if (tx->st_mode == SRS_TX_BW ||
4579 tx->st_mode == SRS_TX_SERIALIZE ||
4580 tx->st_mode == SRS_TX_DEFAULT) {
4581 mac_ring_t *tx_ring = tx->st_arg2;
4582
4583 tx->st_arg2 = NULL;
4584 mac_tx_srs_stat_recreate(mac_srs, B_TRUE);
4585 mac_tx_srs_add_ring(mac_srs, tx_ring);
4586 if (mac_srs->srs_type & SRST_BW_CONTROL) {
4587 tx->st_mode = is_aggr ? SRS_TX_BW_AGGR :
4588 SRS_TX_BW_FANOUT;
4589 } else {
4590 tx->st_mode = is_aggr ? SRS_TX_AGGR :
4591 SRS_TX_FANOUT;
4695 mac_client_impl_t *mcip;
4696 mac_soft_ring_set_t *mac_srs;
4697 mac_soft_ring_t *sringp;
4698 mac_srs_tx_t *srs_tx;
4699
4700 if (mip->mi_state_flags & MIS_IS_AGGR &&
4701 mip->mi_default_tx_ring ==
4702 (mac_ring_handle_t)ring) {
4703 /* pick a new default Tx ring */
4704 mip->mi_default_tx_ring =
4705 (group->mrg_rings != ring) ?
4706 (mac_ring_handle_t)group->mrg_rings :
4707 (mac_ring_handle_t)(ring->mr_next);
4708 }
4709 /* Presently only aggr case comes here */
4710 if (group->mrg_state != MAC_GROUP_STATE_RESERVED)
4711 break;
4712
4713 mcip = MAC_GROUP_ONLY_CLIENT(group);
4714 ASSERT(mcip != NULL);
4715 ASSERT(mcip->mci_state_flags & MCIS_IS_AGGR);
4716 mac_srs = MCIP_TX_SRS(mcip);
4717 ASSERT(mac_srs->srs_tx.st_mode == SRS_TX_AGGR ||
4718 mac_srs->srs_tx.st_mode == SRS_TX_BW_AGGR);
4719 srs_tx = &mac_srs->srs_tx;
4720 /*
4721 * Wakeup any callers blocked on this
4722 * Tx ring due to flow control.
4723 */
4724 sringp = srs_tx->st_soft_rings[ring->mr_index];
4725 ASSERT(sringp != NULL);
4726 mac_tx_invoke_callbacks(mcip, (mac_tx_cookie_t)sringp);
4727 mac_tx_client_quiesce((mac_client_handle_t)mcip);
4728 mac_tx_srs_del_ring(mac_srs, ring);
4729 mac_tx_client_restart((mac_client_handle_t)mcip);
4730 break;
4731 }
4732 ASSERT(ring != (mac_ring_t *)mip->mi_default_tx_ring);
4733 group_type = mip->mi_tx_group_type;
4734 cap_rings = &mip->mi_tx_rings_cap;
4735 /*
4903 /*
4904 * Check whether the MAC address is shared by multiple clients.
4905 */
4906 boolean_t
4907 mac_check_macaddr_shared(mac_address_t *map)
4908 {
4909 ASSERT(MAC_PERIM_HELD((mac_handle_t)map->ma_mip));
4910
4911 return (map->ma_nusers > 1);
4912 }
4913
4914 /*
4915 * Remove the specified MAC address from the MAC address list and free it.
4916 */
4917 static void
4918 mac_free_macaddr(mac_address_t *map)
4919 {
4920 mac_impl_t *mip = map->ma_mip;
4921
4922 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip));
4923 ASSERT(mip->mi_addresses != NULL);
4924
4925 map = mac_find_macaddr(mip, map->ma_addr);
4926
4927 ASSERT(map != NULL);
4928 ASSERT(map->ma_nusers == 0);
4929
4930 if (map == mip->mi_addresses) {
4931 mip->mi_addresses = map->ma_next;
4932 } else {
4933 mac_address_t *pre;
4934
4935 pre = mip->mi_addresses;
4936 while (pre->ma_next != map)
4937 pre = pre->ma_next;
4938 pre->ma_next = map->ma_next;
4939 }
4940
4941 kmem_free(map, sizeof (mac_address_t));
4942 }
4943
4944 /*
4945 * Add a MAC address reference for a client. If the desired MAC address
4946 * exists, add a reference to it. Otherwise, add the new address by adding
4947 * it to a reserved group or setting promiscuous mode. Won't try different
4948 * group is the group is non-NULL, so the caller must explictly share
4949 * default group when needed.
4950 *
4951 * Note, the primary MAC address is initialized at registration time, so
4952 * to add it to default group only need to activate it if its reference
4953 * count is still zero. Also, some drivers may not have advertised RINGS
4954 * capability.
4955 */
4956 int
4957 mac_add_macaddr(mac_impl_t *mip, mac_group_t *group, uint8_t *mac_addr,
4958 boolean_t use_hw)
4959 {
4960 mac_address_t *map;
4961 int err = 0;
4962 boolean_t allocated_map = B_FALSE;
4963
4964 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip));
4965
4966 map = mac_find_macaddr(mip, mac_addr);
4967
4968 /*
4969 * If the new MAC address has not been added. Allocate a new one
4970 * and set it up.
4971 */
4972 if (map == NULL) {
4973 map = kmem_zalloc(sizeof (mac_address_t), KM_SLEEP);
4974 map->ma_len = mip->mi_type->mt_addr_length;
4975 bcopy(mac_addr, map->ma_addr, map->ma_len);
4976 map->ma_nusers = 0;
4977 map->ma_group = group;
4978 map->ma_mip = mip;
4979
4980 /* add the new MAC address to the head of the address list */
4981 map->ma_next = mip->mi_addresses;
4982 mip->mi_addresses = map;
4983
4984 allocated_map = B_TRUE;
4985 }
4986
4987 ASSERT(map->ma_group == NULL || map->ma_group == group);
4988 if (map->ma_group == NULL)
4989 map->ma_group = group;
4990
4991 /*
4992 * If the MAC address is already in use, simply account for the
4993 * new client.
4994 */
4995 if (map->ma_nusers++ > 0)
4996 return (0);
4997
4998 /*
4999 * Activate this MAC address by adding it to the reserved group.
5000 */
5001 if (group != NULL) {
5002 err = mac_group_addmac(group, (const uint8_t *)mac_addr);
5003 if (err == 0) {
5004 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED;
5005 return (0);
5006 }
5007 }
5008
5009 /*
5010 * The MAC address addition failed. If the client requires a
5011 * hardware classified MAC address, fail the operation.
5012 */
5013 if (use_hw) {
5014 err = ENOSPC;
5015 goto bail;
5016 }
5017
5018 /*
5019 * Try promiscuous mode.
5020 *
5021 * For drivers that don't advertise RINGS capability, do
5022 * nothing for the primary address.
5023 */
5024 if ((group == NULL) &&
5025 (bcmp(map->ma_addr, mip->mi_addr, map->ma_len) == 0)) {
5026 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED;
5027 return (0);
5028 }
5029
5030 /*
5031 * Enable promiscuous mode in order to receive traffic
5032 * to the new MAC address.
5033 */
5034 if ((err = i_mac_promisc_set(mip, B_TRUE)) == 0) {
5035 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_PROMISC;
5036 return (0);
5037 }
5038
5039 /*
5040 * Free the MAC address that could not be added. Don't free
5041 * a pre-existing address, it could have been the entry
5042 * for the primary MAC address which was pre-allocated by
5043 * mac_init_macaddr(), and which must remain on the list.
5044 */
5045 bail:
5046 map->ma_nusers--;
5047 if (allocated_map)
5048 mac_free_macaddr(map);
5049 return (err);
5050 }
5051
5052 /*
5053 * Remove a reference to a MAC address. This may cause to remove the MAC
5054 * address from an associated group or to turn off promiscuous mode.
5055 * The caller needs to handle the failure properly.
5056 */
5057 int
5058 mac_remove_macaddr(mac_address_t *map)
5059 {
5060 mac_impl_t *mip = map->ma_mip;
5061 int err = 0;
5062
5063 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip));
5064
5065 ASSERT(map == mac_find_macaddr(mip, map->ma_addr));
5066
5067 /*
5068 * If it's not the last client using this MAC address, only update
5069 * the MAC clients count.
5070 */
5071 if (--map->ma_nusers > 0)
5072 return (0);
5073
5074 /*
5075 * The MAC address is no longer used by any MAC client, so remove
5076 * it from its associated group, or turn off promiscuous mode
5077 * if it was enabled for the MAC address.
5078 */
5079 switch (map->ma_type) {
5080 case MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED:
5081 /*
5082 * Don't free the preset primary address for drivers that
5083 * don't advertise RINGS capability.
5084 */
5085 if (map->ma_group == NULL)
5086 return (0);
5087
5088 err = mac_group_remmac(map->ma_group, map->ma_addr);
5089 if (err == 0)
5090 map->ma_group = NULL;
5091 break;
5092 case MAC_ADDRESS_TYPE_UNICAST_PROMISC:
5093 err = i_mac_promisc_set(mip, B_FALSE);
5094 break;
5095 default:
5096 ASSERT(B_FALSE);
5097 }
5098
5099 if (err != 0)
5100 return (err);
5101
5102 /*
5103 * We created MAC address for the primary one at registration, so we
5104 * won't free it here. mac_fini_macaddr() will take care of it.
5105 */
5106 if (bcmp(map->ma_addr, mip->mi_addr, map->ma_len) != 0)
5107 mac_free_macaddr(map);
5108
5109 return (0);
5110 }
5111
5112 /*
5113 * Update an existing MAC address. The caller need to make sure that the new
5114 * value has not been used.
5115 */
5116 int
5233
5234 mip->mi_addresses = map;
5235 }
5236
5237 /*
5238 * Clean up the primary MAC address. Note, only one primary MAC address
5239 * is allowed. All other MAC addresses must have been freed appropriately.
5240 */
5241 void
5242 mac_fini_macaddr(mac_impl_t *mip)
5243 {
5244 mac_address_t *map = mip->mi_addresses;
5245
5246 if (map == NULL)
5247 return;
5248
5249 /*
5250 * If mi_addresses is initialized, there should be exactly one
5251 * entry left on the list with no users.
5252 */
5253 ASSERT(map->ma_nusers == 0);
5254 ASSERT(map->ma_next == NULL);
5255
5256 kmem_free(map, sizeof (mac_address_t));
5257 mip->mi_addresses = NULL;
5258 }
5259
5260 /*
5261 * Logging related functions.
5262 *
5263 * Note that Kernel statistics have been extended to maintain fine
5264 * granularity of statistics viz. hardware lane, software lane, fanout
5265 * stats etc. However, extended accounting continues to support only
5266 * aggregate statistics like before.
5267 */
5268
5269 /* Write the flow description to a netinfo_t record */
5270 static netinfo_t *
5271 mac_write_flow_desc(flow_entry_t *flent, mac_client_impl_t *mcip)
5272 {
5273 netinfo_t *ninfo;
5274 net_desc_t *ndesc;
5796 mac_flow_log_enable = B_FALSE;
5797 mac_link_log_enable = B_FALSE;
5798 break;
5799 }
5800 /* FALLTHRU */
5801 case MAC_LOGTYPE_LINK:
5802 if (!lstate.mi_lenable || mac_flow_log_enable) {
5803 rw_exit(&i_mac_impl_lock);
5804 return;
5805 }
5806 mac_link_log_enable = B_FALSE;
5807 break;
5808 default:
5809 ASSERT(0);
5810 }
5811
5812 /* Reenable fastpath */
5813 mod_hash_walk(i_mac_impl_hash, i_mac_fastpath_walker, &estate);
5814
5815 (void) untimeout(mac_logging_timer);
5816 mac_logging_timer = 0;
5817
5818 /* Write log entries for each mac_impl in the list */
5819 i_mac_log_info(&net_log_list, &lstate);
5820 }
5821
5822 /*
5823 * Walk the rx and tx SRS/SRs for a flow and update the priority value.
5824 */
5825 void
5826 mac_flow_update_priority(mac_client_impl_t *mcip, flow_entry_t *flent)
5827 {
5828 pri_t pri;
5829 int count;
5830 mac_soft_ring_set_t *mac_srs;
5831
5832 if (flent->fe_rx_srs_cnt <= 0)
5833 return;
5834
5835 if (((mac_soft_ring_set_t *)flent->fe_rx_srs[0])->srs_type ==
5836 SRST_FLOW) {
5914 }
5915 /*
5916 * There are clients using this ring, so let's move the clients
5917 * away from using this ring.
5918 */
5919 for (mgcp = group->mrg_clients; mgcp != NULL; mgcp = mgcp->mgc_next) {
5920 mcip = mgcp->mgc_client;
5921 mac_tx_client_quiesce((mac_client_handle_t)mcip);
5922 srs = MCIP_TX_SRS(mcip);
5923 ASSERT(mac_tx_srs_ring_present(srs, desired_ring));
5924 mac_tx_invoke_callbacks(mcip,
5925 (mac_tx_cookie_t)mac_tx_srs_get_soft_ring(srs,
5926 desired_ring));
5927 mac_tx_srs_del_ring(srs, desired_ring);
5928 mac_tx_client_restart((mac_client_handle_t)mcip);
5929 }
5930 return (desired_ring);
5931 }
5932
5933 /*
5934 * For a reserved group with multiple clients, return the primary client.
5935 */
5936 static mac_client_impl_t *
5937 mac_get_grp_primary(mac_group_t *grp)
5938 {
5939 mac_grp_client_t *mgcp = grp->mrg_clients;
5940 mac_client_impl_t *mcip;
5941
5942 while (mgcp != NULL) {
5943 mcip = mgcp->mgc_client;
5944 if (mcip->mci_flent->fe_type & FLOW_PRIMARY_MAC)
5945 return (mcip);
5946 mgcp = mgcp->mgc_next;
5947 }
5948 return (NULL);
5949 }
5950
5951 /*
5952 * Hybrid I/O specifies the ring that should be given to a share.
5953 * If the ring is already used by clients, then we need to release
5954 * the ring back to the default group so that we can give it to
6273 if (share != 0)
6274 mip->mi_share_capab.ms_sadd(share, new_group->mrg_driver);
6275
6276 bail:
6277 /* free temporary array of rings */
6278 kmem_free(rings, nrings * sizeof (mac_ring_handle_t));
6279
6280 return (rv);
6281 }
6282
6283 void
6284 mac_group_add_client(mac_group_t *grp, mac_client_impl_t *mcip)
6285 {
6286 mac_grp_client_t *mgcp;
6287
6288 for (mgcp = grp->mrg_clients; mgcp != NULL; mgcp = mgcp->mgc_next) {
6289 if (mgcp->mgc_client == mcip)
6290 break;
6291 }
6292
6293 VERIFY(mgcp == NULL);
6294
6295 mgcp = kmem_zalloc(sizeof (mac_grp_client_t), KM_SLEEP);
6296 mgcp->mgc_client = mcip;
6297 mgcp->mgc_next = grp->mrg_clients;
6298 grp->mrg_clients = mgcp;
6299
6300 }
6301
6302 void
6303 mac_group_remove_client(mac_group_t *grp, mac_client_impl_t *mcip)
6304 {
6305 mac_grp_client_t *mgcp, **pprev;
6306
6307 for (pprev = &grp->mrg_clients, mgcp = *pprev; mgcp != NULL;
6308 pprev = &mgcp->mgc_next, mgcp = *pprev) {
6309 if (mgcp->mgc_client == mcip)
6310 break;
6311 }
6312
6313 ASSERT(mgcp != NULL);
6314
6315 *pprev = mgcp->mgc_next;
6316 kmem_free(mgcp, sizeof (mac_grp_client_t));
6317 }
6318
6319 /*
6320 * mac_reserve_rx_group()
6321 *
6322 * Finds an available group and exclusively reserves it for a client.
6323 * The group is chosen to suit the flow's resource controls (bandwidth and
6324 * fanout requirements) and the address type.
6325 * If the requestor is the pimary MAC then return the group with the
6326 * largest number of rings, otherwise the default ring when available.
6327 */
6328 mac_group_t *
6329 mac_reserve_rx_group(mac_client_impl_t *mcip, uint8_t *mac_addr, boolean_t move)
6330 {
6331 mac_share_handle_t share = mcip->mci_share;
6332 mac_impl_t *mip = mcip->mci_mip;
6333 mac_group_t *grp = NULL;
6334 int i;
6335 int err = 0;
6336 mac_address_t *map;
6337 mac_resource_props_t *mrp = MCIP_RESOURCE_PROPS(mcip);
6338 int nrings;
6339 int donor_grp_rcnt;
6340 boolean_t need_exclgrp = B_FALSE;
6341 int need_rings = 0;
6342 mac_group_t *candidate_grp = NULL;
6343 mac_client_impl_t *gclient;
6344 mac_resource_props_t *gmrp;
6345 mac_group_t *donorgrp = NULL;
6346 boolean_t rxhw = mrp->mrp_mask & MRP_RX_RINGS;
6347 boolean_t unspec = mrp->mrp_mask & MRP_RXRINGS_UNSPEC;
6348 boolean_t isprimary;
6349
6350 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip));
6351
6352 isprimary = mcip->mci_flent->fe_type & FLOW_PRIMARY_MAC;
6353
6354 /*
6355 * Check if a group already has this mac address (case of VLANs)
6356 * unless we are moving this MAC client from one group to another.
6357 */
6358 if (!move && (map = mac_find_macaddr(mip, mac_addr)) != NULL) {
6359 if (map->ma_group != NULL)
6360 return (map->ma_group);
6361 }
6362 if (mip->mi_rx_groups == NULL || mip->mi_rx_group_count == 0)
6363 return (NULL);
6364 /*
6365 * If exclusive open, return NULL which will enable the
6366 * caller to use the default group.
6367 */
6368 if (mcip->mci_state_flags & MCIS_EXCLUSIVE)
6369 return (NULL);
6370
6371 /* For dynamic groups default unspecified to 1 */
6372 if (rxhw && unspec &&
6373 mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) {
6374 mrp->mrp_nrxrings = 1;
6375 }
6376 /*
6377 * For static grouping we allow only specifying rings=0 and
6378 * unspecified
6379 */
6380 if (rxhw && mrp->mrp_nrxrings > 0 &&
6381 mip->mi_rx_group_type == MAC_GROUP_TYPE_STATIC) {
6382 return (NULL);
6383 }
6384 if (rxhw) {
6385 /*
6386 * We have explicitly asked for a group (with nrxrings,
6387 * if unspec).
6388 */
6389 if (unspec || mrp->mrp_nrxrings > 0) {
6390 need_exclgrp = B_TRUE;
6391 need_rings = mrp->mrp_nrxrings;
6392 } else if (mrp->mrp_nrxrings == 0) {
6393 /*
6394 * We have asked for a software group.
6395 */
6396 return (NULL);
6397 }
6398 } else if (isprimary && mip->mi_nactiveclients == 1 &&
6399 mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) {
6400 /*
6401 * If the primary is the only active client on this
6402 * mip and we have not asked for any rings, we give
6403 * it the default group so that the primary gets to
6425 * For flows requiring HW_RING (unicast flow of other clients), try
6426 * to reserve non-default RX group with the specified number of
6427 * rings, if available.
6428 *
6429 * For flows that have not asked for software or hardware ring,
6430 * try to reserve a non-default group with 1 ring, if available.
6431 */
6432 for (i = 1; i < mip->mi_rx_group_count; i++) {
6433 grp = &mip->mi_rx_groups[i];
6434
6435 DTRACE_PROBE3(rx__group__trying, char *, mip->mi_name,
6436 int, grp->mrg_index, mac_group_state_t, grp->mrg_state);
6437
6438 /*
6439 * Check if this group could be a candidate group for
6440 * eviction if we need a group for this MAC client,
6441 * but there aren't any. A candidate group is one
6442 * that didn't ask for an exclusive group, but got
6443 * one and it has enough rings (combined with what
6444 * the donor group can donate) for the new MAC
6445 * client
6446 */
6447 if (grp->mrg_state >= MAC_GROUP_STATE_RESERVED) {
6448 /*
6449 * If the primary/donor group is not the default
6450 * group, don't bother looking for a candidate group.
6451 * If we don't have enough rings we will check
6452 * if the primary group can be vacated.
6453 */
6454 if (candidate_grp == NULL &&
6455 donorgrp == MAC_DEFAULT_RX_GROUP(mip)) {
6456 ASSERT(!MAC_GROUP_NO_CLIENT(grp));
6457 gclient = MAC_GROUP_ONLY_CLIENT(grp);
6458 if (gclient == NULL)
6459 gclient = mac_get_grp_primary(grp);
6460 ASSERT(gclient != NULL);
6461 gmrp = MCIP_RESOURCE_PROPS(gclient);
6462 if (gclient->mci_share == 0 &&
6463 (gmrp->mrp_mask & MRP_RX_RINGS) == 0 &&
6464 (unspec ||
6465 (grp->mrg_cur_count + donor_grp_rcnt >=
6466 need_rings))) {
6467 candidate_grp = grp;
6468 }
6469 }
6470 continue;
6471 }
6472 /*
6473 * This group could already be SHARED by other multicast
6474 * flows on this client. In that case, the group would
6475 * be shared and has already been started.
6476 */
6477 ASSERT(grp->mrg_state != MAC_GROUP_STATE_UNINIT);
6478
6479 if ((grp->mrg_state == MAC_GROUP_STATE_REGISTERED) &&
6480 (mac_start_group(grp) != 0)) {
6481 continue;
6482 }
6483
6509 if (share != 0) {
6510 mac_client_set_rings(
6511 (mac_client_handle_t)mcip,
6512 grp->mrg_cur_count, -1);
6513 }
6514 if (mac_is_primary_client(mcip) && !rxhw)
6515 mip->mi_rx_donor_grp = grp;
6516 break;
6517 }
6518 }
6519
6520 DTRACE_PROBE3(rx__group__reserve__alloc__rings, char *,
6521 mip->mi_name, int, grp->mrg_index, int, err);
6522
6523 /*
6524 * It's a dynamic group but the grouping operation
6525 * failed.
6526 */
6527 mac_stop_group(grp);
6528 }
6529 /* We didn't find an exclusive group for this MAC client */
6530 if (i >= mip->mi_rx_group_count) {
6531
6532 if (!need_exclgrp)
6533 return (NULL);
6534
6535 /*
6536 * If we found a candidate group then we switch the
6537 * MAC client from the candidate_group to the default
6538 * group and give the group to this MAC client. If
6539 * we didn't find a candidate_group, check if the
6540 * primary is in its own group and if it can make way
6541 * for this MAC client.
6542 */
6543 if (candidate_grp == NULL &&
6544 donorgrp != MAC_DEFAULT_RX_GROUP(mip) &&
6545 donorgrp->mrg_cur_count >= need_rings) {
6546 candidate_grp = donorgrp;
6547 }
6548 if (candidate_grp != NULL) {
6549 boolean_t prim_grp = B_FALSE;
6550
6551 /*
6552 * Switch the MAC client from the candidate group
6553 * to the default group.. If this group was the
6554 * donor group, then after the switch we need
6555 * to update the donor group too.
6556 */
6557 grp = candidate_grp;
6558 gclient = MAC_GROUP_ONLY_CLIENT(grp);
6559 if (gclient == NULL)
6560 gclient = mac_get_grp_primary(grp);
6561 if (grp == mip->mi_rx_donor_grp)
6562 prim_grp = B_TRUE;
6563 if (mac_rx_switch_group(gclient, grp,
6564 MAC_DEFAULT_RX_GROUP(mip)) != 0) {
6565 return (NULL);
6566 }
6567 if (prim_grp) {
6568 mip->mi_rx_donor_grp =
6569 MAC_DEFAULT_RX_GROUP(mip);
6570 donorgrp = MAC_DEFAULT_RX_GROUP(mip);
6571 }
6572
6573
6574 /*
6575 * Now give this group with the required rings
6576 * to this MAC client.
6577 */
6578 ASSERT(grp->mrg_state == MAC_GROUP_STATE_REGISTERED);
6579 if (mac_start_group(grp) != 0)
6580 return (NULL);
6581
6582 if (mip->mi_rx_group_type != MAC_GROUP_TYPE_DYNAMIC)
6583 return (grp);
6584
6585 donor_grp_rcnt = donorgrp->mrg_cur_count - 1;
6586 ASSERT(grp->mrg_cur_count == 0);
6587 ASSERT(donor_grp_rcnt >= need_rings);
6588 err = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_RX,
6589 donorgrp, grp, share, need_rings);
6590 if (err == 0) {
6591 /*
6592 * For a share i_mac_group_allocate_rings gets
6593 * the rings from the driver, let's populate
6601 DTRACE_PROBE2(rx__group__reserved,
6602 char *, mip->mi_name, int, grp->mrg_index);
6603 return (grp);
6604 }
6605 DTRACE_PROBE3(rx__group__reserve__alloc__rings, char *,
6606 mip->mi_name, int, grp->mrg_index, int, err);
6607 mac_stop_group(grp);
6608 }
6609 return (NULL);
6610 }
6611 ASSERT(grp != NULL);
6612
6613 DTRACE_PROBE2(rx__group__reserved,
6614 char *, mip->mi_name, int, grp->mrg_index);
6615 return (grp);
6616 }
6617
6618 /*
6619 * mac_rx_release_group()
6620 *
6621 * This is called when there are no clients left for the group.
6622 * The group is stopped and marked MAC_GROUP_STATE_REGISTERED,
6623 * and if it is a non default group, the shares are removed and
6624 * all rings are assigned back to default group.
6625 */
6626 void
6627 mac_release_rx_group(mac_client_impl_t *mcip, mac_group_t *group)
6628 {
6629 mac_impl_t *mip = mcip->mci_mip;
6630 mac_ring_t *ring;
6631
6632 ASSERT(group != MAC_DEFAULT_RX_GROUP(mip));
6633
6634 if (mip->mi_rx_donor_grp == group)
6635 mip->mi_rx_donor_grp = MAC_DEFAULT_RX_GROUP(mip);
6636
6637 /*
6638 * This is the case where there are no clients left. Any
6639 * SRS etc on this group have also be quiesced.
6640 */
6641 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) {
6642 if (ring->mr_classify_type == MAC_HW_CLASSIFIER) {
6643 ASSERT(group->mrg_state == MAC_GROUP_STATE_RESERVED);
6644 /*
6645 * Remove the SRS associated with the HW ring.
6646 * As a result, polling will be disabled.
6647 */
6648 ring->mr_srs = NULL;
6649 }
6650 ASSERT(group->mrg_state < MAC_GROUP_STATE_RESERVED ||
6651 ring->mr_state == MR_INUSE);
6652 if (ring->mr_state == MR_INUSE) {
6664 if (mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) {
6665 mac_ring_t *ring;
6666
6667 /*
6668 * Rings were dynamically allocated to group.
6669 * Move rings back to default group.
6670 */
6671 while ((ring = group->mrg_rings) != NULL) {
6672 (void) mac_group_mov_ring(mip, mip->mi_rx_donor_grp,
6673 ring);
6674 }
6675 }
6676 mac_stop_group(group);
6677 /*
6678 * Possible improvement: See if we can assign the group just released
6679 * to a another client of the mip
6680 */
6681 }
6682
6683 /*
6684 * When we move the primary's mac address between groups, we need to also
6685 * take all the clients sharing the same mac address along with it (VLANs)
6686 * We remove the mac address for such clients from the group after quiescing
6687 * them. When we add the mac address we restart the client. Note that
6688 * the primary's mac address is removed from the group after all the
6689 * other clients sharing the address are removed. Similarly, the primary's
6690 * mac address is added before all the other client's mac address are
6691 * added. While grp is the group where the clients reside, tgrp is
6692 * the group where the addresses have to be added.
6693 */
6694 static void
6695 mac_rx_move_macaddr_prim(mac_client_impl_t *mcip, mac_group_t *grp,
6696 mac_group_t *tgrp, uint8_t *maddr, boolean_t add)
6697 {
6698 mac_impl_t *mip = mcip->mci_mip;
6699 mac_grp_client_t *mgcp = grp->mrg_clients;
6700 mac_client_impl_t *gmcip;
6701 boolean_t prim;
6702
6703 prim = (mcip->mci_state_flags & MCIS_UNICAST_HW) != 0;
6704
6705 /*
6706 * If the clients are in a non-default group, we just have to
6707 * walk the group's client list. If it is in the default group
6708 * (which will be shared by other clients as well, we need to
6709 * check if the unicast address matches mcip's unicast.
6710 */
6711 while (mgcp != NULL) {
6712 gmcip = mgcp->mgc_client;
6713 if (gmcip != mcip &&
6714 (grp != MAC_DEFAULT_RX_GROUP(mip) ||
6715 mcip->mci_unicast == gmcip->mci_unicast)) {
6716 if (!add) {
6717 mac_rx_client_quiesce(
6718 (mac_client_handle_t)gmcip);
6719 (void) mac_remove_macaddr(mcip->mci_unicast);
6720 } else {
6721 (void) mac_add_macaddr(mip, tgrp, maddr, prim);
6722 mac_rx_client_restart(
6723 (mac_client_handle_t)gmcip);
6724 }
6725 }
6726 mgcp = mgcp->mgc_next;
6727 }
6728 }
6729
6730
6731 /*
6732 * Move the MAC address from fgrp to tgrp. If this is the primary client,
6733 * we need to take any VLANs etc. together too.
6734 */
6735 static int
6736 mac_rx_move_macaddr(mac_client_impl_t *mcip, mac_group_t *fgrp,
6737 mac_group_t *tgrp)
6738 {
6739 mac_impl_t *mip = mcip->mci_mip;
6740 uint8_t maddr[MAXMACADDRLEN];
6741 int err = 0;
6742 boolean_t prim;
6743 boolean_t multiclnt = B_FALSE;
6744
6745 mac_rx_client_quiesce((mac_client_handle_t)mcip);
6746 ASSERT(mcip->mci_unicast != NULL);
6747 bcopy(mcip->mci_unicast->ma_addr, maddr, mcip->mci_unicast->ma_len);
6748
6749 prim = (mcip->mci_state_flags & MCIS_UNICAST_HW) != 0;
6750 if (mcip->mci_unicast->ma_nusers > 1) {
6751 mac_rx_move_macaddr_prim(mcip, fgrp, NULL, maddr, B_FALSE);
6752 multiclnt = B_TRUE;
6753 }
6754 ASSERT(mcip->mci_unicast->ma_nusers == 1);
6755 err = mac_remove_macaddr(mcip->mci_unicast);
6756 if (err != 0) {
6757 mac_rx_client_restart((mac_client_handle_t)mcip);
6758 if (multiclnt) {
6759 mac_rx_move_macaddr_prim(mcip, fgrp, fgrp, maddr,
6760 B_TRUE);
6761 }
6762 return (err);
6763 }
6764 /*
6765 * Program the H/W Classifier first, if this fails we need
6766 * not proceed with the other stuff.
6767 */
6768 if ((err = mac_add_macaddr(mip, tgrp, maddr, prim)) != 0) {
6769 /* Revert back the H/W Classifier */
6770 if ((err = mac_add_macaddr(mip, fgrp, maddr, prim)) != 0) {
6771 /*
6772 * This should not fail now since it worked earlier,
6773 * should we panic?
6774 */
6775 cmn_err(CE_WARN,
6776 "mac_rx_switch_group: switching %p back"
6777 " to group %p failed!!", (void *)mcip,
6778 (void *)fgrp);
6779 }
6780 mac_rx_client_restart((mac_client_handle_t)mcip);
6781 if (multiclnt) {
6782 mac_rx_move_macaddr_prim(mcip, fgrp, fgrp, maddr,
6783 B_TRUE);
6784 }
6785 return (err);
6786 }
6787 mcip->mci_unicast = mac_find_macaddr(mip, maddr);
6788 mac_rx_client_restart((mac_client_handle_t)mcip);
6789 if (multiclnt)
6790 mac_rx_move_macaddr_prim(mcip, fgrp, tgrp, maddr, B_TRUE);
6791 return (err);
6792 }
6793
6794 /*
6795 * Switch the MAC client from one group to another. This means we need
6796 * to remove the MAC address from the group, remove the MAC client,
6797 * teardown the SRSs and revert the group state. Then, we add the client
6798 * to the destination group, set the SRSs, and add the MAC address to the
6799 * group.
6800 */
6801 int
6802 mac_rx_switch_group(mac_client_impl_t *mcip, mac_group_t *fgrp,
6803 mac_group_t *tgrp)
6804 {
6805 int err;
6806 mac_group_state_t next_state;
6807 mac_client_impl_t *group_only_mcip;
6808 mac_client_impl_t *gmcip;
6809 mac_impl_t *mip = mcip->mci_mip;
6810 mac_grp_client_t *mgcp;
6811
6812 ASSERT(fgrp == mcip->mci_flent->fe_rx_ring_group);
6813
6814 if ((err = mac_rx_move_macaddr(mcip, fgrp, tgrp)) != 0)
6815 return (err);
6816
6817 /*
6818 * The group might be reserved, but SRSs may not be set up, e.g.
6819 * primary and its vlans using a reserved group.
6820 */
6821 if (fgrp->mrg_state == MAC_GROUP_STATE_RESERVED &&
6822 MAC_GROUP_ONLY_CLIENT(fgrp) != NULL) {
6823 mac_rx_srs_group_teardown(mcip->mci_flent, B_TRUE);
6824 }
6825 if (fgrp != MAC_DEFAULT_RX_GROUP(mip)) {
6826 mgcp = fgrp->mrg_clients;
6827 while (mgcp != NULL) {
6828 gmcip = mgcp->mgc_client;
6829 mgcp = mgcp->mgc_next;
6830 mac_group_remove_client(fgrp, gmcip);
6831 mac_group_add_client(tgrp, gmcip);
6832 gmcip->mci_flent->fe_rx_ring_group = tgrp;
6833 }
6834 mac_release_rx_group(mcip, fgrp);
6835 ASSERT(MAC_GROUP_NO_CLIENT(fgrp));
6836 mac_set_group_state(fgrp, MAC_GROUP_STATE_REGISTERED);
6837 } else {
6838 mac_group_remove_client(fgrp, mcip);
6839 mac_group_add_client(tgrp, mcip);
6840 mcip->mci_flent->fe_rx_ring_group = tgrp;
6841 /*
6842 * If there are other clients (VLANs) sharing this address
6843 * we should be here only for the primary.
6844 */
6845 if (mcip->mci_unicast->ma_nusers > 1) {
6846 /*
6847 * We need to move all the clients that are using
6848 * this h/w address.
6849 */
6850 mgcp = fgrp->mrg_clients;
6851 while (mgcp != NULL) {
6852 gmcip = mgcp->mgc_client;
6853 mgcp = mgcp->mgc_next;
6854 if (mcip->mci_unicast == gmcip->mci_unicast) {
6855 mac_group_remove_client(fgrp, gmcip);
6856 mac_group_add_client(tgrp, gmcip);
6857 gmcip->mci_flent->fe_rx_ring_group =
6858 tgrp;
6859 }
6860 }
6861 }
6862 /*
6863 * The default group will still take the multicast,
6864 * broadcast traffic etc., so it won't go to
6865 * MAC_GROUP_STATE_REGISTERED.
6866 */
6867 if (fgrp->mrg_state == MAC_GROUP_STATE_RESERVED)
6868 mac_rx_group_unmark(fgrp, MR_CONDEMNED);
6869 mac_set_group_state(fgrp, MAC_GROUP_STATE_SHARED);
6870 }
6871 next_state = mac_group_next_state(tgrp, &group_only_mcip,
6872 MAC_DEFAULT_RX_GROUP(mip), B_TRUE);
6873 mac_set_group_state(tgrp, next_state);
6874 /*
6875 * If the destination group is reserved, setup the SRSs etc.
6876 */
6877 if (tgrp->mrg_state == MAC_GROUP_STATE_RESERVED) {
6878 mac_rx_srs_group_setup(mcip, mcip->mci_flent, SRST_LINK);
6879 mac_fanout_setup(mcip, mcip->mci_flent,
6880 MCIP_RESOURCE_PROPS(mcip), mac_rx_deliver, mcip, NULL,
6881 NULL);
6882 mac_rx_group_unmark(tgrp, MR_INCIPIENT);
6883 } else {
6884 mac_rx_switch_grp_to_sw(tgrp);
6885 }
6886 return (0);
6887 }
6888
6889 /*
6890 * Reserves a TX group for the specified share. Invoked by mac_tx_srs_setup()
6891 * when a share was allocated to the client.
6892 */
6893 mac_group_t *
6894 mac_reserve_tx_group(mac_client_impl_t *mcip, boolean_t move)
6895 {
6896 mac_impl_t *mip = mcip->mci_mip;
6897 mac_group_t *grp = NULL;
6898 int rv;
6899 int i;
6900 int err;
6901 mac_group_t *defgrp;
6902 mac_share_handle_t share = mcip->mci_share;
6903 mac_resource_props_t *mrp = MCIP_RESOURCE_PROPS(mcip);
6904 int nrings;
6905 int defnrings;
6906 boolean_t need_exclgrp = B_FALSE;
6907 int need_rings = 0;
6908 mac_group_t *candidate_grp = NULL;
6909 mac_client_impl_t *gclient;
6910 mac_resource_props_t *gmrp;
6911 boolean_t txhw = mrp->mrp_mask & MRP_TX_RINGS;
6912 boolean_t unspec = mrp->mrp_mask & MRP_TXRINGS_UNSPEC;
6913 boolean_t isprimary;
6914
6915 isprimary = mcip->mci_flent->fe_type & FLOW_PRIMARY_MAC;
6916 /*
6917 * When we come here for a VLAN on the primary (dladm create-vlan),
6918 * we need to pair it along with the primary (to keep it consistent
6919 * with the RX side). So, we check if the primary is already assigned
6920 * to a group and return the group if so. The other way is also
6921 * true, i.e. the VLAN is already created and now we are plumbing
6922 * the primary.
6923 */
6924 if (!move && isprimary) {
6925 for (gclient = mip->mi_clients_list; gclient != NULL;
6926 gclient = gclient->mci_client_next) {
6927 if (gclient->mci_flent->fe_type & FLOW_PRIMARY_MAC &&
6928 gclient->mci_flent->fe_tx_ring_group != NULL) {
6929 return (gclient->mci_flent->fe_tx_ring_group);
6930 }
6931 }
6932 }
6933
6934 if (mip->mi_tx_groups == NULL || mip->mi_tx_group_count == 0)
6935 return (NULL);
6977 */
6978 if (isprimary && !need_exclgrp)
6979 return (NULL);
6980
6981 nrings = (mrp->mrp_mask & MRP_TX_RINGS) != 0 ? mrp->mrp_ntxrings : 1;
6982 for (i = 0; i < mip->mi_tx_group_count; i++) {
6983 grp = &mip->mi_tx_groups[i];
6984 if ((grp->mrg_state == MAC_GROUP_STATE_RESERVED) ||
6985 (grp->mrg_state == MAC_GROUP_STATE_UNINIT)) {
6986 /*
6987 * Select a candidate for replacement if we don't
6988 * get an exclusive group. A candidate group is one
6989 * that didn't ask for an exclusive group, but got
6990 * one and it has enough rings (combined with what
6991 * the default group can donate) for the new MAC
6992 * client.
6993 */
6994 if (grp->mrg_state == MAC_GROUP_STATE_RESERVED &&
6995 candidate_grp == NULL) {
6996 gclient = MAC_GROUP_ONLY_CLIENT(grp);
6997 if (gclient == NULL)
6998 gclient = mac_get_grp_primary(grp);
6999 gmrp = MCIP_RESOURCE_PROPS(gclient);
7000 if (gclient->mci_share == 0 &&
7001 (gmrp->mrp_mask & MRP_TX_RINGS) == 0 &&
7002 (unspec ||
7003 (grp->mrg_cur_count + defnrings) >=
7004 need_rings)) {
7005 candidate_grp = grp;
7006 }
7007 }
7008 continue;
7009 }
7010 /*
7011 * If the default can't donate let's just walk and
7012 * see if someone can vacate a group, so that we have
7013 * enough rings for this.
7014 */
7015 if (mip->mi_tx_group_type != MAC_GROUP_TYPE_DYNAMIC ||
7016 nrings <= defnrings) {
7017 if (grp->mrg_state == MAC_GROUP_STATE_REGISTERED) {
7018 rv = mac_start_group(grp);
7019 ASSERT(rv == 0);
7020 }
7021 break;
7022 }
7023 }
7024
7025 /* The default group */
7026 if (i >= mip->mi_tx_group_count) {
7027 /*
7028 * If we need an exclusive group and have identified a
7029 * candidate group we switch the MAC client from the
7030 * candidate group to the default group and give the
7031 * candidate group to this client.
7032 */
7033 if (need_exclgrp && candidate_grp != NULL) {
7034 /*
7035 * Switch the MAC client from the candidate group
7036 * to the default group.
7037 */
7038 grp = candidate_grp;
7039 gclient = MAC_GROUP_ONLY_CLIENT(grp);
7040 if (gclient == NULL)
7041 gclient = mac_get_grp_primary(grp);
7042 mac_tx_client_quiesce((mac_client_handle_t)gclient);
7043 mac_tx_switch_group(gclient, grp, defgrp);
7044 mac_tx_client_restart((mac_client_handle_t)gclient);
7045
7046 /*
7047 * Give the candidate group with the specified number
7048 * of rings to this MAC client.
7049 */
7050 ASSERT(grp->mrg_state == MAC_GROUP_STATE_REGISTERED);
7051 rv = mac_start_group(grp);
7052 ASSERT(rv == 0);
7053
7054 if (mip->mi_tx_group_type != MAC_GROUP_TYPE_DYNAMIC)
7055 return (grp);
7056
7057 ASSERT(grp->mrg_cur_count == 0);
7058 ASSERT(defgrp->mrg_cur_count > need_rings);
7059
7060 err = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_TX,
7061 defgrp, grp, share, need_rings);
7189 mac_group_t *tgrp)
7190 {
7191 mac_client_impl_t *group_only_mcip;
7192 mac_impl_t *mip = mcip->mci_mip;
7193 flow_entry_t *flent = mcip->mci_flent;
7194 mac_group_t *defgrp;
7195 mac_grp_client_t *mgcp;
7196 mac_client_impl_t *gmcip;
7197 flow_entry_t *gflent;
7198
7199 defgrp = MAC_DEFAULT_TX_GROUP(mip);
7200 ASSERT(fgrp == flent->fe_tx_ring_group);
7201
7202 if (fgrp == defgrp) {
7203 /*
7204 * If this is the primary we need to find any VLANs on
7205 * the primary and move them too.
7206 */
7207 mac_group_remove_client(fgrp, mcip);
7208 mac_tx_dismantle_soft_rings(fgrp, flent);
7209 if (mcip->mci_unicast->ma_nusers > 1) {
7210 mgcp = fgrp->mrg_clients;
7211 while (mgcp != NULL) {
7212 gmcip = mgcp->mgc_client;
7213 mgcp = mgcp->mgc_next;
7214 if (mcip->mci_unicast != gmcip->mci_unicast)
7215 continue;
7216 mac_tx_client_quiesce(
7217 (mac_client_handle_t)gmcip);
7218
7219 gflent = gmcip->mci_flent;
7220 mac_group_remove_client(fgrp, gmcip);
7221 mac_tx_dismantle_soft_rings(fgrp, gflent);
7222
7223 mac_group_add_client(tgrp, gmcip);
7224 gflent->fe_tx_ring_group = tgrp;
7225 /* We could directly set this to SHARED */
7226 tgrp->mrg_state = mac_group_next_state(tgrp,
7227 &group_only_mcip, defgrp, B_FALSE);
7228
7229 mac_tx_srs_group_setup(gmcip, gflent,
7435 mutex_exit(&mip->mi_bridge_lock);
7436 mac_poll_state_change(mh, B_TRUE);
7437 mac_capab_update(mh);
7438 }
7439
7440 void
7441 mac_no_active(mac_handle_t mh)
7442 {
7443 mac_impl_t *mip = (mac_impl_t *)mh;
7444
7445 i_mac_perim_enter(mip);
7446 mip->mi_state_flags |= MIS_NO_ACTIVE;
7447 i_mac_perim_exit(mip);
7448 }
7449
7450 /*
7451 * Walk the primary VLAN clients whenever the primary's rings property
7452 * changes and update the mac_resource_props_t for the VLAN's client.
7453 * We need to do this since we don't support setting these properties
7454 * on the primary's VLAN clients, but the VLAN clients have to
7455 * follow the primary w.r.t the rings property;
7456 */
7457 void
7458 mac_set_prim_vlan_rings(mac_impl_t *mip, mac_resource_props_t *mrp)
7459 {
7460 mac_client_impl_t *vmcip;
7461 mac_resource_props_t *vmrp;
7462
7463 for (vmcip = mip->mi_clients_list; vmcip != NULL;
7464 vmcip = vmcip->mci_client_next) {
7465 if (!(vmcip->mci_flent->fe_type & FLOW_PRIMARY_MAC) ||
7466 mac_client_vid((mac_client_handle_t)vmcip) ==
7467 VLAN_ID_NONE) {
7468 continue;
7469 }
7470 vmrp = MCIP_RESOURCE_PROPS(vmcip);
7471
7472 vmrp->mrp_nrxrings = mrp->mrp_nrxrings;
7473 if (mrp->mrp_mask & MRP_RX_RINGS)
7474 vmrp->mrp_mask |= MRP_RX_RINGS;
7475 else if (vmrp->mrp_mask & MRP_RX_RINGS)
7584 start = 1;
7585 end = mip->mi_rx_group_count;
7586 } else {
7587 start = 0;
7588 end = mip->mi_tx_group_count - 1;
7589 }
7590 /*
7591 * If the default doesn't have any rings, lets see if we can
7592 * take rings given to an h/w client that doesn't need it.
7593 * For now, we just see if there is any one client that can donate
7594 * all the required rings.
7595 */
7596 if (defgrp->mrg_cur_count < (modify + 1)) {
7597 for (i = start; i < end; i++) {
7598 if (rx_group) {
7599 tgrp = &mip->mi_rx_groups[i];
7600 if (tgrp == group || tgrp->mrg_state <
7601 MAC_GROUP_STATE_RESERVED) {
7602 continue;
7603 }
7604 mcip = MAC_GROUP_ONLY_CLIENT(tgrp);
7605 if (mcip == NULL)
7606 mcip = mac_get_grp_primary(tgrp);
7607 ASSERT(mcip != NULL);
7608 mrp = MCIP_RESOURCE_PROPS(mcip);
7609 if ((mrp->mrp_mask & MRP_RX_RINGS) != 0)
7610 continue;
7611 if ((tgrp->mrg_cur_count +
7612 defgrp->mrg_cur_count) < (modify + 1)) {
7613 continue;
7614 }
7615 if (mac_rx_switch_group(mcip, tgrp,
7616 defgrp) != 0) {
7617 return (ENOSPC);
7618 }
7619 } else {
7620 tgrp = &mip->mi_tx_groups[i];
7621 if (tgrp == group || tgrp->mrg_state <
7622 MAC_GROUP_STATE_RESERVED) {
7623 continue;
7624 }
7625 mcip = MAC_GROUP_ONLY_CLIENT(tgrp);
7626 if (mcip == NULL)
7627 mcip = mac_get_grp_primary(tgrp);
7628 mrp = MCIP_RESOURCE_PROPS(mcip);
7629 if ((mrp->mrp_mask & MRP_TX_RINGS) != 0)
7630 continue;
7631 if ((tgrp->mrg_cur_count +
7632 defgrp->mrg_cur_count) < (modify + 1)) {
7633 continue;
7634 }
7635 /* OK, we can switch this to s/w */
7636 mac_tx_client_quiesce(
7637 (mac_client_handle_t)mcip);
7638 mac_tx_switch_group(mcip, tgrp, defgrp);
7639 mac_tx_client_restart(
7640 (mac_client_handle_t)mcip);
7641 }
7642 }
7643 if (defgrp->mrg_cur_count < (modify + 1))
7644 return (ENOSPC);
7645 }
7646 if ((rv = i_mac_group_allocate_rings(mip, group->mrg_type, defgrp,
7647 group, mcip->mci_share, modify)) != 0) {
7648 return (rv);
7649 }
7650 return (0);
7883
7884 default:
7885 kmem_free(mpa, sizeof (struct mac_pool_arg));
7886 pool_unlock();
7887 return;
7888 }
7889 pool_unlock();
7890
7891 mpa->mpa_what = what;
7892
7893 mac_pool_update(mpa);
7894 }
7895
7896 /*
7897 * Set effective rings property. This could be called from datapath_setup/
7898 * datapath_teardown or set-linkprop.
7899 * If the group is reserved we just go ahead and set the effective rings.
7900 * Additionally, for TX this could mean the default group has lost/gained
7901 * some rings, so if the default group is reserved, we need to adjust the
7902 * effective rings for the default group clients. For RX, if we are working
7903 * with the non-default group, we just need * to reset the effective props
7904 * for the default group clients.
7905 */
7906 void
7907 mac_set_rings_effective(mac_client_impl_t *mcip)
7908 {
7909 mac_impl_t *mip = mcip->mci_mip;
7910 mac_group_t *grp;
7911 mac_group_t *defgrp;
7912 flow_entry_t *flent = mcip->mci_flent;
7913 mac_resource_props_t *emrp = MCIP_EFFECTIVE_PROPS(mcip);
7914 mac_grp_client_t *mgcp;
7915 mac_client_impl_t *gmcip;
7916
7917 grp = flent->fe_rx_ring_group;
7918 if (grp != NULL) {
7919 defgrp = MAC_DEFAULT_RX_GROUP(mip);
7920 /*
7921 * If we have reserved a group, set the effective rings
7922 * to the ring count in the group.
7923 */
8013 * Check if the primary is in the default group, if not
8014 * or if it is explicitly configured to be in the default
8015 * group OR set the RX rings property, return.
8016 */
8017 if (flent->fe_rx_ring_group != defgrp || mrp->mrp_mask & MRP_RX_RINGS)
8018 return (NULL);
8019
8020 /*
8021 * If the new client needs an exclusive group and we
8022 * don't have another for the primary, return.
8023 */
8024 if (rxhw && mip->mi_rxhwclnt_avail < 2)
8025 return (NULL);
8026
8027 mac_addr = flent->fe_flow_desc.fd_dst_mac;
8028 /*
8029 * We call this when we are setting up the datapath for
8030 * the first non-primary.
8031 */
8032 ASSERT(mip->mi_nactiveclients == 2);
8033 /*
8034 * OK, now we have the primary that needs to be relocated.
8035 */
8036 ngrp = mac_reserve_rx_group(mcip, mac_addr, B_TRUE);
8037 if (ngrp == NULL)
8038 return (NULL);
8039 if (mac_rx_switch_group(mcip, defgrp, ngrp) != 0) {
8040 mac_stop_group(ngrp);
8041 return (NULL);
8042 }
8043 return (mcip);
8044 }
8045
8046 void
8047 mac_transceiver_init(mac_impl_t *mip)
8048 {
8049 if (mac_capab_get((mac_handle_t)mip, MAC_CAPAB_TRANSCEIVER,
8050 &mip->mi_transceiver)) {
8051 /*
8052 * The driver set a flag that we don't know about. In this case,
|
443
444 i_mactype_hash = mod_hash_create_extended("mactype_hash",
445 MACTYPE_HASHSZ,
446 mod_hash_null_keydtor, mod_hash_null_valdtor,
447 mod_hash_bystr, NULL, mod_hash_strkey_cmp, KM_SLEEP);
448
449 /*
450 * Allocate an id space to manage minor numbers. The range of the
451 * space will be from MAC_MAX_MINOR+1 to MAC_PRIVATE_MINOR-1. This
452 * leaves half of the 32-bit minors available for driver private use.
453 */
454 minor_ids = id_space_create("mac_minor_ids", MAC_MAX_MINOR+1,
455 MAC_PRIVATE_MINOR-1);
456 ASSERT(minor_ids != NULL);
457 minor_count = 0;
458
459 /* Let's default to 20 seconds */
460 mac_logging_interval = 20;
461 mac_flow_log_enable = B_FALSE;
462 mac_link_log_enable = B_FALSE;
463 mac_logging_timer = NULL;
464
465 /* Register to be notified of noteworthy pools events */
466 mac_pool_event_reg.pec_func = mac_pool_event_cb;
467 mac_pool_event_reg.pec_arg = NULL;
468 pool_event_cb_register(&mac_pool_event_reg);
469 }
470
471 int
472 mac_fini(void)
473 {
474
475 if (i_mac_impl_count > 0 || minor_count > 0)
476 return (EBUSY);
477
478 pool_event_cb_unregister(&mac_pool_event_reg);
479
480 id_space_destroy(minor_ids);
481 mac_flow_fini();
482
483 mod_hash_destroy_hash(i_mac_impl_hash);
1098 return (err);
1099 }
1100
1101 /*
1102 * Start the default tx ring.
1103 */
1104 if (mip->mi_default_tx_ring != NULL) {
1105
1106 ring = (mac_ring_t *)mip->mi_default_tx_ring;
1107 if (ring->mr_state != MR_INUSE) {
1108 err = mac_start_ring(ring);
1109 if (err != 0) {
1110 mip->mi_active--;
1111 return (err);
1112 }
1113 }
1114 }
1115
1116 if ((defgrp = MAC_DEFAULT_RX_GROUP(mip)) != NULL) {
1117 /*
1118 * Start the default group which is responsible
1119 * for receiving broadcast and multicast
1120 * traffic for both primary and non-primary
1121 * MAC clients.
1122 */
1123 ASSERT(defgrp->mrg_state == MAC_GROUP_STATE_REGISTERED);
1124 err = mac_start_group_and_rings(defgrp);
1125 if (err != 0) {
1126 mip->mi_active--;
1127 if ((ring != NULL) &&
1128 (ring->mr_state == MR_INUSE))
1129 mac_stop_ring(ring);
1130 return (err);
1131 }
1132 mac_set_group_state(defgrp, MAC_GROUP_STATE_SHARED);
1133 }
1134 }
1135
1136 return (err);
1137 }
1138
1139 /*
1140 * Private GLDv3 function to stop a MAC instance.
1141 */
1714 mip->mi_default_tx_ring = rh;
1715 }
1716
1717 int
1718 mac_hwgroup_addmac(mac_group_handle_t gh, const uint8_t *addr)
1719 {
1720 mac_group_t *group = (mac_group_t *)gh;
1721
1722 return (mac_group_addmac(group, addr));
1723 }
1724
1725 int
1726 mac_hwgroup_remmac(mac_group_handle_t gh, const uint8_t *addr)
1727 {
1728 mac_group_t *group = (mac_group_t *)gh;
1729
1730 return (mac_group_remmac(group, addr));
1731 }
1732
1733 /*
1734 * Program the group's HW VLAN filter if it has such support.
1735 * Otherwise, the group will implicitly accept tagged traffic and
1736 * there is nothing to do.
1737 */
1738 int
1739 mac_hwgroup_addvlan(mac_group_handle_t gh, uint16_t vid)
1740 {
1741 mac_group_t *group = (mac_group_t *)gh;
1742
1743 if (!MAC_GROUP_HW_VLAN(group))
1744 return (0);
1745
1746 return (mac_group_addvlan(group, vid));
1747 }
1748
1749 int
1750 mac_hwgroup_remvlan(mac_group_handle_t gh, uint16_t vid)
1751 {
1752 mac_group_t *group = (mac_group_t *)gh;
1753
1754 if (!MAC_GROUP_HW_VLAN(group))
1755 return (0);
1756
1757 return (mac_group_remvlan(group, vid));
1758 }
1759
1760 /*
1761 * Determine if a MAC has HW VLAN support. This is a private API
1762 * consumed by aggr. In the future it might be nice to have a bitfield
1763 * in mac_capab_rings_t to track which forms of HW filtering are
1764 * supported by the MAC.
1765 */
1766 boolean_t
1767 mac_has_hw_vlan(mac_handle_t mh)
1768 {
1769 mac_impl_t *mip = (mac_impl_t *)mh;
1770
1771 return (MAC_GROUP_HW_VLAN(mip->mi_rx_groups));
1772 }
1773
1774 /*
1775 * Set the RX group to be shared/reserved. Note that the group must be
1776 * started/stopped outside of this function.
1777 */
1778 void
1779 mac_set_group_state(mac_group_t *grp, mac_group_state_t state)
1780 {
1781 /*
1782 * If there is no change in the group state, just return.
1783 */
1784 if (grp->mrg_state == state)
1785 return;
1786
1787 switch (state) {
1788 case MAC_GROUP_STATE_RESERVED:
1789 /*
1790 * Successfully reserved the group.
1791 *
1792 * Given that there is an exclusive client controlling this
1793 * group, we enable the group level polling when available,
1794 * so that SRSs get to turn on/off individual rings they's
2439 {
2440 mac_impl_t *mip = (mac_impl_t *)mh;
2441 int err;
2442
2443 i_mac_perim_enter(mip);
2444 err = i_mac_disable(mip);
2445 i_mac_perim_exit(mip);
2446
2447 /*
2448 * Clean up notification thread and wait for it to exit.
2449 */
2450 if (err == 0)
2451 i_mac_notify_exit(mip);
2452
2453 return (err);
2454 }
2455
2456 /*
2457 * Called when the MAC instance has a non empty flow table, to de-multiplex
2458 * incoming packets to the right flow.
2459 */
2460 /* ARGSUSED */
2461 static mblk_t *
2462 mac_rx_classify(mac_impl_t *mip, mac_resource_handle_t mrh, mblk_t *mp)
2463 {
2464 flow_entry_t *flent = NULL;
2465 uint_t flags = FLOW_INBOUND;
2466 int err;
2467
2468 /*
2469 * If the MAC is a port of an aggregation, pass FLOW_IGNORE_VLAN
2470 * to mac_flow_lookup() so that the VLAN packets can be successfully
2471 * passed to the non-VLAN aggregation flows.
2472 *
2473 * Note that there is possibly a race between this and
2474 * mac_unicast_remove/add() and VLAN packets could be incorrectly
2475 * classified to non-VLAN flows of non-aggregation MAC clients. These
2476 * VLAN packets will be then filtered out by the MAC module.
2477 */
2478 if ((mip->mi_state_flags & MIS_EXCLUSIVE) != 0)
2479 flags |= FLOW_IGNORE_VLAN;
2480
2481 err = mac_flow_lookup(mip->mi_flow_tab, mp, flags, &flent);
2482 if (err != 0) {
2483 /* no registered receive function */
2484 return (mp);
2485 } else {
2486 mac_client_impl_t *mcip;
2487
2488 /*
2489 * This flent might just be an additional one on the MAC client,
2490 * i.e. for classification purposes (different fdesc), however
2491 * the resources, SRS et. al., are in the mci_flent, so if
2492 * this isn't the mci_flent, we need to get it.
2493 */
2494 if ((mcip = flent->fe_mcip) != NULL &&
2495 mcip->mci_flent != flent) {
2496 FLOW_REFRELE(flent);
4099 break;
4100 }
4101 break;
4102 case MAC_GROUP_TYPE_STATIC:
4103 /*
4104 * Note that an empty group is allowed, e.g., an aggr
4105 * would start with an empty group.
4106 */
4107 break;
4108 default:
4109 /* unknown group type */
4110 DTRACE_PROBE2(mac__init__rings__unknown__type,
4111 char *, mip->mi_name,
4112 int, cap_rings->mr_group_type);
4113 err = EINVAL;
4114 goto bail;
4115 }
4116
4117
4118 /*
4119 * The driver must register some form of hardware MAC
4120 * filter in order for Rx groups to support multiple
4121 * MAC addresses.
4122 */
4123 if (rtype == MAC_RING_TYPE_RX &&
4124 (group_info.mgi_addmac == NULL ||
4125 group_info.mgi_remmac == NULL)) {
4126 DTRACE_PROBE1(mac__init__rings__no__mac__filter,
4127 char *, mip->mi_name);
4128 err = EINVAL;
4129 goto bail;
4130 }
4131
4132 /* Cache driver-supplied information */
4133 group->mrg_info = group_info;
4134
4135 /* Update the group's status and group count. */
4136 mac_set_group_state(group, MAC_GROUP_STATE_REGISTERED);
4137 group_free++;
4138
4139 group->mrg_rings = NULL;
4140 group->mrg_cur_count = 0;
4141 mac_init_group(mip, group, group_info.mgi_count, cap_rings);
4142 ring_left -= group_info.mgi_count;
4143
4144 /* The current group size should be equal to default value */
4145 ASSERT(group->mrg_cur_count == group_info.mgi_count);
4146 }
4147
4154 group->mrg_state = MAC_GROUP_STATE_UNINIT;
4155 group->mrg_mh = (mac_handle_t)mip;
4156 group->mrg_next = NULL;
4157
4158 /*
4159 * If there are ungrouped rings, allocate a continuous buffer for
4160 * remaining resources.
4161 */
4162 if (ring_left != 0) {
4163 group->mrg_rings = NULL;
4164 group->mrg_cur_count = 0;
4165 mac_init_group(mip, group, ring_left, cap_rings);
4166
4167 /* The current group size should be equal to ring_left */
4168 ASSERT(group->mrg_cur_count == ring_left);
4169
4170 ring_left = 0;
4171
4172 /* Update this group's status */
4173 mac_set_group_state(group, MAC_GROUP_STATE_REGISTERED);
4174 } else {
4175 group->mrg_rings = NULL;
4176 }
4177
4178 ASSERT(ring_left == 0);
4179
4180 bail:
4181
4182 /* Cache other important information to finalize the initialization */
4183 switch (rtype) {
4184 case MAC_RING_TYPE_RX:
4185 mip->mi_rx_group_type = cap_rings->mr_group_type;
4186 mip->mi_rx_group_count = cap_rings->mr_gnum;
4187 mip->mi_rx_groups = groups;
4188 mip->mi_rx_donor_grp = groups;
4189 if (mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) {
4190 /*
4191 * The default ring is reserved since it is
4192 * used for sending the broadcast etc. packets.
4193 */
4194 mip->mi_rxrings_avail =
4195 mip->mi_rx_groups->mrg_cur_count - 1;
4196 mip->mi_rxrings_rsvd = 1;
4346 mac_ring_t *ring;
4347
4348 if (group->mrg_cur_count == 0)
4349 continue;
4350
4351 ASSERT(group->mrg_rings != NULL);
4352
4353 while ((ring = group->mrg_rings) != NULL) {
4354 group->mrg_rings = ring->mr_next;
4355 mac_ring_free(mip, ring);
4356 }
4357 }
4358
4359 /* Free all the cached rings */
4360 mac_ring_freeall(mip);
4361 /* Free the block of group data strutures */
4362 kmem_free(groups, sizeof (mac_group_t) * (group_count + 1));
4363 }
4364
4365 /*
4366 * Associate the VLAN filter to the receive group.
4367 */
4368 int
4369 mac_group_addvlan(mac_group_t *group, uint16_t vlan)
4370 {
4371 VERIFY3S(group->mrg_type, ==, MAC_RING_TYPE_RX);
4372 VERIFY3P(group->mrg_info.mgi_addvlan, !=, NULL);
4373
4374 if (vlan > VLAN_ID_MAX)
4375 return (EINVAL);
4376
4377 vlan = MAC_VLAN_UNTAGGED_VID(vlan);
4378 return (group->mrg_info.mgi_addvlan(group->mrg_info.mgi_driver, vlan));
4379 }
4380
4381 /*
4382 * Dissociate the VLAN from the receive group.
4383 */
4384 int
4385 mac_group_remvlan(mac_group_t *group, uint16_t vlan)
4386 {
4387 VERIFY3S(group->mrg_type, ==, MAC_RING_TYPE_RX);
4388 VERIFY3P(group->mrg_info.mgi_remvlan, !=, NULL);
4389
4390 if (vlan > VLAN_ID_MAX)
4391 return (EINVAL);
4392
4393 vlan = MAC_VLAN_UNTAGGED_VID(vlan);
4394 return (group->mrg_info.mgi_remvlan(group->mrg_info.mgi_driver, vlan));
4395 }
4396
4397 /*
4398 * Associate a MAC address with a receive group.
4399 *
4400 * The return value of this function should always be checked properly, because
4401 * any type of failure could cause unexpected results. A group can be added
4402 * or removed with a MAC address only after it has been reserved. Ideally,
4403 * a successful reservation always leads to calling mac_group_addmac() to
4404 * steer desired traffic. Failure of adding an unicast MAC address doesn't
4405 * always imply that the group is functioning abnormally.
4406 *
4407 * Currently this function is called everywhere, and it reflects assumptions
4408 * about MAC addresses in the implementation. CR 6735196.
4409 */
4410 int
4411 mac_group_addmac(mac_group_t *group, const uint8_t *addr)
4412 {
4413 VERIFY3S(group->mrg_type, ==, MAC_RING_TYPE_RX);
4414 VERIFY3P(group->mrg_info.mgi_addmac, !=, NULL);
4415
4416 return (group->mrg_info.mgi_addmac(group->mrg_info.mgi_driver, addr));
4417 }
4418
4419 /*
4420 * Remove the association between MAC address and receive group.
4421 */
4422 int
4423 mac_group_remmac(mac_group_t *group, const uint8_t *addr)
4424 {
4425 VERIFY3S(group->mrg_type, ==, MAC_RING_TYPE_RX);
4426 VERIFY3P(group->mrg_info.mgi_remmac, !=, NULL);
4427
4428 return (group->mrg_info.mgi_remmac(group->mrg_info.mgi_driver, addr));
4429 }
4430
4431 /*
4432 * This is the entry point for packets transmitted through the bridging code.
4433 * If no bridge is in place, MAC_RING_TX transmits using tx ring. The 'rh'
4434 * pointer may be NULL to select the default ring.
4435 */
4436 mblk_t *
4437 mac_bridge_tx(mac_impl_t *mip, mac_ring_handle_t rh, mblk_t *mp)
4438 {
4439 mac_handle_t mh;
4440
4441 /*
4442 * Once we take a reference on the bridge link, the bridge
4443 * module itself can't unload, so the callback pointers are
4444 * stable.
4445 */
4446 mutex_enter(&mip->mi_bridge_lock);
4581 ring->mr_driver, ring->mr_type);
4582 }
4583 group->mrg_cur_count--;
4584 group->mrg_rings = ring->mr_next;
4585
4586 ring->mr_gh = NULL;
4587
4588 if (driver_call)
4589 mac_ring_free(mip, ring);
4590
4591 return (ret);
4592 }
4593 }
4594
4595 /*
4596 * Set up SRS/SR according to the ring type.
4597 */
4598 switch (ring->mr_type) {
4599 case MAC_RING_TYPE_RX:
4600 /*
4601 * Setup an SRS on top of the new ring if the group is
4602 * reserved for someone's exclusive use.
4603 */
4604 if (group->mrg_state == MAC_GROUP_STATE_RESERVED) {
4605 mac_client_impl_t *mcip = MAC_GROUP_ONLY_CLIENT(group);
4606
4607 VERIFY3P(mcip, !=, NULL);
4608 flent = mcip->mci_flent;
4609 VERIFY3S(flent->fe_rx_srs_cnt, >, 0);
4610 mac_rx_srs_group_setup(mcip, flent, SRST_LINK);
4611 mac_fanout_setup(mcip, flent, MCIP_RESOURCE_PROPS(mcip),
4612 mac_rx_deliver, mcip, NULL, NULL);
4613 } else {
4614 ring->mr_classify_type = MAC_SW_CLASSIFIER;
4615 }
4616 break;
4617 case MAC_RING_TYPE_TX:
4618 {
4619 mac_grp_client_t *mgcp = group->mrg_clients;
4620 mac_client_impl_t *mcip;
4621 mac_soft_ring_set_t *mac_srs;
4622 mac_srs_tx_t *tx;
4623
4624 if (MAC_GROUP_NO_CLIENT(group)) {
4625 if (ring->mr_state == MR_INUSE)
4626 mac_stop_ring(ring);
4627 ring->mr_flag = 0;
4628 break;
4629 }
4630 /*
4631 * If the rings are being moved to a group that has
4632 * clients using it, then add the new rings to the
4633 * clients SRS.
4634 */
4635 while (mgcp != NULL) {
4636 boolean_t is_aggr;
4637
4638 mcip = mgcp->mgc_client;
4639 flent = mcip->mci_flent;
4640 is_aggr = (mcip->mci_state_flags & MCIS_IS_AGGR_CLIENT);
4641 mac_srs = MCIP_TX_SRS(mcip);
4642 tx = &mac_srs->srs_tx;
4643 mac_tx_client_quiesce((mac_client_handle_t)mcip);
4644 /*
4645 * If we are growing from 1 to multiple rings.
4646 */
4647 if (tx->st_mode == SRS_TX_BW ||
4648 tx->st_mode == SRS_TX_SERIALIZE ||
4649 tx->st_mode == SRS_TX_DEFAULT) {
4650 mac_ring_t *tx_ring = tx->st_arg2;
4651
4652 tx->st_arg2 = NULL;
4653 mac_tx_srs_stat_recreate(mac_srs, B_TRUE);
4654 mac_tx_srs_add_ring(mac_srs, tx_ring);
4655 if (mac_srs->srs_type & SRST_BW_CONTROL) {
4656 tx->st_mode = is_aggr ? SRS_TX_BW_AGGR :
4657 SRS_TX_BW_FANOUT;
4658 } else {
4659 tx->st_mode = is_aggr ? SRS_TX_AGGR :
4660 SRS_TX_FANOUT;
4764 mac_client_impl_t *mcip;
4765 mac_soft_ring_set_t *mac_srs;
4766 mac_soft_ring_t *sringp;
4767 mac_srs_tx_t *srs_tx;
4768
4769 if (mip->mi_state_flags & MIS_IS_AGGR &&
4770 mip->mi_default_tx_ring ==
4771 (mac_ring_handle_t)ring) {
4772 /* pick a new default Tx ring */
4773 mip->mi_default_tx_ring =
4774 (group->mrg_rings != ring) ?
4775 (mac_ring_handle_t)group->mrg_rings :
4776 (mac_ring_handle_t)(ring->mr_next);
4777 }
4778 /* Presently only aggr case comes here */
4779 if (group->mrg_state != MAC_GROUP_STATE_RESERVED)
4780 break;
4781
4782 mcip = MAC_GROUP_ONLY_CLIENT(group);
4783 ASSERT(mcip != NULL);
4784 ASSERT(mcip->mci_state_flags & MCIS_IS_AGGR_CLIENT);
4785 mac_srs = MCIP_TX_SRS(mcip);
4786 ASSERT(mac_srs->srs_tx.st_mode == SRS_TX_AGGR ||
4787 mac_srs->srs_tx.st_mode == SRS_TX_BW_AGGR);
4788 srs_tx = &mac_srs->srs_tx;
4789 /*
4790 * Wakeup any callers blocked on this
4791 * Tx ring due to flow control.
4792 */
4793 sringp = srs_tx->st_soft_rings[ring->mr_index];
4794 ASSERT(sringp != NULL);
4795 mac_tx_invoke_callbacks(mcip, (mac_tx_cookie_t)sringp);
4796 mac_tx_client_quiesce((mac_client_handle_t)mcip);
4797 mac_tx_srs_del_ring(mac_srs, ring);
4798 mac_tx_client_restart((mac_client_handle_t)mcip);
4799 break;
4800 }
4801 ASSERT(ring != (mac_ring_t *)mip->mi_default_tx_ring);
4802 group_type = mip->mi_tx_group_type;
4803 cap_rings = &mip->mi_tx_rings_cap;
4804 /*
4972 /*
4973 * Check whether the MAC address is shared by multiple clients.
4974 */
4975 boolean_t
4976 mac_check_macaddr_shared(mac_address_t *map)
4977 {
4978 ASSERT(MAC_PERIM_HELD((mac_handle_t)map->ma_mip));
4979
4980 return (map->ma_nusers > 1);
4981 }
4982
4983 /*
4984 * Remove the specified MAC address from the MAC address list and free it.
4985 */
4986 static void
4987 mac_free_macaddr(mac_address_t *map)
4988 {
4989 mac_impl_t *mip = map->ma_mip;
4990
4991 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip));
4992 VERIFY3P(mip->mi_addresses, !=, NULL);
4993
4994 VERIFY3P(map, ==, mac_find_macaddr(mip, map->ma_addr));
4995 VERIFY3P(map, !=, NULL);
4996 VERIFY3S(map->ma_nusers, ==, 0);
4997 VERIFY3P(map->ma_vlans, ==, NULL);
4998
4999 if (map == mip->mi_addresses) {
5000 mip->mi_addresses = map->ma_next;
5001 } else {
5002 mac_address_t *pre;
5003
5004 pre = mip->mi_addresses;
5005 while (pre->ma_next != map)
5006 pre = pre->ma_next;
5007 pre->ma_next = map->ma_next;
5008 }
5009
5010 kmem_free(map, sizeof (mac_address_t));
5011 }
5012
5013 static mac_vlan_t *
5014 mac_find_vlan(mac_address_t *map, uint16_t vid)
5015 {
5016 mac_vlan_t *mvp;
5017
5018 for (mvp = map->ma_vlans; mvp != NULL; mvp = mvp->mv_next) {
5019 if (mvp->mv_vid == vid)
5020 return (mvp);
5021 }
5022
5023 return (NULL);
5024 }
5025
5026 static mac_vlan_t *
5027 mac_add_vlan(mac_address_t *map, uint16_t vid)
5028 {
5029 mac_vlan_t *mvp;
5030
5031 /*
5032 * We should never add the same {addr, VID} tuple more
5033 * than once, but let's be sure.
5034 */
5035 for (mvp = map->ma_vlans; mvp != NULL; mvp = mvp->mv_next)
5036 VERIFY3U(mvp->mv_vid, !=, vid);
5037
5038 /* Add the VLAN to the head of the VLAN list. */
5039 mvp = kmem_zalloc(sizeof (mac_vlan_t), KM_SLEEP);
5040 mvp->mv_vid = vid;
5041 mvp->mv_next = map->ma_vlans;
5042 map->ma_vlans = mvp;
5043
5044 return (mvp);
5045 }
5046
5047 static void
5048 mac_rem_vlan(mac_address_t *map, mac_vlan_t *mvp)
5049 {
5050 mac_vlan_t *pre;
5051
5052 if (map->ma_vlans == mvp) {
5053 map->ma_vlans = mvp->mv_next;
5054 } else {
5055 pre = map->ma_vlans;
5056 while (pre->mv_next != mvp) {
5057 pre = pre->mv_next;
5058
5059 /*
5060 * We've reached the end of the list without
5061 * finding mvp.
5062 */
5063 VERIFY3P(pre, !=, NULL);
5064 }
5065 pre->mv_next = mvp->mv_next;
5066 }
5067
5068 kmem_free(mvp, sizeof (mac_vlan_t));
5069 }
5070
5071 /*
5072 * Create a new mac_address_t if this is the first use of the address
5073 * or add a VID to an existing address. In either case, the
5074 * mac_address_t acts as a list of {addr, VID} tuples where each tuple
5075 * shares the same addr. If group is non-NULL then attempt to program
5076 * the MAC's HW filters for this group. Otherwise, if group is NULL,
5077 * then the MAC has no rings and there is nothing to program.
5078 */
5079 int
5080 mac_add_macaddr_vlan(mac_impl_t *mip, mac_group_t *group, uint8_t *addr,
5081 uint16_t vid, boolean_t use_hw)
5082 {
5083 mac_address_t *map;
5084 mac_vlan_t *mvp;
5085 int err = 0;
5086 boolean_t allocated_map = B_FALSE;
5087 boolean_t hw_mac = B_FALSE;
5088 boolean_t hw_vlan = B_FALSE;
5089
5090 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip));
5091
5092 map = mac_find_macaddr(mip, addr);
5093
5094 /*
5095 * If this is the first use of this MAC address then allocate
5096 * and initialize a new structure.
5097 */
5098 if (map == NULL) {
5099 map = kmem_zalloc(sizeof (mac_address_t), KM_SLEEP);
5100 map->ma_len = mip->mi_type->mt_addr_length;
5101 bcopy(addr, map->ma_addr, map->ma_len);
5102 map->ma_nusers = 0;
5103 map->ma_group = group;
5104 map->ma_mip = mip;
5105 map->ma_untagged = B_FALSE;
5106
5107 /* Add the new MAC address to the head of the address list. */
5108 map->ma_next = mip->mi_addresses;
5109 mip->mi_addresses = map;
5110
5111 allocated_map = B_TRUE;
5112 }
5113
5114 VERIFY(map->ma_group == NULL || map->ma_group == group);
5115 if (map->ma_group == NULL)
5116 map->ma_group = group;
5117
5118 if (vid == VLAN_ID_NONE) {
5119 map->ma_untagged = B_TRUE;
5120 mvp = NULL;
5121 } else {
5122 mvp = mac_add_vlan(map, vid);
5123 }
5124
5125 /*
5126 * Set the VLAN HW filter if:
5127 *
5128 * o the MAC's VLAN HW filtering is enabled, and
5129 * o the address does not currently rely on promisc mode.
5130 *
5131 * This is called even when the client specifies an untagged
5132 * address (VLAN_ID_NONE) because some MAC providers require
5133 * setting additional bits to accept untagged traffic when
5134 * VLAN HW filtering is enabled.
5135 */
5136 if (MAC_GROUP_HW_VLAN(group) &&
5137 map->ma_type != MAC_ADDRESS_TYPE_UNICAST_PROMISC) {
5138 if ((err = mac_group_addvlan(group, vid)) != 0)
5139 goto bail;
5140
5141 hw_vlan = B_TRUE;
5142 }
5143
5144 VERIFY3S(map->ma_nusers, >=, 0);
5145 map->ma_nusers++;
5146
5147 /*
5148 * If this MAC address already has a HW filter then simply
5149 * increment the counter.
5150 */
5151 if (map->ma_nusers > 1)
5152 return (0);
5153
5154 /*
5155 * All logic from here on out is executed during initial
5156 * creation only.
5157 */
5158 VERIFY3S(map->ma_nusers, ==, 1);
5159
5160 /*
5161 * Activate this MAC address by adding it to the reserved group.
5162 */
5163 if (group != NULL) {
5164 err = mac_group_addmac(group, (const uint8_t *)addr);
5165
5166 /*
5167 * If the driver is out of filters then we can
5168 * continue and use promisc mode. For any other error,
5169 * assume the driver is in a state where we can't
5170 * program the filters or use promisc mode; so we must
5171 * bail.
5172 */
5173 if (err != 0 && err != ENOSPC) {
5174 map->ma_nusers--;
5175 goto bail;
5176 }
5177
5178 hw_mac = (err == 0);
5179 }
5180
5181 if (hw_mac) {
5182 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED;
5183 return (0);
5184 }
5185
5186 /*
5187 * The MAC address addition failed. If the client requires a
5188 * hardware classified MAC address, fail the operation. This
5189 * feature is only used by sun4v vsw.
5190 */
5191 if (use_hw && !hw_mac) {
5192 err = ENOSPC;
5193 map->ma_nusers--;
5194 goto bail;
5195 }
5196
5197 /*
5198 * If we reach this point then either the MAC doesn't have
5199 * RINGS capability or we are out of MAC address HW filters.
5200 * In any case we must put the MAC into promiscuous mode.
5201 */
5202 VERIFY(group == NULL || !hw_mac);
5203
5204 /*
5205 * The one exception is the primary address. A non-RINGS
5206 * driver filters the primary address by default; promisc mode
5207 * is not needed.
5208 */
5209 if ((group == NULL) &&
5210 (bcmp(map->ma_addr, mip->mi_addr, map->ma_len) == 0)) {
5211 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED;
5212 return (0);
5213 }
5214
5215 /*
5216 * Enable promiscuous mode in order to receive traffic to the
5217 * new MAC address. All existing HW filters still send their
5218 * traffic to their respective group/SRSes. But with promisc
5219 * enabled all unknown traffic is delivered to the default
5220 * group where it is SW classified via mac_rx_classify().
5221 */
5222 if ((err = i_mac_promisc_set(mip, B_TRUE)) == 0) {
5223 map->ma_type = MAC_ADDRESS_TYPE_UNICAST_PROMISC;
5224 return (0);
5225 }
5226
5227 bail:
5228 if (hw_vlan) {
5229 int err2 = mac_group_remvlan(group, vid);
5230
5231 if (err2 != 0) {
5232 cmn_err(CE_WARN, "Failed to remove VLAN %u from group"
5233 " %d on MAC %s: %d.", vid, group->mrg_index,
5234 mip->mi_name, err2);
5235 }
5236 }
5237
5238 if (mvp != NULL)
5239 mac_rem_vlan(map, mvp);
5240
5241 if (allocated_map)
5242 mac_free_macaddr(map);
5243
5244 return (err);
5245 }
5246
5247 int
5248 mac_remove_macaddr_vlan(mac_address_t *map, uint16_t vid)
5249 {
5250 mac_vlan_t *mvp;
5251 mac_impl_t *mip = map->ma_mip;
5252 mac_group_t *group = map->ma_group;
5253 int err = 0;
5254
5255 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip));
5256 VERIFY3P(map, ==, mac_find_macaddr(mip, map->ma_addr));
5257
5258 if (vid == VLAN_ID_NONE) {
5259 map->ma_untagged = B_FALSE;
5260 mvp = NULL;
5261 } else {
5262 mvp = mac_find_vlan(map, vid);
5263 VERIFY3P(mvp, !=, NULL);
5264 }
5265
5266 if (MAC_GROUP_HW_VLAN(group) &&
5267 map->ma_type == MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED &&
5268 ((err = mac_group_remvlan(group, vid)) != 0))
5269 return (err);
5270
5271 if (mvp != NULL)
5272 mac_rem_vlan(map, mvp);
5273
5274 /*
5275 * If it's not the last client using this MAC address, only update
5276 * the MAC clients count.
5277 */
5278 map->ma_nusers--;
5279 if (map->ma_nusers > 0)
5280 return (0);
5281
5282 /*
5283 * The MAC address is no longer used by any MAC client, so
5284 * remove it from its associated group. Turn off promiscuous
5285 * mode if this is the last address relying on it.
5286 */
5287 switch (map->ma_type) {
5288 case MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED:
5289 /*
5290 * Don't free the preset primary address for drivers that
5291 * don't advertise RINGS capability.
5292 */
5293 if (group == NULL)
5294 return (0);
5295
5296 if ((err = mac_group_remmac(group, map->ma_addr)) != 0) {
5297 if (vid == VLAN_ID_NONE)
5298 map->ma_untagged = B_TRUE;
5299 else
5300 (void) mac_add_vlan(map, vid);
5301
5302 /*
5303 * If we fail to remove the MAC address HW
5304 * filter but then also fail to re-add the
5305 * VLAN HW filter then we are in a busted
5306 * state and should just crash.
5307 */
5308 if (MAC_GROUP_HW_VLAN(group)) {
5309 int err2;
5310
5311 err2 = mac_group_addvlan(group, vid);
5312 if (err2 != 0) {
5313 cmn_err(CE_WARN, "Failed to readd VLAN"
5314 " %u to group %d on MAC %s: %d.",
5315 vid, group->mrg_index, mip->mi_name,
5316 err2);
5317 }
5318 }
5319
5320 return (err);
5321 }
5322
5323 map->ma_group = NULL;
5324 break;
5325 case MAC_ADDRESS_TYPE_UNICAST_PROMISC:
5326 err = i_mac_promisc_set(mip, B_FALSE);
5327 break;
5328 default:
5329 panic("Unexpected ma_type 0x%x, file: %s, line %d",
5330 map->ma_type, __FILE__, __LINE__);
5331 }
5332
5333 if (err != 0)
5334 return (err);
5335
5336 /*
5337 * We created MAC address for the primary one at registration, so we
5338 * won't free it here. mac_fini_macaddr() will take care of it.
5339 */
5340 if (bcmp(map->ma_addr, mip->mi_addr, map->ma_len) != 0)
5341 mac_free_macaddr(map);
5342
5343 return (0);
5344 }
5345
5346 /*
5347 * Update an existing MAC address. The caller need to make sure that the new
5348 * value has not been used.
5349 */
5350 int
5467
5468 mip->mi_addresses = map;
5469 }
5470
5471 /*
5472 * Clean up the primary MAC address. Note, only one primary MAC address
5473 * is allowed. All other MAC addresses must have been freed appropriately.
5474 */
5475 void
5476 mac_fini_macaddr(mac_impl_t *mip)
5477 {
5478 mac_address_t *map = mip->mi_addresses;
5479
5480 if (map == NULL)
5481 return;
5482
5483 /*
5484 * If mi_addresses is initialized, there should be exactly one
5485 * entry left on the list with no users.
5486 */
5487 VERIFY3S(map->ma_nusers, ==, 0);
5488 VERIFY3P(map->ma_next, ==, NULL);
5489 VERIFY3P(map->ma_vlans, ==, NULL);
5490
5491 kmem_free(map, sizeof (mac_address_t));
5492 mip->mi_addresses = NULL;
5493 }
5494
5495 /*
5496 * Logging related functions.
5497 *
5498 * Note that Kernel statistics have been extended to maintain fine
5499 * granularity of statistics viz. hardware lane, software lane, fanout
5500 * stats etc. However, extended accounting continues to support only
5501 * aggregate statistics like before.
5502 */
5503
5504 /* Write the flow description to a netinfo_t record */
5505 static netinfo_t *
5506 mac_write_flow_desc(flow_entry_t *flent, mac_client_impl_t *mcip)
5507 {
5508 netinfo_t *ninfo;
5509 net_desc_t *ndesc;
6031 mac_flow_log_enable = B_FALSE;
6032 mac_link_log_enable = B_FALSE;
6033 break;
6034 }
6035 /* FALLTHRU */
6036 case MAC_LOGTYPE_LINK:
6037 if (!lstate.mi_lenable || mac_flow_log_enable) {
6038 rw_exit(&i_mac_impl_lock);
6039 return;
6040 }
6041 mac_link_log_enable = B_FALSE;
6042 break;
6043 default:
6044 ASSERT(0);
6045 }
6046
6047 /* Reenable fastpath */
6048 mod_hash_walk(i_mac_impl_hash, i_mac_fastpath_walker, &estate);
6049
6050 (void) untimeout(mac_logging_timer);
6051 mac_logging_timer = NULL;
6052
6053 /* Write log entries for each mac_impl in the list */
6054 i_mac_log_info(&net_log_list, &lstate);
6055 }
6056
6057 /*
6058 * Walk the rx and tx SRS/SRs for a flow and update the priority value.
6059 */
6060 void
6061 mac_flow_update_priority(mac_client_impl_t *mcip, flow_entry_t *flent)
6062 {
6063 pri_t pri;
6064 int count;
6065 mac_soft_ring_set_t *mac_srs;
6066
6067 if (flent->fe_rx_srs_cnt <= 0)
6068 return;
6069
6070 if (((mac_soft_ring_set_t *)flent->fe_rx_srs[0])->srs_type ==
6071 SRST_FLOW) {
6149 }
6150 /*
6151 * There are clients using this ring, so let's move the clients
6152 * away from using this ring.
6153 */
6154 for (mgcp = group->mrg_clients; mgcp != NULL; mgcp = mgcp->mgc_next) {
6155 mcip = mgcp->mgc_client;
6156 mac_tx_client_quiesce((mac_client_handle_t)mcip);
6157 srs = MCIP_TX_SRS(mcip);
6158 ASSERT(mac_tx_srs_ring_present(srs, desired_ring));
6159 mac_tx_invoke_callbacks(mcip,
6160 (mac_tx_cookie_t)mac_tx_srs_get_soft_ring(srs,
6161 desired_ring));
6162 mac_tx_srs_del_ring(srs, desired_ring);
6163 mac_tx_client_restart((mac_client_handle_t)mcip);
6164 }
6165 return (desired_ring);
6166 }
6167
6168 /*
6169 * For a non-default group with multiple clients, return the primary client.
6170 */
6171 static mac_client_impl_t *
6172 mac_get_grp_primary(mac_group_t *grp)
6173 {
6174 mac_grp_client_t *mgcp = grp->mrg_clients;
6175 mac_client_impl_t *mcip;
6176
6177 while (mgcp != NULL) {
6178 mcip = mgcp->mgc_client;
6179 if (mcip->mci_flent->fe_type & FLOW_PRIMARY_MAC)
6180 return (mcip);
6181 mgcp = mgcp->mgc_next;
6182 }
6183 return (NULL);
6184 }
6185
6186 /*
6187 * Hybrid I/O specifies the ring that should be given to a share.
6188 * If the ring is already used by clients, then we need to release
6189 * the ring back to the default group so that we can give it to
6508 if (share != 0)
6509 mip->mi_share_capab.ms_sadd(share, new_group->mrg_driver);
6510
6511 bail:
6512 /* free temporary array of rings */
6513 kmem_free(rings, nrings * sizeof (mac_ring_handle_t));
6514
6515 return (rv);
6516 }
6517
6518 void
6519 mac_group_add_client(mac_group_t *grp, mac_client_impl_t *mcip)
6520 {
6521 mac_grp_client_t *mgcp;
6522
6523 for (mgcp = grp->mrg_clients; mgcp != NULL; mgcp = mgcp->mgc_next) {
6524 if (mgcp->mgc_client == mcip)
6525 break;
6526 }
6527
6528 ASSERT(mgcp == NULL);
6529
6530 mgcp = kmem_zalloc(sizeof (mac_grp_client_t), KM_SLEEP);
6531 mgcp->mgc_client = mcip;
6532 mgcp->mgc_next = grp->mrg_clients;
6533 grp->mrg_clients = mgcp;
6534 }
6535
6536 void
6537 mac_group_remove_client(mac_group_t *grp, mac_client_impl_t *mcip)
6538 {
6539 mac_grp_client_t *mgcp, **pprev;
6540
6541 for (pprev = &grp->mrg_clients, mgcp = *pprev; mgcp != NULL;
6542 pprev = &mgcp->mgc_next, mgcp = *pprev) {
6543 if (mgcp->mgc_client == mcip)
6544 break;
6545 }
6546
6547 ASSERT(mgcp != NULL);
6548
6549 *pprev = mgcp->mgc_next;
6550 kmem_free(mgcp, sizeof (mac_grp_client_t));
6551 }
6552
6553 /*
6554 * Return true if any client on this group explicitly asked for HW
6555 * rings (of type mask) or have a bound share.
6556 */
6557 static boolean_t
6558 i_mac_clients_hw(mac_group_t *grp, uint32_t mask)
6559 {
6560 mac_grp_client_t *mgcip;
6561 mac_client_impl_t *mcip;
6562 mac_resource_props_t *mrp;
6563
6564 for (mgcip = grp->mrg_clients; mgcip != NULL; mgcip = mgcip->mgc_next) {
6565 mcip = mgcip->mgc_client;
6566 mrp = MCIP_RESOURCE_PROPS(mcip);
6567 if (mcip->mci_share != 0 || (mrp->mrp_mask & mask) != 0)
6568 return (B_TRUE);
6569 }
6570
6571 return (B_FALSE);
6572 }
6573
6574 /*
6575 * Finds an available group and exclusively reserves it for a client.
6576 * The group is chosen to suit the flow's resource controls (bandwidth and
6577 * fanout requirements) and the address type.
6578 * If the requestor is the pimary MAC then return the group with the
6579 * largest number of rings, otherwise the default ring when available.
6580 */
6581 mac_group_t *
6582 mac_reserve_rx_group(mac_client_impl_t *mcip, uint8_t *mac_addr, boolean_t move)
6583 {
6584 mac_share_handle_t share = mcip->mci_share;
6585 mac_impl_t *mip = mcip->mci_mip;
6586 mac_group_t *grp = NULL;
6587 int i;
6588 int err = 0;
6589 mac_address_t *map;
6590 mac_resource_props_t *mrp = MCIP_RESOURCE_PROPS(mcip);
6591 int nrings;
6592 int donor_grp_rcnt;
6593 boolean_t need_exclgrp = B_FALSE;
6594 int need_rings = 0;
6595 mac_group_t *candidate_grp = NULL;
6596 mac_client_impl_t *gclient;
6597 mac_group_t *donorgrp = NULL;
6598 boolean_t rxhw = mrp->mrp_mask & MRP_RX_RINGS;
6599 boolean_t unspec = mrp->mrp_mask & MRP_RXRINGS_UNSPEC;
6600 boolean_t isprimary;
6601
6602 ASSERT(MAC_PERIM_HELD((mac_handle_t)mip));
6603
6604 isprimary = mcip->mci_flent->fe_type & FLOW_PRIMARY_MAC;
6605
6606 /*
6607 * Check if a group already has this MAC address (case of VLANs)
6608 * unless we are moving this MAC client from one group to another.
6609 */
6610 if (!move && (map = mac_find_macaddr(mip, mac_addr)) != NULL) {
6611 if (map->ma_group != NULL)
6612 return (map->ma_group);
6613 }
6614
6615 if (mip->mi_rx_groups == NULL || mip->mi_rx_group_count == 0)
6616 return (NULL);
6617
6618 /*
6619 * If this client is requesting exclusive MAC access then
6620 * return NULL to ensure the client uses the default group.
6621 */
6622 if (mcip->mci_state_flags & MCIS_EXCLUSIVE)
6623 return (NULL);
6624
6625 /* For dynamic groups default unspecified to 1 */
6626 if (rxhw && unspec &&
6627 mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) {
6628 mrp->mrp_nrxrings = 1;
6629 }
6630
6631 /*
6632 * For static grouping we allow only specifying rings=0 and
6633 * unspecified
6634 */
6635 if (rxhw && mrp->mrp_nrxrings > 0 &&
6636 mip->mi_rx_group_type == MAC_GROUP_TYPE_STATIC) {
6637 return (NULL);
6638 }
6639
6640 if (rxhw) {
6641 /*
6642 * We have explicitly asked for a group (with nrxrings,
6643 * if unspec).
6644 */
6645 if (unspec || mrp->mrp_nrxrings > 0) {
6646 need_exclgrp = B_TRUE;
6647 need_rings = mrp->mrp_nrxrings;
6648 } else if (mrp->mrp_nrxrings == 0) {
6649 /*
6650 * We have asked for a software group.
6651 */
6652 return (NULL);
6653 }
6654 } else if (isprimary && mip->mi_nactiveclients == 1 &&
6655 mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) {
6656 /*
6657 * If the primary is the only active client on this
6658 * mip and we have not asked for any rings, we give
6659 * it the default group so that the primary gets to
6681 * For flows requiring HW_RING (unicast flow of other clients), try
6682 * to reserve non-default RX group with the specified number of
6683 * rings, if available.
6684 *
6685 * For flows that have not asked for software or hardware ring,
6686 * try to reserve a non-default group with 1 ring, if available.
6687 */
6688 for (i = 1; i < mip->mi_rx_group_count; i++) {
6689 grp = &mip->mi_rx_groups[i];
6690
6691 DTRACE_PROBE3(rx__group__trying, char *, mip->mi_name,
6692 int, grp->mrg_index, mac_group_state_t, grp->mrg_state);
6693
6694 /*
6695 * Check if this group could be a candidate group for
6696 * eviction if we need a group for this MAC client,
6697 * but there aren't any. A candidate group is one
6698 * that didn't ask for an exclusive group, but got
6699 * one and it has enough rings (combined with what
6700 * the donor group can donate) for the new MAC
6701 * client.
6702 */
6703 if (grp->mrg_state >= MAC_GROUP_STATE_RESERVED) {
6704 /*
6705 * If the donor group is not the default
6706 * group, don't bother looking for a candidate
6707 * group. If we don't have enough rings we
6708 * will check if the primary group can be
6709 * vacated.
6710 */
6711 if (candidate_grp == NULL &&
6712 donorgrp == MAC_DEFAULT_RX_GROUP(mip)) {
6713 if (!i_mac_clients_hw(grp, MRP_RX_RINGS) &&
6714 (unspec ||
6715 (grp->mrg_cur_count + donor_grp_rcnt >=
6716 need_rings))) {
6717 candidate_grp = grp;
6718 }
6719 }
6720 continue;
6721 }
6722 /*
6723 * This group could already be SHARED by other multicast
6724 * flows on this client. In that case, the group would
6725 * be shared and has already been started.
6726 */
6727 ASSERT(grp->mrg_state != MAC_GROUP_STATE_UNINIT);
6728
6729 if ((grp->mrg_state == MAC_GROUP_STATE_REGISTERED) &&
6730 (mac_start_group(grp) != 0)) {
6731 continue;
6732 }
6733
6759 if (share != 0) {
6760 mac_client_set_rings(
6761 (mac_client_handle_t)mcip,
6762 grp->mrg_cur_count, -1);
6763 }
6764 if (mac_is_primary_client(mcip) && !rxhw)
6765 mip->mi_rx_donor_grp = grp;
6766 break;
6767 }
6768 }
6769
6770 DTRACE_PROBE3(rx__group__reserve__alloc__rings, char *,
6771 mip->mi_name, int, grp->mrg_index, int, err);
6772
6773 /*
6774 * It's a dynamic group but the grouping operation
6775 * failed.
6776 */
6777 mac_stop_group(grp);
6778 }
6779
6780 /* We didn't find an exclusive group for this MAC client */
6781 if (i >= mip->mi_rx_group_count) {
6782
6783 if (!need_exclgrp)
6784 return (NULL);
6785
6786 /*
6787 * If we found a candidate group then move the
6788 * existing MAC client from the candidate_group to the
6789 * default group and give the candidate_group to the
6790 * new MAC client. If we didn't find a candidate
6791 * group, then check if the primary is in its own
6792 * group and if it can make way for this MAC client.
6793 */
6794 if (candidate_grp == NULL &&
6795 donorgrp != MAC_DEFAULT_RX_GROUP(mip) &&
6796 donorgrp->mrg_cur_count >= need_rings) {
6797 candidate_grp = donorgrp;
6798 }
6799 if (candidate_grp != NULL) {
6800 boolean_t prim_grp = B_FALSE;
6801
6802 /*
6803 * Switch the existing MAC client from the
6804 * candidate group to the default group. If
6805 * the candidate group is the donor group,
6806 * then after the switch we need to update the
6807 * donor group too.
6808 */
6809 grp = candidate_grp;
6810 gclient = grp->mrg_clients->mgc_client;
6811 VERIFY3P(gclient, !=, NULL);
6812 if (grp == mip->mi_rx_donor_grp)
6813 prim_grp = B_TRUE;
6814 if (mac_rx_switch_group(gclient, grp,
6815 MAC_DEFAULT_RX_GROUP(mip)) != 0) {
6816 return (NULL);
6817 }
6818 if (prim_grp) {
6819 mip->mi_rx_donor_grp =
6820 MAC_DEFAULT_RX_GROUP(mip);
6821 donorgrp = MAC_DEFAULT_RX_GROUP(mip);
6822 }
6823
6824 /*
6825 * Now give this group with the required rings
6826 * to this MAC client.
6827 */
6828 ASSERT(grp->mrg_state == MAC_GROUP_STATE_REGISTERED);
6829 if (mac_start_group(grp) != 0)
6830 return (NULL);
6831
6832 if (mip->mi_rx_group_type != MAC_GROUP_TYPE_DYNAMIC)
6833 return (grp);
6834
6835 donor_grp_rcnt = donorgrp->mrg_cur_count - 1;
6836 ASSERT(grp->mrg_cur_count == 0);
6837 ASSERT(donor_grp_rcnt >= need_rings);
6838 err = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_RX,
6839 donorgrp, grp, share, need_rings);
6840 if (err == 0) {
6841 /*
6842 * For a share i_mac_group_allocate_rings gets
6843 * the rings from the driver, let's populate
6851 DTRACE_PROBE2(rx__group__reserved,
6852 char *, mip->mi_name, int, grp->mrg_index);
6853 return (grp);
6854 }
6855 DTRACE_PROBE3(rx__group__reserve__alloc__rings, char *,
6856 mip->mi_name, int, grp->mrg_index, int, err);
6857 mac_stop_group(grp);
6858 }
6859 return (NULL);
6860 }
6861 ASSERT(grp != NULL);
6862
6863 DTRACE_PROBE2(rx__group__reserved,
6864 char *, mip->mi_name, int, grp->mrg_index);
6865 return (grp);
6866 }
6867
6868 /*
6869 * mac_rx_release_group()
6870 *
6871 * Release the group when it has no remaining clients. The group is
6872 * stopped and its shares are removed and all rings are assigned back
6873 * to default group. This should never be called against the default
6874 * group.
6875 */
6876 void
6877 mac_release_rx_group(mac_client_impl_t *mcip, mac_group_t *group)
6878 {
6879 mac_impl_t *mip = mcip->mci_mip;
6880 mac_ring_t *ring;
6881
6882 ASSERT(group != MAC_DEFAULT_RX_GROUP(mip));
6883 ASSERT(MAC_GROUP_NO_CLIENT(group) == B_TRUE);
6884
6885 if (mip->mi_rx_donor_grp == group)
6886 mip->mi_rx_donor_grp = MAC_DEFAULT_RX_GROUP(mip);
6887
6888 /*
6889 * This is the case where there are no clients left. Any
6890 * SRS etc on this group have also be quiesced.
6891 */
6892 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) {
6893 if (ring->mr_classify_type == MAC_HW_CLASSIFIER) {
6894 ASSERT(group->mrg_state == MAC_GROUP_STATE_RESERVED);
6895 /*
6896 * Remove the SRS associated with the HW ring.
6897 * As a result, polling will be disabled.
6898 */
6899 ring->mr_srs = NULL;
6900 }
6901 ASSERT(group->mrg_state < MAC_GROUP_STATE_RESERVED ||
6902 ring->mr_state == MR_INUSE);
6903 if (ring->mr_state == MR_INUSE) {
6915 if (mip->mi_rx_group_type == MAC_GROUP_TYPE_DYNAMIC) {
6916 mac_ring_t *ring;
6917
6918 /*
6919 * Rings were dynamically allocated to group.
6920 * Move rings back to default group.
6921 */
6922 while ((ring = group->mrg_rings) != NULL) {
6923 (void) mac_group_mov_ring(mip, mip->mi_rx_donor_grp,
6924 ring);
6925 }
6926 }
6927 mac_stop_group(group);
6928 /*
6929 * Possible improvement: See if we can assign the group just released
6930 * to a another client of the mip
6931 */
6932 }
6933
6934 /*
6935 * Move the MAC address from fgrp to tgrp.
6936 */
6937 static int
6938 mac_rx_move_macaddr(mac_client_impl_t *mcip, mac_group_t *fgrp,
6939 mac_group_t *tgrp)
6940 {
6941 mac_impl_t *mip = mcip->mci_mip;
6942 uint8_t maddr[MAXMACADDRLEN];
6943 int err = 0;
6944 uint16_t vid;
6945 mac_unicast_impl_t *muip;
6946 boolean_t use_hw;
6947
6948 mac_rx_client_quiesce((mac_client_handle_t)mcip);
6949 VERIFY3P(mcip->mci_unicast, !=, NULL);
6950 bcopy(mcip->mci_unicast->ma_addr, maddr, mcip->mci_unicast->ma_len);
6951
6952 /*
6953 * Does the client require MAC address hardware classifiction?
6954 */
6955 use_hw = (mcip->mci_state_flags & MCIS_UNICAST_HW) != 0;
6956 vid = i_mac_flow_vid(mcip->mci_flent);
6957
6958 /*
6959 * You can never move an address that is shared by multiple
6960 * clients. mac_datapath_setup() ensures that clients sharing
6961 * an address are placed on the default group. This guarantees
6962 * that a non-default group will only ever have one client and
6963 * thus make full use of HW filters.
6964 */
6965 if (mac_check_macaddr_shared(mcip->mci_unicast))
6966 return (EINVAL);
6967
6968 err = mac_remove_macaddr_vlan(mcip->mci_unicast, vid);
6969
6970 if (err != 0) {
6971 mac_rx_client_restart((mac_client_handle_t)mcip);
6972 return (err);
6973 }
6974
6975 /*
6976 * If this isn't the primary MAC address then the
6977 * mac_address_t has been freed by the last call to
6978 * mac_remove_macaddr_vlan(). In any case, NULL the reference
6979 * to avoid a dangling pointer.
6980 */
6981 mcip->mci_unicast = NULL;
6982
6983 /*
6984 * We also have to NULL all the mui_map references -- sun4v
6985 * strikes again!
6986 */
6987 rw_enter(&mcip->mci_rw_lock, RW_WRITER);
6988 for (muip = mcip->mci_unicast_list; muip != NULL; muip = muip->mui_next)
6989 muip->mui_map = NULL;
6990 rw_exit(&mcip->mci_rw_lock);
6991
6992 /*
6993 * Program the H/W Classifier first, if this fails we need not
6994 * proceed with the other stuff.
6995 */
6996 if ((err = mac_add_macaddr_vlan(mip, tgrp, maddr, vid, use_hw)) != 0) {
6997 int err2;
6998
6999 /* Revert back the H/W Classifier */
7000 err2 = mac_add_macaddr_vlan(mip, fgrp, maddr, vid, use_hw);
7001
7002 if (err2 != 0) {
7003 cmn_err(CE_WARN, "Failed to revert HW classification"
7004 " on MAC %s, for client %s: %d.", mip->mi_name,
7005 mcip->mci_name, err2);
7006 }
7007
7008 mac_rx_client_restart((mac_client_handle_t)mcip);
7009 return (err);
7010 }
7011
7012 /*
7013 * Get a reference to the new mac_address_t and update the
7014 * client's reference. Then restart the client and add the
7015 * other clients of this MAC addr (if they exsit).
7016 */
7017 mcip->mci_unicast = mac_find_macaddr(mip, maddr);
7018 rw_enter(&mcip->mci_rw_lock, RW_WRITER);
7019 for (muip = mcip->mci_unicast_list; muip != NULL; muip = muip->mui_next)
7020 muip->mui_map = mcip->mci_unicast;
7021 rw_exit(&mcip->mci_rw_lock);
7022 mac_rx_client_restart((mac_client_handle_t)mcip);
7023 return (0);
7024 }
7025
7026 /*
7027 * Switch the MAC client from one group to another. This means we need
7028 * to remove the MAC address from the group, remove the MAC client,
7029 * teardown the SRSs and revert the group state. Then, we add the client
7030 * to the destination group, set the SRSs, and add the MAC address to the
7031 * group.
7032 */
7033 int
7034 mac_rx_switch_group(mac_client_impl_t *mcip, mac_group_t *fgrp,
7035 mac_group_t *tgrp)
7036 {
7037 int err;
7038 mac_group_state_t next_state;
7039 mac_client_impl_t *group_only_mcip;
7040 mac_client_impl_t *gmcip;
7041 mac_impl_t *mip = mcip->mci_mip;
7042 mac_grp_client_t *mgcp;
7043
7044 VERIFY3P(fgrp, ==, mcip->mci_flent->fe_rx_ring_group);
7045
7046 if ((err = mac_rx_move_macaddr(mcip, fgrp, tgrp)) != 0)
7047 return (err);
7048
7049 /*
7050 * If the group is marked as reserved and in use by a single
7051 * client, then there is an SRS to teardown.
7052 */
7053 if (fgrp->mrg_state == MAC_GROUP_STATE_RESERVED &&
7054 MAC_GROUP_ONLY_CLIENT(fgrp) != NULL) {
7055 mac_rx_srs_group_teardown(mcip->mci_flent, B_TRUE);
7056 }
7057
7058 /*
7059 * If we are moving the client from a non-default group, then
7060 * we know that any additional clients on this group share the
7061 * same MAC address. Since we moved the MAC address filter, we
7062 * need to move these clients too.
7063 *
7064 * If we are moving the client from the default group and its
7065 * MAC address has VLAN clients, then we must move those
7066 * clients as well.
7067 *
7068 * In both cases the idea is the same: we moved the MAC
7069 * address filter to the tgrp, so we must move all clients
7070 * using that MAC address to tgrp as well.
7071 */
7072 if (fgrp != MAC_DEFAULT_RX_GROUP(mip)) {
7073 mgcp = fgrp->mrg_clients;
7074 while (mgcp != NULL) {
7075 gmcip = mgcp->mgc_client;
7076 mgcp = mgcp->mgc_next;
7077 mac_group_remove_client(fgrp, gmcip);
7078 mac_group_add_client(tgrp, gmcip);
7079 gmcip->mci_flent->fe_rx_ring_group = tgrp;
7080 }
7081 mac_release_rx_group(mcip, fgrp);
7082 VERIFY3B(MAC_GROUP_NO_CLIENT(fgrp), ==, B_TRUE);
7083 mac_set_group_state(fgrp, MAC_GROUP_STATE_REGISTERED);
7084 } else {
7085 mac_group_remove_client(fgrp, mcip);
7086 mac_group_add_client(tgrp, mcip);
7087 mcip->mci_flent->fe_rx_ring_group = tgrp;
7088
7089 /*
7090 * If there are other clients (VLANs) sharing this address
7091 * then move them too.
7092 */
7093 if (mac_check_macaddr_shared(mcip->mci_unicast)) {
7094 /*
7095 * We need to move all the clients that are using
7096 * this MAC address.
7097 */
7098 mgcp = fgrp->mrg_clients;
7099 while (mgcp != NULL) {
7100 gmcip = mgcp->mgc_client;
7101 mgcp = mgcp->mgc_next;
7102 if (mcip->mci_unicast == gmcip->mci_unicast) {
7103 mac_group_remove_client(fgrp, gmcip);
7104 mac_group_add_client(tgrp, gmcip);
7105 gmcip->mci_flent->fe_rx_ring_group =
7106 tgrp;
7107 }
7108 }
7109 }
7110
7111 /*
7112 * The default group still handles multicast and
7113 * broadcast traffic; it won't transition to
7114 * MAC_GROUP_STATE_REGISTERED.
7115 */
7116 if (fgrp->mrg_state == MAC_GROUP_STATE_RESERVED)
7117 mac_rx_group_unmark(fgrp, MR_CONDEMNED);
7118 mac_set_group_state(fgrp, MAC_GROUP_STATE_SHARED);
7119 }
7120
7121 next_state = mac_group_next_state(tgrp, &group_only_mcip,
7122 MAC_DEFAULT_RX_GROUP(mip), B_TRUE);
7123 mac_set_group_state(tgrp, next_state);
7124
7125 /*
7126 * If the destination group is reserved, then setup the SRSes.
7127 * Otherwise make sure to use SW classification.
7128 */
7129 if (tgrp->mrg_state == MAC_GROUP_STATE_RESERVED) {
7130 mac_rx_srs_group_setup(mcip, mcip->mci_flent, SRST_LINK);
7131 mac_fanout_setup(mcip, mcip->mci_flent,
7132 MCIP_RESOURCE_PROPS(mcip), mac_rx_deliver, mcip, NULL,
7133 NULL);
7134 mac_rx_group_unmark(tgrp, MR_INCIPIENT);
7135 } else {
7136 mac_rx_switch_grp_to_sw(tgrp);
7137 }
7138
7139 return (0);
7140 }
7141
7142 /*
7143 * Reserves a TX group for the specified share. Invoked by mac_tx_srs_setup()
7144 * when a share was allocated to the client.
7145 */
7146 mac_group_t *
7147 mac_reserve_tx_group(mac_client_impl_t *mcip, boolean_t move)
7148 {
7149 mac_impl_t *mip = mcip->mci_mip;
7150 mac_group_t *grp = NULL;
7151 int rv;
7152 int i;
7153 int err;
7154 mac_group_t *defgrp;
7155 mac_share_handle_t share = mcip->mci_share;
7156 mac_resource_props_t *mrp = MCIP_RESOURCE_PROPS(mcip);
7157 int nrings;
7158 int defnrings;
7159 boolean_t need_exclgrp = B_FALSE;
7160 int need_rings = 0;
7161 mac_group_t *candidate_grp = NULL;
7162 mac_client_impl_t *gclient;
7163 mac_resource_props_t *gmrp;
7164 boolean_t txhw = mrp->mrp_mask & MRP_TX_RINGS;
7165 boolean_t unspec = mrp->mrp_mask & MRP_TXRINGS_UNSPEC;
7166 boolean_t isprimary;
7167
7168 isprimary = mcip->mci_flent->fe_type & FLOW_PRIMARY_MAC;
7169
7170 /*
7171 * When we come here for a VLAN on the primary (dladm create-vlan),
7172 * we need to pair it along with the primary (to keep it consistent
7173 * with the RX side). So, we check if the primary is already assigned
7174 * to a group and return the group if so. The other way is also
7175 * true, i.e. the VLAN is already created and now we are plumbing
7176 * the primary.
7177 */
7178 if (!move && isprimary) {
7179 for (gclient = mip->mi_clients_list; gclient != NULL;
7180 gclient = gclient->mci_client_next) {
7181 if (gclient->mci_flent->fe_type & FLOW_PRIMARY_MAC &&
7182 gclient->mci_flent->fe_tx_ring_group != NULL) {
7183 return (gclient->mci_flent->fe_tx_ring_group);
7184 }
7185 }
7186 }
7187
7188 if (mip->mi_tx_groups == NULL || mip->mi_tx_group_count == 0)
7189 return (NULL);
7231 */
7232 if (isprimary && !need_exclgrp)
7233 return (NULL);
7234
7235 nrings = (mrp->mrp_mask & MRP_TX_RINGS) != 0 ? mrp->mrp_ntxrings : 1;
7236 for (i = 0; i < mip->mi_tx_group_count; i++) {
7237 grp = &mip->mi_tx_groups[i];
7238 if ((grp->mrg_state == MAC_GROUP_STATE_RESERVED) ||
7239 (grp->mrg_state == MAC_GROUP_STATE_UNINIT)) {
7240 /*
7241 * Select a candidate for replacement if we don't
7242 * get an exclusive group. A candidate group is one
7243 * that didn't ask for an exclusive group, but got
7244 * one and it has enough rings (combined with what
7245 * the default group can donate) for the new MAC
7246 * client.
7247 */
7248 if (grp->mrg_state == MAC_GROUP_STATE_RESERVED &&
7249 candidate_grp == NULL) {
7250 gclient = MAC_GROUP_ONLY_CLIENT(grp);
7251 VERIFY3P(gclient, !=, NULL);
7252 gmrp = MCIP_RESOURCE_PROPS(gclient);
7253 if (gclient->mci_share == 0 &&
7254 (gmrp->mrp_mask & MRP_TX_RINGS) == 0 &&
7255 (unspec ||
7256 (grp->mrg_cur_count + defnrings) >=
7257 need_rings)) {
7258 candidate_grp = grp;
7259 }
7260 }
7261 continue;
7262 }
7263 /*
7264 * If the default can't donate let's just walk and
7265 * see if someone can vacate a group, so that we have
7266 * enough rings for this.
7267 */
7268 if (mip->mi_tx_group_type != MAC_GROUP_TYPE_DYNAMIC ||
7269 nrings <= defnrings) {
7270 if (grp->mrg_state == MAC_GROUP_STATE_REGISTERED) {
7271 rv = mac_start_group(grp);
7272 ASSERT(rv == 0);
7273 }
7274 break;
7275 }
7276 }
7277
7278 /* The default group */
7279 if (i >= mip->mi_tx_group_count) {
7280 /*
7281 * If we need an exclusive group and have identified a
7282 * candidate group we switch the MAC client from the
7283 * candidate group to the default group and give the
7284 * candidate group to this client.
7285 */
7286 if (need_exclgrp && candidate_grp != NULL) {
7287 /*
7288 * Switch the MAC client from the candidate
7289 * group to the default group. We know the
7290 * candidate_grp came from a reserved group
7291 * and thus only has one client.
7292 */
7293 grp = candidate_grp;
7294 gclient = MAC_GROUP_ONLY_CLIENT(grp);
7295 VERIFY3P(gclient, !=, NULL);
7296 mac_tx_client_quiesce((mac_client_handle_t)gclient);
7297 mac_tx_switch_group(gclient, grp, defgrp);
7298 mac_tx_client_restart((mac_client_handle_t)gclient);
7299
7300 /*
7301 * Give the candidate group with the specified number
7302 * of rings to this MAC client.
7303 */
7304 ASSERT(grp->mrg_state == MAC_GROUP_STATE_REGISTERED);
7305 rv = mac_start_group(grp);
7306 ASSERT(rv == 0);
7307
7308 if (mip->mi_tx_group_type != MAC_GROUP_TYPE_DYNAMIC)
7309 return (grp);
7310
7311 ASSERT(grp->mrg_cur_count == 0);
7312 ASSERT(defgrp->mrg_cur_count > need_rings);
7313
7314 err = i_mac_group_allocate_rings(mip, MAC_RING_TYPE_TX,
7315 defgrp, grp, share, need_rings);
7443 mac_group_t *tgrp)
7444 {
7445 mac_client_impl_t *group_only_mcip;
7446 mac_impl_t *mip = mcip->mci_mip;
7447 flow_entry_t *flent = mcip->mci_flent;
7448 mac_group_t *defgrp;
7449 mac_grp_client_t *mgcp;
7450 mac_client_impl_t *gmcip;
7451 flow_entry_t *gflent;
7452
7453 defgrp = MAC_DEFAULT_TX_GROUP(mip);
7454 ASSERT(fgrp == flent->fe_tx_ring_group);
7455
7456 if (fgrp == defgrp) {
7457 /*
7458 * If this is the primary we need to find any VLANs on
7459 * the primary and move them too.
7460 */
7461 mac_group_remove_client(fgrp, mcip);
7462 mac_tx_dismantle_soft_rings(fgrp, flent);
7463 if (mac_check_macaddr_shared(mcip->mci_unicast)) {
7464 mgcp = fgrp->mrg_clients;
7465 while (mgcp != NULL) {
7466 gmcip = mgcp->mgc_client;
7467 mgcp = mgcp->mgc_next;
7468 if (mcip->mci_unicast != gmcip->mci_unicast)
7469 continue;
7470 mac_tx_client_quiesce(
7471 (mac_client_handle_t)gmcip);
7472
7473 gflent = gmcip->mci_flent;
7474 mac_group_remove_client(fgrp, gmcip);
7475 mac_tx_dismantle_soft_rings(fgrp, gflent);
7476
7477 mac_group_add_client(tgrp, gmcip);
7478 gflent->fe_tx_ring_group = tgrp;
7479 /* We could directly set this to SHARED */
7480 tgrp->mrg_state = mac_group_next_state(tgrp,
7481 &group_only_mcip, defgrp, B_FALSE);
7482
7483 mac_tx_srs_group_setup(gmcip, gflent,
7689 mutex_exit(&mip->mi_bridge_lock);
7690 mac_poll_state_change(mh, B_TRUE);
7691 mac_capab_update(mh);
7692 }
7693
7694 void
7695 mac_no_active(mac_handle_t mh)
7696 {
7697 mac_impl_t *mip = (mac_impl_t *)mh;
7698
7699 i_mac_perim_enter(mip);
7700 mip->mi_state_flags |= MIS_NO_ACTIVE;
7701 i_mac_perim_exit(mip);
7702 }
7703
7704 /*
7705 * Walk the primary VLAN clients whenever the primary's rings property
7706 * changes and update the mac_resource_props_t for the VLAN's client.
7707 * We need to do this since we don't support setting these properties
7708 * on the primary's VLAN clients, but the VLAN clients have to
7709 * follow the primary w.r.t the rings property.
7710 */
7711 void
7712 mac_set_prim_vlan_rings(mac_impl_t *mip, mac_resource_props_t *mrp)
7713 {
7714 mac_client_impl_t *vmcip;
7715 mac_resource_props_t *vmrp;
7716
7717 for (vmcip = mip->mi_clients_list; vmcip != NULL;
7718 vmcip = vmcip->mci_client_next) {
7719 if (!(vmcip->mci_flent->fe_type & FLOW_PRIMARY_MAC) ||
7720 mac_client_vid((mac_client_handle_t)vmcip) ==
7721 VLAN_ID_NONE) {
7722 continue;
7723 }
7724 vmrp = MCIP_RESOURCE_PROPS(vmcip);
7725
7726 vmrp->mrp_nrxrings = mrp->mrp_nrxrings;
7727 if (mrp->mrp_mask & MRP_RX_RINGS)
7728 vmrp->mrp_mask |= MRP_RX_RINGS;
7729 else if (vmrp->mrp_mask & MRP_RX_RINGS)
7838 start = 1;
7839 end = mip->mi_rx_group_count;
7840 } else {
7841 start = 0;
7842 end = mip->mi_tx_group_count - 1;
7843 }
7844 /*
7845 * If the default doesn't have any rings, lets see if we can
7846 * take rings given to an h/w client that doesn't need it.
7847 * For now, we just see if there is any one client that can donate
7848 * all the required rings.
7849 */
7850 if (defgrp->mrg_cur_count < (modify + 1)) {
7851 for (i = start; i < end; i++) {
7852 if (rx_group) {
7853 tgrp = &mip->mi_rx_groups[i];
7854 if (tgrp == group || tgrp->mrg_state <
7855 MAC_GROUP_STATE_RESERVED) {
7856 continue;
7857 }
7858 if (i_mac_clients_hw(tgrp, MRP_RX_RINGS))
7859 continue;
7860 mcip = tgrp->mrg_clients->mgc_client;
7861 VERIFY3P(mcip, !=, NULL);
7862 if ((tgrp->mrg_cur_count +
7863 defgrp->mrg_cur_count) < (modify + 1)) {
7864 continue;
7865 }
7866 if (mac_rx_switch_group(mcip, tgrp,
7867 defgrp) != 0) {
7868 return (ENOSPC);
7869 }
7870 } else {
7871 tgrp = &mip->mi_tx_groups[i];
7872 if (tgrp == group || tgrp->mrg_state <
7873 MAC_GROUP_STATE_RESERVED) {
7874 continue;
7875 }
7876 if (i_mac_clients_hw(tgrp, MRP_TX_RINGS))
7877 continue;
7878 mcip = tgrp->mrg_clients->mgc_client;
7879 VERIFY3P(mcip, !=, NULL);
7880 if ((tgrp->mrg_cur_count +
7881 defgrp->mrg_cur_count) < (modify + 1)) {
7882 continue;
7883 }
7884 /* OK, we can switch this to s/w */
7885 mac_tx_client_quiesce(
7886 (mac_client_handle_t)mcip);
7887 mac_tx_switch_group(mcip, tgrp, defgrp);
7888 mac_tx_client_restart(
7889 (mac_client_handle_t)mcip);
7890 }
7891 }
7892 if (defgrp->mrg_cur_count < (modify + 1))
7893 return (ENOSPC);
7894 }
7895 if ((rv = i_mac_group_allocate_rings(mip, group->mrg_type, defgrp,
7896 group, mcip->mci_share, modify)) != 0) {
7897 return (rv);
7898 }
7899 return (0);
8132
8133 default:
8134 kmem_free(mpa, sizeof (struct mac_pool_arg));
8135 pool_unlock();
8136 return;
8137 }
8138 pool_unlock();
8139
8140 mpa->mpa_what = what;
8141
8142 mac_pool_update(mpa);
8143 }
8144
8145 /*
8146 * Set effective rings property. This could be called from datapath_setup/
8147 * datapath_teardown or set-linkprop.
8148 * If the group is reserved we just go ahead and set the effective rings.
8149 * Additionally, for TX this could mean the default group has lost/gained
8150 * some rings, so if the default group is reserved, we need to adjust the
8151 * effective rings for the default group clients. For RX, if we are working
8152 * with the non-default group, we just need to reset the effective props
8153 * for the default group clients.
8154 */
8155 void
8156 mac_set_rings_effective(mac_client_impl_t *mcip)
8157 {
8158 mac_impl_t *mip = mcip->mci_mip;
8159 mac_group_t *grp;
8160 mac_group_t *defgrp;
8161 flow_entry_t *flent = mcip->mci_flent;
8162 mac_resource_props_t *emrp = MCIP_EFFECTIVE_PROPS(mcip);
8163 mac_grp_client_t *mgcp;
8164 mac_client_impl_t *gmcip;
8165
8166 grp = flent->fe_rx_ring_group;
8167 if (grp != NULL) {
8168 defgrp = MAC_DEFAULT_RX_GROUP(mip);
8169 /*
8170 * If we have reserved a group, set the effective rings
8171 * to the ring count in the group.
8172 */
8262 * Check if the primary is in the default group, if not
8263 * or if it is explicitly configured to be in the default
8264 * group OR set the RX rings property, return.
8265 */
8266 if (flent->fe_rx_ring_group != defgrp || mrp->mrp_mask & MRP_RX_RINGS)
8267 return (NULL);
8268
8269 /*
8270 * If the new client needs an exclusive group and we
8271 * don't have another for the primary, return.
8272 */
8273 if (rxhw && mip->mi_rxhwclnt_avail < 2)
8274 return (NULL);
8275
8276 mac_addr = flent->fe_flow_desc.fd_dst_mac;
8277 /*
8278 * We call this when we are setting up the datapath for
8279 * the first non-primary.
8280 */
8281 ASSERT(mip->mi_nactiveclients == 2);
8282
8283 /*
8284 * OK, now we have the primary that needs to be relocated.
8285 */
8286 ngrp = mac_reserve_rx_group(mcip, mac_addr, B_TRUE);
8287 if (ngrp == NULL)
8288 return (NULL);
8289 if (mac_rx_switch_group(mcip, defgrp, ngrp) != 0) {
8290 mac_stop_group(ngrp);
8291 return (NULL);
8292 }
8293 return (mcip);
8294 }
8295
8296 void
8297 mac_transceiver_init(mac_impl_t *mip)
8298 {
8299 if (mac_capab_get((mac_handle_t)mip, MAC_CAPAB_TRANSCEIVER,
8300 &mip->mi_transceiver)) {
8301 /*
8302 * The driver set a flag that we don't know about. In this case,
|