| .. | .. |
|---|
| 35 | 35 | |
|---|
| 36 | 36 | #include <net/ip_tunnels.h> |
|---|
| 37 | 37 | #include <linux/rhashtable.h> |
|---|
| 38 | +#include <linux/mutex.h> |
|---|
| 38 | 39 | #include "eswitch.h" |
|---|
| 39 | 40 | #include "en.h" |
|---|
| 41 | +#include "lib/port_tun.h" |
|---|
| 40 | 42 | |
|---|
| 41 | 43 | #ifdef CONFIG_MLX5_ESWITCH |
|---|
| 44 | +extern const struct mlx5e_rx_handlers mlx5e_rx_handlers_rep; |
|---|
| 45 | + |
|---|
| 42 | 46 | struct mlx5e_neigh_update_table { |
|---|
| 43 | 47 | struct rhashtable neigh_ht; |
|---|
| 44 | 48 | /* Save the neigh hash entries in a list in addition to the hash table |
|---|
| .. | .. |
|---|
| 47 | 51 | */ |
|---|
| 48 | 52 | struct list_head neigh_list; |
|---|
| 49 | 53 | /* protect lookup/remove operations */ |
|---|
| 50 | | - spinlock_t encap_lock; |
|---|
| 54 | + struct mutex encap_lock; |
|---|
| 51 | 55 | struct notifier_block netevent_nb; |
|---|
| 52 | 56 | struct delayed_work neigh_stats_work; |
|---|
| 53 | 57 | unsigned long min_interval; /* jiffies */ |
|---|
| 58 | +}; |
|---|
| 59 | + |
|---|
| 60 | +struct mlx5_tc_ct_priv; |
|---|
| 61 | +struct mlx5e_rep_bond; |
|---|
| 62 | +struct mlx5_rep_uplink_priv { |
|---|
| 63 | + /* Filters DB - instantiated by the uplink representor and shared by |
|---|
| 64 | + * the uplink's VFs |
|---|
| 65 | + */ |
|---|
| 66 | + struct rhashtable tc_ht; |
|---|
| 67 | + |
|---|
| 68 | + /* indirect block callbacks are invoked on bind/unbind events |
|---|
| 69 | + * on registered higher level devices (e.g. tunnel devices) |
|---|
| 70 | + * |
|---|
| 71 | + * tc_indr_block_cb_priv_list is used to lookup indirect callback |
|---|
| 72 | + * private data |
|---|
| 73 | + * |
|---|
| 74 | + */ |
|---|
| 75 | + struct list_head tc_indr_block_priv_list; |
|---|
| 76 | + |
|---|
| 77 | + struct mlx5_tun_entropy tun_entropy; |
|---|
| 78 | + |
|---|
| 79 | + /* protects unready_flows */ |
|---|
| 80 | + struct mutex unready_flows_lock; |
|---|
| 81 | + struct list_head unready_flows; |
|---|
| 82 | + struct work_struct reoffload_flows_work; |
|---|
| 83 | + |
|---|
| 84 | + /* maps tun_info to a unique id*/ |
|---|
| 85 | + struct mapping_ctx *tunnel_mapping; |
|---|
| 86 | + /* maps tun_enc_opts to a unique id*/ |
|---|
| 87 | + struct mapping_ctx *tunnel_enc_opts_mapping; |
|---|
| 88 | + |
|---|
| 89 | + struct mlx5_tc_ct_priv *ct_priv; |
|---|
| 90 | + |
|---|
| 91 | + /* support eswitch vports bonding */ |
|---|
| 92 | + struct mlx5e_rep_bond *bond; |
|---|
| 54 | 93 | }; |
|---|
| 55 | 94 | |
|---|
| 56 | 95 | struct mlx5e_rep_priv { |
|---|
| 57 | 96 | struct mlx5_eswitch_rep *rep; |
|---|
| 58 | 97 | struct mlx5e_neigh_update_table neigh_update; |
|---|
| 59 | 98 | struct net_device *netdev; |
|---|
| 99 | + struct mlx5_flow_table *root_ft; |
|---|
| 60 | 100 | struct mlx5_flow_handle *vport_rx_rule; |
|---|
| 61 | 101 | struct list_head vport_sqs_list; |
|---|
| 62 | | - struct rhashtable tc_ht; /* valid for uplink rep */ |
|---|
| 102 | + struct mlx5_rep_uplink_priv uplink_priv; /* valid for uplink rep */ |
|---|
| 103 | + struct rtnl_link_stats64 prev_vf_vport_stats; |
|---|
| 63 | 104 | }; |
|---|
| 64 | 105 | |
|---|
| 65 | 106 | static inline |
|---|
| 66 | 107 | struct mlx5e_rep_priv *mlx5e_rep_to_rep_priv(struct mlx5_eswitch_rep *rep) |
|---|
| 67 | 108 | { |
|---|
| 68 | | - return (struct mlx5e_rep_priv *)rep->rep_if[REP_ETH].priv; |
|---|
| 109 | + return rep->rep_data[REP_ETH].priv; |
|---|
| 69 | 110 | } |
|---|
| 70 | 111 | |
|---|
| 71 | 112 | struct mlx5e_neigh { |
|---|
| .. | .. |
|---|
| 80 | 121 | struct mlx5e_neigh_hash_entry { |
|---|
| 81 | 122 | struct rhash_head rhash_node; |
|---|
| 82 | 123 | struct mlx5e_neigh m_neigh; |
|---|
| 124 | + struct mlx5e_priv *priv; |
|---|
| 83 | 125 | |
|---|
| 84 | 126 | /* Save the neigh hash entry in a list on the representor in |
|---|
| 85 | 127 | * addition to the hash table. In order to iterate easily over the |
|---|
| .. | .. |
|---|
| 87 | 129 | */ |
|---|
| 88 | 130 | struct list_head neigh_list; |
|---|
| 89 | 131 | |
|---|
| 132 | + /* protects encap list */ |
|---|
| 133 | + spinlock_t encap_list_lock; |
|---|
| 90 | 134 | /* encap list sharing the same neigh */ |
|---|
| 91 | 135 | struct list_head encap_list; |
|---|
| 92 | | - |
|---|
| 93 | | - /* valid only when the neigh reference is taken during |
|---|
| 94 | | - * neigh_update_work workqueue callback. |
|---|
| 95 | | - */ |
|---|
| 96 | | - struct neighbour *n; |
|---|
| 97 | | - struct work_struct neigh_update_work; |
|---|
| 98 | 136 | |
|---|
| 99 | 137 | /* neigh hash entry can be deleted only when the refcount is zero. |
|---|
| 100 | 138 | * refcount is needed to avoid neigh hash entry removal by TC, while |
|---|
| .. | .. |
|---|
| 107 | 145 | * 'used' value and avoid neigh deleting by the kernel. |
|---|
| 108 | 146 | */ |
|---|
| 109 | 147 | unsigned long reported_lastuse; |
|---|
| 148 | + |
|---|
| 149 | + struct rcu_head rcu; |
|---|
| 110 | 150 | }; |
|---|
| 111 | 151 | |
|---|
| 112 | 152 | enum { |
|---|
| 113 | 153 | /* set when the encap entry is successfully offloaded into HW */ |
|---|
| 114 | 154 | MLX5_ENCAP_ENTRY_VALID = BIT(0), |
|---|
| 155 | + MLX5_REFORMAT_DECAP = BIT(1), |
|---|
| 156 | +}; |
|---|
| 157 | + |
|---|
| 158 | +struct mlx5e_decap_key { |
|---|
| 159 | + struct ethhdr key; |
|---|
| 160 | +}; |
|---|
| 161 | + |
|---|
| 162 | +struct mlx5e_decap_entry { |
|---|
| 163 | + struct mlx5e_decap_key key; |
|---|
| 164 | + struct list_head flows; |
|---|
| 165 | + struct hlist_node hlist; |
|---|
| 166 | + refcount_t refcnt; |
|---|
| 167 | + struct completion res_ready; |
|---|
| 168 | + int compl_result; |
|---|
| 169 | + struct mlx5_pkt_reformat *pkt_reformat; |
|---|
| 170 | + struct rcu_head rcu; |
|---|
| 115 | 171 | }; |
|---|
| 116 | 172 | |
|---|
| 117 | 173 | struct mlx5e_encap_entry { |
|---|
| 174 | + /* attached neigh hash entry */ |
|---|
| 175 | + struct mlx5e_neigh_hash_entry *nhe; |
|---|
| 118 | 176 | /* neigh hash entry list of encaps sharing the same neigh */ |
|---|
| 119 | 177 | struct list_head encap_list; |
|---|
| 120 | 178 | struct mlx5e_neigh m_neigh; |
|---|
| .. | .. |
|---|
| 123 | 181 | */ |
|---|
| 124 | 182 | struct hlist_node encap_hlist; |
|---|
| 125 | 183 | struct list_head flows; |
|---|
| 126 | | - u32 encap_id; |
|---|
| 127 | | - struct ip_tunnel_info tun_info; |
|---|
| 184 | + struct mlx5_pkt_reformat *pkt_reformat; |
|---|
| 185 | + const struct ip_tunnel_info *tun_info; |
|---|
| 128 | 186 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ |
|---|
| 129 | 187 | |
|---|
| 130 | 188 | struct net_device *out_dev; |
|---|
| 131 | | - int tunnel_type; |
|---|
| 189 | + int route_dev_ifindex; |
|---|
| 190 | + struct mlx5e_tc_tunnel *tunnel; |
|---|
| 191 | + int reformat_type; |
|---|
| 132 | 192 | u8 flags; |
|---|
| 133 | 193 | char *encap_header; |
|---|
| 134 | 194 | int encap_size; |
|---|
| 195 | + refcount_t refcnt; |
|---|
| 196 | + struct completion res_ready; |
|---|
| 197 | + int compl_result; |
|---|
| 198 | + struct rcu_head rcu; |
|---|
| 135 | 199 | }; |
|---|
| 136 | 200 | |
|---|
| 137 | 201 | struct mlx5e_rep_sq { |
|---|
| .. | .. |
|---|
| 139 | 203 | struct list_head list; |
|---|
| 140 | 204 | }; |
|---|
| 141 | 205 | |
|---|
| 142 | | -void *mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev); |
|---|
| 143 | | -void mlx5e_register_vport_reps(struct mlx5e_priv *priv); |
|---|
| 144 | | -void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv); |
|---|
| 206 | +void mlx5e_rep_register_vport_reps(struct mlx5_core_dev *mdev); |
|---|
| 207 | +void mlx5e_rep_unregister_vport_reps(struct mlx5_core_dev *mdev); |
|---|
| 208 | +int mlx5e_rep_bond_init(struct mlx5e_rep_priv *rpriv); |
|---|
| 209 | +void mlx5e_rep_bond_cleanup(struct mlx5e_rep_priv *rpriv); |
|---|
| 210 | +int mlx5e_rep_bond_enslave(struct mlx5_eswitch *esw, struct net_device *netdev, |
|---|
| 211 | + struct net_device *lag_dev); |
|---|
| 212 | +void mlx5e_rep_bond_unslave(struct mlx5_eswitch *esw, |
|---|
| 213 | + const struct net_device *netdev, |
|---|
| 214 | + const struct net_device *lag_dev); |
|---|
| 215 | +int mlx5e_rep_bond_update(struct mlx5e_priv *priv, bool cleanup); |
|---|
| 216 | + |
|---|
| 145 | 217 | bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv); |
|---|
| 146 | 218 | int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv); |
|---|
| 147 | 219 | void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv); |
|---|
| 148 | 220 | |
|---|
| 149 | | -int mlx5e_get_offload_stats(int attr_id, const struct net_device *dev, void *sp); |
|---|
| 150 | | -bool mlx5e_has_offload_stats(const struct net_device *dev, int attr_id); |
|---|
| 151 | | - |
|---|
| 152 | | -int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr); |
|---|
| 153 | | -void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe); |
|---|
| 154 | | - |
|---|
| 155 | | -int mlx5e_rep_encap_entry_attach(struct mlx5e_priv *priv, |
|---|
| 156 | | - struct mlx5e_encap_entry *e); |
|---|
| 157 | | -void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv, |
|---|
| 158 | | - struct mlx5e_encap_entry *e); |
|---|
| 159 | | - |
|---|
| 160 | 221 | void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv); |
|---|
| 222 | + |
|---|
| 223 | +bool mlx5e_eswitch_vf_rep(struct net_device *netdev); |
|---|
| 224 | +bool mlx5e_eswitch_uplink_rep(struct net_device *netdev); |
|---|
| 225 | +static inline bool mlx5e_eswitch_rep(struct net_device *netdev) |
|---|
| 226 | +{ |
|---|
| 227 | + return mlx5e_eswitch_vf_rep(netdev) || |
|---|
| 228 | + mlx5e_eswitch_uplink_rep(netdev); |
|---|
| 229 | +} |
|---|
| 230 | + |
|---|
| 161 | 231 | #else /* CONFIG_MLX5_ESWITCH */ |
|---|
| 162 | | -static inline void mlx5e_register_vport_reps(struct mlx5e_priv *priv) {} |
|---|
| 163 | | -static inline void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv) {} |
|---|
| 164 | 232 | static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; } |
|---|
| 165 | 233 | static inline int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv) { return 0; } |
|---|
| 166 | 234 | static inline void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv) {} |
|---|
| 167 | 235 | #endif |
|---|
| 168 | 236 | |
|---|
| 237 | +static inline bool mlx5e_is_vport_rep(struct mlx5e_priv *priv) |
|---|
| 238 | +{ |
|---|
| 239 | + return (MLX5_ESWITCH_MANAGER(priv->mdev) && priv->ppriv); |
|---|
| 240 | +} |
|---|
| 169 | 241 | #endif /* __MLX5E_REP_H__ */ |
|---|