.. | .. |
---|
1 | | -/* |
---|
2 | | - * Copyright (C) 2017 Netronome Systems, Inc. |
---|
3 | | - * |
---|
4 | | - * This software is dual licensed under the GNU General License Version 2, |
---|
5 | | - * June 1991 as shown in the file COPYING in the top-level directory of this |
---|
6 | | - * source tree or the BSD 2-Clause License provided below. You have the |
---|
7 | | - * option to license this software under the complete terms of either license. |
---|
8 | | - * |
---|
9 | | - * The BSD 2-Clause License: |
---|
10 | | - * |
---|
11 | | - * Redistribution and use in source and binary forms, with or |
---|
12 | | - * without modification, are permitted provided that the following |
---|
13 | | - * conditions are met: |
---|
14 | | - * |
---|
15 | | - * 1. Redistributions of source code must retain the above |
---|
16 | | - * copyright notice, this list of conditions and the following |
---|
17 | | - * disclaimer. |
---|
18 | | - * |
---|
19 | | - * 2. Redistributions in binary form must reproduce the above |
---|
20 | | - * copyright notice, this list of conditions and the following |
---|
21 | | - * disclaimer in the documentation and/or other materials |
---|
22 | | - * provided with the distribution. |
---|
23 | | - * |
---|
24 | | - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
---|
25 | | - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
---|
26 | | - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
---|
27 | | - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
---|
28 | | - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
---|
29 | | - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
---|
30 | | - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
---|
31 | | - * SOFTWARE. |
---|
32 | | - */ |
---|
| 1 | +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
---|
| 2 | +/* Copyright (C) 2017-2018 Netronome Systems, Inc. */ |
---|
33 | 3 | |
---|
34 | 4 | #include <linux/etherdevice.h> |
---|
35 | 5 | #include <linux/io-64-nonatomic-hi-lo.h> |
---|
36 | 6 | #include <linux/lockdep.h> |
---|
37 | 7 | #include <net/dst_metadata.h> |
---|
38 | | -#include <net/switchdev.h> |
---|
39 | 8 | |
---|
40 | 9 | #include "nfpcore/nfp_cpp.h" |
---|
41 | 10 | #include "nfpcore/nfp_nsp.h" |
---|
42 | 11 | #include "nfp_app.h" |
---|
43 | 12 | #include "nfp_main.h" |
---|
| 13 | +#include "nfp_net.h" |
---|
44 | 14 | #include "nfp_net_ctrl.h" |
---|
45 | 15 | #include "nfp_net_repr.h" |
---|
46 | 16 | #include "nfp_net_sriov.h" |
---|
.. | .. |
---|
261 | 231 | return err; |
---|
262 | 232 | } |
---|
263 | 233 | |
---|
| 234 | +static netdev_features_t |
---|
| 235 | +nfp_repr_fix_features(struct net_device *netdev, netdev_features_t features) |
---|
| 236 | +{ |
---|
| 237 | + struct nfp_repr *repr = netdev_priv(netdev); |
---|
| 238 | + netdev_features_t old_features = features; |
---|
| 239 | + netdev_features_t lower_features; |
---|
| 240 | + struct net_device *lower_dev; |
---|
| 241 | + |
---|
| 242 | + lower_dev = repr->dst->u.port_info.lower_dev; |
---|
| 243 | + |
---|
| 244 | + lower_features = lower_dev->features; |
---|
| 245 | + if (lower_features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) |
---|
| 246 | + lower_features |= NETIF_F_HW_CSUM; |
---|
| 247 | + |
---|
| 248 | + features = netdev_intersect_features(features, lower_features); |
---|
| 249 | + features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_HW_TC); |
---|
| 250 | + features |= NETIF_F_LLTX; |
---|
| 251 | + |
---|
| 252 | + return features; |
---|
| 253 | +} |
---|
| 254 | + |
---|
264 | 255 | const struct net_device_ops nfp_repr_netdev_ops = { |
---|
265 | 256 | .ndo_init = nfp_app_ndo_init, |
---|
266 | 257 | .ndo_uninit = nfp_app_ndo_uninit, |
---|
.. | .. |
---|
276 | 267 | .ndo_set_vf_mac = nfp_app_set_vf_mac, |
---|
277 | 268 | .ndo_set_vf_vlan = nfp_app_set_vf_vlan, |
---|
278 | 269 | .ndo_set_vf_spoofchk = nfp_app_set_vf_spoofchk, |
---|
| 270 | + .ndo_set_vf_trust = nfp_app_set_vf_trust, |
---|
279 | 271 | .ndo_get_vf_config = nfp_app_get_vf_config, |
---|
280 | 272 | .ndo_set_vf_link_state = nfp_app_set_vf_link_state, |
---|
| 273 | + .ndo_fix_features = nfp_repr_fix_features, |
---|
281 | 274 | .ndo_set_features = nfp_port_set_features, |
---|
282 | 275 | .ndo_set_mac_address = eth_mac_addr, |
---|
| 276 | + .ndo_get_port_parent_id = nfp_port_get_port_parent_id, |
---|
| 277 | + .ndo_get_devlink_port = nfp_devlink_get_devlink_port, |
---|
283 | 278 | }; |
---|
| 279 | + |
---|
| 280 | +void |
---|
| 281 | +nfp_repr_transfer_features(struct net_device *netdev, struct net_device *lower) |
---|
| 282 | +{ |
---|
| 283 | + struct nfp_repr *repr = netdev_priv(netdev); |
---|
| 284 | + |
---|
| 285 | + if (repr->dst->u.port_info.lower_dev != lower) |
---|
| 286 | + return; |
---|
| 287 | + |
---|
| 288 | + netdev->gso_max_size = lower->gso_max_size; |
---|
| 289 | + netdev->gso_max_segs = lower->gso_max_segs; |
---|
| 290 | + |
---|
| 291 | + netdev_update_features(netdev); |
---|
| 292 | +} |
---|
284 | 293 | |
---|
285 | 294 | static void nfp_repr_clean(struct nfp_repr *repr) |
---|
286 | 295 | { |
---|
.. | .. |
---|
291 | 300 | } |
---|
292 | 301 | |
---|
293 | 302 | static struct lock_class_key nfp_repr_netdev_xmit_lock_key; |
---|
294 | | -static struct lock_class_key nfp_repr_netdev_addr_lock_key; |
---|
295 | 303 | |
---|
296 | 304 | static void nfp_repr_set_lockdep_class_one(struct net_device *dev, |
---|
297 | 305 | struct netdev_queue *txq, |
---|
.. | .. |
---|
302 | 310 | |
---|
303 | 311 | static void nfp_repr_set_lockdep_class(struct net_device *dev) |
---|
304 | 312 | { |
---|
305 | | - lockdep_set_class(&dev->addr_list_lock, &nfp_repr_netdev_addr_lock_key); |
---|
306 | 313 | netdev_for_each_tx_queue(dev, nfp_repr_set_lockdep_class_one, NULL); |
---|
307 | 314 | } |
---|
308 | 315 | |
---|
.. | .. |
---|
311 | 318 | struct net_device *pf_netdev) |
---|
312 | 319 | { |
---|
313 | 320 | struct nfp_repr *repr = netdev_priv(netdev); |
---|
| 321 | + struct nfp_net *nn = netdev_priv(pf_netdev); |
---|
| 322 | + u32 repr_cap = nn->tlv_caps.repr_cap; |
---|
314 | 323 | int err; |
---|
315 | 324 | |
---|
316 | 325 | nfp_repr_set_lockdep_class(netdev); |
---|
.. | .. |
---|
327 | 336 | |
---|
328 | 337 | netdev->max_mtu = pf_netdev->max_mtu; |
---|
329 | 338 | |
---|
330 | | - SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops); |
---|
| 339 | + /* Set features the lower device can support with representors */ |
---|
| 340 | + if (repr_cap & NFP_NET_CFG_CTRL_LIVE_ADDR) |
---|
| 341 | + netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE; |
---|
331 | 342 | |
---|
332 | | - netdev->priv_flags |= IFF_DISABLE_NETPOLL; |
---|
| 343 | + netdev->hw_features = NETIF_F_HIGHDMA; |
---|
| 344 | + if (repr_cap & NFP_NET_CFG_CTRL_RXCSUM_ANY) |
---|
| 345 | + netdev->hw_features |= NETIF_F_RXCSUM; |
---|
| 346 | + if (repr_cap & NFP_NET_CFG_CTRL_TXCSUM) |
---|
| 347 | + netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; |
---|
| 348 | + if (repr_cap & NFP_NET_CFG_CTRL_GATHER) |
---|
| 349 | + netdev->hw_features |= NETIF_F_SG; |
---|
| 350 | + if ((repr_cap & NFP_NET_CFG_CTRL_LSO && nn->fw_ver.major > 2) || |
---|
| 351 | + repr_cap & NFP_NET_CFG_CTRL_LSO2) |
---|
| 352 | + netdev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6; |
---|
| 353 | + if (repr_cap & NFP_NET_CFG_CTRL_RSS_ANY) |
---|
| 354 | + netdev->hw_features |= NETIF_F_RXHASH; |
---|
| 355 | + if (repr_cap & NFP_NET_CFG_CTRL_VXLAN) { |
---|
| 356 | + if (repr_cap & NFP_NET_CFG_CTRL_LSO) |
---|
| 357 | + netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL; |
---|
| 358 | + } |
---|
| 359 | + if (repr_cap & NFP_NET_CFG_CTRL_NVGRE) { |
---|
| 360 | + if (repr_cap & NFP_NET_CFG_CTRL_LSO) |
---|
| 361 | + netdev->hw_features |= NETIF_F_GSO_GRE; |
---|
| 362 | + } |
---|
| 363 | + if (repr_cap & (NFP_NET_CFG_CTRL_VXLAN | NFP_NET_CFG_CTRL_NVGRE)) |
---|
| 364 | + netdev->hw_enc_features = netdev->hw_features; |
---|
| 365 | + |
---|
| 366 | + netdev->vlan_features = netdev->hw_features; |
---|
| 367 | + |
---|
| 368 | + if (repr_cap & NFP_NET_CFG_CTRL_RXVLAN) |
---|
| 369 | + netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX; |
---|
| 370 | + if (repr_cap & NFP_NET_CFG_CTRL_TXVLAN) { |
---|
| 371 | + if (repr_cap & NFP_NET_CFG_CTRL_LSO2) |
---|
| 372 | + netdev_warn(netdev, "Device advertises both TSO2 and TXVLAN. Refusing to enable TXVLAN.\n"); |
---|
| 373 | + else |
---|
| 374 | + netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX; |
---|
| 375 | + } |
---|
| 376 | + if (repr_cap & NFP_NET_CFG_CTRL_CTAG_FILTER) |
---|
| 377 | + netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; |
---|
| 378 | + |
---|
| 379 | + netdev->features = netdev->hw_features; |
---|
| 380 | + |
---|
| 381 | + /* Advertise but disable TSO by default. */ |
---|
| 382 | + netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); |
---|
| 383 | + netdev->gso_max_segs = NFP_NET_LSO_MAX_SEGS; |
---|
| 384 | + |
---|
| 385 | + netdev->priv_flags |= IFF_NO_QUEUE | IFF_DISABLE_NETPOLL; |
---|
| 386 | + netdev->features |= NETIF_F_LLTX; |
---|
333 | 387 | |
---|
334 | 388 | if (nfp_app_has_tc(app)) { |
---|
335 | 389 | netdev->features |= NETIF_F_HW_TC; |
---|
.. | .. |
---|
474 | 528 | continue; |
---|
475 | 529 | |
---|
476 | 530 | nfp_app_repr_preclean(app, netdev); |
---|
| 531 | + rtnl_lock(); |
---|
477 | 532 | rcu_assign_pointer(reprs->reprs[i], NULL); |
---|
| 533 | + rtnl_unlock(); |
---|
478 | 534 | synchronize_rcu(); |
---|
479 | 535 | nfp_repr_clean(repr); |
---|
480 | 536 | } |
---|