1440 mac_impl_t *mip = (mac_impl_t *)mh;
1441
1442 return (mip->mi_factory_addr_num);
1443 }
1444
1445
1446 void
1447 mac_rx_group_unmark(mac_group_t *grp, uint_t flag)
1448 {
1449 mac_ring_t *ring;
1450
1451 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next)
1452 ring->mr_flag &= ~flag;
1453 }
1454
1455 /*
1456 * The following mac_hwrings_xxx() functions are private mac client functions
1457 * used by the aggr driver to access and control the underlying HW Rx group
1458 * and rings. In this case, the aggr driver has exclusive control of the
1459 * underlying HW Rx group/rings, it calls the following functions to
1460 * start/stop the HW Rx rings, disable/enable polling, add/remove mac'
1461 * addresses, or set up the Rx callback.
1462 */
1463 /* ARGSUSED */
1464 static void
1465 mac_hwrings_rx_process(void *arg, mac_resource_handle_t srs,
1466 mblk_t *mp_chain, boolean_t loopback)
1467 {
1468 mac_soft_ring_set_t *mac_srs = (mac_soft_ring_set_t *)srs;
1469 mac_srs_rx_t *srs_rx = &mac_srs->srs_rx;
1470 mac_direct_rx_t proc;
1471 void *arg1;
1472 mac_resource_handle_t arg2;
1473
1474 proc = srs_rx->sr_func;
1475 arg1 = srs_rx->sr_arg1;
1476 arg2 = mac_srs->srs_mrh;
1477
1478 proc(arg1, arg2, mp_chain, NULL);
1479 }
1480
1485 * Return value: the number of HW rings.
1486 */
1487 int
1488 mac_hwrings_get(mac_client_handle_t mch, mac_group_handle_t *hwgh,
1489 mac_ring_handle_t *hwrh, mac_ring_type_t rtype)
1490 {
1491 mac_client_impl_t *mcip = (mac_client_impl_t *)mch;
1492 flow_entry_t *flent = mcip->mci_flent;
1493 mac_group_t *grp;
1494 mac_ring_t *ring;
1495 int cnt = 0;
1496
1497 if (rtype == MAC_RING_TYPE_RX) {
1498 grp = flent->fe_rx_ring_group;
1499 } else if (rtype == MAC_RING_TYPE_TX) {
1500 grp = flent->fe_tx_ring_group;
1501 } else {
1502 ASSERT(B_FALSE);
1503 return (-1);
1504 }
1505 /*
1506 * The mac client did not reserve any RX group, return directly.
1507 * This is probably because the underlying MAC does not support
1508 * any groups.
1509 */
1510 if (hwgh != NULL)
1511 *hwgh = NULL;
1512 if (grp == NULL)
1513 return (0);
1514 /*
1515 * This group must be reserved by this mac client.
1516 */
1517 ASSERT((grp->mrg_state == MAC_GROUP_STATE_RESERVED) &&
1518 (mcip == MAC_GROUP_ONLY_CLIENT(grp)));
1519
1520 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next, cnt++) {
1521 ASSERT(cnt < MAX_RINGS_PER_GROUP);
1522 hwrh[cnt] = (mac_ring_handle_t)ring;
1523 }
1524 if (hwgh != NULL)
1525 *hwgh = (mac_group_handle_t)grp;
1526
1527 return (cnt);
1528 }
1529
1530 /*
1531 * This function is called to get info about Tx/Rx rings.
1532 *
1533 * Return value: returns uint_t which will have various bits set
1534 * that indicates different properties of the ring.
1535 */
1536 uint_t
1537 mac_hwring_getinfo(mac_ring_handle_t rh)
1538 {
1539 mac_ring_t *ring = (mac_ring_t *)rh;
1540 mac_ring_info_t *info = &ring->mr_info;
1541
1542 return (info->mri_flags);
1543 }
1544
1545 /*
1546 * Export ddi interrupt handles from the HW ring to the pseudo ring and
1547 * setup the RX callback of the mac client which exclusively controls
1548 * HW ring.
1549 */
1550 void
1551 mac_hwring_setup(mac_ring_handle_t hwrh, mac_resource_handle_t prh,
1552 mac_ring_handle_t pseudo_rh)
1553 {
1554 mac_ring_t *hw_ring = (mac_ring_t *)hwrh;
1555 mac_ring_t *pseudo_ring;
1556 mac_soft_ring_set_t *mac_srs = hw_ring->mr_srs;
1557
1558 if (pseudo_rh != NULL) {
1559 pseudo_ring = (mac_ring_t *)pseudo_rh;
1560 /* Export the ddi handles to pseudo ring */
1561 pseudo_ring->mr_info.mri_intr.mi_ddi_handle =
1562 hw_ring->mr_info.mri_intr.mi_ddi_handle;
1563 pseudo_ring->mr_info.mri_intr.mi_ddi_shared =
1564 hw_ring->mr_info.mri_intr.mi_ddi_shared;
1565 /*
1597 }
1598
1599 int
1600 mac_hwring_disable_intr(mac_ring_handle_t rh)
1601 {
1602 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1603 mac_intr_t *intr = &rr_ring->mr_info.mri_intr;
1604
1605 return (intr->mi_disable(intr->mi_handle));
1606 }
1607
1608 int
1609 mac_hwring_enable_intr(mac_ring_handle_t rh)
1610 {
1611 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1612 mac_intr_t *intr = &rr_ring->mr_info.mri_intr;
1613
1614 return (intr->mi_enable(intr->mi_handle));
1615 }
1616
1617 int
1618 mac_hwring_start(mac_ring_handle_t rh)
1619 {
1620 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1621
1622 MAC_RING_UNMARK(rr_ring, MR_QUIESCE);
1623 return (0);
1624 }
1625
1626 void
1627 mac_hwring_stop(mac_ring_handle_t rh)
1628 {
1629 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1630
1631 mac_rx_ring_quiesce(rr_ring, MR_QUIESCE);
1632 }
1633
1634 mblk_t *
1635 mac_hwring_poll(mac_ring_handle_t rh, int bytes_to_pickup)
1636 {
1637 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1638 mac_ring_info_t *info = &rr_ring->mr_info;
1639
1640 return (info->mri_poll(info->mri_driver, bytes_to_pickup));
1641 }
1642
1643 /*
1644 * Send packets through a selected tx ring.
1645 */
1646 mblk_t *
1647 mac_hwring_tx(mac_ring_handle_t rh, mblk_t *mp)
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
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);
2497 flent = mcip->mci_flent;
2498 FLOW_TRY_REFHOLD(flent, err);
2499 if (err != 0)
2500 return (mp);
3794 /*
3795 * Called from mac_start() on the default Rx group. Broadcast and multicast
3796 * packets are received only on the default group. Hence the default group
3797 * needs to be up even if the primary client is not up, for the other groups
3798 * to be functional. We do this by calling this function at mac_start time
3799 * itself. However the broadcast packets that are received can't make their
3800 * way beyond mac_rx until a mac client creates a broadcast flow.
3801 */
3802 static int
3803 mac_start_group_and_rings(mac_group_t *group)
3804 {
3805 mac_ring_t *ring;
3806 int rv = 0;
3807
3808 ASSERT(group->mrg_state == MAC_GROUP_STATE_REGISTERED);
3809 if ((rv = mac_start_group(group)) != 0)
3810 return (rv);
3811
3812 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) {
3813 ASSERT(ring->mr_state == MR_FREE);
3814 if ((rv = mac_start_ring(ring)) != 0)
3815 goto error;
3816 ring->mr_classify_type = MAC_SW_CLASSIFIER;
3817 }
3818 return (0);
3819
3820 error:
3821 mac_stop_group_and_rings(group);
3822 return (rv);
3823 }
3824
3825 /* Called from mac_stop on the default Rx group */
3826 static void
3827 mac_stop_group_and_rings(mac_group_t *group)
3828 {
3829 mac_ring_t *ring;
3830
3831 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) {
3832 if (ring->mr_state != MR_FREE) {
3833 mac_stop_ring(ring);
3834 ring->mr_flag = 0;
3835 ring->mr_classify_type = MAC_NO_CLASSIFIER;
3836 }
|
1440 mac_impl_t *mip = (mac_impl_t *)mh;
1441
1442 return (mip->mi_factory_addr_num);
1443 }
1444
1445
1446 void
1447 mac_rx_group_unmark(mac_group_t *grp, uint_t flag)
1448 {
1449 mac_ring_t *ring;
1450
1451 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next)
1452 ring->mr_flag &= ~flag;
1453 }
1454
1455 /*
1456 * The following mac_hwrings_xxx() functions are private mac client functions
1457 * used by the aggr driver to access and control the underlying HW Rx group
1458 * and rings. In this case, the aggr driver has exclusive control of the
1459 * underlying HW Rx group/rings, it calls the following functions to
1460 * start/stop the HW Rx rings, disable/enable polling, add/remove MAC
1461 * addresses, or set up the Rx callback.
1462 */
1463 /* ARGSUSED */
1464 static void
1465 mac_hwrings_rx_process(void *arg, mac_resource_handle_t srs,
1466 mblk_t *mp_chain, boolean_t loopback)
1467 {
1468 mac_soft_ring_set_t *mac_srs = (mac_soft_ring_set_t *)srs;
1469 mac_srs_rx_t *srs_rx = &mac_srs->srs_rx;
1470 mac_direct_rx_t proc;
1471 void *arg1;
1472 mac_resource_handle_t arg2;
1473
1474 proc = srs_rx->sr_func;
1475 arg1 = srs_rx->sr_arg1;
1476 arg2 = mac_srs->srs_mrh;
1477
1478 proc(arg1, arg2, mp_chain, NULL);
1479 }
1480
1485 * Return value: the number of HW rings.
1486 */
1487 int
1488 mac_hwrings_get(mac_client_handle_t mch, mac_group_handle_t *hwgh,
1489 mac_ring_handle_t *hwrh, mac_ring_type_t rtype)
1490 {
1491 mac_client_impl_t *mcip = (mac_client_impl_t *)mch;
1492 flow_entry_t *flent = mcip->mci_flent;
1493 mac_group_t *grp;
1494 mac_ring_t *ring;
1495 int cnt = 0;
1496
1497 if (rtype == MAC_RING_TYPE_RX) {
1498 grp = flent->fe_rx_ring_group;
1499 } else if (rtype == MAC_RING_TYPE_TX) {
1500 grp = flent->fe_tx_ring_group;
1501 } else {
1502 ASSERT(B_FALSE);
1503 return (-1);
1504 }
1505
1506 /*
1507 * The MAC client did not reserve an Rx group, return directly.
1508 * This is probably because the underlying MAC does not support
1509 * any groups.
1510 */
1511 if (hwgh != NULL)
1512 *hwgh = NULL;
1513 if (grp == NULL)
1514 return (0);
1515 /*
1516 * This group must be reserved by this MAC client.
1517 */
1518 ASSERT((grp->mrg_state == MAC_GROUP_STATE_RESERVED) &&
1519 (mcip == MAC_GROUP_ONLY_CLIENT(grp)));
1520
1521 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next, cnt++) {
1522 ASSERT(cnt < MAX_RINGS_PER_GROUP);
1523 hwrh[cnt] = (mac_ring_handle_t)ring;
1524 }
1525 if (hwgh != NULL)
1526 *hwgh = (mac_group_handle_t)grp;
1527
1528 return (cnt);
1529 }
1530
1531 /*
1532 * Get the HW ring handles of the given group index. If the MAC
1533 * doesn't have a group at this index, or any groups at all, then 0 is
1534 * returned and hwgh is set to NULL. This is a private client API. The
1535 * MAC perimeter must be held when calling this function.
1536 *
1537 * mh: A handle to the MAC that owns the group.
1538 *
1539 * idx: The index of the HW group to be read.
1540 *
1541 * hwgh: If non-NULL, contains a handle to the HW group on return.
1542 *
1543 * hwrh: An array of ring handles pointing to the HW rings in the
1544 * group. The array must be large enough to hold a handle to each ring
1545 * in the group. To be safe, this array should be of size MAX_RINGS_PER_GROUP.
1546 *
1547 * rtype: Used to determine if we are fetching Rx or Tx rings.
1548 *
1549 * Returns the number of rings in the group.
1550 */
1551 uint_t
1552 mac_hwrings_idx_get(mac_handle_t mh, uint_t idx, mac_group_handle_t *hwgh,
1553 mac_ring_handle_t *hwrh, mac_ring_type_t rtype)
1554 {
1555 mac_impl_t *mip = (mac_impl_t *)mh;
1556 mac_group_t *grp;
1557 mac_ring_t *ring;
1558 uint_t cnt = 0;
1559
1560 /*
1561 * The MAC perimeter must be held when accessing the
1562 * mi_{rx,tx}_groups fields.
1563 */
1564 ASSERT(MAC_PERIM_HELD(mh));
1565 ASSERT(rtype == MAC_RING_TYPE_RX || rtype == MAC_RING_TYPE_TX);
1566
1567 if (rtype == MAC_RING_TYPE_RX) {
1568 grp = mip->mi_rx_groups;
1569 } else if (rtype == MAC_RING_TYPE_TX) {
1570 grp = mip->mi_tx_groups;
1571 }
1572
1573 while (grp != NULL && grp->mrg_index != idx)
1574 grp = grp->mrg_next;
1575
1576 /*
1577 * If the MAC doesn't have a group at this index or doesn't
1578 * impelement RINGS capab, then set hwgh to NULL and return 0.
1579 */
1580 if (hwgh != NULL)
1581 *hwgh = NULL;
1582
1583 if (grp == NULL)
1584 return (0);
1585
1586 ASSERT3U(idx, ==, grp->mrg_index);
1587
1588 for (ring = grp->mrg_rings; ring != NULL; ring = ring->mr_next, cnt++) {
1589 ASSERT3U(cnt, <, MAX_RINGS_PER_GROUP);
1590 hwrh[cnt] = (mac_ring_handle_t)ring;
1591 }
1592
1593 /* A group should always have at least one ring. */
1594 ASSERT3U(cnt, >, 0);
1595
1596 if (hwgh != NULL)
1597 *hwgh = (mac_group_handle_t)grp;
1598
1599 return (cnt);
1600 }
1601
1602 /*
1603 * This function is called to get info about Tx/Rx rings.
1604 *
1605 * Return value: returns uint_t which will have various bits set
1606 * that indicates different properties of the ring.
1607 */
1608 uint_t
1609 mac_hwring_getinfo(mac_ring_handle_t rh)
1610 {
1611 mac_ring_t *ring = (mac_ring_t *)rh;
1612 mac_ring_info_t *info = &ring->mr_info;
1613
1614 return (info->mri_flags);
1615 }
1616
1617 /*
1618 * Set the passthru callback on the hardware ring.
1619 */
1620 void
1621 mac_hwring_set_passthru(mac_ring_handle_t hwrh, mac_rx_t fn, void *arg1,
1622 mac_resource_handle_t arg2)
1623 {
1624 mac_ring_t *hwring = (mac_ring_t *)hwrh;
1625
1626 ASSERT3S(hwring->mr_type, ==, MAC_RING_TYPE_RX);
1627
1628 hwring->mr_classify_type = MAC_PASSTHRU_CLASSIFIER;
1629
1630 hwring->mr_pt_fn = fn;
1631 hwring->mr_pt_arg1 = arg1;
1632 hwring->mr_pt_arg2 = arg2;
1633 }
1634
1635 /*
1636 * Clear the passthru callback on the hardware ring.
1637 */
1638 void
1639 mac_hwring_clear_passthru(mac_ring_handle_t hwrh)
1640 {
1641 mac_ring_t *hwring = (mac_ring_t *)hwrh;
1642
1643 ASSERT3S(hwring->mr_type, ==, MAC_RING_TYPE_RX);
1644
1645 hwring->mr_classify_type = MAC_NO_CLASSIFIER;
1646
1647 hwring->mr_pt_fn = NULL;
1648 hwring->mr_pt_arg1 = NULL;
1649 hwring->mr_pt_arg2 = NULL;
1650 }
1651
1652 void
1653 mac_client_set_flow_cb(mac_client_handle_t mch, mac_rx_t func, void *arg1)
1654 {
1655 mac_client_impl_t *mcip = (mac_client_impl_t *)mch;
1656 flow_entry_t *flent = mcip->mci_flent;
1657
1658 mutex_enter(&flent->fe_lock);
1659 flent->fe_cb_fn = (flow_fn_t)func;
1660 flent->fe_cb_arg1 = arg1;
1661 flent->fe_cb_arg2 = NULL;
1662 flent->fe_flags &= ~FE_MC_NO_DATAPATH;
1663 mutex_exit(&flent->fe_lock);
1664 }
1665
1666 void
1667 mac_client_clear_flow_cb(mac_client_handle_t mch)
1668 {
1669 mac_client_impl_t *mcip = (mac_client_impl_t *)mch;
1670 flow_entry_t *flent = mcip->mci_flent;
1671
1672 mutex_enter(&flent->fe_lock);
1673 flent->fe_cb_fn = (flow_fn_t)mac_pkt_drop;
1674 flent->fe_cb_arg1 = NULL;
1675 flent->fe_cb_arg2 = NULL;
1676 flent->fe_flags |= FE_MC_NO_DATAPATH;
1677 mutex_exit(&flent->fe_lock);
1678 }
1679
1680 /*
1681 * Export ddi interrupt handles from the HW ring to the pseudo ring and
1682 * setup the RX callback of the mac client which exclusively controls
1683 * HW ring.
1684 */
1685 void
1686 mac_hwring_setup(mac_ring_handle_t hwrh, mac_resource_handle_t prh,
1687 mac_ring_handle_t pseudo_rh)
1688 {
1689 mac_ring_t *hw_ring = (mac_ring_t *)hwrh;
1690 mac_ring_t *pseudo_ring;
1691 mac_soft_ring_set_t *mac_srs = hw_ring->mr_srs;
1692
1693 if (pseudo_rh != NULL) {
1694 pseudo_ring = (mac_ring_t *)pseudo_rh;
1695 /* Export the ddi handles to pseudo ring */
1696 pseudo_ring->mr_info.mri_intr.mi_ddi_handle =
1697 hw_ring->mr_info.mri_intr.mi_ddi_handle;
1698 pseudo_ring->mr_info.mri_intr.mi_ddi_shared =
1699 hw_ring->mr_info.mri_intr.mi_ddi_shared;
1700 /*
1732 }
1733
1734 int
1735 mac_hwring_disable_intr(mac_ring_handle_t rh)
1736 {
1737 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1738 mac_intr_t *intr = &rr_ring->mr_info.mri_intr;
1739
1740 return (intr->mi_disable(intr->mi_handle));
1741 }
1742
1743 int
1744 mac_hwring_enable_intr(mac_ring_handle_t rh)
1745 {
1746 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1747 mac_intr_t *intr = &rr_ring->mr_info.mri_intr;
1748
1749 return (intr->mi_enable(intr->mi_handle));
1750 }
1751
1752 /*
1753 * Start the HW ring pointed to by rh.
1754 *
1755 * This is used by special MAC clients that are MAC themselves and
1756 * need to exert control over the underlying HW rings of the NIC.
1757 */
1758 int
1759 mac_hwring_start(mac_ring_handle_t rh)
1760 {
1761 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1762 int rv = 0;
1763
1764 if (rr_ring->mr_state != MR_INUSE)
1765 rv = mac_start_ring(rr_ring);
1766
1767 return (rv);
1768 }
1769
1770 /*
1771 * Stop the HW ring pointed to by rh. Also see mac_hwring_start().
1772 */
1773 void
1774 mac_hwring_stop(mac_ring_handle_t rh)
1775 {
1776 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1777
1778 if (rr_ring->mr_state != MR_FREE)
1779 mac_stop_ring(rr_ring);
1780 }
1781
1782 /*
1783 * Remove the quiesced flag from the HW ring pointed to by rh.
1784 *
1785 * This is used by special MAC clients that are MAC themselves and
1786 * need to exert control over the underlying HW rings of the NIC.
1787 */
1788 int
1789 mac_hwring_activate(mac_ring_handle_t rh)
1790 {
1791 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1792
1793 MAC_RING_UNMARK(rr_ring, MR_QUIESCE);
1794 return (0);
1795 }
1796
1797 /*
1798 * Quiesce the HW ring pointed to by rh. Also see mac_hwring_activate().
1799 */
1800 void
1801 mac_hwring_quiesce(mac_ring_handle_t rh)
1802 {
1803 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1804
1805 mac_rx_ring_quiesce(rr_ring, MR_QUIESCE);
1806 }
1807
1808 mblk_t *
1809 mac_hwring_poll(mac_ring_handle_t rh, int bytes_to_pickup)
1810 {
1811 mac_ring_t *rr_ring = (mac_ring_t *)rh;
1812 mac_ring_info_t *info = &rr_ring->mr_info;
1813
1814 return (info->mri_poll(info->mri_driver, bytes_to_pickup));
1815 }
1816
1817 /*
1818 * Send packets through a selected tx ring.
1819 */
1820 mblk_t *
1821 mac_hwring_tx(mac_ring_handle_t rh, mblk_t *mp)
1929 return (0);
1930
1931 return (mac_group_remvlan(group, vid));
1932 }
1933
1934 /*
1935 * Determine if a MAC has HW VLAN support. This is a private API
1936 * consumed by aggr. In the future it might be nice to have a bitfield
1937 * in mac_capab_rings_t to track which forms of HW filtering are
1938 * supported by the MAC.
1939 */
1940 boolean_t
1941 mac_has_hw_vlan(mac_handle_t mh)
1942 {
1943 mac_impl_t *mip = (mac_impl_t *)mh;
1944
1945 return (MAC_GROUP_HW_VLAN(mip->mi_rx_groups));
1946 }
1947
1948 /*
1949 * Get the number of Rx HW groups on this MAC.
1950 */
1951 uint_t
1952 mac_get_num_rx_groups(mac_handle_t mh)
1953 {
1954 mac_impl_t *mip = (mac_impl_t *)mh;
1955
1956 ASSERT(MAC_PERIM_HELD(mh));
1957 return (mip->mi_rx_group_count);
1958 }
1959
1960 int
1961 mac_set_promisc(mac_handle_t mh, boolean_t value)
1962 {
1963 mac_impl_t *mip = (mac_impl_t *)mh;
1964
1965 ASSERT(MAC_PERIM_HELD(mh));
1966 return (i_mac_promisc_set(mip, value));
1967 }
1968
1969 /*
1970 * Set the RX group to be shared/reserved. Note that the group must be
1971 * started/stopped outside of this function.
1972 */
1973 void
1974 mac_set_group_state(mac_group_t *grp, mac_group_state_t state)
1975 {
1976 /*
1977 * If there is no change in the group state, just return.
1978 */
1979 if (grp->mrg_state == state)
1980 return;
1981
1982 switch (state) {
1983 case MAC_GROUP_STATE_RESERVED:
1984 /*
1985 * Successfully reserved the group.
1986 *
1987 * Given that there is an exclusive client controlling this
1988 * group, we enable the group level polling when available,
1989 * so that SRSs get to turn on/off individual rings they's
2643 * Clean up notification thread and wait for it to exit.
2644 */
2645 if (err == 0)
2646 i_mac_notify_exit(mip);
2647
2648 return (err);
2649 }
2650
2651 /*
2652 * Called when the MAC instance has a non empty flow table, to de-multiplex
2653 * incoming packets to the right flow.
2654 */
2655 /* ARGSUSED */
2656 static mblk_t *
2657 mac_rx_classify(mac_impl_t *mip, mac_resource_handle_t mrh, mblk_t *mp)
2658 {
2659 flow_entry_t *flent = NULL;
2660 uint_t flags = FLOW_INBOUND;
2661 int err;
2662
2663 err = mac_flow_lookup(mip->mi_flow_tab, mp, flags, &flent);
2664 if (err != 0) {
2665 /* no registered receive function */
2666 return (mp);
2667 } else {
2668 mac_client_impl_t *mcip;
2669
2670 /*
2671 * This flent might just be an additional one on the MAC client,
2672 * i.e. for classification purposes (different fdesc), however
2673 * the resources, SRS et. al., are in the mci_flent, so if
2674 * this isn't the mci_flent, we need to get it.
2675 */
2676 if ((mcip = flent->fe_mcip) != NULL &&
2677 mcip->mci_flent != flent) {
2678 FLOW_REFRELE(flent);
2679 flent = mcip->mci_flent;
2680 FLOW_TRY_REFHOLD(flent, err);
2681 if (err != 0)
2682 return (mp);
3976 /*
3977 * Called from mac_start() on the default Rx group. Broadcast and multicast
3978 * packets are received only on the default group. Hence the default group
3979 * needs to be up even if the primary client is not up, for the other groups
3980 * to be functional. We do this by calling this function at mac_start time
3981 * itself. However the broadcast packets that are received can't make their
3982 * way beyond mac_rx until a mac client creates a broadcast flow.
3983 */
3984 static int
3985 mac_start_group_and_rings(mac_group_t *group)
3986 {
3987 mac_ring_t *ring;
3988 int rv = 0;
3989
3990 ASSERT(group->mrg_state == MAC_GROUP_STATE_REGISTERED);
3991 if ((rv = mac_start_group(group)) != 0)
3992 return (rv);
3993
3994 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) {
3995 ASSERT(ring->mr_state == MR_FREE);
3996
3997 if ((rv = mac_start_ring(ring)) != 0)
3998 goto error;
3999
4000 /*
4001 * When aggr_set_port_sdu() is called, it will remove
4002 * the port client's unicast address. This will cause
4003 * MAC to stop the default group's rings on the port
4004 * MAC. After it modifies the SDU, it will then re-add
4005 * the unicast address. At which time, this function is
4006 * called to start the default group's rings. Normally
4007 * this function would set the classify type to
4008 * MAC_SW_CLASSIFIER; but that will break aggr which
4009 * relies on the passthru classify mode being set for
4010 * correct delivery (see mac_rx_common()). To avoid
4011 * that, we check for a passthru callback and set the
4012 * classify type to MAC_PASSTHRU_CLASSIFIER; as it was
4013 * before the rings were stopped.
4014 */
4015 ring->mr_classify_type = (ring->mr_pt_fn != NULL) ?
4016 MAC_PASSTHRU_CLASSIFIER : MAC_SW_CLASSIFIER;
4017 }
4018 return (0);
4019
4020 error:
4021 mac_stop_group_and_rings(group);
4022 return (rv);
4023 }
4024
4025 /* Called from mac_stop on the default Rx group */
4026 static void
4027 mac_stop_group_and_rings(mac_group_t *group)
4028 {
4029 mac_ring_t *ring;
4030
4031 for (ring = group->mrg_rings; ring != NULL; ring = ring->mr_next) {
4032 if (ring->mr_state != MR_FREE) {
4033 mac_stop_ring(ring);
4034 ring->mr_flag = 0;
4035 ring->mr_classify_type = MAC_NO_CLASSIFIER;
4036 }
|