.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * drivers/net/ethernet/rocker/rocker_ofdpa.c - Rocker switch OF-DPA-like |
---|
3 | 4 | * implementation |
---|
4 | 5 | * Copyright (c) 2014 Scott Feldman <sfeldma@gmail.com> |
---|
5 | 6 | * Copyright (c) 2014-2016 Jiri Pirko <jiri@mellanox.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the GNU General Public License as published by |
---|
9 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
10 | | - * (at your option) any later version. |
---|
11 | 7 | */ |
---|
12 | 8 | |
---|
13 | 9 | #include <linux/kernel.h> |
---|
.. | .. |
---|
22 | 18 | #include <net/neighbour.h> |
---|
23 | 19 | #include <net/switchdev.h> |
---|
24 | 20 | #include <net/ip_fib.h> |
---|
| 21 | +#include <net/nexthop.h> |
---|
25 | 22 | #include <net/arp.h> |
---|
26 | 23 | |
---|
27 | 24 | #include "rocker.h" |
---|
.. | .. |
---|
1276 | 1273 | bool removing; |
---|
1277 | 1274 | int err = 0; |
---|
1278 | 1275 | |
---|
1279 | | - entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
---|
| 1276 | + entry = kzalloc(sizeof(*entry), GFP_ATOMIC); |
---|
1280 | 1277 | if (!entry) |
---|
1281 | 1278 | return -ENOMEM; |
---|
1282 | 1279 | |
---|
.. | .. |
---|
1833 | 1830 | rtnl_lock(); |
---|
1834 | 1831 | if (learned && removing) |
---|
1835 | 1832 | call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, |
---|
1836 | | - lw->ofdpa_port->dev, &info.info); |
---|
| 1833 | + lw->ofdpa_port->dev, &info.info, NULL); |
---|
1837 | 1834 | else if (learned && !removing) |
---|
1838 | 1835 | call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE, |
---|
1839 | | - lw->ofdpa_port->dev, &info.info); |
---|
| 1836 | + lw->ofdpa_port->dev, &info.info, NULL); |
---|
1840 | 1837 | rtnl_unlock(); |
---|
1841 | 1838 | |
---|
1842 | 1839 | kfree(work); |
---|
.. | .. |
---|
2286 | 2283 | |
---|
2287 | 2284 | /* XXX support ECMP */ |
---|
2288 | 2285 | |
---|
2289 | | - nh = fi->fib_nh; |
---|
2290 | | - nh_on_port = (fi->fib_dev == ofdpa_port->dev); |
---|
2291 | | - has_gw = !!nh->nh_gw; |
---|
| 2286 | + nh = fib_info_nh(fi, 0); |
---|
| 2287 | + nh_on_port = (nh->fib_nh_dev == ofdpa_port->dev); |
---|
| 2288 | + has_gw = !!nh->fib_nh_gw4; |
---|
2292 | 2289 | |
---|
2293 | 2290 | if (has_gw && nh_on_port) { |
---|
2294 | 2291 | err = ofdpa_port_ipv4_nh(ofdpa_port, flags, |
---|
2295 | | - nh->nh_gw, &index); |
---|
| 2292 | + nh->fib_nh_gw4, &index); |
---|
2296 | 2293 | if (err) |
---|
2297 | 2294 | return err; |
---|
2298 | 2295 | |
---|
.. | .. |
---|
2509 | 2506 | ofdpa_port->brport_flags = orig_flags; |
---|
2510 | 2507 | |
---|
2511 | 2508 | return err; |
---|
2512 | | -} |
---|
2513 | | - |
---|
2514 | | -static int |
---|
2515 | | -ofdpa_port_attr_bridge_flags_get(const struct rocker_port *rocker_port, |
---|
2516 | | - unsigned long *p_brport_flags) |
---|
2517 | | -{ |
---|
2518 | | - const struct ofdpa_port *ofdpa_port = rocker_port->wpriv; |
---|
2519 | | - |
---|
2520 | | - *p_brport_flags = ofdpa_port->brport_flags; |
---|
2521 | | - return 0; |
---|
2522 | 2509 | } |
---|
2523 | 2510 | |
---|
2524 | 2511 | static int |
---|
.. | .. |
---|
2747 | 2734 | { |
---|
2748 | 2735 | struct ofdpa *ofdpa = rocker->wpriv; |
---|
2749 | 2736 | struct ofdpa_port *ofdpa_port; |
---|
| 2737 | + struct fib_nh *nh; |
---|
2750 | 2738 | int err; |
---|
2751 | 2739 | |
---|
2752 | 2740 | if (ofdpa->fib_aborted) |
---|
2753 | 2741 | return 0; |
---|
2754 | | - ofdpa_port = ofdpa_port_dev_lower_find(fen_info->fi->fib_dev, rocker); |
---|
| 2742 | + nh = fib_info_nh(fen_info->fi, 0); |
---|
| 2743 | + ofdpa_port = ofdpa_port_dev_lower_find(nh->fib_nh_dev, rocker); |
---|
2755 | 2744 | if (!ofdpa_port) |
---|
2756 | 2745 | return 0; |
---|
2757 | 2746 | err = ofdpa_port_fib_ipv4(ofdpa_port, htonl(fen_info->dst), |
---|
.. | .. |
---|
2759 | 2748 | fen_info->tb_id, 0); |
---|
2760 | 2749 | if (err) |
---|
2761 | 2750 | return err; |
---|
2762 | | - fen_info->fi->fib_nh->nh_flags |= RTNH_F_OFFLOAD; |
---|
| 2751 | + nh->fib_nh_flags |= RTNH_F_OFFLOAD; |
---|
2763 | 2752 | return 0; |
---|
2764 | 2753 | } |
---|
2765 | 2754 | |
---|
.. | .. |
---|
2768 | 2757 | { |
---|
2769 | 2758 | struct ofdpa *ofdpa = rocker->wpriv; |
---|
2770 | 2759 | struct ofdpa_port *ofdpa_port; |
---|
| 2760 | + struct fib_nh *nh; |
---|
2771 | 2761 | |
---|
2772 | 2762 | if (ofdpa->fib_aborted) |
---|
2773 | 2763 | return 0; |
---|
2774 | | - ofdpa_port = ofdpa_port_dev_lower_find(fen_info->fi->fib_dev, rocker); |
---|
| 2764 | + nh = fib_info_nh(fen_info->fi, 0); |
---|
| 2765 | + ofdpa_port = ofdpa_port_dev_lower_find(nh->fib_nh_dev, rocker); |
---|
2775 | 2766 | if (!ofdpa_port) |
---|
2776 | 2767 | return 0; |
---|
2777 | | - fen_info->fi->fib_nh->nh_flags &= ~RTNH_F_OFFLOAD; |
---|
| 2768 | + nh->fib_nh_flags &= ~RTNH_F_OFFLOAD; |
---|
2778 | 2769 | return ofdpa_port_fib_ipv4(ofdpa_port, htonl(fen_info->dst), |
---|
2779 | 2770 | fen_info->dst_len, fen_info->fi, |
---|
2780 | 2771 | fen_info->tb_id, OFDPA_OP_FLAG_REMOVE); |
---|
.. | .. |
---|
2794 | 2785 | |
---|
2795 | 2786 | spin_lock_irqsave(&ofdpa->flow_tbl_lock, flags); |
---|
2796 | 2787 | hash_for_each_safe(ofdpa->flow_tbl, bkt, tmp, flow_entry, entry) { |
---|
| 2788 | + struct fib_nh *nh; |
---|
| 2789 | + |
---|
2797 | 2790 | if (flow_entry->key.tbl_id != |
---|
2798 | 2791 | ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING) |
---|
2799 | 2792 | continue; |
---|
2800 | | - ofdpa_port = ofdpa_port_dev_lower_find(flow_entry->fi->fib_dev, |
---|
2801 | | - rocker); |
---|
| 2793 | + nh = fib_info_nh(flow_entry->fi, 0); |
---|
| 2794 | + ofdpa_port = ofdpa_port_dev_lower_find(nh->fib_nh_dev, rocker); |
---|
2802 | 2795 | if (!ofdpa_port) |
---|
2803 | 2796 | continue; |
---|
2804 | | - flow_entry->fi->fib_nh->nh_flags &= ~RTNH_F_OFFLOAD; |
---|
2805 | | - ofdpa_flow_tbl_del(ofdpa_port, OFDPA_OP_FLAG_REMOVE, |
---|
| 2797 | + nh->fib_nh_flags &= ~RTNH_F_OFFLOAD; |
---|
| 2798 | + ofdpa_flow_tbl_del(ofdpa_port, |
---|
| 2799 | + OFDPA_OP_FLAG_REMOVE | OFDPA_OP_FLAG_NOWAIT, |
---|
2806 | 2800 | flow_entry); |
---|
2807 | 2801 | } |
---|
2808 | 2802 | spin_unlock_irqrestore(&ofdpa->flow_tbl_lock, flags); |
---|
.. | .. |
---|
2823 | 2817 | .port_stop = ofdpa_port_stop, |
---|
2824 | 2818 | .port_attr_stp_state_set = ofdpa_port_attr_stp_state_set, |
---|
2825 | 2819 | .port_attr_bridge_flags_set = ofdpa_port_attr_bridge_flags_set, |
---|
2826 | | - .port_attr_bridge_flags_get = ofdpa_port_attr_bridge_flags_get, |
---|
2827 | 2820 | .port_attr_bridge_flags_support_get = ofdpa_port_attr_bridge_flags_support_get, |
---|
2828 | 2821 | .port_attr_bridge_ageing_time_set = ofdpa_port_attr_bridge_ageing_time_set, |
---|
2829 | 2822 | .port_obj_vlan_add = ofdpa_port_obj_vlan_add, |
---|