Skip to content

Commit 37165e3

Browse files
Michal Swiatkowskianguy11
authored andcommitted
ice: introduce VF port representor
Port representor is used to manage VF from host side. To allow it each created representor registers netdevice with random hw address. Also devlink port is created for all representors. Port representor name is created based on switch id or managed by devlink core if devlink port was registered with success. Open and stop ndo ops are implemented to allow managing the VF link state. Link state is tracked in VF struct. Struct ice_netdev_priv is extended by pointer to representor field. This is needed to get correct representor from netdev struct mostly used in ndo calls. Implement helper functions to check if given netdev is netdev of port representor (ice_is_port_repr_netdev) and to get representor from netdev (ice_netdev_to_repr). As driver mostly will create or destroy port representors on all VFs instead of on single one, write functions to add and remove representor for each VF. Representor struct contains pointer to source VSI, which is VSI configured on VF, backpointer to VF, backpointer to netdev, q_vector pointer and metadata_dst which will be used in data path. Co-developed-by: Grzegorz Nitka <[email protected]> Signed-off-by: Grzegorz Nitka <[email protected]> Signed-off-by: Michal Swiatkowski <[email protected]> Tested-by: Sandeep Penigalapati <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 2ae0aa4 commit 37165e3

File tree

6 files changed

+286
-2
lines changed

6 files changed

+286
-2
lines changed

drivers/net/ethernet/intel/ice/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ ice-y := ice_main.o \
2626
ice_devlink.o \
2727
ice_fw_update.o \
2828
ice_lag.o \
29-
ice_ethtool.o
29+
ice_ethtool.o \
30+
ice_repr.o
3031
ice-$(CONFIG_PCI_IOV) += ice_virtchnl_allowlist.o
3132
ice-$(CONFIG_PCI_IOV) += ice_virtchnl_pf.o ice_sriov.o ice_virtchnl_fdir.o
3233
ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include "ice_fdir.h"
6464
#include "ice_xsk.h"
6565
#include "ice_arfs.h"
66+
#include "ice_repr.h"
6667
#include "ice_lag.h"
6768

6869
#define ICE_BAR0 0
@@ -518,6 +519,7 @@ struct ice_pf {
518519

519520
struct ice_netdev_priv {
520521
struct ice_vsi *vsi;
522+
struct ice_repr *repr;
521523
};
522524

523525
/**
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (C) 2019-2021, Intel Corporation. */
3+
4+
#include "ice.h"
5+
#include "ice_eswitch.h"
6+
#include "ice_devlink.h"
7+
#include "ice_virtchnl_pf.h"
8+
9+
/**
10+
* ice_repr_get_sw_port_id - get port ID associated with representor
11+
* @repr: pointer to port representor
12+
*/
13+
static int ice_repr_get_sw_port_id(struct ice_repr *repr)
14+
{
15+
return repr->vf->pf->hw.port_info->lport;
16+
}
17+
18+
/**
19+
* ice_repr_get_phys_port_name - get phys port name
20+
* @netdev: pointer to port representor netdev
21+
* @buf: write here port name
22+
* @len: max length of buf
23+
*/
24+
static int
25+
ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len)
26+
{
27+
struct ice_netdev_priv *np = netdev_priv(netdev);
28+
struct ice_repr *repr = np->repr;
29+
int res;
30+
31+
/* Devlink port is registered and devlink core is taking care of name formatting. */
32+
if (repr->vf->devlink_port.devlink)
33+
return -EOPNOTSUPP;
34+
35+
res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr),
36+
repr->vf->vf_id);
37+
if (res <= 0)
38+
return -EOPNOTSUPP;
39+
return 0;
40+
}
41+
42+
/**
43+
* ice_netdev_to_repr - Get port representor for given netdevice
44+
* @netdev: pointer to port representor netdev
45+
*/
46+
struct ice_repr *ice_netdev_to_repr(struct net_device *netdev)
47+
{
48+
struct ice_netdev_priv *np = netdev_priv(netdev);
49+
50+
return np->repr;
51+
}
52+
53+
/**
54+
* ice_repr_open - Enable port representor's network interface
55+
* @netdev: network interface device structure
56+
*
57+
* The open entry point is called when a port representor's network
58+
* interface is made active by the system (IFF_UP). Corresponding
59+
* VF is notified about link status change.
60+
*
61+
* Returns 0 on success
62+
*/
63+
static int ice_repr_open(struct net_device *netdev)
64+
{
65+
struct ice_repr *repr = ice_netdev_to_repr(netdev);
66+
struct ice_vf *vf;
67+
68+
vf = repr->vf;
69+
vf->link_forced = true;
70+
vf->link_up = true;
71+
ice_vc_notify_vf_link_state(vf);
72+
73+
netif_carrier_on(netdev);
74+
netif_tx_start_all_queues(netdev);
75+
76+
return 0;
77+
}
78+
79+
/**
80+
* ice_repr_stop - Disable port representor's network interface
81+
* @netdev: network interface device structure
82+
*
83+
* The stop entry point is called when a port representor's network
84+
* interface is de-activated by the system. Corresponding
85+
* VF is notified about link status change.
86+
*
87+
* Returns 0 on success
88+
*/
89+
static int ice_repr_stop(struct net_device *netdev)
90+
{
91+
struct ice_repr *repr = ice_netdev_to_repr(netdev);
92+
struct ice_vf *vf;
93+
94+
vf = repr->vf;
95+
vf->link_forced = true;
96+
vf->link_up = false;
97+
ice_vc_notify_vf_link_state(vf);
98+
99+
netif_carrier_off(netdev);
100+
netif_tx_stop_all_queues(netdev);
101+
102+
return 0;
103+
}
104+
105+
static struct devlink_port *
106+
ice_repr_get_devlink_port(struct net_device *netdev)
107+
{
108+
struct ice_repr *repr = ice_netdev_to_repr(netdev);
109+
110+
return &repr->vf->devlink_port;
111+
}
112+
113+
static const struct net_device_ops ice_repr_netdev_ops = {
114+
.ndo_get_phys_port_name = ice_repr_get_phys_port_name,
115+
.ndo_open = ice_repr_open,
116+
.ndo_stop = ice_repr_stop,
117+
.ndo_get_devlink_port = ice_repr_get_devlink_port,
118+
};
119+
120+
/**
121+
* ice_is_port_repr_netdev - Check if a given netdevice is a port representor netdev
122+
* @netdev: pointer to netdev
123+
*/
124+
bool ice_is_port_repr_netdev(struct net_device *netdev)
125+
{
126+
return netdev && (netdev->netdev_ops == &ice_repr_netdev_ops);
127+
}
128+
129+
/**
130+
* ice_repr_reg_netdev - register port representor netdev
131+
* @netdev: pointer to port representor netdev
132+
*/
133+
static int
134+
ice_repr_reg_netdev(struct net_device *netdev)
135+
{
136+
eth_hw_addr_random(netdev);
137+
netdev->netdev_ops = &ice_repr_netdev_ops;
138+
139+
netif_carrier_off(netdev);
140+
netif_tx_stop_all_queues(netdev);
141+
142+
return register_netdev(netdev);
143+
}
144+
145+
/**
146+
* ice_repr_add - add representor for VF
147+
* @vf: pointer to VF structure
148+
*/
149+
static int ice_repr_add(struct ice_vf *vf)
150+
{
151+
struct ice_q_vector *q_vector;
152+
struct ice_netdev_priv *np;
153+
struct ice_repr *repr;
154+
int err;
155+
156+
repr = kzalloc(sizeof(*repr), GFP_KERNEL);
157+
if (!repr)
158+
return -ENOMEM;
159+
160+
repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv));
161+
if (!repr->netdev) {
162+
err = -ENOMEM;
163+
goto err_alloc;
164+
}
165+
166+
repr->src_vsi = ice_get_vf_vsi(vf);
167+
repr->vf = vf;
168+
vf->repr = repr;
169+
np = netdev_priv(repr->netdev);
170+
np->repr = repr;
171+
172+
q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL);
173+
if (!q_vector) {
174+
err = -ENOMEM;
175+
goto err_alloc_q_vector;
176+
}
177+
repr->q_vector = q_vector;
178+
179+
err = ice_devlink_create_vf_port(vf);
180+
if (err)
181+
goto err_devlink;
182+
183+
err = ice_repr_reg_netdev(repr->netdev);
184+
if (err)
185+
goto err_netdev;
186+
187+
devlink_port_type_eth_set(&vf->devlink_port, repr->netdev);
188+
189+
return 0;
190+
191+
err_netdev:
192+
ice_devlink_destroy_vf_port(vf);
193+
err_devlink:
194+
kfree(repr->q_vector);
195+
vf->repr->q_vector = NULL;
196+
err_alloc_q_vector:
197+
free_netdev(repr->netdev);
198+
repr->netdev = NULL;
199+
err_alloc:
200+
kfree(repr);
201+
vf->repr = NULL;
202+
return err;
203+
}
204+
205+
/**
206+
* ice_repr_rem - remove representor from VF
207+
* @vf: pointer to VF structure
208+
*/
209+
static void ice_repr_rem(struct ice_vf *vf)
210+
{
211+
ice_devlink_destroy_vf_port(vf);
212+
kfree(vf->repr->q_vector);
213+
vf->repr->q_vector = NULL;
214+
unregister_netdev(vf->repr->netdev);
215+
free_netdev(vf->repr->netdev);
216+
vf->repr->netdev = NULL;
217+
kfree(vf->repr);
218+
vf->repr = NULL;
219+
}
220+
221+
/**
222+
* ice_repr_add_for_all_vfs - add port representor for all VFs
223+
* @pf: pointer to PF structure
224+
*/
225+
int ice_repr_add_for_all_vfs(struct ice_pf *pf)
226+
{
227+
int err;
228+
int i;
229+
230+
ice_for_each_vf(pf, i) {
231+
err = ice_repr_add(&pf->vf[i]);
232+
if (err)
233+
goto err;
234+
}
235+
return 0;
236+
237+
err:
238+
for (i = i - 1; i >= 0; i--)
239+
ice_repr_rem(&pf->vf[i]);
240+
241+
return err;
242+
}
243+
244+
/**
245+
* ice_repr_rem_from_all_vfs - remove port representor for all VFs
246+
* @pf: pointer to PF structure
247+
*/
248+
void ice_repr_rem_from_all_vfs(struct ice_pf *pf)
249+
{
250+
int i;
251+
252+
ice_for_each_vf(pf, i)
253+
ice_repr_rem(&pf->vf[i]);
254+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (C) 2019-2021, Intel Corporation. */
3+
4+
#ifndef _ICE_REPR_H_
5+
#define _ICE_REPR_H_
6+
7+
#include <net/dst_metadata.h>
8+
#include "ice.h"
9+
10+
struct ice_repr {
11+
struct ice_vsi *src_vsi;
12+
struct ice_vf *vf;
13+
struct ice_q_vector *q_vector;
14+
struct net_device *netdev;
15+
struct metadata_dst *dst;
16+
};
17+
18+
int ice_repr_add_for_all_vfs(struct ice_pf *pf);
19+
void ice_repr_rem_from_all_vfs(struct ice_pf *pf);
20+
21+
struct ice_repr *ice_netdev_to_repr(struct net_device *netdev);
22+
bool ice_is_port_repr_netdev(struct net_device *netdev);
23+
#endif

drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ static bool ice_is_vf_link_up(struct ice_vf *vf)
412412
*
413413
* send a link status message to a single VF
414414
*/
415-
static void ice_vc_notify_vf_link_state(struct ice_vf *vf)
415+
void ice_vc_notify_vf_link_state(struct ice_vf *vf)
416416
{
417417
struct virtchnl_pf_event pfe = { 0 };
418418
struct ice_hw *hw = &vf->pf->hw;

drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ struct ice_vf {
112112
struct ice_mdd_vf_events mdd_tx_events;
113113
DECLARE_BITMAP(opcodes_allowlist, VIRTCHNL_OP_MAX);
114114

115+
struct ice_repr *repr;
116+
115117
/* devlink port data */
116118
struct devlink_port devlink_port;
117119
};
@@ -128,6 +130,7 @@ void ice_free_vfs(struct ice_pf *pf);
128130
void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event);
129131
void ice_vc_notify_link_state(struct ice_pf *pf);
130132
void ice_vc_notify_reset(struct ice_pf *pf);
133+
void ice_vc_notify_vf_link_state(struct ice_vf *vf);
131134
bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr);
132135
bool ice_reset_vf(struct ice_vf *vf, bool is_vflr);
133136
void ice_restore_all_vfs_msi_state(struct pci_dev *pdev);
@@ -168,6 +171,7 @@ static inline
168171
void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) { }
169172
static inline void ice_vc_notify_link_state(struct ice_pf *pf) { }
170173
static inline void ice_vc_notify_reset(struct ice_pf *pf) { }
174+
static inline void ice_vc_notify_vf_link_state(struct ice_vf *vf) { }
171175
static inline void ice_set_vf_state_qs_dis(struct ice_vf *vf) { }
172176
static inline
173177
void ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event) { }

0 commit comments

Comments
 (0)