Skip to content

Commit e5c5180

Browse files
committed
Merge branch 'nfp-ctrl-vNIC'
Jakub Kicinski says: ==================== nfp: ctrl vNIC This series adds the ability to use one vNIC as a control channel for passing messages to and from the application firmware. The implementation restructures the existing netdev vNIC code to be able to deal with nfp_nets with netdev pointer set to NULL. Control vNICs are not visible to userspace (other than for dumping ring state), and since they don't have netdevs we use a tasklet for RX and simple skb list for TX queuing. Due to special status of the control vNIC we have to reshuffle the init code a bit to make sure control vNIC will be fully brought up (and therefore communication with app FW can happen) before any netdev or port is visible to user space. FW will designate which vNIC is supposed to be used as control one by setting _pf%u_net_ctrl_bar symbol. Some FWs depend on metadata being prepended to control message, some prefer to look at queue ID to decide that something is a control message. Our implementation can cater to both. First two users of this code will be eBPF maps and flower offloads. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 2b30842 + f938062 commit e5c5180

File tree

9 files changed

+874
-372
lines changed

9 files changed

+874
-372
lines changed

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* SOFTWARE.
3232
*/
3333

34+
#include <linux/skbuff.h>
3435
#include <linux/slab.h>
3536

3637
#include "nfpcore/nfp_cpp.h"
@@ -42,6 +43,23 @@ static const struct nfp_app_type *apps[] = {
4243
&app_bpf,
4344
};
4445

46+
struct sk_buff *nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size)
47+
{
48+
struct sk_buff *skb;
49+
50+
if (nfp_app_ctrl_has_meta(app))
51+
size += 8;
52+
53+
skb = alloc_skb(size, GFP_ATOMIC);
54+
if (!skb)
55+
return NULL;
56+
57+
if (nfp_app_ctrl_has_meta(app))
58+
skb_reserve(skb, 8);
59+
60+
return skb;
61+
}
62+
4563
struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id)
4664
{
4765
struct nfp_app *app;

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
struct bpf_prog;
3838
struct net_device;
3939
struct pci_dev;
40+
struct sk_buff;
4041
struct tc_to_netdev;
42+
struct sk_buff;
4143
struct nfp_app;
4244
struct nfp_cpp;
4345
struct nfp_pf;
@@ -55,12 +57,16 @@ extern const struct nfp_app_type app_bpf;
5557
* struct nfp_app_type - application definition
5658
* @id: application ID
5759
* @name: application name
60+
* @ctrl_has_meta: control messages have prepend of type:5/port:CTRL
5861
*
5962
* Callbacks
6063
* @init: perform basic app checks
6164
* @extra_cap: extra capabilities string
6265
* @vnic_init: init vNICs (assign port types, etc.)
6366
* @vnic_clean: clean up app's vNIC state
67+
* @start: start application logic
68+
* @stop: stop application logic
69+
* @ctrl_msg_rx: control message handler
6470
* @setup_tc: setup TC ndo
6571
* @tc_busy: TC HW offload busy (rules loaded)
6672
* @xdp_offload: offload an XDP program
@@ -69,6 +75,8 @@ struct nfp_app_type {
6975
enum nfp_app_id id;
7076
const char *name;
7177

78+
bool ctrl_has_meta;
79+
7280
int (*init)(struct nfp_app *app);
7381

7482
const char *(*extra_cap)(struct nfp_app *app, struct nfp_net *nn);
@@ -77,6 +85,11 @@ struct nfp_app_type {
7785
unsigned int id);
7886
void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn);
7987

88+
int (*start)(struct nfp_app *app);
89+
void (*stop)(struct nfp_app *app);
90+
91+
void (*ctrl_msg_rx)(struct nfp_app *app, struct sk_buff *skb);
92+
8093
int (*setup_tc)(struct nfp_app *app, struct net_device *netdev,
8194
u32 handle, __be16 proto, struct tc_to_netdev *tc);
8295
bool (*tc_busy)(struct nfp_app *app, struct nfp_net *nn);
@@ -89,16 +102,21 @@ struct nfp_app_type {
89102
* @pdev: backpointer to PCI device
90103
* @pf: backpointer to NFP PF structure
91104
* @cpp: pointer to the CPP handle
105+
* @ctrl: pointer to ctrl vNIC struct
92106
* @type: pointer to const application ops and info
93107
*/
94108
struct nfp_app {
95109
struct pci_dev *pdev;
96110
struct nfp_pf *pf;
97111
struct nfp_cpp *cpp;
98112

113+
struct nfp_net *ctrl;
114+
99115
const struct nfp_app_type *type;
100116
};
101117

118+
bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
119+
102120
static inline int nfp_app_init(struct nfp_app *app)
103121
{
104122
if (!app->type->init)
@@ -118,13 +136,38 @@ static inline void nfp_app_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
118136
app->type->vnic_clean(app, nn);
119137
}
120138

139+
static inline int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl)
140+
{
141+
app->ctrl = ctrl;
142+
if (!app->type->start)
143+
return 0;
144+
return app->type->start(app);
145+
}
146+
147+
static inline void nfp_app_stop(struct nfp_app *app)
148+
{
149+
if (!app->type->stop)
150+
return;
151+
app->type->stop(app);
152+
}
153+
121154
static inline const char *nfp_app_name(struct nfp_app *app)
122155
{
123156
if (!app)
124157
return "";
125158
return app->type->name;
126159
}
127160

161+
static inline bool nfp_app_needs_ctrl_vnic(struct nfp_app *app)
162+
{
163+
return app && app->type->ctrl_msg_rx;
164+
}
165+
166+
static inline bool nfp_app_ctrl_has_meta(struct nfp_app *app)
167+
{
168+
return app->type->ctrl_has_meta;
169+
}
170+
128171
static inline const char *nfp_app_extra_cap(struct nfp_app *app,
129172
struct nfp_net *nn)
130173
{
@@ -163,6 +206,18 @@ static inline int nfp_app_xdp_offload(struct nfp_app *app, struct nfp_net *nn,
163206
return app->type->xdp_offload(app, nn, prog);
164207
}
165208

209+
static inline bool nfp_app_ctrl_tx(struct nfp_app *app, struct sk_buff *skb)
210+
{
211+
return nfp_ctrl_tx(app->ctrl, skb);
212+
}
213+
214+
static inline void nfp_app_ctrl_rx(struct nfp_app *app, struct sk_buff *skb)
215+
{
216+
app->type->ctrl_msg_rx(app, skb);
217+
}
218+
219+
struct sk_buff *nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size);
220+
166221
struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id);
167222
void nfp_app_free(struct nfp_app *app);
168223

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,13 @@ struct nfp_nsp_identify;
6363
* @cpp: Pointer to the CPP handle
6464
* @app: Pointer to the APP handle
6565
* @data_vnic_bar: Pointer to the CPP area for the data vNICs' BARs
66-
* @tx_area: Pointer to the CPP area for the TX queues
67-
* @rx_area: Pointer to the CPP area for the FL/RX queues
66+
* @ctrl_vnic_bar: Pointer to the CPP area for the ctrl vNIC's BAR
67+
* @qc_area: Pointer to the CPP area for the queues
6868
* @irq_entries: Array of MSI-X entries for all vNICs
6969
* @limit_vfs: Number of VFs supported by firmware (~0 for PCI limit)
7070
* @num_vfs: Number of SR-IOV VFs enabled
7171
* @fw_loaded: Is the firmware loaded?
72+
* @ctrl_vnic: Pointer to the control vNIC if available
7273
* @eth_tbl: NSP ETH table
7374
* @nspi: NSP identification info
7475
* @hwmon_dev: pointer to hwmon device
@@ -88,8 +89,8 @@ struct nfp_pf {
8889
struct nfp_app *app;
8990

9091
struct nfp_cpp_area *data_vnic_bar;
91-
struct nfp_cpp_area *tx_area;
92-
struct nfp_cpp_area *rx_area;
92+
struct nfp_cpp_area *ctrl_vnic_bar;
93+
struct nfp_cpp_area *qc_area;
9394

9495
struct msix_entry *irq_entries;
9596

@@ -98,6 +99,8 @@ struct nfp_pf {
9899

99100
bool fw_loaded;
100101

102+
struct nfp_net *ctrl_vnic;
103+
101104
struct nfp_eth_table *eth_tbl;
102105
struct nfp_nsp_identify *nspi;
103106

@@ -129,4 +132,6 @@ nfp_net_find_port(struct nfp_eth_table *eth_tbl, unsigned int id);
129132
void
130133
nfp_net_get_mac_addr(struct nfp_net *nn, struct nfp_cpp *cpp, unsigned int id);
131134

135+
bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
136+
132137
#endif /* NFP_MAIN_H */

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

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,32 @@
5050

5151
#include "nfp_net_ctrl.h"
5252

53-
#define nn_err(nn, fmt, args...) netdev_err((nn)->dp.netdev, fmt, ## args)
54-
#define nn_warn(nn, fmt, args...) netdev_warn((nn)->dp.netdev, fmt, ## args)
55-
#define nn_info(nn, fmt, args...) netdev_info((nn)->dp.netdev, fmt, ## args)
56-
#define nn_dbg(nn, fmt, args...) netdev_dbg((nn)->dp.netdev, fmt, ## args)
53+
#define nn_pr(nn, lvl, fmt, args...) \
54+
({ \
55+
struct nfp_net *__nn = (nn); \
56+
\
57+
if (__nn->dp.netdev) \
58+
netdev_printk(lvl, __nn->dp.netdev, fmt, ## args); \
59+
else \
60+
dev_printk(lvl, __nn->dp.dev, "ctrl: " fmt, ## args); \
61+
})
62+
63+
#define nn_err(nn, fmt, args...) nn_pr(nn, KERN_ERR, fmt, ## args)
64+
#define nn_warn(nn, fmt, args...) nn_pr(nn, KERN_WARNING, fmt, ## args)
65+
#define nn_info(nn, fmt, args...) nn_pr(nn, KERN_INFO, fmt, ## args)
66+
#define nn_dbg(nn, fmt, args...) nn_pr(nn, KERN_DEBUG, fmt, ## args)
67+
5768
#define nn_dp_warn(dp, fmt, args...) \
58-
do { \
59-
if (unlikely(net_ratelimit())) \
60-
netdev_warn((dp)->netdev, fmt, ## args); \
61-
} while (0)
69+
({ \
70+
struct nfp_net_dp *__dp = (dp); \
71+
\
72+
if (unlikely(net_ratelimit())) { \
73+
if (__dp->netdev) \
74+
netdev_warn(__dp->netdev, fmt, ## args); \
75+
else \
76+
dev_warn(__dp->dev, fmt, ## args); \
77+
} \
78+
})
6279

6380
/* Max time to wait for NFP to respond on updates (in seconds) */
6481
#define NFP_NET_POLL_TIMEOUT 5
@@ -388,7 +405,14 @@ struct nfp_net_rx_ring {
388405
*/
389406
struct nfp_net_r_vector {
390407
struct nfp_net *nfp_net;
391-
struct napi_struct napi;
408+
union {
409+
struct napi_struct napi;
410+
struct {
411+
struct tasklet_struct tasklet;
412+
struct sk_buff_head queue;
413+
struct spinlock lock;
414+
};
415+
};
392416

393417
struct nfp_net_tx_ring *tx_ring;
394418
struct nfp_net_rx_ring *rx_ring;
@@ -681,6 +705,7 @@ static inline void nn_pci_flush(struct nfp_net *nn)
681705
* either add to a pointer or to read the pointer value.
682706
*/
683707
#define NFP_QCP_QUEUE_ADDR_SZ 0x800
708+
#define NFP_QCP_QUEUE_AREA_SZ 0x80000
684709
#define NFP_QCP_QUEUE_OFF(_x) ((_x) * NFP_QCP_QUEUE_ADDR_SZ)
685710
#define NFP_QCP_QUEUE_ADD_RPTR 0x0000
686711
#define NFP_QCP_QUEUE_ADD_WPTR 0x0004
@@ -788,6 +813,22 @@ static inline u32 nfp_qcp_wr_ptr_read(u8 __iomem *q)
788813
return _nfp_qcp_read(q, NFP_QCP_WRITE_PTR);
789814
}
790815

816+
static inline bool nfp_net_is_data_vnic(struct nfp_net *nn)
817+
{
818+
WARN_ON_ONCE(!nn->dp.netdev && nn->port);
819+
return !!nn->dp.netdev;
820+
}
821+
822+
static inline bool nfp_net_running(struct nfp_net *nn)
823+
{
824+
return nn->dp.ctrl & NFP_NET_CFG_CTRL_ENABLE;
825+
}
826+
827+
static inline const char *nfp_net_name(struct nfp_net *nn)
828+
{
829+
return nn->dp.netdev ? nn->dp.netdev->name : "ctrl";
830+
}
831+
791832
/* Globals */
792833
extern const char nfp_driver_version[];
793834

@@ -803,13 +844,16 @@ void nfp_net_get_fw_version(struct nfp_net_fw_version *fw_ver,
803844
void __iomem *ctrl_bar);
804845

805846
struct nfp_net *
806-
nfp_net_alloc(struct pci_dev *pdev,
847+
nfp_net_alloc(struct pci_dev *pdev, bool needs_netdev,
807848
unsigned int max_tx_rings, unsigned int max_rx_rings);
808849
void nfp_net_free(struct nfp_net *nn);
809850

810851
int nfp_net_init(struct nfp_net *nn);
811852
void nfp_net_clean(struct nfp_net *nn);
812853

854+
int nfp_ctrl_open(struct nfp_net *nn);
855+
void nfp_ctrl_close(struct nfp_net *nn);
856+
813857
void nfp_net_set_ethtool_ops(struct net_device *netdev);
814858
void nfp_net_info(struct nfp_net *nn);
815859
int nfp_net_reconfig(struct nfp_net *nn, u32 update);

0 commit comments

Comments
 (0)