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 --- |