Skip to content

Commit 5de73ee

Browse files
shorman-netronomedavem330
authored andcommitted
nfp: general representor implementation
Provide infrastructure to create and destroy representors of a given type. Parts based on work by Bert van Leeuwen, Benjamin LaHaise, and Jakub Kicinski. Signed-off-by: Simon Horman <[email protected]> Reviewed-by: Jakub Kicinski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a595018 commit 5de73ee

File tree

5 files changed

+287
-0
lines changed

5 files changed

+287
-0
lines changed

drivers/net/ethernet/netronome/nfp/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ nfp-objs := \
2222
nfp_net_common.o \
2323
nfp_net_ethtool.o \
2424
nfp_net_main.o \
25+
nfp_net_repr.o \
2526
nfp_netvf_main.o \
2627
nfp_port.o \
2728
bpf/main.o \

drivers/net/ethernet/netronome/nfp/nfp_app.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "nfpcore/nfp_nffw.h"
3939
#include "nfp_app.h"
4040
#include "nfp_main.h"
41+
#include "nfp_net_repr.h"
4142

4243
static const struct nfp_app_type *apps[] = {
4344
&app_nic,
@@ -68,6 +69,25 @@ struct sk_buff *nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size)
6869
return skb;
6970
}
7071

72+
struct nfp_reprs *
73+
nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
74+
struct nfp_reprs *reprs)
75+
{
76+
struct nfp_reprs *old;
77+
78+
old = rcu_dereference_protected(app->reprs[type],
79+
lockdep_is_held(&app->pf->lock));
80+
if (reprs && old) {
81+
old = ERR_PTR(-EBUSY);
82+
goto exit_unlock;
83+
}
84+
85+
rcu_assign_pointer(app->reprs[type], reprs);
86+
87+
exit_unlock:
88+
return old;
89+
}
90+
7191
struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id)
7292
{
7393
struct nfp_app *app;

drivers/net/ethernet/netronome/nfp/nfp_app.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636

3737
#include <net/devlink.h>
3838

39+
#include "nfp_net_repr.h"
40+
3941
struct bpf_prog;
4042
struct net_device;
4143
struct pci_dev;
@@ -73,6 +75,7 @@ extern const struct nfp_app_type app_bpf;
7375
* @tc_busy: TC HW offload busy (rules loaded)
7476
* @xdp_offload: offload an XDP program
7577
* @eswitch_mode_get: get SR-IOV eswitch mode
78+
* @repr_get: get representor netdev
7679
*/
7780
struct nfp_app_type {
7881
enum nfp_app_id id;
@@ -100,6 +103,7 @@ struct nfp_app_type {
100103
struct bpf_prog *prog);
101104

102105
enum devlink_eswitch_mode (*eswitch_mode_get)(struct nfp_app *app);
106+
struct net_device *(*repr_get)(struct nfp_app *app, u32 id);
103107
};
104108

105109
/**
@@ -108,6 +112,7 @@ struct nfp_app_type {
108112
* @pf: backpointer to NFP PF structure
109113
* @cpp: pointer to the CPP handle
110114
* @ctrl: pointer to ctrl vNIC struct
115+
* @reprs: array of pointers to representors
111116
* @type: pointer to const application ops and info
112117
*/
113118
struct nfp_app {
@@ -116,6 +121,7 @@ struct nfp_app {
116121
struct nfp_cpp *cpp;
117122

118123
struct nfp_net *ctrl;
124+
struct nfp_reprs __rcu *reprs[NFP_REPR_TYPE_MAX + 1];
119125

120126
const struct nfp_app_type *type;
121127
};
@@ -231,6 +237,18 @@ static inline int nfp_app_eswitch_mode_get(struct nfp_app *app, u16 *mode)
231237
return 0;
232238
}
233239

240+
static inline struct net_device *nfp_app_repr_get(struct nfp_app *app, u32 id)
241+
{
242+
if (unlikely(!app || !app->type->repr_get))
243+
return NULL;
244+
245+
return app->type->repr_get(app, id);
246+
}
247+
248+
struct nfp_reprs *
249+
nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
250+
struct nfp_reprs *reprs);
251+
234252
const char *nfp_app_mip_name(struct nfp_app *app);
235253
struct sk_buff *nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size);
236254

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
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+
*/
33+
34+
#include <linux/etherdevice.h>
35+
#include <linux/lockdep.h>
36+
#include <net/dst_metadata.h>
37+
38+
#include "nfpcore/nfp_cpp.h"
39+
#include "nfp_app.h"
40+
#include "nfp_main.h"
41+
#include "nfp_net_repr.h"
42+
#include "nfp_port.h"
43+
44+
static void nfp_repr_clean(struct nfp_repr *repr)
45+
{
46+
unregister_netdev(repr->netdev);
47+
dst_release((struct dst_entry *)repr->dst);
48+
nfp_port_free(repr->port);
49+
}
50+
51+
static struct lock_class_key nfp_repr_netdev_xmit_lock_key;
52+
static struct lock_class_key nfp_repr_netdev_addr_lock_key;
53+
54+
static void nfp_repr_set_lockdep_class_one(struct net_device *dev,
55+
struct netdev_queue *txq,
56+
void *_unused)
57+
{
58+
lockdep_set_class(&txq->_xmit_lock, &nfp_repr_netdev_xmit_lock_key);
59+
}
60+
61+
static void nfp_repr_set_lockdep_class(struct net_device *dev)
62+
{
63+
lockdep_set_class(&dev->addr_list_lock, &nfp_repr_netdev_addr_lock_key);
64+
netdev_for_each_tx_queue(dev, nfp_repr_set_lockdep_class_one, NULL);
65+
}
66+
67+
int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
68+
const struct net_device_ops *netdev_ops, u32 cmsg_port_id,
69+
struct nfp_port *port, struct net_device *pf_netdev)
70+
{
71+
struct nfp_repr *repr = netdev_priv(netdev);
72+
int err;
73+
74+
nfp_repr_set_lockdep_class(netdev);
75+
76+
repr->port = port;
77+
repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL);
78+
if (!repr->dst)
79+
return -ENOMEM;
80+
repr->dst->u.port_info.port_id = cmsg_port_id;
81+
repr->dst->u.port_info.lower_dev = pf_netdev;
82+
83+
netdev->netdev_ops = netdev_ops;
84+
85+
err = register_netdev(netdev);
86+
if (err)
87+
goto err_clean;
88+
89+
return 0;
90+
91+
err_clean:
92+
dst_release((struct dst_entry *)repr->dst);
93+
return err;
94+
}
95+
96+
struct net_device *nfp_repr_alloc(struct nfp_app *app)
97+
{
98+
struct net_device *netdev;
99+
struct nfp_repr *repr;
100+
101+
netdev = alloc_etherdev(sizeof(*repr));
102+
if (!netdev)
103+
return NULL;
104+
105+
repr = netdev_priv(netdev);
106+
repr->netdev = netdev;
107+
repr->app = app;
108+
109+
return netdev;
110+
}
111+
112+
static void nfp_repr_clean_and_free(struct nfp_repr *repr)
113+
{
114+
nfp_info(repr->app->cpp, "Destroying Representor(%s)\n",
115+
repr->netdev->name);
116+
nfp_repr_clean(repr);
117+
free_netdev(repr->netdev);
118+
}
119+
120+
void nfp_reprs_clean_and_free(struct nfp_reprs *reprs)
121+
{
122+
unsigned int i;
123+
124+
for (i = 0; i < reprs->num_reprs; i++)
125+
if (reprs->reprs[i])
126+
nfp_repr_clean_and_free(netdev_priv(reprs->reprs[i]));
127+
128+
kfree(reprs);
129+
}
130+
131+
void
132+
nfp_reprs_clean_and_free_by_type(struct nfp_app *app,
133+
enum nfp_repr_type type)
134+
{
135+
struct nfp_reprs *reprs;
136+
137+
reprs = nfp_app_reprs_set(app, type, NULL);
138+
if (!reprs)
139+
return;
140+
141+
synchronize_rcu();
142+
nfp_reprs_clean_and_free(reprs);
143+
}
144+
145+
struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs)
146+
{
147+
struct nfp_reprs *reprs;
148+
149+
reprs = kzalloc(sizeof(*reprs) +
150+
num_reprs * sizeof(struct net_device *), GFP_KERNEL);
151+
if (!reprs)
152+
return NULL;
153+
reprs->num_reprs = num_reprs;
154+
155+
return reprs;
156+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
*/
33+
34+
#ifndef NFP_NET_REPR_H
35+
#define NFP_NET_REPR_H
36+
37+
struct metadata_dst;
38+
struct nfp_net;
39+
struct nfp_port;
40+
41+
/**
42+
* struct nfp_reprs - container for representor netdevs
43+
* @num_reprs: Number of elements in reprs array
44+
* @reprs: Array of representor netdevs
45+
*/
46+
struct nfp_reprs {
47+
unsigned int num_reprs;
48+
struct net_device *reprs[0];
49+
};
50+
51+
/**
52+
* struct nfp_repr - priv data for representor netdevs
53+
* @netdev: Back pointer to netdev
54+
* @dst: Destination for packet TX
55+
* @port: Port of representor
56+
* @app: APP handle
57+
*/
58+
struct nfp_repr {
59+
struct net_device *netdev;
60+
struct metadata_dst *dst;
61+
struct nfp_port *port;
62+
struct nfp_app *app;
63+
};
64+
65+
/**
66+
* enum nfp_repr_type - type of representor
67+
* @NFP_REPR_TYPE_PHYS_PORT: external NIC port
68+
* @NFP_REPR_TYPE_PF: physical function
69+
* @NFP_REPR_TYPE_VF: virtual function
70+
*/
71+
enum nfp_repr_type {
72+
NFP_REPR_TYPE_PHYS_PORT,
73+
NFP_REPR_TYPE_PF,
74+
NFP_REPR_TYPE_VF,
75+
76+
__NFP_REPR_TYPE_MAX,
77+
};
78+
#define NFP_REPR_TYPE_MAX (__NFP_REPR_TYPE_MAX - 1)
79+
80+
int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
81+
const struct net_device_ops *netdev_ops,
82+
u32 cmsg_port_id, struct nfp_port *port,
83+
struct net_device *pf_netdev);
84+
struct net_device *nfp_repr_alloc(struct nfp_app *app);
85+
void
86+
nfp_reprs_clean_and_free(struct nfp_reprs *reprs);
87+
void
88+
nfp_reprs_clean_and_free_by_type(struct nfp_app *app,
89+
enum nfp_repr_type type);
90+
struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs);
91+
92+
#endif /* NFP_NET_REPR_H */

0 commit comments

Comments
 (0)