ocelot.c (d0a31acc34dc2921ad32a67a7534704114e64f82) ocelot.c (e1846cff2fe614d93a2f89461b5935678fd34bd9)
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Microsemi Ocelot Switch driver
4 *
5 * Copyright (c) 2017 Microsemi Corporation
6 */
7#include <linux/dsa/ocelot.h>
8#include <linux/if_bridge.h>

--- 537 unchanged lines hidden (view full) ---

546}
547
548int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
549 bool vlan_aware, struct netlink_ext_ack *extack)
550{
551 struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1];
552 struct ocelot_port *ocelot_port = ocelot->ports[port];
553 struct ocelot_vcap_filter *filter;
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Microsemi Ocelot Switch driver
4 *
5 * Copyright (c) 2017 Microsemi Corporation
6 */
7#include <linux/dsa/ocelot.h>
8#include <linux/if_bridge.h>

--- 537 unchanged lines hidden (view full) ---

546}
547
548int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
549 bool vlan_aware, struct netlink_ext_ack *extack)
550{
551 struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1];
552 struct ocelot_port *ocelot_port = ocelot->ports[port];
553 struct ocelot_vcap_filter *filter;
554 int err;
554 int err = 0;
555 u32 val;
556
557 list_for_each_entry(filter, &block->rules, list) {
558 if (filter->ingress_port_mask & BIT(port) &&
559 filter->action.vid_replace_ena) {
560 NL_SET_ERR_MSG_MOD(extack,
561 "Cannot change VLAN state with vlan modify rules active");
562 return -EBUSY;
563 }
564 }
565
566 err = ocelot_single_vlan_aware_bridge(ocelot, extack);
567 if (err)
568 return err;
569
570 if (vlan_aware)
571 err = ocelot_del_vlan_unaware_pvid(ocelot, port,
572 ocelot_port->bridge);
555 u32 val;
556
557 list_for_each_entry(filter, &block->rules, list) {
558 if (filter->ingress_port_mask & BIT(port) &&
559 filter->action.vid_replace_ena) {
560 NL_SET_ERR_MSG_MOD(extack,
561 "Cannot change VLAN state with vlan modify rules active");
562 return -EBUSY;
563 }
564 }
565
566 err = ocelot_single_vlan_aware_bridge(ocelot, extack);
567 if (err)
568 return err;
569
570 if (vlan_aware)
571 err = ocelot_del_vlan_unaware_pvid(ocelot, port,
572 ocelot_port->bridge);
573 else
573 else if (ocelot_port->bridge)
574 err = ocelot_add_vlan_unaware_pvid(ocelot, port,
575 ocelot_port->bridge);
576 if (err)
577 return err;
578
579 ocelot_port->vlan_aware = vlan_aware;
580
581 if (vlan_aware)

--- 42 unchanged lines hidden (view full) ---

624}
625EXPORT_SYMBOL(ocelot_vlan_prepare);
626
627int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
628 bool untagged)
629{
630 int err;
631
574 err = ocelot_add_vlan_unaware_pvid(ocelot, port,
575 ocelot_port->bridge);
576 if (err)
577 return err;
578
579 ocelot_port->vlan_aware = vlan_aware;
580
581 if (vlan_aware)

--- 42 unchanged lines hidden (view full) ---

624}
625EXPORT_SYMBOL(ocelot_vlan_prepare);
626
627int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
628 bool untagged)
629{
630 int err;
631
632 /* Ignore VID 0 added to our RX filter by the 8021q module, since
633 * that collides with OCELOT_STANDALONE_PVID and changes it from
634 * egress-untagged to egress-tagged.
635 */
636 if (!vid)
637 return 0;
638
632 err = ocelot_vlan_member_add(ocelot, port, vid, untagged);
633 if (err)
634 return err;
635
636 /* Default ingress vlan classification */
637 if (pvid)
638 ocelot_port_set_pvid(ocelot, port,
639 ocelot_bridge_vlan_find(ocelot, vid));

--- 6 unchanged lines hidden (view full) ---

646EXPORT_SYMBOL(ocelot_vlan_add);
647
648int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
649{
650 struct ocelot_port *ocelot_port = ocelot->ports[port];
651 bool del_pvid = false;
652 int err;
653
639 err = ocelot_vlan_member_add(ocelot, port, vid, untagged);
640 if (err)
641 return err;
642
643 /* Default ingress vlan classification */
644 if (pvid)
645 ocelot_port_set_pvid(ocelot, port,
646 ocelot_bridge_vlan_find(ocelot, vid));

--- 6 unchanged lines hidden (view full) ---

653EXPORT_SYMBOL(ocelot_vlan_add);
654
655int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
656{
657 struct ocelot_port *ocelot_port = ocelot->ports[port];
658 bool del_pvid = false;
659 int err;
660
661 if (!vid)
662 return 0;
663
654 if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid)
655 del_pvid = true;
656
657 err = ocelot_vlan_member_del(ocelot, port, vid);
658 if (err)
659 return err;
660
661 /* Ingress */

--- 945 unchanged lines hidden (view full) ---

1607 trap->id.tc_offload = false;
1608 trap->block_id = VCAP_IS2;
1609 trap->type = OCELOT_VCAP_FILTER_OFFLOAD;
1610 trap->lookup = 0;
1611 trap->action.cpu_copy_ena = true;
1612 trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
1613 trap->action.port_mask = 0;
1614 trap->take_ts = take_ts;
664 if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid)
665 del_pvid = true;
666
667 err = ocelot_vlan_member_del(ocelot, port, vid);
668 if (err)
669 return err;
670
671 /* Ingress */

--- 945 unchanged lines hidden (view full) ---

1617 trap->id.tc_offload = false;
1618 trap->block_id = VCAP_IS2;
1619 trap->type = OCELOT_VCAP_FILTER_OFFLOAD;
1620 trap->lookup = 0;
1621 trap->action.cpu_copy_ena = true;
1622 trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
1623 trap->action.port_mask = 0;
1624 trap->take_ts = take_ts;
1615 list_add_tail(&trap->trap_list, &ocelot->traps);
1625 trap->is_trap = true;
1616 new = true;
1617 }
1618
1619 trap->ingress_port_mask |= BIT(port);
1620
1621 if (new)
1622 err = ocelot_vcap_filter_add(ocelot, trap, NULL);
1623 else
1624 err = ocelot_vcap_filter_replace(ocelot, trap);
1625 if (err) {
1626 trap->ingress_port_mask &= ~BIT(port);
1626 new = true;
1627 }
1628
1629 trap->ingress_port_mask |= BIT(port);
1630
1631 if (new)
1632 err = ocelot_vcap_filter_add(ocelot, trap, NULL);
1633 else
1634 err = ocelot_vcap_filter_replace(ocelot, trap);
1635 if (err) {
1636 trap->ingress_port_mask &= ~BIT(port);
1627 if (!trap->ingress_port_mask) {
1628 list_del(&trap->trap_list);
1637 if (!trap->ingress_port_mask)
1629 kfree(trap);
1638 kfree(trap);
1630 }
1631 return err;
1632 }
1633
1634 return 0;
1635}
1636
1637int ocelot_trap_del(struct ocelot *ocelot, int port, unsigned long cookie)
1638{
1639 struct ocelot_vcap_block *block_vcap_is2;
1640 struct ocelot_vcap_filter *trap;
1641
1642 block_vcap_is2 = &ocelot->block[VCAP_IS2];
1643
1644 trap = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, cookie,
1645 false);
1646 if (!trap)
1647 return 0;
1648
1649 trap->ingress_port_mask &= ~BIT(port);
1639 return err;
1640 }
1641
1642 return 0;
1643}
1644
1645int ocelot_trap_del(struct ocelot *ocelot, int port, unsigned long cookie)
1646{
1647 struct ocelot_vcap_block *block_vcap_is2;
1648 struct ocelot_vcap_filter *trap;
1649
1650 block_vcap_is2 = &ocelot->block[VCAP_IS2];
1651
1652 trap = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, cookie,
1653 false);
1654 if (!trap)
1655 return 0;
1656
1657 trap->ingress_port_mask &= ~BIT(port);
1650 if (!trap->ingress_port_mask) {
1651 list_del(&trap->trap_list);
1652
1658 if (!trap->ingress_port_mask)
1653 return ocelot_vcap_filter_del(ocelot, trap);
1659 return ocelot_vcap_filter_del(ocelot, trap);
1654 }
1655
1656 return ocelot_vcap_filter_replace(ocelot, trap);
1657}
1658
1659static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port)
1660{
1661 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot);
1662

--- 1736 unchanged lines hidden ---
1660
1661 return ocelot_vcap_filter_replace(ocelot, trap);
1662}
1663
1664static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port)
1665{
1666 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot);
1667

--- 1736 unchanged lines hidden ---