diff options
27 files changed, 351 insertions, 218 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 1d5b4becab6f..849133608da7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -11071,6 +11071,15 @@ S: Maintained | |||
11071 | F: drivers/clk/ti/ | 11071 | F: drivers/clk/ti/ |
11072 | F: include/linux/clk/ti.h | 11072 | F: include/linux/clk/ti.h |
11073 | 11073 | ||
11074 | TI ETHERNET SWITCH DRIVER (CPSW) | ||
11075 | M: Mugunthan V N <mugunthanvnm@ti.com> | ||
11076 | R: Grygorii Strashko <grygorii.strashko@ti.com> | ||
11077 | L: linux-omap@vger.kernel.org | ||
11078 | L: netdev@vger.kernel.org | ||
11079 | S: Maintained | ||
11080 | F: drivers/net/ethernet/ti/cpsw* | ||
11081 | F: drivers/net/ethernet/ti/davinci* | ||
11082 | |||
11074 | TI FLASH MEDIA INTERFACE DRIVER | 11083 | TI FLASH MEDIA INTERFACE DRIVER |
11075 | M: Alex Dubov <oakad@yahoo.com> | 11084 | M: Alex Dubov <oakad@yahoo.com> |
11076 | S: Maintained | 11085 | S: Maintained |
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 5acf346e048e..99eb1c1a3b7b 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
@@ -671,8 +671,8 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u8 port, | |||
671 | struct mlx5_ib_dev *dev = to_mdev(ibdev); | 671 | struct mlx5_ib_dev *dev = to_mdev(ibdev); |
672 | struct mlx5_core_dev *mdev = dev->mdev; | 672 | struct mlx5_core_dev *mdev = dev->mdev; |
673 | struct mlx5_hca_vport_context *rep; | 673 | struct mlx5_hca_vport_context *rep; |
674 | int max_mtu; | 674 | u16 max_mtu; |
675 | int oper_mtu; | 675 | u16 oper_mtu; |
676 | int err; | 676 | int err; |
677 | u8 ib_link_width_oper; | 677 | u8 ib_link_width_oper; |
678 | u8 vl_hw_cap; | 678 | u8 vl_hw_cap; |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a24c18eee598..befd67df08e1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -62,9 +62,8 @@ config DUMMY | |||
62 | this device is consigned into oblivion) with a configurable IP | 62 | this device is consigned into oblivion) with a configurable IP |
63 | address. It is most commonly used in order to make your currently | 63 | address. It is most commonly used in order to make your currently |
64 | inactive SLIP address seem like a real address for local programs. | 64 | inactive SLIP address seem like a real address for local programs. |
65 | If you use SLIP or PPP, you might want to say Y here. Since this | 65 | If you use SLIP or PPP, you might want to say Y here. It won't |
66 | thing often comes in handy, the default is Y. It won't enlarge your | 66 | enlarge your kernel. What a deal. Read about it in the Network |
67 | kernel either. What a deal. Read about it in the Network | ||
68 | Administrator's Guide, available from | 67 | Administrator's Guide, available from |
69 | <http://www.tldp.org/docs.html#guide>. | 68 | <http://www.tldp.org/docs.html#guide>. |
70 | 69 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index c0d7b7296236..a386f047c1af 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -405,7 +405,6 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev, | |||
405 | u32 packets = 0; | 405 | u32 packets = 0; |
406 | u32 bytes = 0; | 406 | u32 bytes = 0; |
407 | int factor = priv->cqe_factor; | 407 | int factor = priv->cqe_factor; |
408 | u64 timestamp = 0; | ||
409 | int done = 0; | 408 | int done = 0; |
410 | int budget = priv->tx_work_limit; | 409 | int budget = priv->tx_work_limit; |
411 | u32 last_nr_txbb; | 410 | u32 last_nr_txbb; |
@@ -445,9 +444,12 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev, | |||
445 | new_index = be16_to_cpu(cqe->wqe_index) & size_mask; | 444 | new_index = be16_to_cpu(cqe->wqe_index) & size_mask; |
446 | 445 | ||
447 | do { | 446 | do { |
447 | u64 timestamp = 0; | ||
448 | |||
448 | txbbs_skipped += last_nr_txbb; | 449 | txbbs_skipped += last_nr_txbb; |
449 | ring_index = (ring_index + last_nr_txbb) & size_mask; | 450 | ring_index = (ring_index + last_nr_txbb) & size_mask; |
450 | if (ring->tx_info[ring_index].ts_requested) | 451 | |
452 | if (unlikely(ring->tx_info[ring_index].ts_requested)) | ||
451 | timestamp = mlx4_en_get_cqe_ts(cqe); | 453 | timestamp = mlx4_en_get_cqe_ts(cqe); |
452 | 454 | ||
453 | /* free next descriptor */ | 455 | /* free next descriptor */ |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index 879e6276c473..e80ce94b5dcf 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h | |||
@@ -609,7 +609,7 @@ enum mlx5e_link_mode { | |||
609 | MLX5E_100GBASE_KR4 = 22, | 609 | MLX5E_100GBASE_KR4 = 22, |
610 | MLX5E_100GBASE_LR4 = 23, | 610 | MLX5E_100GBASE_LR4 = 23, |
611 | MLX5E_100BASE_TX = 24, | 611 | MLX5E_100BASE_TX = 24, |
612 | MLX5E_100BASE_T = 25, | 612 | MLX5E_1000BASE_T = 25, |
613 | MLX5E_10GBASE_T = 26, | 613 | MLX5E_10GBASE_T = 26, |
614 | MLX5E_25GBASE_CR = 27, | 614 | MLX5E_25GBASE_CR = 27, |
615 | MLX5E_25GBASE_KR = 28, | 615 | MLX5E_25GBASE_KR = 28, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 68834b715f6c..3476ab844634 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | |||
@@ -138,10 +138,10 @@ static const struct { | |||
138 | [MLX5E_100BASE_TX] = { | 138 | [MLX5E_100BASE_TX] = { |
139 | .speed = 100, | 139 | .speed = 100, |
140 | }, | 140 | }, |
141 | [MLX5E_100BASE_T] = { | 141 | [MLX5E_1000BASE_T] = { |
142 | .supported = SUPPORTED_100baseT_Full, | 142 | .supported = SUPPORTED_1000baseT_Full, |
143 | .advertised = ADVERTISED_100baseT_Full, | 143 | .advertised = ADVERTISED_1000baseT_Full, |
144 | .speed = 100, | 144 | .speed = 1000, |
145 | }, | 145 | }, |
146 | [MLX5E_10GBASE_T] = { | 146 | [MLX5E_10GBASE_T] = { |
147 | .supported = SUPPORTED_10000baseT_Full, | 147 | .supported = SUPPORTED_10000baseT_Full, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index e0adb604f461..67d548b70e14 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
@@ -1404,24 +1404,50 @@ static int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5e_priv *priv) | |||
1404 | return 0; | 1404 | return 0; |
1405 | } | 1405 | } |
1406 | 1406 | ||
1407 | static int mlx5e_set_dev_port_mtu(struct net_device *netdev) | 1407 | static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu) |
1408 | { | 1408 | { |
1409 | struct mlx5e_priv *priv = netdev_priv(netdev); | ||
1410 | struct mlx5_core_dev *mdev = priv->mdev; | 1409 | struct mlx5_core_dev *mdev = priv->mdev; |
1411 | int hw_mtu; | 1410 | u16 hw_mtu = MLX5E_SW2HW_MTU(mtu); |
1412 | int err; | 1411 | int err; |
1413 | 1412 | ||
1414 | err = mlx5_set_port_mtu(mdev, MLX5E_SW2HW_MTU(netdev->mtu), 1); | 1413 | err = mlx5_set_port_mtu(mdev, hw_mtu, 1); |
1415 | if (err) | 1414 | if (err) |
1416 | return err; | 1415 | return err; |
1417 | 1416 | ||
1418 | mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1); | 1417 | /* Update vport context MTU */ |
1418 | mlx5_modify_nic_vport_mtu(mdev, hw_mtu); | ||
1419 | return 0; | ||
1420 | } | ||
1419 | 1421 | ||
1420 | if (MLX5E_HW2SW_MTU(hw_mtu) != netdev->mtu) | 1422 | static void mlx5e_query_mtu(struct mlx5e_priv *priv, u16 *mtu) |
1421 | netdev_warn(netdev, "%s: Port MTU %d is different than netdev mtu %d\n", | 1423 | { |
1422 | __func__, MLX5E_HW2SW_MTU(hw_mtu), netdev->mtu); | 1424 | struct mlx5_core_dev *mdev = priv->mdev; |
1425 | u16 hw_mtu = 0; | ||
1426 | int err; | ||
1423 | 1427 | ||
1424 | netdev->mtu = MLX5E_HW2SW_MTU(hw_mtu); | 1428 | err = mlx5_query_nic_vport_mtu(mdev, &hw_mtu); |
1429 | if (err || !hw_mtu) /* fallback to port oper mtu */ | ||
1430 | mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1); | ||
1431 | |||
1432 | *mtu = MLX5E_HW2SW_MTU(hw_mtu); | ||
1433 | } | ||
1434 | |||
1435 | static int mlx5e_set_dev_port_mtu(struct net_device *netdev) | ||
1436 | { | ||
1437 | struct mlx5e_priv *priv = netdev_priv(netdev); | ||
1438 | u16 mtu; | ||
1439 | int err; | ||
1440 | |||
1441 | err = mlx5e_set_mtu(priv, netdev->mtu); | ||
1442 | if (err) | ||
1443 | return err; | ||
1444 | |||
1445 | mlx5e_query_mtu(priv, &mtu); | ||
1446 | if (mtu != netdev->mtu) | ||
1447 | netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n", | ||
1448 | __func__, mtu, netdev->mtu); | ||
1449 | |||
1450 | netdev->mtu = mtu; | ||
1425 | return 0; | 1451 | return 0; |
1426 | } | 1452 | } |
1427 | 1453 | ||
@@ -1999,22 +2025,27 @@ static int mlx5e_set_features(struct net_device *netdev, | |||
1999 | return err; | 2025 | return err; |
2000 | } | 2026 | } |
2001 | 2027 | ||
2028 | #define MXL5_HW_MIN_MTU 64 | ||
2029 | #define MXL5E_MIN_MTU (MXL5_HW_MIN_MTU + ETH_FCS_LEN) | ||
2030 | |||
2002 | static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) | 2031 | static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) |
2003 | { | 2032 | { |
2004 | struct mlx5e_priv *priv = netdev_priv(netdev); | 2033 | struct mlx5e_priv *priv = netdev_priv(netdev); |
2005 | struct mlx5_core_dev *mdev = priv->mdev; | 2034 | struct mlx5_core_dev *mdev = priv->mdev; |
2006 | bool was_opened; | 2035 | bool was_opened; |
2007 | int max_mtu; | 2036 | u16 max_mtu; |
2037 | u16 min_mtu; | ||
2008 | int err = 0; | 2038 | int err = 0; |
2009 | 2039 | ||
2010 | mlx5_query_port_max_mtu(mdev, &max_mtu, 1); | 2040 | mlx5_query_port_max_mtu(mdev, &max_mtu, 1); |
2011 | 2041 | ||
2012 | max_mtu = MLX5E_HW2SW_MTU(max_mtu); | 2042 | max_mtu = MLX5E_HW2SW_MTU(max_mtu); |
2043 | min_mtu = MLX5E_HW2SW_MTU(MXL5E_MIN_MTU); | ||
2013 | 2044 | ||
2014 | if (new_mtu > max_mtu) { | 2045 | if (new_mtu > max_mtu || new_mtu < min_mtu) { |
2015 | netdev_err(netdev, | 2046 | netdev_err(netdev, |
2016 | "%s: Bad MTU (%d) > (%d) Max\n", | 2047 | "%s: Bad MTU (%d), valid range is: [%d..%d]\n", |
2017 | __func__, new_mtu, max_mtu); | 2048 | __func__, new_mtu, min_mtu, max_mtu); |
2018 | return -EINVAL; | 2049 | return -EINVAL; |
2019 | } | 2050 | } |
2020 | 2051 | ||
@@ -2602,7 +2633,16 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) | |||
2602 | schedule_work(&priv->set_rx_mode_work); | 2633 | schedule_work(&priv->set_rx_mode_work); |
2603 | mlx5e_disable_async_events(priv); | 2634 | mlx5e_disable_async_events(priv); |
2604 | flush_scheduled_work(); | 2635 | flush_scheduled_work(); |
2605 | unregister_netdev(netdev); | 2636 | if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) { |
2637 | netif_device_detach(netdev); | ||
2638 | mutex_lock(&priv->state_lock); | ||
2639 | if (test_bit(MLX5E_STATE_OPENED, &priv->state)) | ||
2640 | mlx5e_close_locked(netdev); | ||
2641 | mutex_unlock(&priv->state_lock); | ||
2642 | } else { | ||
2643 | unregister_netdev(netdev); | ||
2644 | } | ||
2645 | |||
2606 | mlx5e_tc_cleanup(priv); | 2646 | mlx5e_tc_cleanup(priv); |
2607 | mlx5e_vxlan_cleanup(priv); | 2647 | mlx5e_vxlan_cleanup(priv); |
2608 | mlx5e_destroy_flow_tables(priv); | 2648 | mlx5e_destroy_flow_tables(priv); |
@@ -2615,7 +2655,9 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) | |||
2615 | mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn); | 2655 | mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn); |
2616 | mlx5_core_dealloc_pd(priv->mdev, priv->pdn); | 2656 | mlx5_core_dealloc_pd(priv->mdev, priv->pdn); |
2617 | mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar); | 2657 | mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar); |
2618 | free_netdev(netdev); | 2658 | |
2659 | if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) | ||
2660 | free_netdev(netdev); | ||
2619 | } | 2661 | } |
2620 | 2662 | ||
2621 | static void *mlx5e_get_netdev(void *vpriv) | 2663 | static void *mlx5e_get_netdev(void *vpriv) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 5121be4675d1..89cce97d46c6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | |||
@@ -1065,33 +1065,6 @@ unlock_fg: | |||
1065 | return rule; | 1065 | return rule; |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | static struct mlx5_flow_rule *add_rule_to_auto_fg(struct mlx5_flow_table *ft, | ||
1069 | u8 match_criteria_enable, | ||
1070 | u32 *match_criteria, | ||
1071 | u32 *match_value, | ||
1072 | u8 action, | ||
1073 | u32 flow_tag, | ||
1074 | struct mlx5_flow_destination *dest) | ||
1075 | { | ||
1076 | struct mlx5_flow_rule *rule; | ||
1077 | struct mlx5_flow_group *g; | ||
1078 | |||
1079 | g = create_autogroup(ft, match_criteria_enable, match_criteria); | ||
1080 | if (IS_ERR(g)) | ||
1081 | return (void *)g; | ||
1082 | |||
1083 | rule = add_rule_fg(g, match_value, | ||
1084 | action, flow_tag, dest); | ||
1085 | if (IS_ERR(rule)) { | ||
1086 | /* Remove assumes refcount > 0 and autogroup creates a group | ||
1087 | * with a refcount = 0. | ||
1088 | */ | ||
1089 | tree_get_node(&g->node); | ||
1090 | tree_remove_node(&g->node); | ||
1091 | } | ||
1092 | return rule; | ||
1093 | } | ||
1094 | |||
1095 | static struct mlx5_flow_rule * | 1068 | static struct mlx5_flow_rule * |
1096 | _mlx5_add_flow_rule(struct mlx5_flow_table *ft, | 1069 | _mlx5_add_flow_rule(struct mlx5_flow_table *ft, |
1097 | u8 match_criteria_enable, | 1070 | u8 match_criteria_enable, |
@@ -1119,8 +1092,23 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft, | |||
1119 | goto unlock; | 1092 | goto unlock; |
1120 | } | 1093 | } |
1121 | 1094 | ||
1122 | rule = add_rule_to_auto_fg(ft, match_criteria_enable, match_criteria, | 1095 | g = create_autogroup(ft, match_criteria_enable, match_criteria); |
1123 | match_value, action, flow_tag, dest); | 1096 | if (IS_ERR(g)) { |
1097 | rule = (void *)g; | ||
1098 | goto unlock; | ||
1099 | } | ||
1100 | |||
1101 | rule = add_rule_fg(g, match_value, | ||
1102 | action, flow_tag, dest); | ||
1103 | if (IS_ERR(rule)) { | ||
1104 | /* Remove assumes refcount > 0 and autogroup creates a group | ||
1105 | * with a refcount = 0. | ||
1106 | */ | ||
1107 | unlock_ref_node(&ft->node); | ||
1108 | tree_get_node(&g->node); | ||
1109 | tree_remove_node(&g->node); | ||
1110 | return rule; | ||
1111 | } | ||
1124 | unlock: | 1112 | unlock: |
1125 | unlock_ref_node(&ft->node); | 1113 | unlock_ref_node(&ft->node); |
1126 | return rule; | 1114 | return rule; |
@@ -1288,7 +1276,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, | |||
1288 | { | 1276 | { |
1289 | struct mlx5_flow_root_namespace *root_ns = dev->priv.root_ns; | 1277 | struct mlx5_flow_root_namespace *root_ns = dev->priv.root_ns; |
1290 | int prio; | 1278 | int prio; |
1291 | static struct fs_prio *fs_prio; | 1279 | struct fs_prio *fs_prio; |
1292 | struct mlx5_flow_namespace *ns; | 1280 | struct mlx5_flow_namespace *ns; |
1293 | 1281 | ||
1294 | if (!root_ns) | 1282 | if (!root_ns) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 3f3b2fae4991..6892746fd10d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
@@ -966,7 +966,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) | |||
966 | int err; | 966 | int err; |
967 | 967 | ||
968 | mutex_lock(&dev->intf_state_mutex); | 968 | mutex_lock(&dev->intf_state_mutex); |
969 | if (dev->interface_state == MLX5_INTERFACE_STATE_UP) { | 969 | if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { |
970 | dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n", | 970 | dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n", |
971 | __func__); | 971 | __func__); |
972 | goto out; | 972 | goto out; |
@@ -1133,7 +1133,8 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) | |||
1133 | if (err) | 1133 | if (err) |
1134 | pr_info("failed request module on %s\n", MLX5_IB_MOD); | 1134 | pr_info("failed request module on %s\n", MLX5_IB_MOD); |
1135 | 1135 | ||
1136 | dev->interface_state = MLX5_INTERFACE_STATE_UP; | 1136 | clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); |
1137 | set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); | ||
1137 | out: | 1138 | out: |
1138 | mutex_unlock(&dev->intf_state_mutex); | 1139 | mutex_unlock(&dev->intf_state_mutex); |
1139 | 1140 | ||
@@ -1207,7 +1208,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) | |||
1207 | } | 1208 | } |
1208 | 1209 | ||
1209 | mutex_lock(&dev->intf_state_mutex); | 1210 | mutex_lock(&dev->intf_state_mutex); |
1210 | if (dev->interface_state == MLX5_INTERFACE_STATE_DOWN) { | 1211 | if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) { |
1211 | dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", | 1212 | dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", |
1212 | __func__); | 1213 | __func__); |
1213 | goto out; | 1214 | goto out; |
@@ -1241,7 +1242,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) | |||
1241 | mlx5_cmd_cleanup(dev); | 1242 | mlx5_cmd_cleanup(dev); |
1242 | 1243 | ||
1243 | out: | 1244 | out: |
1244 | dev->interface_state = MLX5_INTERFACE_STATE_DOWN; | 1245 | clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); |
1246 | set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); | ||
1245 | mutex_unlock(&dev->intf_state_mutex); | 1247 | mutex_unlock(&dev->intf_state_mutex); |
1246 | return err; | 1248 | return err; |
1247 | } | 1249 | } |
@@ -1452,6 +1454,18 @@ static const struct pci_error_handlers mlx5_err_handler = { | |||
1452 | .resume = mlx5_pci_resume | 1454 | .resume = mlx5_pci_resume |
1453 | }; | 1455 | }; |
1454 | 1456 | ||
1457 | static void shutdown(struct pci_dev *pdev) | ||
1458 | { | ||
1459 | struct mlx5_core_dev *dev = pci_get_drvdata(pdev); | ||
1460 | struct mlx5_priv *priv = &dev->priv; | ||
1461 | |||
1462 | dev_info(&pdev->dev, "Shutdown was called\n"); | ||
1463 | /* Notify mlx5 clients that the kernel is being shut down */ | ||
1464 | set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state); | ||
1465 | mlx5_unload_one(dev, priv); | ||
1466 | mlx5_pci_disable_device(dev); | ||
1467 | } | ||
1468 | |||
1455 | static const struct pci_device_id mlx5_core_pci_table[] = { | 1469 | static const struct pci_device_id mlx5_core_pci_table[] = { |
1456 | { PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */ | 1470 | { PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */ |
1457 | { PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF}, /* Connect-IB VF */ | 1471 | { PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF}, /* Connect-IB VF */ |
@@ -1459,6 +1473,8 @@ static const struct pci_device_id mlx5_core_pci_table[] = { | |||
1459 | { PCI_VDEVICE(MELLANOX, 0x1014), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4 VF */ | 1473 | { PCI_VDEVICE(MELLANOX, 0x1014), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4 VF */ |
1460 | { PCI_VDEVICE(MELLANOX, 0x1015) }, /* ConnectX-4LX */ | 1474 | { PCI_VDEVICE(MELLANOX, 0x1015) }, /* ConnectX-4LX */ |
1461 | { PCI_VDEVICE(MELLANOX, 0x1016), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4LX VF */ | 1475 | { PCI_VDEVICE(MELLANOX, 0x1016), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4LX VF */ |
1476 | { PCI_VDEVICE(MELLANOX, 0x1017) }, /* ConnectX-5 */ | ||
1477 | { PCI_VDEVICE(MELLANOX, 0x1018), MLX5_PCI_DEV_IS_VF}, /* ConnectX-5 VF */ | ||
1462 | { 0, } | 1478 | { 0, } |
1463 | }; | 1479 | }; |
1464 | 1480 | ||
@@ -1469,6 +1485,7 @@ static struct pci_driver mlx5_core_driver = { | |||
1469 | .id_table = mlx5_core_pci_table, | 1485 | .id_table = mlx5_core_pci_table, |
1470 | .probe = init_one, | 1486 | .probe = init_one, |
1471 | .remove = remove_one, | 1487 | .remove = remove_one, |
1488 | .shutdown = shutdown, | ||
1472 | .err_handler = &mlx5_err_handler, | 1489 | .err_handler = &mlx5_err_handler, |
1473 | .sriov_configure = mlx5_core_sriov_configure, | 1490 | .sriov_configure = mlx5_core_sriov_configure, |
1474 | }; | 1491 | }; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index ae378c575deb..53cc1e2c693b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c | |||
@@ -247,8 +247,8 @@ int mlx5_query_port_admin_status(struct mlx5_core_dev *dev, | |||
247 | } | 247 | } |
248 | EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status); | 248 | EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status); |
249 | 249 | ||
250 | static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu, | 250 | static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, u16 *admin_mtu, |
251 | int *max_mtu, int *oper_mtu, u8 port) | 251 | u16 *max_mtu, u16 *oper_mtu, u8 port) |
252 | { | 252 | { |
253 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; | 253 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; |
254 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; | 254 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; |
@@ -268,7 +268,7 @@ static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu, | |||
268 | *admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu); | 268 | *admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu); |
269 | } | 269 | } |
270 | 270 | ||
271 | int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port) | 271 | int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port) |
272 | { | 272 | { |
273 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; | 273 | u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; |
274 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; | 274 | u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; |
@@ -283,14 +283,14 @@ int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port) | |||
283 | } | 283 | } |
284 | EXPORT_SYMBOL_GPL(mlx5_set_port_mtu); | 284 | EXPORT_SYMBOL_GPL(mlx5_set_port_mtu); |
285 | 285 | ||
286 | void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, | 286 | void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, |
287 | u8 port) | 287 | u8 port) |
288 | { | 288 | { |
289 | mlx5_query_port_mtu(dev, NULL, max_mtu, NULL, port); | 289 | mlx5_query_port_mtu(dev, NULL, max_mtu, NULL, port); |
290 | } | 290 | } |
291 | EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu); | 291 | EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu); |
292 | 292 | ||
293 | void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu, | 293 | void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu, |
294 | u8 port) | 294 | u8 port) |
295 | { | 295 | { |
296 | mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu, port); | 296 | mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu, port); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c index bd518405859e..b69dadcfb897 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c | |||
@@ -196,6 +196,46 @@ int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev, | |||
196 | } | 196 | } |
197 | EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_address); | 197 | EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_address); |
198 | 198 | ||
199 | int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu) | ||
200 | { | ||
201 | int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); | ||
202 | u32 *out; | ||
203 | int err; | ||
204 | |||
205 | out = mlx5_vzalloc(outlen); | ||
206 | if (!out) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | err = mlx5_query_nic_vport_context(mdev, 0, out, outlen); | ||
210 | if (!err) | ||
211 | *mtu = MLX5_GET(query_nic_vport_context_out, out, | ||
212 | nic_vport_context.mtu); | ||
213 | |||
214 | kvfree(out); | ||
215 | return err; | ||
216 | } | ||
217 | EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mtu); | ||
218 | |||
219 | int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu) | ||
220 | { | ||
221 | int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in); | ||
222 | void *in; | ||
223 | int err; | ||
224 | |||
225 | in = mlx5_vzalloc(inlen); | ||
226 | if (!in) | ||
227 | return -ENOMEM; | ||
228 | |||
229 | MLX5_SET(modify_nic_vport_context_in, in, field_select.mtu, 1); | ||
230 | MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.mtu, mtu); | ||
231 | |||
232 | err = mlx5_modify_nic_vport_context(mdev, in, inlen); | ||
233 | |||
234 | kvfree(in); | ||
235 | return err; | ||
236 | } | ||
237 | EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu); | ||
238 | |||
199 | int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev, | 239 | int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev, |
200 | u32 vport, | 240 | u32 vport, |
201 | enum mlx5_list_type list_type, | 241 | enum mlx5_list_type list_type, |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 55007f1e6bbc..caf6ddb7ea76 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -37,8 +37,8 @@ | |||
37 | 37 | ||
38 | #define _QLCNIC_LINUX_MAJOR 5 | 38 | #define _QLCNIC_LINUX_MAJOR 5 |
39 | #define _QLCNIC_LINUX_MINOR 3 | 39 | #define _QLCNIC_LINUX_MINOR 3 |
40 | #define _QLCNIC_LINUX_SUBVERSION 63 | 40 | #define _QLCNIC_LINUX_SUBVERSION 64 |
41 | #define QLCNIC_LINUX_VERSIONID "5.3.63" | 41 | #define QLCNIC_LINUX_VERSIONID "5.3.64" |
42 | #define QLCNIC_DRV_IDC_VER 0x01 | 42 | #define QLCNIC_DRV_IDC_VER 0x01 |
43 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ | 43 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ |
44 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) | 44 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index 44022b1845ce..afb90d129cb6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | |||
@@ -49,7 +49,6 @@ struct socfpga_dwmac { | |||
49 | u32 reg_shift; | 49 | u32 reg_shift; |
50 | struct device *dev; | 50 | struct device *dev; |
51 | struct regmap *sys_mgr_base_addr; | 51 | struct regmap *sys_mgr_base_addr; |
52 | struct reset_control *stmmac_rst; | ||
53 | void __iomem *splitter_base; | 52 | void __iomem *splitter_base; |
54 | bool f2h_ptp_ref_clk; | 53 | bool f2h_ptp_ref_clk; |
55 | }; | 54 | }; |
@@ -92,15 +91,6 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device * | |||
92 | struct device_node *np_splitter; | 91 | struct device_node *np_splitter; |
93 | struct resource res_splitter; | 92 | struct resource res_splitter; |
94 | 93 | ||
95 | dwmac->stmmac_rst = devm_reset_control_get(dev, | ||
96 | STMMAC_RESOURCE_NAME); | ||
97 | if (IS_ERR(dwmac->stmmac_rst)) { | ||
98 | dev_info(dev, "Could not get reset control!\n"); | ||
99 | if (PTR_ERR(dwmac->stmmac_rst) == -EPROBE_DEFER) | ||
100 | return -EPROBE_DEFER; | ||
101 | dwmac->stmmac_rst = NULL; | ||
102 | } | ||
103 | |||
104 | dwmac->interface = of_get_phy_mode(np); | 94 | dwmac->interface = of_get_phy_mode(np); |
105 | 95 | ||
106 | sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); | 96 | sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); |
@@ -194,30 +184,23 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac) | |||
194 | return 0; | 184 | return 0; |
195 | } | 185 | } |
196 | 186 | ||
197 | static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv) | ||
198 | { | ||
199 | struct socfpga_dwmac *dwmac = priv; | ||
200 | |||
201 | /* On socfpga platform exit, assert and hold reset to the | ||
202 | * enet controller - the default state after a hard reset. | ||
203 | */ | ||
204 | if (dwmac->stmmac_rst) | ||
205 | reset_control_assert(dwmac->stmmac_rst); | ||
206 | } | ||
207 | |||
208 | static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) | 187 | static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) |
209 | { | 188 | { |
210 | struct socfpga_dwmac *dwmac = priv; | 189 | struct socfpga_dwmac *dwmac = priv; |
211 | struct net_device *ndev = platform_get_drvdata(pdev); | 190 | struct net_device *ndev = platform_get_drvdata(pdev); |
212 | struct stmmac_priv *stpriv = NULL; | 191 | struct stmmac_priv *stpriv = NULL; |
213 | int ret = 0; | 192 | int ret = 0; |
214 | 193 | ||
215 | if (ndev) | 194 | if (!ndev) |
216 | stpriv = netdev_priv(ndev); | 195 | return -EINVAL; |
196 | |||
197 | stpriv = netdev_priv(ndev); | ||
198 | if (!stpriv) | ||
199 | return -EINVAL; | ||
217 | 200 | ||
218 | /* Assert reset to the enet controller before changing the phy mode */ | 201 | /* Assert reset to the enet controller before changing the phy mode */ |
219 | if (dwmac->stmmac_rst) | 202 | if (stpriv->stmmac_rst) |
220 | reset_control_assert(dwmac->stmmac_rst); | 203 | reset_control_assert(stpriv->stmmac_rst); |
221 | 204 | ||
222 | /* Setup the phy mode in the system manager registers according to | 205 | /* Setup the phy mode in the system manager registers according to |
223 | * devicetree configuration | 206 | * devicetree configuration |
@@ -227,8 +210,8 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) | |||
227 | /* Deassert reset for the phy configuration to be sampled by | 210 | /* Deassert reset for the phy configuration to be sampled by |
228 | * the enet controller, and operation to start in requested mode | 211 | * the enet controller, and operation to start in requested mode |
229 | */ | 212 | */ |
230 | if (dwmac->stmmac_rst) | 213 | if (stpriv->stmmac_rst) |
231 | reset_control_deassert(dwmac->stmmac_rst); | 214 | reset_control_deassert(stpriv->stmmac_rst); |
232 | 215 | ||
233 | /* Before the enet controller is suspended, the phy is suspended. | 216 | /* Before the enet controller is suspended, the phy is suspended. |
234 | * This causes the phy clock to be gated. The enet controller is | 217 | * This causes the phy clock to be gated. The enet controller is |
@@ -245,7 +228,7 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) | |||
245 | * control register 0, and can be modified by the phy driver | 228 | * control register 0, and can be modified by the phy driver |
246 | * framework. | 229 | * framework. |
247 | */ | 230 | */ |
248 | if (stpriv && stpriv->phydev) | 231 | if (stpriv->phydev) |
249 | phy_resume(stpriv->phydev); | 232 | phy_resume(stpriv->phydev); |
250 | 233 | ||
251 | return ret; | 234 | return ret; |
@@ -285,14 +268,13 @@ static int socfpga_dwmac_probe(struct platform_device *pdev) | |||
285 | 268 | ||
286 | plat_dat->bsp_priv = dwmac; | 269 | plat_dat->bsp_priv = dwmac; |
287 | plat_dat->init = socfpga_dwmac_init; | 270 | plat_dat->init = socfpga_dwmac_init; |
288 | plat_dat->exit = socfpga_dwmac_exit; | ||
289 | plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; | 271 | plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; |
290 | 272 | ||
291 | ret = socfpga_dwmac_init(pdev, plat_dat->bsp_priv); | 273 | ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); |
292 | if (ret) | 274 | if (!ret) |
293 | return ret; | 275 | ret = socfpga_dwmac_init(pdev, dwmac); |
294 | 276 | ||
295 | return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); | 277 | return ret; |
296 | } | 278 | } |
297 | 279 | ||
298 | static const struct of_device_id socfpga_dwmac_match[] = { | 280 | static const struct of_device_id socfpga_dwmac_match[] = { |
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 84d3e5ca8817..c6385617bfb2 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c | |||
@@ -880,12 +880,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | |||
880 | macsec_skb_cb(skb)->valid = false; | 880 | macsec_skb_cb(skb)->valid = false; |
881 | skb = skb_share_check(skb, GFP_ATOMIC); | 881 | skb = skb_share_check(skb, GFP_ATOMIC); |
882 | if (!skb) | 882 | if (!skb) |
883 | return NULL; | 883 | return ERR_PTR(-ENOMEM); |
884 | 884 | ||
885 | req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC); | 885 | req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC); |
886 | if (!req) { | 886 | if (!req) { |
887 | kfree_skb(skb); | 887 | kfree_skb(skb); |
888 | return NULL; | 888 | return ERR_PTR(-ENOMEM); |
889 | } | 889 | } |
890 | 890 | ||
891 | hdr = (struct macsec_eth_header *)skb->data; | 891 | hdr = (struct macsec_eth_header *)skb->data; |
@@ -905,7 +905,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | |||
905 | skb = skb_unshare(skb, GFP_ATOMIC); | 905 | skb = skb_unshare(skb, GFP_ATOMIC); |
906 | if (!skb) { | 906 | if (!skb) { |
907 | aead_request_free(req); | 907 | aead_request_free(req); |
908 | return NULL; | 908 | return ERR_PTR(-ENOMEM); |
909 | } | 909 | } |
910 | } else { | 910 | } else { |
911 | /* integrity only: all headers + data authenticated */ | 911 | /* integrity only: all headers + data authenticated */ |
@@ -921,14 +921,14 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | |||
921 | dev_hold(dev); | 921 | dev_hold(dev); |
922 | ret = crypto_aead_decrypt(req); | 922 | ret = crypto_aead_decrypt(req); |
923 | if (ret == -EINPROGRESS) { | 923 | if (ret == -EINPROGRESS) { |
924 | return NULL; | 924 | return ERR_PTR(ret); |
925 | } else if (ret != 0) { | 925 | } else if (ret != 0) { |
926 | /* decryption/authentication failed | 926 | /* decryption/authentication failed |
927 | * 10.6 if validateFrames is disabled, deliver anyway | 927 | * 10.6 if validateFrames is disabled, deliver anyway |
928 | */ | 928 | */ |
929 | if (ret != -EBADMSG) { | 929 | if (ret != -EBADMSG) { |
930 | kfree_skb(skb); | 930 | kfree_skb(skb); |
931 | skb = NULL; | 931 | skb = ERR_PTR(ret); |
932 | } | 932 | } |
933 | } else { | 933 | } else { |
934 | macsec_skb_cb(skb)->valid = true; | 934 | macsec_skb_cb(skb)->valid = true; |
@@ -1146,8 +1146,10 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) | |||
1146 | secy->validate_frames != MACSEC_VALIDATE_DISABLED) | 1146 | secy->validate_frames != MACSEC_VALIDATE_DISABLED) |
1147 | skb = macsec_decrypt(skb, dev, rx_sa, sci, secy); | 1147 | skb = macsec_decrypt(skb, dev, rx_sa, sci, secy); |
1148 | 1148 | ||
1149 | if (!skb) { | 1149 | if (IS_ERR(skb)) { |
1150 | macsec_rxsa_put(rx_sa); | 1150 | /* the decrypt callback needs the reference */ |
1151 | if (PTR_ERR(skb) != -EINPROGRESS) | ||
1152 | macsec_rxsa_put(rx_sa); | ||
1151 | rcu_read_unlock(); | 1153 | rcu_read_unlock(); |
1152 | *pskb = NULL; | 1154 | *pskb = NULL; |
1153 | return RX_HANDLER_CONSUMED; | 1155 | return RX_HANDLER_CONSUMED; |
@@ -1161,7 +1163,8 @@ deliver: | |||
1161 | macsec_extra_len(macsec_skb_cb(skb)->has_sci)); | 1163 | macsec_extra_len(macsec_skb_cb(skb)->has_sci)); |
1162 | macsec_reset_skb(skb, secy->netdev); | 1164 | macsec_reset_skb(skb, secy->netdev); |
1163 | 1165 | ||
1164 | macsec_rxsa_put(rx_sa); | 1166 | if (rx_sa) |
1167 | macsec_rxsa_put(rx_sa); | ||
1165 | count_rx(dev, skb->len); | 1168 | count_rx(dev, skb->len); |
1166 | 1169 | ||
1167 | rcu_read_unlock(); | 1170 | rcu_read_unlock(); |
@@ -1622,8 +1625,9 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info) | |||
1622 | } | 1625 | } |
1623 | 1626 | ||
1624 | rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); | 1627 | rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); |
1625 | if (init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len, | 1628 | if (!rx_sa || init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), |
1626 | secy->icv_len)) { | 1629 | secy->key_len, secy->icv_len)) { |
1630 | kfree(rx_sa); | ||
1627 | rtnl_unlock(); | 1631 | rtnl_unlock(); |
1628 | return -ENOMEM; | 1632 | return -ENOMEM; |
1629 | } | 1633 | } |
@@ -1768,6 +1772,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info) | |||
1768 | tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL); | 1772 | tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL); |
1769 | if (!tx_sa || init_tx_sa(tx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), | 1773 | if (!tx_sa || init_tx_sa(tx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), |
1770 | secy->key_len, secy->icv_len)) { | 1774 | secy->key_len, secy->icv_len)) { |
1775 | kfree(tx_sa); | ||
1771 | rtnl_unlock(); | 1776 | rtnl_unlock(); |
1772 | return -ENOMEM; | 1777 | return -ENOMEM; |
1773 | } | 1778 | } |
@@ -2227,7 +2232,8 @@ static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb) | |||
2227 | return 1; | 2232 | return 1; |
2228 | 2233 | ||
2229 | if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) || | 2234 | if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) || |
2230 | nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, DEFAULT_CIPHER_ID) || | 2235 | nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, |
2236 | MACSEC_DEFAULT_CIPHER_ID) || | ||
2231 | nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || | 2237 | nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || |
2232 | nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || | 2238 | nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || |
2233 | nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || | 2239 | nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || |
@@ -2268,7 +2274,7 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, | |||
2268 | if (!hdr) | 2274 | if (!hdr) |
2269 | return -EMSGSIZE; | 2275 | return -EMSGSIZE; |
2270 | 2276 | ||
2271 | rtnl_lock(); | 2277 | genl_dump_check_consistent(cb, hdr, &macsec_fam); |
2272 | 2278 | ||
2273 | if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) | 2279 | if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) |
2274 | goto nla_put_failure; | 2280 | goto nla_put_failure; |
@@ -2429,18 +2435,17 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, | |||
2429 | 2435 | ||
2430 | nla_nest_end(skb, rxsc_list); | 2436 | nla_nest_end(skb, rxsc_list); |
2431 | 2437 | ||
2432 | rtnl_unlock(); | ||
2433 | |||
2434 | genlmsg_end(skb, hdr); | 2438 | genlmsg_end(skb, hdr); |
2435 | 2439 | ||
2436 | return 0; | 2440 | return 0; |
2437 | 2441 | ||
2438 | nla_put_failure: | 2442 | nla_put_failure: |
2439 | rtnl_unlock(); | ||
2440 | genlmsg_cancel(skb, hdr); | 2443 | genlmsg_cancel(skb, hdr); |
2441 | return -EMSGSIZE; | 2444 | return -EMSGSIZE; |
2442 | } | 2445 | } |
2443 | 2446 | ||
2447 | static int macsec_generation = 1; /* protected by RTNL */ | ||
2448 | |||
2444 | static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) | 2449 | static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) |
2445 | { | 2450 | { |
2446 | struct net *net = sock_net(skb->sk); | 2451 | struct net *net = sock_net(skb->sk); |
@@ -2450,6 +2455,10 @@ static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) | |||
2450 | dev_idx = cb->args[0]; | 2455 | dev_idx = cb->args[0]; |
2451 | 2456 | ||
2452 | d = 0; | 2457 | d = 0; |
2458 | rtnl_lock(); | ||
2459 | |||
2460 | cb->seq = macsec_generation; | ||
2461 | |||
2453 | for_each_netdev(net, dev) { | 2462 | for_each_netdev(net, dev) { |
2454 | struct macsec_secy *secy; | 2463 | struct macsec_secy *secy; |
2455 | 2464 | ||
@@ -2467,6 +2476,7 @@ next: | |||
2467 | } | 2476 | } |
2468 | 2477 | ||
2469 | done: | 2478 | done: |
2479 | rtnl_unlock(); | ||
2470 | cb->args[0] = d; | 2480 | cb->args[0] = d; |
2471 | return skb->len; | 2481 | return skb->len; |
2472 | } | 2482 | } |
@@ -2920,10 +2930,14 @@ static void macsec_dellink(struct net_device *dev, struct list_head *head) | |||
2920 | struct net_device *real_dev = macsec->real_dev; | 2930 | struct net_device *real_dev = macsec->real_dev; |
2921 | struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev); | 2931 | struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev); |
2922 | 2932 | ||
2933 | macsec_generation++; | ||
2934 | |||
2923 | unregister_netdevice_queue(dev, head); | 2935 | unregister_netdevice_queue(dev, head); |
2924 | list_del_rcu(&macsec->secys); | 2936 | list_del_rcu(&macsec->secys); |
2925 | if (list_empty(&rxd->secys)) | 2937 | if (list_empty(&rxd->secys)) { |
2926 | netdev_rx_handler_unregister(real_dev); | 2938 | netdev_rx_handler_unregister(real_dev); |
2939 | kfree(rxd); | ||
2940 | } | ||
2927 | 2941 | ||
2928 | macsec_del_dev(macsec); | 2942 | macsec_del_dev(macsec); |
2929 | } | 2943 | } |
@@ -2945,8 +2959,10 @@ static int register_macsec_dev(struct net_device *real_dev, | |||
2945 | 2959 | ||
2946 | err = netdev_rx_handler_register(real_dev, macsec_handle_frame, | 2960 | err = netdev_rx_handler_register(real_dev, macsec_handle_frame, |
2947 | rxd); | 2961 | rxd); |
2948 | if (err < 0) | 2962 | if (err < 0) { |
2963 | kfree(rxd); | ||
2949 | return err; | 2964 | return err; |
2965 | } | ||
2950 | } | 2966 | } |
2951 | 2967 | ||
2952 | list_add_tail_rcu(&macsec->secys, &rxd->secys); | 2968 | list_add_tail_rcu(&macsec->secys, &rxd->secys); |
@@ -3066,6 +3082,8 @@ static int macsec_newlink(struct net *net, struct net_device *dev, | |||
3066 | if (err < 0) | 3082 | if (err < 0) |
3067 | goto del_dev; | 3083 | goto del_dev; |
3068 | 3084 | ||
3085 | macsec_generation++; | ||
3086 | |||
3069 | dev_hold(real_dev); | 3087 | dev_hold(real_dev); |
3070 | 3088 | ||
3071 | return 0; | 3089 | return 0; |
@@ -3079,7 +3097,7 @@ unregister: | |||
3079 | 3097 | ||
3080 | static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) | 3098 | static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) |
3081 | { | 3099 | { |
3082 | u64 csid = DEFAULT_CIPHER_ID; | 3100 | u64 csid = MACSEC_DEFAULT_CIPHER_ID; |
3083 | u8 icv_len = DEFAULT_ICV_LEN; | 3101 | u8 icv_len = DEFAULT_ICV_LEN; |
3084 | int flag; | 3102 | int flag; |
3085 | bool es, scb, sci; | 3103 | bool es, scb, sci; |
@@ -3094,8 +3112,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) | |||
3094 | icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); | 3112 | icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); |
3095 | 3113 | ||
3096 | switch (csid) { | 3114 | switch (csid) { |
3097 | case DEFAULT_CIPHER_ID: | 3115 | case MACSEC_DEFAULT_CIPHER_ID: |
3098 | case DEFAULT_CIPHER_ALT: | 3116 | case MACSEC_DEFAULT_CIPHER_ALT: |
3099 | if (icv_len < MACSEC_MIN_ICV_LEN || | 3117 | if (icv_len < MACSEC_MIN_ICV_LEN || |
3100 | icv_len > MACSEC_MAX_ICV_LEN) | 3118 | icv_len > MACSEC_MAX_ICV_LEN) |
3101 | return -EINVAL; | 3119 | return -EINVAL; |
@@ -3129,8 +3147,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) | |||
3129 | nla_get_u8(data[IFLA_MACSEC_VALIDATION]) > MACSEC_VALIDATE_MAX) | 3147 | nla_get_u8(data[IFLA_MACSEC_VALIDATION]) > MACSEC_VALIDATE_MAX) |
3130 | return -EINVAL; | 3148 | return -EINVAL; |
3131 | 3149 | ||
3132 | if ((data[IFLA_MACSEC_PROTECT] && | 3150 | if ((data[IFLA_MACSEC_REPLAY_PROTECT] && |
3133 | nla_get_u8(data[IFLA_MACSEC_PROTECT])) && | 3151 | nla_get_u8(data[IFLA_MACSEC_REPLAY_PROTECT])) && |
3134 | !data[IFLA_MACSEC_WINDOW]) | 3152 | !data[IFLA_MACSEC_WINDOW]) |
3135 | return -EINVAL; | 3153 | return -EINVAL; |
3136 | 3154 | ||
@@ -3168,7 +3186,8 @@ static int macsec_fill_info(struct sk_buff *skb, | |||
3168 | 3186 | ||
3169 | if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) || | 3187 | if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) || |
3170 | nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || | 3188 | nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || |
3171 | nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, DEFAULT_CIPHER_ID) || | 3189 | nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, |
3190 | MACSEC_DEFAULT_CIPHER_ID) || | ||
3172 | nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || | 3191 | nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || |
3173 | nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || | 3192 | nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || |
3174 | nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || | 3193 | nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || |
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index f3bb7af4e984..ead83a24bcd1 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c | |||
@@ -688,6 +688,7 @@ static struct rt6_info *find_route_ipv6(const struct in6_addr *saddr, | |||
688 | { | 688 | { |
689 | struct flowi6 fl; | 689 | struct flowi6 fl; |
690 | 690 | ||
691 | memset(&fl, 0, sizeof(fl)); | ||
691 | if (saddr) | 692 | if (saddr) |
692 | memcpy(&fl.saddr, saddr, sizeof(struct in6_addr)); | 693 | memcpy(&fl.saddr, saddr, sizeof(struct in6_addr)); |
693 | if (daddr) | 694 | if (daddr) |
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index dcd5ac8d3b14..369c837d40f5 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h | |||
@@ -519,8 +519,9 @@ enum mlx5_device_state { | |||
519 | }; | 519 | }; |
520 | 520 | ||
521 | enum mlx5_interface_state { | 521 | enum mlx5_interface_state { |
522 | MLX5_INTERFACE_STATE_DOWN, | 522 | MLX5_INTERFACE_STATE_DOWN = BIT(0), |
523 | MLX5_INTERFACE_STATE_UP, | 523 | MLX5_INTERFACE_STATE_UP = BIT(1), |
524 | MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2), | ||
524 | }; | 525 | }; |
525 | 526 | ||
526 | enum mlx5_pci_status { | 527 | enum mlx5_pci_status { |
@@ -544,7 +545,7 @@ struct mlx5_core_dev { | |||
544 | enum mlx5_device_state state; | 545 | enum mlx5_device_state state; |
545 | /* sync interface state */ | 546 | /* sync interface state */ |
546 | struct mutex intf_state_mutex; | 547 | struct mutex intf_state_mutex; |
547 | enum mlx5_interface_state interface_state; | 548 | unsigned long intf_state; |
548 | void (*event) (struct mlx5_core_dev *dev, | 549 | void (*event) (struct mlx5_core_dev *dev, |
549 | enum mlx5_dev_event event, | 550 | enum mlx5_dev_event event, |
550 | unsigned long param); | 551 | unsigned long param); |
diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h index a1d145abd4eb..b30250ab7604 100644 --- a/include/linux/mlx5/port.h +++ b/include/linux/mlx5/port.h | |||
@@ -54,9 +54,9 @@ int mlx5_set_port_admin_status(struct mlx5_core_dev *dev, | |||
54 | int mlx5_query_port_admin_status(struct mlx5_core_dev *dev, | 54 | int mlx5_query_port_admin_status(struct mlx5_core_dev *dev, |
55 | enum mlx5_port_status *status); | 55 | enum mlx5_port_status *status); |
56 | 56 | ||
57 | int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port); | 57 | int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port); |
58 | void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, u8 port); | 58 | void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, u8 port); |
59 | void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu, | 59 | void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu, |
60 | u8 port); | 60 | u8 port); |
61 | 61 | ||
62 | int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev, | 62 | int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev, |
diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h index bd93e6323603..301da4a5e6bf 100644 --- a/include/linux/mlx5/vport.h +++ b/include/linux/mlx5/vport.h | |||
@@ -45,6 +45,8 @@ int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, | |||
45 | u16 vport, u8 *addr); | 45 | u16 vport, u8 *addr); |
46 | int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev, | 46 | int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev, |
47 | u16 vport, u8 *addr); | 47 | u16 vport, u8 *addr); |
48 | int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu); | ||
49 | int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu); | ||
48 | int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev, | 50 | int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev, |
49 | u64 *system_image_guid); | 51 | u64 *system_image_guid); |
50 | int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid); | 52 | int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid); |
diff --git a/include/net/switchdev.h b/include/net/switchdev.h index d451122e8404..51d77b2ce2b2 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h | |||
@@ -54,6 +54,8 @@ struct switchdev_attr { | |||
54 | struct net_device *orig_dev; | 54 | struct net_device *orig_dev; |
55 | enum switchdev_attr_id id; | 55 | enum switchdev_attr_id id; |
56 | u32 flags; | 56 | u32 flags; |
57 | void *complete_priv; | ||
58 | void (*complete)(struct net_device *dev, int err, void *priv); | ||
57 | union { | 59 | union { |
58 | struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */ | 60 | struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */ |
59 | u8 stp_state; /* PORT_STP_STATE */ | 61 | u8 stp_state; /* PORT_STP_STATE */ |
@@ -75,6 +77,8 @@ struct switchdev_obj { | |||
75 | struct net_device *orig_dev; | 77 | struct net_device *orig_dev; |
76 | enum switchdev_obj_id id; | 78 | enum switchdev_obj_id id; |
77 | u32 flags; | 79 | u32 flags; |
80 | void *complete_priv; | ||
81 | void (*complete)(struct net_device *dev, int err, void *priv); | ||
78 | }; | 82 | }; |
79 | 83 | ||
80 | /* SWITCHDEV_OBJ_ID_PORT_VLAN */ | 84 | /* SWITCHDEV_OBJ_ID_PORT_VLAN */ |
diff --git a/include/uapi/linux/if_macsec.h b/include/uapi/linux/if_macsec.h index 26b0d1e3e3e7..4c58d9917aa4 100644 --- a/include/uapi/linux/if_macsec.h +++ b/include/uapi/linux/if_macsec.h | |||
@@ -19,8 +19,8 @@ | |||
19 | 19 | ||
20 | #define MACSEC_MAX_KEY_LEN 128 | 20 | #define MACSEC_MAX_KEY_LEN 128 |
21 | 21 | ||
22 | #define DEFAULT_CIPHER_ID 0x0080020001000001ULL | 22 | #define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL |
23 | #define DEFAULT_CIPHER_ALT 0x0080C20001000001ULL | 23 | #define MACSEC_DEFAULT_CIPHER_ALT 0x0080C20001000001ULL |
24 | 24 | ||
25 | #define MACSEC_MIN_ICV_LEN 8 | 25 | #define MACSEC_MIN_ICV_LEN 8 |
26 | #define MACSEC_MAX_ICV_LEN 32 | 26 | #define MACSEC_MAX_ICV_LEN 32 |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 618ef77c302a..db2574e7b8b0 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
@@ -2030,7 +2030,6 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env) | |||
2030 | if (IS_ERR(map)) { | 2030 | if (IS_ERR(map)) { |
2031 | verbose("fd %d is not pointing to valid bpf_map\n", | 2031 | verbose("fd %d is not pointing to valid bpf_map\n", |
2032 | insn->imm); | 2032 | insn->imm); |
2033 | fdput(f); | ||
2034 | return PTR_ERR(map); | 2033 | return PTR_ERR(map); |
2035 | } | 2034 | } |
2036 | 2035 | ||
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index 253bc77eda3b..7dbc80d01eb0 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c | |||
@@ -61,6 +61,19 @@ static void __mdb_entry_fill_flags(struct br_mdb_entry *e, unsigned char flags) | |||
61 | e->flags |= MDB_FLAGS_OFFLOAD; | 61 | e->flags |= MDB_FLAGS_OFFLOAD; |
62 | } | 62 | } |
63 | 63 | ||
64 | static void __mdb_entry_to_br_ip(struct br_mdb_entry *entry, struct br_ip *ip) | ||
65 | { | ||
66 | memset(ip, 0, sizeof(struct br_ip)); | ||
67 | ip->vid = entry->vid; | ||
68 | ip->proto = entry->addr.proto; | ||
69 | if (ip->proto == htons(ETH_P_IP)) | ||
70 | ip->u.ip4 = entry->addr.u.ip4; | ||
71 | #if IS_ENABLED(CONFIG_IPV6) | ||
72 | else | ||
73 | ip->u.ip6 = entry->addr.u.ip6; | ||
74 | #endif | ||
75 | } | ||
76 | |||
64 | static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, | 77 | static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, |
65 | struct net_device *dev) | 78 | struct net_device *dev) |
66 | { | 79 | { |
@@ -243,9 +256,45 @@ static inline size_t rtnl_mdb_nlmsg_size(void) | |||
243 | + nla_total_size(sizeof(struct br_mdb_entry)); | 256 | + nla_total_size(sizeof(struct br_mdb_entry)); |
244 | } | 257 | } |
245 | 258 | ||
246 | static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, | 259 | struct br_mdb_complete_info { |
247 | int type, struct net_bridge_port_group *pg) | 260 | struct net_bridge_port *port; |
261 | struct br_ip ip; | ||
262 | }; | ||
263 | |||
264 | static void br_mdb_complete(struct net_device *dev, int err, void *priv) | ||
248 | { | 265 | { |
266 | struct br_mdb_complete_info *data = priv; | ||
267 | struct net_bridge_port_group __rcu **pp; | ||
268 | struct net_bridge_port_group *p; | ||
269 | struct net_bridge_mdb_htable *mdb; | ||
270 | struct net_bridge_mdb_entry *mp; | ||
271 | struct net_bridge_port *port = data->port; | ||
272 | struct net_bridge *br = port->br; | ||
273 | |||
274 | if (err) | ||
275 | goto err; | ||
276 | |||
277 | spin_lock_bh(&br->multicast_lock); | ||
278 | mdb = mlock_dereference(br->mdb, br); | ||
279 | mp = br_mdb_ip_get(mdb, &data->ip); | ||
280 | if (!mp) | ||
281 | goto out; | ||
282 | for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL; | ||
283 | pp = &p->next) { | ||
284 | if (p->port != port) | ||
285 | continue; | ||
286 | p->flags |= MDB_PG_FLAGS_OFFLOAD; | ||
287 | } | ||
288 | out: | ||
289 | spin_unlock_bh(&br->multicast_lock); | ||
290 | err: | ||
291 | kfree(priv); | ||
292 | } | ||
293 | |||
294 | static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p, | ||
295 | struct br_mdb_entry *entry, int type) | ||
296 | { | ||
297 | struct br_mdb_complete_info *complete_info; | ||
249 | struct switchdev_obj_port_mdb mdb = { | 298 | struct switchdev_obj_port_mdb mdb = { |
250 | .obj = { | 299 | .obj = { |
251 | .id = SWITCHDEV_OBJ_ID_PORT_MDB, | 300 | .id = SWITCHDEV_OBJ_ID_PORT_MDB, |
@@ -268,9 +317,14 @@ static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, | |||
268 | 317 | ||
269 | mdb.obj.orig_dev = port_dev; | 318 | mdb.obj.orig_dev = port_dev; |
270 | if (port_dev && type == RTM_NEWMDB) { | 319 | if (port_dev && type == RTM_NEWMDB) { |
271 | err = switchdev_port_obj_add(port_dev, &mdb.obj); | 320 | complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC); |
272 | if (!err && pg) | 321 | if (complete_info) { |
273 | pg->flags |= MDB_PG_FLAGS_OFFLOAD; | 322 | complete_info->port = p; |
323 | __mdb_entry_to_br_ip(entry, &complete_info->ip); | ||
324 | mdb.obj.complete_priv = complete_info; | ||
325 | mdb.obj.complete = br_mdb_complete; | ||
326 | switchdev_port_obj_add(port_dev, &mdb.obj); | ||
327 | } | ||
274 | } else if (port_dev && type == RTM_DELMDB) { | 328 | } else if (port_dev && type == RTM_DELMDB) { |
275 | switchdev_port_obj_del(port_dev, &mdb.obj); | 329 | switchdev_port_obj_del(port_dev, &mdb.obj); |
276 | } | 330 | } |
@@ -291,21 +345,21 @@ errout: | |||
291 | rtnl_set_sk_err(net, RTNLGRP_MDB, err); | 345 | rtnl_set_sk_err(net, RTNLGRP_MDB, err); |
292 | } | 346 | } |
293 | 347 | ||
294 | void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg, | 348 | void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, |
295 | int type) | 349 | struct br_ip *group, int type, u8 flags) |
296 | { | 350 | { |
297 | struct br_mdb_entry entry; | 351 | struct br_mdb_entry entry; |
298 | 352 | ||
299 | memset(&entry, 0, sizeof(entry)); | 353 | memset(&entry, 0, sizeof(entry)); |
300 | entry.ifindex = pg->port->dev->ifindex; | 354 | entry.ifindex = port->dev->ifindex; |
301 | entry.addr.proto = pg->addr.proto; | 355 | entry.addr.proto = group->proto; |
302 | entry.addr.u.ip4 = pg->addr.u.ip4; | 356 | entry.addr.u.ip4 = group->u.ip4; |
303 | #if IS_ENABLED(CONFIG_IPV6) | 357 | #if IS_ENABLED(CONFIG_IPV6) |
304 | entry.addr.u.ip6 = pg->addr.u.ip6; | 358 | entry.addr.u.ip6 = group->u.ip6; |
305 | #endif | 359 | #endif |
306 | entry.vid = pg->addr.vid; | 360 | entry.vid = group->vid; |
307 | __mdb_entry_fill_flags(&entry, pg->flags); | 361 | __mdb_entry_fill_flags(&entry, flags); |
308 | __br_mdb_notify(dev, &entry, type, pg); | 362 | __br_mdb_notify(dev, port, &entry, type); |
309 | } | 363 | } |
310 | 364 | ||
311 | static int nlmsg_populate_rtr_fill(struct sk_buff *skb, | 365 | static int nlmsg_populate_rtr_fill(struct sk_buff *skb, |
@@ -450,8 +504,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
450 | } | 504 | } |
451 | 505 | ||
452 | static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, | 506 | static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, |
453 | struct br_ip *group, unsigned char state, | 507 | struct br_ip *group, unsigned char state) |
454 | struct net_bridge_port_group **pg) | ||
455 | { | 508 | { |
456 | struct net_bridge_mdb_entry *mp; | 509 | struct net_bridge_mdb_entry *mp; |
457 | struct net_bridge_port_group *p; | 510 | struct net_bridge_port_group *p; |
@@ -482,7 +535,6 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, | |||
482 | if (unlikely(!p)) | 535 | if (unlikely(!p)) |
483 | return -ENOMEM; | 536 | return -ENOMEM; |
484 | rcu_assign_pointer(*pp, p); | 537 | rcu_assign_pointer(*pp, p); |
485 | *pg = p; | ||
486 | if (state == MDB_TEMPORARY) | 538 | if (state == MDB_TEMPORARY) |
487 | mod_timer(&p->timer, now + br->multicast_membership_interval); | 539 | mod_timer(&p->timer, now + br->multicast_membership_interval); |
488 | 540 | ||
@@ -490,8 +542,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, | |||
490 | } | 542 | } |
491 | 543 | ||
492 | static int __br_mdb_add(struct net *net, struct net_bridge *br, | 544 | static int __br_mdb_add(struct net *net, struct net_bridge *br, |
493 | struct br_mdb_entry *entry, | 545 | struct br_mdb_entry *entry) |
494 | struct net_bridge_port_group **pg) | ||
495 | { | 546 | { |
496 | struct br_ip ip; | 547 | struct br_ip ip; |
497 | struct net_device *dev; | 548 | struct net_device *dev; |
@@ -509,18 +560,10 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, | |||
509 | if (!p || p->br != br || p->state == BR_STATE_DISABLED) | 560 | if (!p || p->br != br || p->state == BR_STATE_DISABLED) |
510 | return -EINVAL; | 561 | return -EINVAL; |
511 | 562 | ||
512 | memset(&ip, 0, sizeof(ip)); | 563 | __mdb_entry_to_br_ip(entry, &ip); |
513 | ip.vid = entry->vid; | ||
514 | ip.proto = entry->addr.proto; | ||
515 | if (ip.proto == htons(ETH_P_IP)) | ||
516 | ip.u.ip4 = entry->addr.u.ip4; | ||
517 | #if IS_ENABLED(CONFIG_IPV6) | ||
518 | else | ||
519 | ip.u.ip6 = entry->addr.u.ip6; | ||
520 | #endif | ||
521 | 564 | ||
522 | spin_lock_bh(&br->multicast_lock); | 565 | spin_lock_bh(&br->multicast_lock); |
523 | ret = br_mdb_add_group(br, p, &ip, entry->state, pg); | 566 | ret = br_mdb_add_group(br, p, &ip, entry->state); |
524 | spin_unlock_bh(&br->multicast_lock); | 567 | spin_unlock_bh(&br->multicast_lock); |
525 | return ret; | 568 | return ret; |
526 | } | 569 | } |
@@ -528,7 +571,6 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, | |||
528 | static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) | 571 | static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) |
529 | { | 572 | { |
530 | struct net *net = sock_net(skb->sk); | 573 | struct net *net = sock_net(skb->sk); |
531 | struct net_bridge_port_group *pg; | ||
532 | struct net_bridge_vlan_group *vg; | 574 | struct net_bridge_vlan_group *vg; |
533 | struct net_device *dev, *pdev; | 575 | struct net_device *dev, *pdev; |
534 | struct br_mdb_entry *entry; | 576 | struct br_mdb_entry *entry; |
@@ -558,15 +600,15 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
558 | if (br_vlan_enabled(br) && vg && entry->vid == 0) { | 600 | if (br_vlan_enabled(br) && vg && entry->vid == 0) { |
559 | list_for_each_entry(v, &vg->vlan_list, vlist) { | 601 | list_for_each_entry(v, &vg->vlan_list, vlist) { |
560 | entry->vid = v->vid; | 602 | entry->vid = v->vid; |
561 | err = __br_mdb_add(net, br, entry, &pg); | 603 | err = __br_mdb_add(net, br, entry); |
562 | if (err) | 604 | if (err) |
563 | break; | 605 | break; |
564 | __br_mdb_notify(dev, entry, RTM_NEWMDB, pg); | 606 | __br_mdb_notify(dev, p, entry, RTM_NEWMDB); |
565 | } | 607 | } |
566 | } else { | 608 | } else { |
567 | err = __br_mdb_add(net, br, entry, &pg); | 609 | err = __br_mdb_add(net, br, entry); |
568 | if (!err) | 610 | if (!err) |
569 | __br_mdb_notify(dev, entry, RTM_NEWMDB, pg); | 611 | __br_mdb_notify(dev, p, entry, RTM_NEWMDB); |
570 | } | 612 | } |
571 | 613 | ||
572 | return err; | 614 | return err; |
@@ -584,15 +626,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) | |||
584 | if (!netif_running(br->dev) || br->multicast_disabled) | 626 | if (!netif_running(br->dev) || br->multicast_disabled) |
585 | return -EINVAL; | 627 | return -EINVAL; |
586 | 628 | ||
587 | memset(&ip, 0, sizeof(ip)); | 629 | __mdb_entry_to_br_ip(entry, &ip); |
588 | ip.vid = entry->vid; | ||
589 | ip.proto = entry->addr.proto; | ||
590 | if (ip.proto == htons(ETH_P_IP)) | ||
591 | ip.u.ip4 = entry->addr.u.ip4; | ||
592 | #if IS_ENABLED(CONFIG_IPV6) | ||
593 | else | ||
594 | ip.u.ip6 = entry->addr.u.ip6; | ||
595 | #endif | ||
596 | 630 | ||
597 | spin_lock_bh(&br->multicast_lock); | 631 | spin_lock_bh(&br->multicast_lock); |
598 | mdb = mlock_dereference(br->mdb, br); | 632 | mdb = mlock_dereference(br->mdb, br); |
@@ -662,12 +696,12 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
662 | entry->vid = v->vid; | 696 | entry->vid = v->vid; |
663 | err = __br_mdb_del(br, entry); | 697 | err = __br_mdb_del(br, entry); |
664 | if (!err) | 698 | if (!err) |
665 | __br_mdb_notify(dev, entry, RTM_DELMDB, NULL); | 699 | __br_mdb_notify(dev, p, entry, RTM_DELMDB); |
666 | } | 700 | } |
667 | } else { | 701 | } else { |
668 | err = __br_mdb_del(br, entry); | 702 | err = __br_mdb_del(br, entry); |
669 | if (!err) | 703 | if (!err) |
670 | __br_mdb_notify(dev, entry, RTM_DELMDB, NULL); | 704 | __br_mdb_notify(dev, p, entry, RTM_DELMDB); |
671 | } | 705 | } |
672 | 706 | ||
673 | return err; | 707 | return err; |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index a4c15df2b792..191ea66e4d92 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -283,7 +283,8 @@ static void br_multicast_del_pg(struct net_bridge *br, | |||
283 | rcu_assign_pointer(*pp, p->next); | 283 | rcu_assign_pointer(*pp, p->next); |
284 | hlist_del_init(&p->mglist); | 284 | hlist_del_init(&p->mglist); |
285 | del_timer(&p->timer); | 285 | del_timer(&p->timer); |
286 | br_mdb_notify(br->dev, p, RTM_DELMDB); | 286 | br_mdb_notify(br->dev, p->port, &pg->addr, RTM_DELMDB, |
287 | p->flags); | ||
287 | call_rcu_bh(&p->rcu, br_multicast_free_pg); | 288 | call_rcu_bh(&p->rcu, br_multicast_free_pg); |
288 | 289 | ||
289 | if (!mp->ports && !mp->mglist && | 290 | if (!mp->ports && !mp->mglist && |
@@ -705,7 +706,7 @@ static int br_multicast_add_group(struct net_bridge *br, | |||
705 | if (unlikely(!p)) | 706 | if (unlikely(!p)) |
706 | goto err; | 707 | goto err; |
707 | rcu_assign_pointer(*pp, p); | 708 | rcu_assign_pointer(*pp, p); |
708 | br_mdb_notify(br->dev, p, RTM_NEWMDB); | 709 | br_mdb_notify(br->dev, port, group, RTM_NEWMDB, 0); |
709 | 710 | ||
710 | found: | 711 | found: |
711 | mod_timer(&p->timer, now + br->multicast_membership_interval); | 712 | mod_timer(&p->timer, now + br->multicast_membership_interval); |
@@ -1461,7 +1462,8 @@ br_multicast_leave_group(struct net_bridge *br, | |||
1461 | hlist_del_init(&p->mglist); | 1462 | hlist_del_init(&p->mglist); |
1462 | del_timer(&p->timer); | 1463 | del_timer(&p->timer); |
1463 | call_rcu_bh(&p->rcu, br_multicast_free_pg); | 1464 | call_rcu_bh(&p->rcu, br_multicast_free_pg); |
1464 | br_mdb_notify(br->dev, p, RTM_DELMDB); | 1465 | br_mdb_notify(br->dev, port, group, RTM_DELMDB, |
1466 | p->flags); | ||
1465 | 1467 | ||
1466 | if (!mp->ports && !mp->mglist && | 1468 | if (!mp->ports && !mp->mglist && |
1467 | netif_running(br->dev)) | 1469 | netif_running(br->dev)) |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 1b5d145dfcbf..d9da857182ef 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -560,8 +560,8 @@ br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group, | |||
560 | unsigned char flags); | 560 | unsigned char flags); |
561 | void br_mdb_init(void); | 561 | void br_mdb_init(void); |
562 | void br_mdb_uninit(void); | 562 | void br_mdb_uninit(void); |
563 | void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg, | 563 | void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, |
564 | int type); | 564 | struct br_ip *group, int type, u8 flags); |
565 | void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, | 565 | void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, |
566 | int type); | 566 | int type); |
567 | 567 | ||
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 8a9246deccfe..63566ec54794 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -904,7 +904,11 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim) | |||
904 | if (ifa->ifa_flags & IFA_F_SECONDARY) { | 904 | if (ifa->ifa_flags & IFA_F_SECONDARY) { |
905 | prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); | 905 | prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); |
906 | if (!prim) { | 906 | if (!prim) { |
907 | pr_warn("%s: bug: prim == NULL\n", __func__); | 907 | /* if the device has been deleted, we don't perform |
908 | * address promotion | ||
909 | */ | ||
910 | if (!in_dev->dead) | ||
911 | pr_warn("%s: bug: prim == NULL\n", __func__); | ||
908 | return; | 912 | return; |
909 | } | 913 | } |
910 | if (iprim && iprim != prim) { | 914 | if (iprim && iprim != prim) { |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 23cec53b568a..8ec4b3089e20 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3176,35 +3176,9 @@ static void addrconf_gre_config(struct net_device *dev) | |||
3176 | } | 3176 | } |
3177 | #endif | 3177 | #endif |
3178 | 3178 | ||
3179 | #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) | ||
3180 | /* If the host route is cached on the addr struct make sure it is associated | ||
3181 | * with the proper table. e.g., enslavement can change and if so the cached | ||
3182 | * host route needs to move to the new table. | ||
3183 | */ | ||
3184 | static void l3mdev_check_host_rt(struct inet6_dev *idev, | ||
3185 | struct inet6_ifaddr *ifp) | ||
3186 | { | ||
3187 | if (ifp->rt) { | ||
3188 | u32 tb_id = l3mdev_fib_table(idev->dev) ? : RT6_TABLE_LOCAL; | ||
3189 | |||
3190 | if (tb_id != ifp->rt->rt6i_table->tb6_id) { | ||
3191 | ip6_del_rt(ifp->rt); | ||
3192 | ifp->rt = NULL; | ||
3193 | } | ||
3194 | } | ||
3195 | } | ||
3196 | #else | ||
3197 | static void l3mdev_check_host_rt(struct inet6_dev *idev, | ||
3198 | struct inet6_ifaddr *ifp) | ||
3199 | { | ||
3200 | } | ||
3201 | #endif | ||
3202 | |||
3203 | static int fixup_permanent_addr(struct inet6_dev *idev, | 3179 | static int fixup_permanent_addr(struct inet6_dev *idev, |
3204 | struct inet6_ifaddr *ifp) | 3180 | struct inet6_ifaddr *ifp) |
3205 | { | 3181 | { |
3206 | l3mdev_check_host_rt(idev, ifp); | ||
3207 | |||
3208 | if (!ifp->rt) { | 3182 | if (!ifp->rt) { |
3209 | struct rt6_info *rt; | 3183 | struct rt6_info *rt; |
3210 | 3184 | ||
@@ -3304,6 +3278,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3304 | break; | 3278 | break; |
3305 | 3279 | ||
3306 | if (event == NETDEV_UP) { | 3280 | if (event == NETDEV_UP) { |
3281 | /* restore routes for permanent addresses */ | ||
3282 | addrconf_permanent_addr(dev); | ||
3283 | |||
3307 | if (!addrconf_qdisc_ok(dev)) { | 3284 | if (!addrconf_qdisc_ok(dev)) { |
3308 | /* device is not ready yet. */ | 3285 | /* device is not ready yet. */ |
3309 | pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n", | 3286 | pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n", |
@@ -3337,9 +3314,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
3337 | run_pending = 1; | 3314 | run_pending = 1; |
3338 | } | 3315 | } |
3339 | 3316 | ||
3340 | /* restore routes for permanent addresses */ | ||
3341 | addrconf_permanent_addr(dev); | ||
3342 | |||
3343 | switch (dev->type) { | 3317 | switch (dev->type) { |
3344 | #if IS_ENABLED(CONFIG_IPV6_SIT) | 3318 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
3345 | case ARPHRD_SIT: | 3319 | case ARPHRD_SIT: |
@@ -3556,6 +3530,8 @@ restart: | |||
3556 | 3530 | ||
3557 | INIT_LIST_HEAD(&del_list); | 3531 | INIT_LIST_HEAD(&del_list); |
3558 | list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { | 3532 | list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { |
3533 | struct rt6_info *rt = NULL; | ||
3534 | |||
3559 | addrconf_del_dad_work(ifa); | 3535 | addrconf_del_dad_work(ifa); |
3560 | 3536 | ||
3561 | write_unlock_bh(&idev->lock); | 3537 | write_unlock_bh(&idev->lock); |
@@ -3568,6 +3544,9 @@ restart: | |||
3568 | ifa->state = 0; | 3544 | ifa->state = 0; |
3569 | if (!(ifa->flags & IFA_F_NODAD)) | 3545 | if (!(ifa->flags & IFA_F_NODAD)) |
3570 | ifa->flags |= IFA_F_TENTATIVE; | 3546 | ifa->flags |= IFA_F_TENTATIVE; |
3547 | |||
3548 | rt = ifa->rt; | ||
3549 | ifa->rt = NULL; | ||
3571 | } else { | 3550 | } else { |
3572 | state = ifa->state; | 3551 | state = ifa->state; |
3573 | ifa->state = INET6_IFADDR_STATE_DEAD; | 3552 | ifa->state = INET6_IFADDR_STATE_DEAD; |
@@ -3578,6 +3557,9 @@ restart: | |||
3578 | 3557 | ||
3579 | spin_unlock_bh(&ifa->lock); | 3558 | spin_unlock_bh(&ifa->lock); |
3580 | 3559 | ||
3560 | if (rt) | ||
3561 | ip6_del_rt(rt); | ||
3562 | |||
3581 | if (state != INET6_IFADDR_STATE_DEAD) { | 3563 | if (state != INET6_IFADDR_STATE_DEAD) { |
3582 | __ipv6_ifa_notify(RTM_DELADDR, ifa); | 3564 | __ipv6_ifa_notify(RTM_DELADDR, ifa); |
3583 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); | 3565 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); |
@@ -5343,10 +5325,10 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
5343 | if (rt) | 5325 | if (rt) |
5344 | ip6_del_rt(rt); | 5326 | ip6_del_rt(rt); |
5345 | } | 5327 | } |
5346 | dst_hold(&ifp->rt->dst); | 5328 | if (ifp->rt) { |
5347 | 5329 | dst_hold(&ifp->rt->dst); | |
5348 | ip6_del_rt(ifp->rt); | 5330 | ip6_del_rt(ifp->rt); |
5349 | 5331 | } | |
5350 | rt_genid_bump_ipv6(net); | 5332 | rt_genid_bump_ipv6(net); |
5351 | break; | 5333 | break; |
5352 | } | 5334 | } |
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 2b9b98f1c2ff..b7e01d88bdc5 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c | |||
@@ -305,6 +305,8 @@ static void switchdev_port_attr_set_deferred(struct net_device *dev, | |||
305 | if (err && err != -EOPNOTSUPP) | 305 | if (err && err != -EOPNOTSUPP) |
306 | netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n", | 306 | netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n", |
307 | err, attr->id); | 307 | err, attr->id); |
308 | if (attr->complete) | ||
309 | attr->complete(dev, err, attr->complete_priv); | ||
308 | } | 310 | } |
309 | 311 | ||
310 | static int switchdev_port_attr_set_defer(struct net_device *dev, | 312 | static int switchdev_port_attr_set_defer(struct net_device *dev, |
@@ -434,6 +436,8 @@ static void switchdev_port_obj_add_deferred(struct net_device *dev, | |||
434 | if (err && err != -EOPNOTSUPP) | 436 | if (err && err != -EOPNOTSUPP) |
435 | netdev_err(dev, "failed (err=%d) to add object (id=%d)\n", | 437 | netdev_err(dev, "failed (err=%d) to add object (id=%d)\n", |
436 | err, obj->id); | 438 | err, obj->id); |
439 | if (obj->complete) | ||
440 | obj->complete(dev, err, obj->complete_priv); | ||
437 | } | 441 | } |
438 | 442 | ||
439 | static int switchdev_port_obj_add_defer(struct net_device *dev, | 443 | static int switchdev_port_obj_add_defer(struct net_device *dev, |
@@ -502,6 +506,8 @@ static void switchdev_port_obj_del_deferred(struct net_device *dev, | |||
502 | if (err && err != -EOPNOTSUPP) | 506 | if (err && err != -EOPNOTSUPP) |
503 | netdev_err(dev, "failed (err=%d) to del object (id=%d)\n", | 507 | netdev_err(dev, "failed (err=%d) to del object (id=%d)\n", |
504 | err, obj->id); | 508 | err, obj->id); |
509 | if (obj->complete) | ||
510 | obj->complete(dev, err, obj->complete_priv); | ||
505 | } | 511 | } |
506 | 512 | ||
507 | static int switchdev_port_obj_del_defer(struct net_device *dev, | 513 | static int switchdev_port_obj_del_defer(struct net_device *dev, |