aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c1072
1 files changed, 799 insertions, 273 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index d23948b88962..c812513e079d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -51,6 +51,7 @@
51#include <linux/list.h> 51#include <linux/list.h>
52#include <linux/notifier.h> 52#include <linux/notifier.h>
53#include <linux/dcbnl.h> 53#include <linux/dcbnl.h>
54#include <linux/inetdevice.h>
54#include <net/switchdev.h> 55#include <net/switchdev.h>
55#include <generated/utsrelease.h> 56#include <generated/utsrelease.h>
56 57
@@ -210,23 +211,6 @@ static int mlxsw_sp_port_dev_addr_init(struct mlxsw_sp_port *mlxsw_sp_port)
210 return mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr); 211 return mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr);
211} 212}
212 213
213static int mlxsw_sp_port_stp_state_set(struct mlxsw_sp_port *mlxsw_sp_port,
214 u16 vid, enum mlxsw_reg_spms_state state)
215{
216 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
217 char *spms_pl;
218 int err;
219
220 spms_pl = kmalloc(MLXSW_REG_SPMS_LEN, GFP_KERNEL);
221 if (!spms_pl)
222 return -ENOMEM;
223 mlxsw_reg_spms_pack(spms_pl, mlxsw_sp_port->local_port);
224 mlxsw_reg_spms_vid_pack(spms_pl, vid, state);
225 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spms), spms_pl);
226 kfree(spms_pl);
227 return err;
228}
229
230static int mlxsw_sp_port_mtu_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu) 214static int mlxsw_sp_port_mtu_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
231{ 215{
232 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 216 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
@@ -409,7 +393,11 @@ static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
409 } 393 }
410 394
411 mlxsw_sp_txhdr_construct(skb, &tx_info); 395 mlxsw_sp_txhdr_construct(skb, &tx_info);
412 len = skb->len; 396 /* TX header is consumed by HW on the way so we shouldn't count its
397 * bytes as being sent.
398 */
399 len = skb->len - MLXSW_TXHDR_LEN;
400
413 /* Due to a race we might fail here because of a full queue. In that 401 /* Due to a race we might fail here because of a full queue. In that
414 * unlikely case we simply drop the packet. 402 * unlikely case we simply drop the packet.
415 */ 403 */
@@ -633,87 +621,6 @@ static int mlxsw_sp_port_vlan_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
633 return 0; 621 return 0;
634} 622}
635 623
636static struct mlxsw_sp_fid *
637mlxsw_sp_vfid_find(const struct mlxsw_sp *mlxsw_sp, u16 vid)
638{
639 struct mlxsw_sp_fid *f;
640
641 list_for_each_entry(f, &mlxsw_sp->port_vfids.list, list) {
642 if (f->vid == vid)
643 return f;
644 }
645
646 return NULL;
647}
648
649static u16 mlxsw_sp_avail_vfid_get(const struct mlxsw_sp *mlxsw_sp)
650{
651 return find_first_zero_bit(mlxsw_sp->port_vfids.mapped,
652 MLXSW_SP_VFID_PORT_MAX);
653}
654
655static int mlxsw_sp_vfid_op(struct mlxsw_sp *mlxsw_sp, u16 fid, bool create)
656{
657 char sfmr_pl[MLXSW_REG_SFMR_LEN];
658
659 mlxsw_reg_sfmr_pack(sfmr_pl, !create, fid, 0);
660 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
661}
662
663static void mlxsw_sp_vport_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport);
664
665static struct mlxsw_sp_fid *mlxsw_sp_vfid_create(struct mlxsw_sp *mlxsw_sp,
666 u16 vid)
667{
668 struct device *dev = mlxsw_sp->bus_info->dev;
669 struct mlxsw_sp_fid *f;
670 u16 vfid, fid;
671 int err;
672
673 vfid = mlxsw_sp_avail_vfid_get(mlxsw_sp);
674 if (vfid == MLXSW_SP_VFID_PORT_MAX) {
675 dev_err(dev, "No available vFIDs\n");
676 return ERR_PTR(-ERANGE);
677 }
678
679 fid = mlxsw_sp_vfid_to_fid(vfid);
680 err = mlxsw_sp_vfid_op(mlxsw_sp, fid, true);
681 if (err) {
682 dev_err(dev, "Failed to create FID=%d\n", fid);
683 return ERR_PTR(err);
684 }
685
686 f = kzalloc(sizeof(*f), GFP_KERNEL);
687 if (!f)
688 goto err_allocate_vfid;
689
690 f->leave = mlxsw_sp_vport_vfid_leave;
691 f->fid = fid;
692 f->vid = vid;
693
694 list_add(&f->list, &mlxsw_sp->port_vfids.list);
695 set_bit(vfid, mlxsw_sp->port_vfids.mapped);
696
697 return f;
698
699err_allocate_vfid:
700 mlxsw_sp_vfid_op(mlxsw_sp, fid, false);
701 return ERR_PTR(-ENOMEM);
702}
703
704static void mlxsw_sp_vfid_destroy(struct mlxsw_sp *mlxsw_sp,
705 struct mlxsw_sp_fid *f)
706{
707 u16 vfid = mlxsw_sp_fid_to_vfid(f->fid);
708
709 clear_bit(vfid, mlxsw_sp->port_vfids.mapped);
710 list_del(&f->list);
711
712 mlxsw_sp_vfid_op(mlxsw_sp, f->fid, false);
713
714 kfree(f);
715}
716
717static struct mlxsw_sp_port * 624static struct mlxsw_sp_port *
718mlxsw_sp_port_vport_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid) 625mlxsw_sp_port_vport_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
719{ 626{
@@ -746,72 +653,12 @@ static void mlxsw_sp_port_vport_destroy(struct mlxsw_sp_port *mlxsw_sp_vport)
746 kfree(mlxsw_sp_vport); 653 kfree(mlxsw_sp_vport);
747} 654}
748 655
749static int mlxsw_sp_vport_fid_map(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
750 bool valid)
751{
752 enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
753 u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
754
755 return mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport, mt, valid, fid,
756 vid);
757}
758
759static int mlxsw_sp_vport_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport)
760{
761 u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
762 struct mlxsw_sp_fid *f;
763 int err;
764
765 f = mlxsw_sp_vfid_find(mlxsw_sp_vport->mlxsw_sp, vid);
766 if (!f) {
767 f = mlxsw_sp_vfid_create(mlxsw_sp_vport->mlxsw_sp, vid);
768 if (IS_ERR(f))
769 return PTR_ERR(f);
770 }
771
772 if (!f->ref_count) {
773 err = mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, true);
774 if (err)
775 goto err_vport_flood_set;
776 }
777
778 err = mlxsw_sp_vport_fid_map(mlxsw_sp_vport, f->fid, true);
779 if (err)
780 goto err_vport_fid_map;
781
782 mlxsw_sp_vport_fid_set(mlxsw_sp_vport, f);
783 f->ref_count++;
784
785 return 0;
786
787err_vport_fid_map:
788 if (!f->ref_count)
789 mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false);
790err_vport_flood_set:
791 if (!f->ref_count)
792 mlxsw_sp_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f);
793 return err;
794}
795
796static void mlxsw_sp_vport_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
797{
798 struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
799
800 mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL);
801
802 mlxsw_sp_vport_fid_map(mlxsw_sp_vport, f->fid, false);
803
804 if (--f->ref_count == 0) {
805 mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false);
806 mlxsw_sp_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f);
807 }
808}
809
810int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto, 656int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto,
811 u16 vid) 657 u16 vid)
812{ 658{
813 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 659 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
814 struct mlxsw_sp_port *mlxsw_sp_vport; 660 struct mlxsw_sp_port *mlxsw_sp_vport;
661 bool untagged = vid == 1;
815 int err; 662 int err;
816 663
817 /* VLAN 0 is added to HW filter when device goes up, but it is 664 /* VLAN 0 is added to HW filter when device goes up, but it is
@@ -843,41 +690,24 @@ int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto,
843 } 690 }
844 } 691 }
845 692
846 err = mlxsw_sp_vport_vfid_join(mlxsw_sp_vport);
847 if (err) {
848 netdev_err(dev, "Failed to join vFID\n");
849 goto err_vport_vfid_join;
850 }
851
852 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false); 693 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false);
853 if (err) { 694 if (err) {
854 netdev_err(dev, "Failed to disable learning for VID=%d\n", vid); 695 netdev_err(dev, "Failed to disable learning for VID=%d\n", vid);
855 goto err_port_vid_learning_set; 696 goto err_port_vid_learning_set;
856 } 697 }
857 698
858 err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, true, false); 699 err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, true, untagged);
859 if (err) { 700 if (err) {
860 netdev_err(dev, "Failed to set VLAN membership for VID=%d\n", 701 netdev_err(dev, "Failed to set VLAN membership for VID=%d\n",
861 vid); 702 vid);
862 goto err_port_add_vid; 703 goto err_port_add_vid;
863 } 704 }
864 705
865 err = mlxsw_sp_port_stp_state_set(mlxsw_sp_vport, vid,
866 MLXSW_REG_SPMS_STATE_FORWARDING);
867 if (err) {
868 netdev_err(dev, "Failed to set STP state for VID=%d\n", vid);
869 goto err_port_stp_state_set;
870 }
871
872 return 0; 706 return 0;
873 707
874err_port_stp_state_set:
875 mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, false, false);
876err_port_add_vid: 708err_port_add_vid:
877 mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true); 709 mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
878err_port_vid_learning_set: 710err_port_vid_learning_set:
879 mlxsw_sp_vport_vfid_leave(mlxsw_sp_vport);
880err_vport_vfid_join:
881 if (list_is_singular(&mlxsw_sp_port->vports_list)) 711 if (list_is_singular(&mlxsw_sp_port->vports_list))
882 mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port); 712 mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
883err_port_vp_mode_trans: 713err_port_vp_mode_trans:
@@ -885,8 +715,8 @@ err_port_vp_mode_trans:
885 return err; 715 return err;
886} 716}
887 717
888int mlxsw_sp_port_kill_vid(struct net_device *dev, 718static int mlxsw_sp_port_kill_vid(struct net_device *dev,
889 __be16 __always_unused proto, u16 vid) 719 __be16 __always_unused proto, u16 vid)
890{ 720{
891 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 721 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
892 struct mlxsw_sp_port *mlxsw_sp_vport; 722 struct mlxsw_sp_port *mlxsw_sp_vport;
@@ -905,13 +735,6 @@ int mlxsw_sp_port_kill_vid(struct net_device *dev,
905 return 0; 735 return 0;
906 } 736 }
907 737
908 err = mlxsw_sp_port_stp_state_set(mlxsw_sp_vport, vid,
909 MLXSW_REG_SPMS_STATE_DISCARDING);
910 if (err) {
911 netdev_err(dev, "Failed to set STP state for VID=%d\n", vid);
912 return err;
913 }
914
915 err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, false, false); 738 err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, false, false);
916 if (err) { 739 if (err) {
917 netdev_err(dev, "Failed to set VLAN membership for VID=%d\n", 740 netdev_err(dev, "Failed to set VLAN membership for VID=%d\n",
@@ -980,6 +803,8 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
980 .ndo_get_stats64 = mlxsw_sp_port_get_stats64, 803 .ndo_get_stats64 = mlxsw_sp_port_get_stats64,
981 .ndo_vlan_rx_add_vid = mlxsw_sp_port_add_vid, 804 .ndo_vlan_rx_add_vid = mlxsw_sp_port_add_vid,
982 .ndo_vlan_rx_kill_vid = mlxsw_sp_port_kill_vid, 805 .ndo_vlan_rx_kill_vid = mlxsw_sp_port_kill_vid,
806 .ndo_neigh_construct = mlxsw_sp_router_neigh_construct,
807 .ndo_neigh_destroy = mlxsw_sp_router_neigh_destroy,
983 .ndo_fdb_add = switchdev_port_fdb_add, 808 .ndo_fdb_add = switchdev_port_fdb_add,
984 .ndo_fdb_del = switchdev_port_fdb_del, 809 .ndo_fdb_del = switchdev_port_fdb_del,
985 .ndo_fdb_dump = switchdev_port_fdb_dump, 810 .ndo_fdb_dump = switchdev_port_fdb_dump,
@@ -1840,23 +1665,6 @@ err_port_active_vlans_alloc:
1840 return err; 1665 return err;
1841} 1666}
1842 1667
1843static void mlxsw_sp_port_vports_fini(struct mlxsw_sp_port *mlxsw_sp_port)
1844{
1845 struct net_device *dev = mlxsw_sp_port->dev;
1846 struct mlxsw_sp_port *mlxsw_sp_vport, *tmp;
1847
1848 list_for_each_entry_safe(mlxsw_sp_vport, tmp,
1849 &mlxsw_sp_port->vports_list, vport.list) {
1850 u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
1851
1852 /* vPorts created for VLAN devices should already be gone
1853 * by now, since we unregistered the port netdev.
1854 */
1855 WARN_ON(is_vlan_dev(mlxsw_sp_vport->dev));
1856 mlxsw_sp_port_kill_vid(dev, 0, vid);
1857 }
1858}
1859
1860static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port) 1668static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
1861{ 1669{
1862 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port]; 1670 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
@@ -1867,13 +1675,14 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
1867 mlxsw_core_port_fini(&mlxsw_sp_port->core_port); 1675 mlxsw_core_port_fini(&mlxsw_sp_port->core_port);
1868 unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */ 1676 unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
1869 mlxsw_sp_port_dcb_fini(mlxsw_sp_port); 1677 mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
1870 mlxsw_sp_port_vports_fini(mlxsw_sp_port); 1678 mlxsw_sp_port_kill_vid(mlxsw_sp_port->dev, 0, 1);
1871 mlxsw_sp_port_switchdev_fini(mlxsw_sp_port); 1679 mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
1872 mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT); 1680 mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
1873 mlxsw_sp_port_module_unmap(mlxsw_sp, mlxsw_sp_port->local_port); 1681 mlxsw_sp_port_module_unmap(mlxsw_sp, mlxsw_sp_port->local_port);
1874 free_percpu(mlxsw_sp_port->pcpu_stats); 1682 free_percpu(mlxsw_sp_port->pcpu_stats);
1875 kfree(mlxsw_sp_port->untagged_vlans); 1683 kfree(mlxsw_sp_port->untagged_vlans);
1876 kfree(mlxsw_sp_port->active_vlans); 1684 kfree(mlxsw_sp_port->active_vlans);
1685 WARN_ON_ONCE(!list_empty(&mlxsw_sp_port->vports_list));
1877 free_netdev(mlxsw_sp_port->dev); 1686 free_netdev(mlxsw_sp_port->dev);
1878} 1687}
1879 1688
@@ -2110,11 +1919,8 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
2110 1919
2111 local_port = mlxsw_reg_pude_local_port_get(pude_pl); 1920 local_port = mlxsw_reg_pude_local_port_get(pude_pl);
2112 mlxsw_sp_port = mlxsw_sp->ports[local_port]; 1921 mlxsw_sp_port = mlxsw_sp->ports[local_port];
2113 if (!mlxsw_sp_port) { 1922 if (!mlxsw_sp_port)
2114 dev_warn(mlxsw_sp->bus_info->dev, "Port %d: Link event received for non-existent port\n",
2115 local_port);
2116 return; 1923 return;
2117 }
2118 1924
2119 status = mlxsw_reg_pude_oper_status_get(pude_pl); 1925 status = mlxsw_reg_pude_oper_status_get(pude_pl);
2120 if (status == MLXSW_PORT_OPER_STATUS_UP) { 1926 if (status == MLXSW_PORT_OPER_STATUS_UP) {
@@ -2269,6 +2075,31 @@ static const struct mlxsw_rx_listener mlxsw_sp_rx_listener[] = {
2269 .local_port = MLXSW_PORT_DONT_CARE, 2075 .local_port = MLXSW_PORT_DONT_CARE,
2270 .trap_id = MLXSW_TRAP_ID_IGMP_V3_REPORT, 2076 .trap_id = MLXSW_TRAP_ID_IGMP_V3_REPORT,
2271 }, 2077 },
2078 {
2079 .func = mlxsw_sp_rx_listener_func,
2080 .local_port = MLXSW_PORT_DONT_CARE,
2081 .trap_id = MLXSW_TRAP_ID_ARPBC,
2082 },
2083 {
2084 .func = mlxsw_sp_rx_listener_func,
2085 .local_port = MLXSW_PORT_DONT_CARE,
2086 .trap_id = MLXSW_TRAP_ID_ARPUC,
2087 },
2088 {
2089 .func = mlxsw_sp_rx_listener_func,
2090 .local_port = MLXSW_PORT_DONT_CARE,
2091 .trap_id = MLXSW_TRAP_ID_IP2ME,
2092 },
2093 {
2094 .func = mlxsw_sp_rx_listener_func,
2095 .local_port = MLXSW_PORT_DONT_CARE,
2096 .trap_id = MLXSW_TRAP_ID_RTR_INGRESS0,
2097 },
2098 {
2099 .func = mlxsw_sp_rx_listener_func,
2100 .local_port = MLXSW_PORT_DONT_CARE,
2101 .trap_id = MLXSW_TRAP_ID_HOST_MISS_IPV4,
2102 },
2272}; 2103};
2273 2104
2274static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp) 2105static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
@@ -2309,7 +2140,7 @@ err_rx_trap_set:
2309 mlxsw_sp); 2140 mlxsw_sp);
2310err_rx_listener_register: 2141err_rx_listener_register:
2311 for (i--; i >= 0; i--) { 2142 for (i--; i >= 0; i--) {
2312 mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD, 2143 mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD,
2313 mlxsw_sp_rx_listener[i].trap_id); 2144 mlxsw_sp_rx_listener[i].trap_id);
2314 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl); 2145 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
2315 2146
@@ -2326,7 +2157,7 @@ static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
2326 int i; 2157 int i;
2327 2158
2328 for (i = 0; i < ARRAY_SIZE(mlxsw_sp_rx_listener); i++) { 2159 for (i = 0; i < ARRAY_SIZE(mlxsw_sp_rx_listener); i++) {
2329 mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD, 2160 mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD,
2330 mlxsw_sp_rx_listener[i].trap_id); 2161 mlxsw_sp_rx_listener[i].trap_id);
2331 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl); 2162 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl);
2332 2163
@@ -2406,8 +2237,7 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
2406 mlxsw_sp->core = mlxsw_core; 2237 mlxsw_sp->core = mlxsw_core;
2407 mlxsw_sp->bus_info = mlxsw_bus_info; 2238 mlxsw_sp->bus_info = mlxsw_bus_info;
2408 INIT_LIST_HEAD(&mlxsw_sp->fids); 2239 INIT_LIST_HEAD(&mlxsw_sp->fids);
2409 INIT_LIST_HEAD(&mlxsw_sp->port_vfids.list); 2240 INIT_LIST_HEAD(&mlxsw_sp->vfids.list);
2410 INIT_LIST_HEAD(&mlxsw_sp->br_vfids.list);
2411 INIT_LIST_HEAD(&mlxsw_sp->br_mids.list); 2241 INIT_LIST_HEAD(&mlxsw_sp->br_mids.list);
2412 2242
2413 err = mlxsw_sp_base_mac_get(mlxsw_sp); 2243 err = mlxsw_sp_base_mac_get(mlxsw_sp);
@@ -2416,16 +2246,10 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
2416 return err; 2246 return err;
2417 } 2247 }
2418 2248
2419 err = mlxsw_sp_ports_create(mlxsw_sp);
2420 if (err) {
2421 dev_err(mlxsw_sp->bus_info->dev, "Failed to create ports\n");
2422 return err;
2423 }
2424
2425 err = mlxsw_sp_event_register(mlxsw_sp, MLXSW_TRAP_ID_PUDE); 2249 err = mlxsw_sp_event_register(mlxsw_sp, MLXSW_TRAP_ID_PUDE);
2426 if (err) { 2250 if (err) {
2427 dev_err(mlxsw_sp->bus_info->dev, "Failed to register for PUDE events\n"); 2251 dev_err(mlxsw_sp->bus_info->dev, "Failed to register for PUDE events\n");
2428 goto err_event_register; 2252 return err;
2429 } 2253 }
2430 2254
2431 err = mlxsw_sp_traps_init(mlxsw_sp); 2255 err = mlxsw_sp_traps_init(mlxsw_sp);
@@ -2458,8 +2282,24 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
2458 goto err_switchdev_init; 2282 goto err_switchdev_init;
2459 } 2283 }
2460 2284
2285 err = mlxsw_sp_router_init(mlxsw_sp);
2286 if (err) {
2287 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n");
2288 goto err_router_init;
2289 }
2290
2291 err = mlxsw_sp_ports_create(mlxsw_sp);
2292 if (err) {
2293 dev_err(mlxsw_sp->bus_info->dev, "Failed to create ports\n");
2294 goto err_ports_create;
2295 }
2296
2461 return 0; 2297 return 0;
2462 2298
2299err_ports_create:
2300 mlxsw_sp_router_fini(mlxsw_sp);
2301err_router_init:
2302 mlxsw_sp_switchdev_fini(mlxsw_sp);
2463err_switchdev_init: 2303err_switchdev_init:
2464err_lag_init: 2304err_lag_init:
2465 mlxsw_sp_buffers_fini(mlxsw_sp); 2305 mlxsw_sp_buffers_fini(mlxsw_sp);
@@ -2468,21 +2308,24 @@ err_flood_init:
2468 mlxsw_sp_traps_fini(mlxsw_sp); 2308 mlxsw_sp_traps_fini(mlxsw_sp);
2469err_rx_listener_register: 2309err_rx_listener_register:
2470 mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE); 2310 mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE);
2471err_event_register:
2472 mlxsw_sp_ports_remove(mlxsw_sp);
2473 return err; 2311 return err;
2474} 2312}
2475 2313
2476static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core) 2314static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
2477{ 2315{
2478 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 2316 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
2317 int i;
2479 2318
2319 mlxsw_sp_ports_remove(mlxsw_sp);
2320 mlxsw_sp_router_fini(mlxsw_sp);
2480 mlxsw_sp_switchdev_fini(mlxsw_sp); 2321 mlxsw_sp_switchdev_fini(mlxsw_sp);
2481 mlxsw_sp_buffers_fini(mlxsw_sp); 2322 mlxsw_sp_buffers_fini(mlxsw_sp);
2482 mlxsw_sp_traps_fini(mlxsw_sp); 2323 mlxsw_sp_traps_fini(mlxsw_sp);
2483 mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE); 2324 mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE);
2484 mlxsw_sp_ports_remove(mlxsw_sp); 2325 WARN_ON(!list_empty(&mlxsw_sp->vfids.list));
2485 WARN_ON(!list_empty(&mlxsw_sp->fids)); 2326 WARN_ON(!list_empty(&mlxsw_sp->fids));
2327 for (i = 0; i < MLXSW_SP_RIF_MAX; i++)
2328 WARN_ON_ONCE(mlxsw_sp->rifs[i]);
2486} 2329}
2487 2330
2488static struct mlxsw_config_profile mlxsw_sp_config_profile = { 2331static struct mlxsw_config_profile mlxsw_sp_config_profile = {
@@ -2513,6 +2356,10 @@ static struct mlxsw_config_profile mlxsw_sp_config_profile = {
2513 .max_ib_mc = 0, 2356 .max_ib_mc = 0,
2514 .used_max_pkey = 1, 2357 .used_max_pkey = 1,
2515 .max_pkey = 0, 2358 .max_pkey = 0,
2359 .used_kvd_sizes = 1,
2360 .kvd_linear_size = MLXSW_SP_KVD_LINEAR_SIZE,
2361 .kvd_hash_single_size = MLXSW_SP_KVD_HASH_SINGLE_SIZE,
2362 .kvd_hash_double_size = MLXSW_SP_KVD_HASH_DOUBLE_SIZE,
2516 .swid_config = { 2363 .swid_config = {
2517 { 2364 {
2518 .used_type = 1, 2365 .used_type = 1,
@@ -2544,6 +2391,559 @@ static struct mlxsw_driver mlxsw_sp_driver = {
2544 .profile = &mlxsw_sp_config_profile, 2391 .profile = &mlxsw_sp_config_profile,
2545}; 2392};
2546 2393
2394static bool mlxsw_sp_port_dev_check(const struct net_device *dev)
2395{
2396 return dev->netdev_ops == &mlxsw_sp_port_netdev_ops;
2397}
2398
2399static struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev)
2400{
2401 struct net_device *lower_dev;
2402 struct list_head *iter;
2403
2404 if (mlxsw_sp_port_dev_check(dev))
2405 return netdev_priv(dev);
2406
2407 netdev_for_each_all_lower_dev(dev, lower_dev, iter) {
2408 if (mlxsw_sp_port_dev_check(lower_dev))
2409 return netdev_priv(lower_dev);
2410 }
2411 return NULL;
2412}
2413
2414static struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev)
2415{
2416 struct mlxsw_sp_port *mlxsw_sp_port;
2417
2418 mlxsw_sp_port = mlxsw_sp_port_dev_lower_find(dev);
2419 return mlxsw_sp_port ? mlxsw_sp_port->mlxsw_sp : NULL;
2420}
2421
2422static struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev)
2423{
2424 struct net_device *lower_dev;
2425 struct list_head *iter;
2426
2427 if (mlxsw_sp_port_dev_check(dev))
2428 return netdev_priv(dev);
2429
2430 netdev_for_each_all_lower_dev_rcu(dev, lower_dev, iter) {
2431 if (mlxsw_sp_port_dev_check(lower_dev))
2432 return netdev_priv(lower_dev);
2433 }
2434 return NULL;
2435}
2436
2437struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev)
2438{
2439 struct mlxsw_sp_port *mlxsw_sp_port;
2440
2441 rcu_read_lock();
2442 mlxsw_sp_port = mlxsw_sp_port_dev_lower_find_rcu(dev);
2443 if (mlxsw_sp_port)
2444 dev_hold(mlxsw_sp_port->dev);
2445 rcu_read_unlock();
2446 return mlxsw_sp_port;
2447}
2448
2449void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port)
2450{
2451 dev_put(mlxsw_sp_port->dev);
2452}
2453
2454static bool mlxsw_sp_rif_should_config(struct mlxsw_sp_rif *r,
2455 unsigned long event)
2456{
2457 switch (event) {
2458 case NETDEV_UP:
2459 if (!r)
2460 return true;
2461 r->ref_count++;
2462 return false;
2463 case NETDEV_DOWN:
2464 if (r && --r->ref_count == 0)
2465 return true;
2466 /* It is possible we already removed the RIF ourselves
2467 * if it was assigned to a netdev that is now a bridge
2468 * or LAG slave.
2469 */
2470 return false;
2471 }
2472
2473 return false;
2474}
2475
2476static int mlxsw_sp_avail_rif_get(struct mlxsw_sp *mlxsw_sp)
2477{
2478 int i;
2479
2480 for (i = 0; i < MLXSW_SP_RIF_MAX; i++)
2481 if (!mlxsw_sp->rifs[i])
2482 return i;
2483
2484 return MLXSW_SP_RIF_MAX;
2485}
2486
2487static void mlxsw_sp_vport_rif_sp_attr_get(struct mlxsw_sp_port *mlxsw_sp_vport,
2488 bool *p_lagged, u16 *p_system_port)
2489{
2490 u8 local_port = mlxsw_sp_vport->local_port;
2491
2492 *p_lagged = mlxsw_sp_vport->lagged;
2493 *p_system_port = *p_lagged ? mlxsw_sp_vport->lag_id : local_port;
2494}
2495
2496static int mlxsw_sp_vport_rif_sp_op(struct mlxsw_sp_port *mlxsw_sp_vport,
2497 struct net_device *l3_dev, u16 rif,
2498 bool create)
2499{
2500 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
2501 bool lagged = mlxsw_sp_vport->lagged;
2502 char ritr_pl[MLXSW_REG_RITR_LEN];
2503 u16 system_port;
2504
2505 mlxsw_reg_ritr_pack(ritr_pl, create, MLXSW_REG_RITR_SP_IF, rif,
2506 l3_dev->mtu, l3_dev->dev_addr);
2507
2508 mlxsw_sp_vport_rif_sp_attr_get(mlxsw_sp_vport, &lagged, &system_port);
2509 mlxsw_reg_ritr_sp_if_pack(ritr_pl, lagged, system_port,
2510 mlxsw_sp_vport_vid_get(mlxsw_sp_vport));
2511
2512 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
2513}
2514
2515static void mlxsw_sp_vport_rif_sp_leave(struct mlxsw_sp_port *mlxsw_sp_vport);
2516
2517static struct mlxsw_sp_fid *
2518mlxsw_sp_rfid_alloc(u16 fid, struct net_device *l3_dev)
2519{
2520 struct mlxsw_sp_fid *f;
2521
2522 f = kzalloc(sizeof(*f), GFP_KERNEL);
2523 if (!f)
2524 return NULL;
2525
2526 f->leave = mlxsw_sp_vport_rif_sp_leave;
2527 f->ref_count = 0;
2528 f->dev = l3_dev;
2529 f->fid = fid;
2530
2531 return f;
2532}
2533
2534static struct mlxsw_sp_rif *
2535mlxsw_sp_rif_alloc(u16 rif, struct net_device *l3_dev, struct mlxsw_sp_fid *f)
2536{
2537 struct mlxsw_sp_rif *r;
2538
2539 r = kzalloc(sizeof(*r), GFP_KERNEL);
2540 if (!r)
2541 return NULL;
2542
2543 ether_addr_copy(r->addr, l3_dev->dev_addr);
2544 r->mtu = l3_dev->mtu;
2545 r->ref_count = 1;
2546 r->dev = l3_dev;
2547 r->rif = rif;
2548 r->f = f;
2549
2550 return r;
2551}
2552
2553static struct mlxsw_sp_rif *
2554mlxsw_sp_vport_rif_sp_create(struct mlxsw_sp_port *mlxsw_sp_vport,
2555 struct net_device *l3_dev)
2556{
2557 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
2558 struct mlxsw_sp_fid *f;
2559 struct mlxsw_sp_rif *r;
2560 u16 fid, rif;
2561 int err;
2562
2563 rif = mlxsw_sp_avail_rif_get(mlxsw_sp);
2564 if (rif == MLXSW_SP_RIF_MAX)
2565 return ERR_PTR(-ERANGE);
2566
2567 err = mlxsw_sp_vport_rif_sp_op(mlxsw_sp_vport, l3_dev, rif, true);
2568 if (err)
2569 return ERR_PTR(err);
2570
2571 fid = mlxsw_sp_rif_sp_to_fid(rif);
2572 err = mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, fid, true);
2573 if (err)
2574 goto err_rif_fdb_op;
2575
2576 f = mlxsw_sp_rfid_alloc(fid, l3_dev);
2577 if (!f) {
2578 err = -ENOMEM;
2579 goto err_rfid_alloc;
2580 }
2581
2582 r = mlxsw_sp_rif_alloc(rif, l3_dev, f);
2583 if (!r) {
2584 err = -ENOMEM;
2585 goto err_rif_alloc;
2586 }
2587
2588 f->r = r;
2589 mlxsw_sp->rifs[rif] = r;
2590
2591 return r;
2592
2593err_rif_alloc:
2594 kfree(f);
2595err_rfid_alloc:
2596 mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, fid, false);
2597err_rif_fdb_op:
2598 mlxsw_sp_vport_rif_sp_op(mlxsw_sp_vport, l3_dev, rif, false);
2599 return ERR_PTR(err);
2600}
2601
2602static void mlxsw_sp_vport_rif_sp_destroy(struct mlxsw_sp_port *mlxsw_sp_vport,
2603 struct mlxsw_sp_rif *r)
2604{
2605 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
2606 struct net_device *l3_dev = r->dev;
2607 struct mlxsw_sp_fid *f = r->f;
2608 u16 fid = f->fid;
2609 u16 rif = r->rif;
2610
2611 mlxsw_sp->rifs[rif] = NULL;
2612 f->r = NULL;
2613
2614 kfree(r);
2615
2616 kfree(f);
2617
2618 mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, fid, false);
2619
2620 mlxsw_sp_vport_rif_sp_op(mlxsw_sp_vport, l3_dev, rif, false);
2621}
2622
2623static int mlxsw_sp_vport_rif_sp_join(struct mlxsw_sp_port *mlxsw_sp_vport,
2624 struct net_device *l3_dev)
2625{
2626 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_vport->mlxsw_sp;
2627 struct mlxsw_sp_rif *r;
2628
2629 r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
2630 if (!r) {
2631 r = mlxsw_sp_vport_rif_sp_create(mlxsw_sp_vport, l3_dev);
2632 if (IS_ERR(r))
2633 return PTR_ERR(r);
2634 }
2635
2636 mlxsw_sp_vport_fid_set(mlxsw_sp_vport, r->f);
2637 r->f->ref_count++;
2638
2639 netdev_dbg(mlxsw_sp_vport->dev, "Joined FID=%d\n", r->f->fid);
2640
2641 return 0;
2642}
2643
2644static void mlxsw_sp_vport_rif_sp_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
2645{
2646 struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
2647
2648 netdev_dbg(mlxsw_sp_vport->dev, "Left FID=%d\n", f->fid);
2649
2650 mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL);
2651 if (--f->ref_count == 0)
2652 mlxsw_sp_vport_rif_sp_destroy(mlxsw_sp_vport, f->r);
2653}
2654
2655static int mlxsw_sp_inetaddr_vport_event(struct net_device *l3_dev,
2656 struct net_device *port_dev,
2657 unsigned long event, u16 vid)
2658{
2659 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(port_dev);
2660 struct mlxsw_sp_port *mlxsw_sp_vport;
2661
2662 mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
2663 if (WARN_ON(!mlxsw_sp_vport))
2664 return -EINVAL;
2665
2666 switch (event) {
2667 case NETDEV_UP:
2668 return mlxsw_sp_vport_rif_sp_join(mlxsw_sp_vport, l3_dev);
2669 case NETDEV_DOWN:
2670 mlxsw_sp_vport_rif_sp_leave(mlxsw_sp_vport);
2671 break;
2672 }
2673
2674 return 0;
2675}
2676
2677static int mlxsw_sp_inetaddr_port_event(struct net_device *port_dev,
2678 unsigned long event)
2679{
2680 if (netif_is_bridge_port(port_dev) || netif_is_lag_port(port_dev))
2681 return 0;
2682
2683 return mlxsw_sp_inetaddr_vport_event(port_dev, port_dev, event, 1);
2684}
2685
2686static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev,
2687 struct net_device *lag_dev,
2688 unsigned long event, u16 vid)
2689{
2690 struct net_device *port_dev;
2691 struct list_head *iter;
2692 int err;
2693
2694 netdev_for_each_lower_dev(lag_dev, port_dev, iter) {
2695 if (mlxsw_sp_port_dev_check(port_dev)) {
2696 err = mlxsw_sp_inetaddr_vport_event(l3_dev, port_dev,
2697 event, vid);
2698 if (err)
2699 return err;
2700 }
2701 }
2702
2703 return 0;
2704}
2705
2706static int mlxsw_sp_inetaddr_lag_event(struct net_device *lag_dev,
2707 unsigned long event)
2708{
2709 if (netif_is_bridge_port(lag_dev))
2710 return 0;
2711
2712 return __mlxsw_sp_inetaddr_lag_event(lag_dev, lag_dev, event, 1);
2713}
2714
2715static struct mlxsw_sp_fid *mlxsw_sp_bridge_fid_get(struct mlxsw_sp *mlxsw_sp,
2716 struct net_device *l3_dev)
2717{
2718 u16 fid;
2719
2720 if (is_vlan_dev(l3_dev))
2721 fid = vlan_dev_vlan_id(l3_dev);
2722 else if (mlxsw_sp->master_bridge.dev == l3_dev)
2723 fid = 1;
2724 else
2725 return mlxsw_sp_vfid_find(mlxsw_sp, l3_dev);
2726
2727 return mlxsw_sp_fid_find(mlxsw_sp, fid);
2728}
2729
2730static enum mlxsw_reg_ritr_if_type mlxsw_sp_rif_type_get(u16 fid)
2731{
2732 if (mlxsw_sp_fid_is_vfid(fid))
2733 return MLXSW_REG_RITR_FID_IF;
2734 else
2735 return MLXSW_REG_RITR_VLAN_IF;
2736}
2737
2738static int mlxsw_sp_rif_bridge_op(struct mlxsw_sp *mlxsw_sp,
2739 struct net_device *l3_dev,
2740 u16 fid, u16 rif,
2741 bool create)
2742{
2743 enum mlxsw_reg_ritr_if_type rif_type;
2744 char ritr_pl[MLXSW_REG_RITR_LEN];
2745
2746 rif_type = mlxsw_sp_rif_type_get(fid);
2747 mlxsw_reg_ritr_pack(ritr_pl, create, rif_type, rif, l3_dev->mtu,
2748 l3_dev->dev_addr);
2749 mlxsw_reg_ritr_fid_set(ritr_pl, rif_type, fid);
2750
2751 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
2752}
2753
2754static int mlxsw_sp_rif_bridge_create(struct mlxsw_sp *mlxsw_sp,
2755 struct net_device *l3_dev,
2756 struct mlxsw_sp_fid *f)
2757{
2758 struct mlxsw_sp_rif *r;
2759 u16 rif;
2760 int err;
2761
2762 rif = mlxsw_sp_avail_rif_get(mlxsw_sp);
2763 if (rif == MLXSW_SP_RIF_MAX)
2764 return -ERANGE;
2765
2766 err = mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, true);
2767 if (err)
2768 return err;
2769
2770 err = mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, true);
2771 if (err)
2772 goto err_rif_fdb_op;
2773
2774 r = mlxsw_sp_rif_alloc(rif, l3_dev, f);
2775 if (!r) {
2776 err = -ENOMEM;
2777 goto err_rif_alloc;
2778 }
2779
2780 f->r = r;
2781 mlxsw_sp->rifs[rif] = r;
2782
2783 netdev_dbg(l3_dev, "RIF=%d created\n", rif);
2784
2785 return 0;
2786
2787err_rif_alloc:
2788 mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, false);
2789err_rif_fdb_op:
2790 mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false);
2791 return err;
2792}
2793
2794void mlxsw_sp_rif_bridge_destroy(struct mlxsw_sp *mlxsw_sp,
2795 struct mlxsw_sp_rif *r)
2796{
2797 struct net_device *l3_dev = r->dev;
2798 struct mlxsw_sp_fid *f = r->f;
2799 u16 rif = r->rif;
2800
2801 mlxsw_sp->rifs[rif] = NULL;
2802 f->r = NULL;
2803
2804 kfree(r);
2805
2806 mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, false);
2807
2808 mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false);
2809
2810 netdev_dbg(l3_dev, "RIF=%d destroyed\n", rif);
2811}
2812
2813static int mlxsw_sp_inetaddr_bridge_event(struct net_device *l3_dev,
2814 struct net_device *br_dev,
2815 unsigned long event)
2816{
2817 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(l3_dev);
2818 struct mlxsw_sp_fid *f;
2819
2820 /* FID can either be an actual FID if the L3 device is the
2821 * VLAN-aware bridge or a VLAN device on top. Otherwise, the
2822 * L3 device is a VLAN-unaware bridge and we get a vFID.
2823 */
2824 f = mlxsw_sp_bridge_fid_get(mlxsw_sp, l3_dev);
2825 if (WARN_ON(!f))
2826 return -EINVAL;
2827
2828 switch (event) {
2829 case NETDEV_UP:
2830 return mlxsw_sp_rif_bridge_create(mlxsw_sp, l3_dev, f);
2831 case NETDEV_DOWN:
2832 mlxsw_sp_rif_bridge_destroy(mlxsw_sp, f->r);
2833 break;
2834 }
2835
2836 return 0;
2837}
2838
2839static int mlxsw_sp_inetaddr_vlan_event(struct net_device *vlan_dev,
2840 unsigned long event)
2841{
2842 struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
2843 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(vlan_dev);
2844 u16 vid = vlan_dev_vlan_id(vlan_dev);
2845
2846 if (mlxsw_sp_port_dev_check(real_dev))
2847 return mlxsw_sp_inetaddr_vport_event(vlan_dev, real_dev, event,
2848 vid);
2849 else if (netif_is_lag_master(real_dev))
2850 return __mlxsw_sp_inetaddr_lag_event(vlan_dev, real_dev, event,
2851 vid);
2852 else if (netif_is_bridge_master(real_dev) &&
2853 mlxsw_sp->master_bridge.dev == real_dev)
2854 return mlxsw_sp_inetaddr_bridge_event(vlan_dev, real_dev,
2855 event);
2856
2857 return 0;
2858}
2859
2860static int mlxsw_sp_inetaddr_event(struct notifier_block *unused,
2861 unsigned long event, void *ptr)
2862{
2863 struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
2864 struct net_device *dev = ifa->ifa_dev->dev;
2865 struct mlxsw_sp *mlxsw_sp;
2866 struct mlxsw_sp_rif *r;
2867 int err = 0;
2868
2869 mlxsw_sp = mlxsw_sp_lower_get(dev);
2870 if (!mlxsw_sp)
2871 goto out;
2872
2873 r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
2874 if (!mlxsw_sp_rif_should_config(r, event))
2875 goto out;
2876
2877 if (mlxsw_sp_port_dev_check(dev))
2878 err = mlxsw_sp_inetaddr_port_event(dev, event);
2879 else if (netif_is_lag_master(dev))
2880 err = mlxsw_sp_inetaddr_lag_event(dev, event);
2881 else if (netif_is_bridge_master(dev))
2882 err = mlxsw_sp_inetaddr_bridge_event(dev, dev, event);
2883 else if (is_vlan_dev(dev))
2884 err = mlxsw_sp_inetaddr_vlan_event(dev, event);
2885
2886out:
2887 return notifier_from_errno(err);
2888}
2889
2890static int mlxsw_sp_rif_edit(struct mlxsw_sp *mlxsw_sp, u16 rif,
2891 const char *mac, int mtu)
2892{
2893 char ritr_pl[MLXSW_REG_RITR_LEN];
2894 int err;
2895
2896 mlxsw_reg_ritr_rif_pack(ritr_pl, rif);
2897 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
2898 if (err)
2899 return err;
2900
2901 mlxsw_reg_ritr_mtu_set(ritr_pl, mtu);
2902 mlxsw_reg_ritr_if_mac_memcpy_to(ritr_pl, mac);
2903 mlxsw_reg_ritr_op_set(ritr_pl, MLXSW_REG_RITR_RIF_CREATE);
2904 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
2905}
2906
2907static int mlxsw_sp_netdevice_router_port_event(struct net_device *dev)
2908{
2909 struct mlxsw_sp *mlxsw_sp;
2910 struct mlxsw_sp_rif *r;
2911 int err;
2912
2913 mlxsw_sp = mlxsw_sp_lower_get(dev);
2914 if (!mlxsw_sp)
2915 return 0;
2916
2917 r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
2918 if (!r)
2919 return 0;
2920
2921 err = mlxsw_sp_rif_fdb_op(mlxsw_sp, r->addr, r->f->fid, false);
2922 if (err)
2923 return err;
2924
2925 err = mlxsw_sp_rif_edit(mlxsw_sp, r->rif, dev->dev_addr, dev->mtu);
2926 if (err)
2927 goto err_rif_edit;
2928
2929 err = mlxsw_sp_rif_fdb_op(mlxsw_sp, dev->dev_addr, r->f->fid, true);
2930 if (err)
2931 goto err_rif_fdb_op;
2932
2933 ether_addr_copy(r->addr, dev->dev_addr);
2934 r->mtu = dev->mtu;
2935
2936 netdev_dbg(dev, "Updated RIF=%d\n", r->rif);
2937
2938 return 0;
2939
2940err_rif_fdb_op:
2941 mlxsw_sp_rif_edit(mlxsw_sp, r->rif, r->addr, r->mtu);
2942err_rif_edit:
2943 mlxsw_sp_rif_fdb_op(mlxsw_sp, r->addr, r->f->fid, true);
2944 return err;
2945}
2946
2547static bool mlxsw_sp_lag_port_fid_member(struct mlxsw_sp_port *lag_port, 2947static bool mlxsw_sp_lag_port_fid_member(struct mlxsw_sp_port *lag_port,
2548 u16 fid) 2948 u16 fid)
2549{ 2949{
@@ -2624,9 +3024,15 @@ int mlxsw_sp_port_fdb_flush(struct mlxsw_sp_port *mlxsw_sp_port, u16 fid)
2624 return mlxsw_sp_port_fdb_flush_by_port_fid(mlxsw_sp_port, fid); 3024 return mlxsw_sp_port_fdb_flush_by_port_fid(mlxsw_sp_port, fid);
2625} 3025}
2626 3026
2627static bool mlxsw_sp_port_dev_check(const struct net_device *dev) 3027static void mlxsw_sp_master_bridge_gone_sync(struct mlxsw_sp *mlxsw_sp)
2628{ 3028{
2629 return dev->netdev_ops == &mlxsw_sp_port_netdev_ops; 3029 struct mlxsw_sp_fid *f, *tmp;
3030
3031 list_for_each_entry_safe(f, tmp, &mlxsw_sp->fids, list)
3032 if (--f->ref_count == 0)
3033 mlxsw_sp_fid_destroy(mlxsw_sp, f);
3034 else
3035 WARN_ON_ONCE(1);
2630} 3036}
2631 3037
2632static bool mlxsw_sp_master_bridge_check(struct mlxsw_sp *mlxsw_sp, 3038static bool mlxsw_sp_master_bridge_check(struct mlxsw_sp *mlxsw_sp,
@@ -2645,8 +3051,15 @@ static void mlxsw_sp_master_bridge_inc(struct mlxsw_sp *mlxsw_sp,
2645 3051
2646static void mlxsw_sp_master_bridge_dec(struct mlxsw_sp *mlxsw_sp) 3052static void mlxsw_sp_master_bridge_dec(struct mlxsw_sp *mlxsw_sp)
2647{ 3053{
2648 if (--mlxsw_sp->master_bridge.ref_count == 0) 3054 if (--mlxsw_sp->master_bridge.ref_count == 0) {
2649 mlxsw_sp->master_bridge.dev = NULL; 3055 mlxsw_sp->master_bridge.dev = NULL;
3056 /* It's possible upper VLAN devices are still holding
3057 * references to underlying FIDs. Drop the reference
3058 * and release the resources if it was the last one.
3059 * If it wasn't, then something bad happened.
3060 */
3061 mlxsw_sp_master_bridge_gone_sync(mlxsw_sp);
3062 }
2650} 3063}
2651 3064
2652static int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port, 3065static int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port,
@@ -2806,6 +3219,45 @@ static int mlxsw_sp_port_lag_index_get(struct mlxsw_sp *mlxsw_sp,
2806 return -EBUSY; 3219 return -EBUSY;
2807} 3220}
2808 3221
3222static void
3223mlxsw_sp_port_pvid_vport_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
3224 u16 lag_id)
3225{
3226 struct mlxsw_sp_port *mlxsw_sp_vport;
3227 struct mlxsw_sp_fid *f;
3228
3229 mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, 1);
3230 if (WARN_ON(!mlxsw_sp_vport))
3231 return;
3232
3233 /* If vPort is assigned a RIF, then leave it since it's no
3234 * longer valid.
3235 */
3236 f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
3237 if (f)
3238 f->leave(mlxsw_sp_vport);
3239
3240 mlxsw_sp_vport->lag_id = lag_id;
3241 mlxsw_sp_vport->lagged = 1;
3242}
3243
3244static void
3245mlxsw_sp_port_pvid_vport_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port)
3246{
3247 struct mlxsw_sp_port *mlxsw_sp_vport;
3248 struct mlxsw_sp_fid *f;
3249
3250 mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, 1);
3251 if (WARN_ON(!mlxsw_sp_vport))
3252 return;
3253
3254 f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
3255 if (f)
3256 f->leave(mlxsw_sp_vport);
3257
3258 mlxsw_sp_vport->lagged = 0;
3259}
3260
2809static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port, 3261static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
2810 struct net_device *lag_dev) 3262 struct net_device *lag_dev)
2811{ 3263{
@@ -2841,6 +3293,9 @@ static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
2841 mlxsw_sp_port->lag_id = lag_id; 3293 mlxsw_sp_port->lag_id = lag_id;
2842 mlxsw_sp_port->lagged = 1; 3294 mlxsw_sp_port->lagged = 1;
2843 lag->ref_count++; 3295 lag->ref_count++;
3296
3297 mlxsw_sp_port_pvid_vport_lag_join(mlxsw_sp_port, lag_id);
3298
2844 return 0; 3299 return 0;
2845 3300
2846err_col_port_enable: 3301err_col_port_enable:
@@ -2878,6 +3333,8 @@ static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
2878 mlxsw_sp_port->local_port); 3333 mlxsw_sp_port->local_port);
2879 mlxsw_sp_port->lagged = 0; 3334 mlxsw_sp_port->lagged = 0;
2880 lag->ref_count--; 3335 lag->ref_count--;
3336
3337 mlxsw_sp_port_pvid_vport_lag_leave(mlxsw_sp_port);
2881} 3338}
2882 3339
2883static int mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port *mlxsw_sp_port, 3340static int mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
@@ -3071,47 +3528,97 @@ static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
3071 return 0; 3528 return 0;
3072} 3529}
3073 3530
3074static struct mlxsw_sp_fid * 3531static int mlxsw_sp_master_bridge_vlan_link(struct mlxsw_sp *mlxsw_sp,
3075mlxsw_sp_br_vfid_find(const struct mlxsw_sp *mlxsw_sp, 3532 struct net_device *vlan_dev)
3076 const struct net_device *br_dev)
3077{ 3533{
3534 u16 fid = vlan_dev_vlan_id(vlan_dev);
3078 struct mlxsw_sp_fid *f; 3535 struct mlxsw_sp_fid *f;
3079 3536
3080 list_for_each_entry(f, &mlxsw_sp->br_vfids.list, list) { 3537 f = mlxsw_sp_fid_find(mlxsw_sp, fid);
3081 if (f->dev == br_dev) 3538 if (!f) {
3082 return f; 3539 f = mlxsw_sp_fid_create(mlxsw_sp, fid);
3540 if (IS_ERR(f))
3541 return PTR_ERR(f);
3083 } 3542 }
3084 3543
3085 return NULL; 3544 f->ref_count++;
3545
3546 return 0;
3547}
3548
3549static void mlxsw_sp_master_bridge_vlan_unlink(struct mlxsw_sp *mlxsw_sp,
3550 struct net_device *vlan_dev)
3551{
3552 u16 fid = vlan_dev_vlan_id(vlan_dev);
3553 struct mlxsw_sp_fid *f;
3554
3555 f = mlxsw_sp_fid_find(mlxsw_sp, fid);
3556 if (f && f->r)
3557 mlxsw_sp_rif_bridge_destroy(mlxsw_sp, f->r);
3558 if (f && --f->ref_count == 0)
3559 mlxsw_sp_fid_destroy(mlxsw_sp, f);
3086} 3560}
3087 3561
3088static u16 mlxsw_sp_vfid_to_br_vfid(u16 vfid) 3562static int mlxsw_sp_netdevice_bridge_event(struct net_device *br_dev,
3563 unsigned long event, void *ptr)
3089{ 3564{
3090 return vfid - MLXSW_SP_VFID_PORT_MAX; 3565 struct netdev_notifier_changeupper_info *info;
3566 struct net_device *upper_dev;
3567 struct mlxsw_sp *mlxsw_sp;
3568 int err;
3569
3570 mlxsw_sp = mlxsw_sp_lower_get(br_dev);
3571 if (!mlxsw_sp)
3572 return 0;
3573 if (br_dev != mlxsw_sp->master_bridge.dev)
3574 return 0;
3575
3576 info = ptr;
3577
3578 switch (event) {
3579 case NETDEV_CHANGEUPPER:
3580 upper_dev = info->upper_dev;
3581 if (!is_vlan_dev(upper_dev))
3582 break;
3583 if (info->linking) {
3584 err = mlxsw_sp_master_bridge_vlan_link(mlxsw_sp,
3585 upper_dev);
3586 if (err)
3587 return err;
3588 } else {
3589 mlxsw_sp_master_bridge_vlan_unlink(mlxsw_sp, upper_dev);
3590 }
3591 break;
3592 }
3593
3594 return 0;
3091} 3595}
3092 3596
3093static u16 mlxsw_sp_br_vfid_to_vfid(u16 br_vfid) 3597static u16 mlxsw_sp_avail_vfid_get(const struct mlxsw_sp *mlxsw_sp)
3094{ 3598{
3095 return MLXSW_SP_VFID_PORT_MAX + br_vfid; 3599 return find_first_zero_bit(mlxsw_sp->vfids.mapped,
3600 MLXSW_SP_VFID_MAX);
3096} 3601}
3097 3602
3098static u16 mlxsw_sp_avail_br_vfid_get(const struct mlxsw_sp *mlxsw_sp) 3603static int mlxsw_sp_vfid_op(struct mlxsw_sp *mlxsw_sp, u16 fid, bool create)
3099{ 3604{
3100 return find_first_zero_bit(mlxsw_sp->br_vfids.mapped, 3605 char sfmr_pl[MLXSW_REG_SFMR_LEN];
3101 MLXSW_SP_VFID_BR_MAX); 3606
3607 mlxsw_reg_sfmr_pack(sfmr_pl, !create, fid, 0);
3608 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
3102} 3609}
3103 3610
3104static void mlxsw_sp_vport_br_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport); 3611static void mlxsw_sp_vport_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport);
3105 3612
3106static struct mlxsw_sp_fid *mlxsw_sp_br_vfid_create(struct mlxsw_sp *mlxsw_sp, 3613static struct mlxsw_sp_fid *mlxsw_sp_vfid_create(struct mlxsw_sp *mlxsw_sp,
3107 struct net_device *br_dev) 3614 struct net_device *br_dev)
3108{ 3615{
3109 struct device *dev = mlxsw_sp->bus_info->dev; 3616 struct device *dev = mlxsw_sp->bus_info->dev;
3110 struct mlxsw_sp_fid *f; 3617 struct mlxsw_sp_fid *f;
3111 u16 vfid, fid; 3618 u16 vfid, fid;
3112 int err; 3619 int err;
3113 3620
3114 vfid = mlxsw_sp_br_vfid_to_vfid(mlxsw_sp_avail_br_vfid_get(mlxsw_sp)); 3621 vfid = mlxsw_sp_avail_vfid_get(mlxsw_sp);
3115 if (vfid == MLXSW_SP_VFID_MAX) { 3622 if (vfid == MLXSW_SP_VFID_MAX) {
3116 dev_err(dev, "No available vFIDs\n"); 3623 dev_err(dev, "No available vFIDs\n");
3117 return ERR_PTR(-ERANGE); 3624 return ERR_PTR(-ERANGE);
@@ -3128,12 +3635,12 @@ static struct mlxsw_sp_fid *mlxsw_sp_br_vfid_create(struct mlxsw_sp *mlxsw_sp,
3128 if (!f) 3635 if (!f)
3129 goto err_allocate_vfid; 3636 goto err_allocate_vfid;
3130 3637
3131 f->leave = mlxsw_sp_vport_br_vfid_leave; 3638 f->leave = mlxsw_sp_vport_vfid_leave;
3132 f->fid = fid; 3639 f->fid = fid;
3133 f->dev = br_dev; 3640 f->dev = br_dev;
3134 3641
3135 list_add(&f->list, &mlxsw_sp->br_vfids.list); 3642 list_add(&f->list, &mlxsw_sp->vfids.list);
3136 set_bit(mlxsw_sp_vfid_to_br_vfid(vfid), mlxsw_sp->br_vfids.mapped); 3643 set_bit(vfid, mlxsw_sp->vfids.mapped);
3137 3644
3138 return f; 3645 return f;
3139 3646
@@ -3142,29 +3649,42 @@ err_allocate_vfid:
3142 return ERR_PTR(-ENOMEM); 3649 return ERR_PTR(-ENOMEM);
3143} 3650}
3144 3651
3145static void mlxsw_sp_br_vfid_destroy(struct mlxsw_sp *mlxsw_sp, 3652static void mlxsw_sp_vfid_destroy(struct mlxsw_sp *mlxsw_sp,
3146 struct mlxsw_sp_fid *f) 3653 struct mlxsw_sp_fid *f)
3147{ 3654{
3148 u16 vfid = mlxsw_sp_fid_to_vfid(f->fid); 3655 u16 vfid = mlxsw_sp_fid_to_vfid(f->fid);
3149 u16 br_vfid = mlxsw_sp_vfid_to_br_vfid(vfid); 3656 u16 fid = f->fid;
3150 3657
3151 clear_bit(br_vfid, mlxsw_sp->br_vfids.mapped); 3658 clear_bit(vfid, mlxsw_sp->vfids.mapped);
3152 list_del(&f->list); 3659 list_del(&f->list);
3153 3660
3154 mlxsw_sp_vfid_op(mlxsw_sp, f->fid, false); 3661 if (f->r)
3662 mlxsw_sp_rif_bridge_destroy(mlxsw_sp, f->r);
3155 3663
3156 kfree(f); 3664 kfree(f);
3665
3666 mlxsw_sp_vfid_op(mlxsw_sp, fid, false);
3157} 3667}
3158 3668
3159static int mlxsw_sp_vport_br_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport, 3669static int mlxsw_sp_vport_fid_map(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
3160 struct net_device *br_dev) 3670 bool valid)
3671{
3672 enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
3673 u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
3674
3675 return mlxsw_sp_port_vid_to_fid_set(mlxsw_sp_vport, mt, valid, fid,
3676 vid);
3677}
3678
3679static int mlxsw_sp_vport_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport,
3680 struct net_device *br_dev)
3161{ 3681{
3162 struct mlxsw_sp_fid *f; 3682 struct mlxsw_sp_fid *f;
3163 int err; 3683 int err;
3164 3684
3165 f = mlxsw_sp_br_vfid_find(mlxsw_sp_vport->mlxsw_sp, br_dev); 3685 f = mlxsw_sp_vfid_find(mlxsw_sp_vport->mlxsw_sp, br_dev);
3166 if (!f) { 3686 if (!f) {
3167 f = mlxsw_sp_br_vfid_create(mlxsw_sp_vport->mlxsw_sp, br_dev); 3687 f = mlxsw_sp_vfid_create(mlxsw_sp_vport->mlxsw_sp, br_dev);
3168 if (IS_ERR(f)) 3688 if (IS_ERR(f))
3169 return PTR_ERR(f); 3689 return PTR_ERR(f);
3170 } 3690 }
@@ -3188,11 +3708,11 @@ err_vport_fid_map:
3188 mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false); 3708 mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false);
3189err_vport_flood_set: 3709err_vport_flood_set:
3190 if (!f->ref_count) 3710 if (!f->ref_count)
3191 mlxsw_sp_br_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f); 3711 mlxsw_sp_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f);
3192 return err; 3712 return err;
3193} 3713}
3194 3714
3195static void mlxsw_sp_vport_br_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport) 3715static void mlxsw_sp_vport_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
3196{ 3716{
3197 struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport); 3717 struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
3198 3718
@@ -3206,22 +3726,24 @@ static void mlxsw_sp_vport_br_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
3206 3726
3207 mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL); 3727 mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL);
3208 if (--f->ref_count == 0) 3728 if (--f->ref_count == 0)
3209 mlxsw_sp_br_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f); 3729 mlxsw_sp_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f);
3210} 3730}
3211 3731
3212static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport, 3732static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport,
3213 struct net_device *br_dev) 3733 struct net_device *br_dev)
3214{ 3734{
3735 struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
3215 u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport); 3736 u16 vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
3216 struct net_device *dev = mlxsw_sp_vport->dev; 3737 struct net_device *dev = mlxsw_sp_vport->dev;
3217 int err; 3738 int err;
3218 3739
3219 mlxsw_sp_vport_vfid_leave(mlxsw_sp_vport); 3740 if (f && !WARN_ON(!f->leave))
3741 f->leave(mlxsw_sp_vport);
3220 3742
3221 err = mlxsw_sp_vport_br_vfid_join(mlxsw_sp_vport, br_dev); 3743 err = mlxsw_sp_vport_vfid_join(mlxsw_sp_vport, br_dev);
3222 if (err) { 3744 if (err) {
3223 netdev_err(dev, "Failed to join vFID\n"); 3745 netdev_err(dev, "Failed to join vFID\n");
3224 goto err_vport_br_vfid_join; 3746 return err;
3225 } 3747 }
3226 3748
3227 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true); 3749 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
@@ -3238,9 +3760,7 @@ static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport,
3238 return 0; 3760 return 0;
3239 3761
3240err_port_vid_learning_set: 3762err_port_vid_learning_set:
3241 mlxsw_sp_vport_br_vfid_leave(mlxsw_sp_vport); 3763 mlxsw_sp_vport_vfid_leave(mlxsw_sp_vport);
3242err_vport_br_vfid_join:
3243 mlxsw_sp_vport_vfid_join(mlxsw_sp_vport);
3244 return err; 3764 return err;
3245} 3765}
3246 3766
@@ -3250,12 +3770,7 @@ static void mlxsw_sp_vport_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_vport)
3250 3770
3251 mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false); 3771 mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false);
3252 3772
3253 mlxsw_sp_vport_br_vfid_leave(mlxsw_sp_vport); 3773 mlxsw_sp_vport_vfid_leave(mlxsw_sp_vport);
3254
3255 mlxsw_sp_vport_vfid_join(mlxsw_sp_vport);
3256
3257 mlxsw_sp_port_stp_state_set(mlxsw_sp_vport, vid,
3258 MLXSW_REG_SPMS_STATE_FORWARDING);
3259 3774
3260 mlxsw_sp_vport->learning = 0; 3775 mlxsw_sp_vport->learning = 0;
3261 mlxsw_sp_vport->learning_sync = 0; 3776 mlxsw_sp_vport->learning_sync = 0;
@@ -3271,7 +3786,7 @@ mlxsw_sp_port_master_bridge_check(const struct mlxsw_sp_port *mlxsw_sp_port,
3271 3786
3272 list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list, 3787 list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list,
3273 vport.list) { 3788 vport.list) {
3274 struct net_device *dev = mlxsw_sp_vport_br_get(mlxsw_sp_vport); 3789 struct net_device *dev = mlxsw_sp_vport_dev_get(mlxsw_sp_vport);
3275 3790
3276 if (dev && dev == br_dev) 3791 if (dev && dev == br_dev)
3277 return false; 3792 return false;
@@ -3365,10 +3880,14 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
3365 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 3880 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
3366 int err = 0; 3881 int err = 0;
3367 3882
3368 if (mlxsw_sp_port_dev_check(dev)) 3883 if (event == NETDEV_CHANGEADDR || event == NETDEV_CHANGEMTU)
3884 err = mlxsw_sp_netdevice_router_port_event(dev);
3885 else if (mlxsw_sp_port_dev_check(dev))
3369 err = mlxsw_sp_netdevice_port_event(dev, event, ptr); 3886 err = mlxsw_sp_netdevice_port_event(dev, event, ptr);
3370 else if (netif_is_lag_master(dev)) 3887 else if (netif_is_lag_master(dev))
3371 err = mlxsw_sp_netdevice_lag_event(dev, event, ptr); 3888 err = mlxsw_sp_netdevice_lag_event(dev, event, ptr);
3889 else if (netif_is_bridge_master(dev))
3890 err = mlxsw_sp_netdevice_bridge_event(dev, event, ptr);
3372 else if (is_vlan_dev(dev)) 3891 else if (is_vlan_dev(dev))
3373 err = mlxsw_sp_netdevice_vlan_event(dev, event, ptr); 3892 err = mlxsw_sp_netdevice_vlan_event(dev, event, ptr);
3374 3893
@@ -3379,11 +3898,17 @@ static struct notifier_block mlxsw_sp_netdevice_nb __read_mostly = {
3379 .notifier_call = mlxsw_sp_netdevice_event, 3898 .notifier_call = mlxsw_sp_netdevice_event,
3380}; 3899};
3381 3900
3901static struct notifier_block mlxsw_sp_inetaddr_nb __read_mostly = {
3902 .notifier_call = mlxsw_sp_inetaddr_event,
3903 .priority = 10, /* Must be called before FIB notifier block */
3904};
3905
3382static int __init mlxsw_sp_module_init(void) 3906static int __init mlxsw_sp_module_init(void)
3383{ 3907{
3384 int err; 3908 int err;
3385 3909
3386 register_netdevice_notifier(&mlxsw_sp_netdevice_nb); 3910 register_netdevice_notifier(&mlxsw_sp_netdevice_nb);
3911 register_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
3387 err = mlxsw_core_driver_register(&mlxsw_sp_driver); 3912 err = mlxsw_core_driver_register(&mlxsw_sp_driver);
3388 if (err) 3913 if (err)
3389 goto err_core_driver_register; 3914 goto err_core_driver_register;
@@ -3397,6 +3922,7 @@ err_core_driver_register:
3397static void __exit mlxsw_sp_module_exit(void) 3922static void __exit mlxsw_sp_module_exit(void)
3398{ 3923{
3399 mlxsw_core_driver_unregister(&mlxsw_sp_driver); 3924 mlxsw_core_driver_unregister(&mlxsw_sp_driver);
3925 unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
3400 unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb); 3926 unregister_netdevice_notifier(&mlxsw_sp_netdevice_nb);
3401} 3927}
3402 3928