-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <grzegorz.nitka@intel.com> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com> Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
- Loading branch information
Michal Swiatkowski
authored and
Tony Nguyen
committed
Oct 7, 2021
1 parent
2ae0aa4
commit 37165e3
Showing
6 changed files
with
286 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (C) 2019-2021, Intel Corporation. */ | ||
|
||
#include "ice.h" | ||
#include "ice_eswitch.h" | ||
#include "ice_devlink.h" | ||
#include "ice_virtchnl_pf.h" | ||
|
||
/** | ||
* ice_repr_get_sw_port_id - get port ID associated with representor | ||
* @repr: pointer to port representor | ||
*/ | ||
static int ice_repr_get_sw_port_id(struct ice_repr *repr) | ||
{ | ||
return repr->vf->pf->hw.port_info->lport; | ||
} | ||
|
||
/** | ||
* ice_repr_get_phys_port_name - get phys port name | ||
* @netdev: pointer to port representor netdev | ||
* @buf: write here port name | ||
* @len: max length of buf | ||
*/ | ||
static int | ||
ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len) | ||
{ | ||
struct ice_netdev_priv *np = netdev_priv(netdev); | ||
struct ice_repr *repr = np->repr; | ||
int res; | ||
|
||
/* Devlink port is registered and devlink core is taking care of name formatting. */ | ||
if (repr->vf->devlink_port.devlink) | ||
return -EOPNOTSUPP; | ||
|
||
res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr), | ||
repr->vf->vf_id); | ||
if (res <= 0) | ||
return -EOPNOTSUPP; | ||
return 0; | ||
} | ||
|
||
/** | ||
* ice_netdev_to_repr - Get port representor for given netdevice | ||
* @netdev: pointer to port representor netdev | ||
*/ | ||
struct ice_repr *ice_netdev_to_repr(struct net_device *netdev) | ||
{ | ||
struct ice_netdev_priv *np = netdev_priv(netdev); | ||
|
||
return np->repr; | ||
} | ||
|
||
/** | ||
* ice_repr_open - Enable port representor's network interface | ||
* @netdev: network interface device structure | ||
* | ||
* The open entry point is called when a port representor's network | ||
* interface is made active by the system (IFF_UP). Corresponding | ||
* VF is notified about link status change. | ||
* | ||
* Returns 0 on success | ||
*/ | ||
static int ice_repr_open(struct net_device *netdev) | ||
{ | ||
struct ice_repr *repr = ice_netdev_to_repr(netdev); | ||
struct ice_vf *vf; | ||
|
||
vf = repr->vf; | ||
vf->link_forced = true; | ||
vf->link_up = true; | ||
ice_vc_notify_vf_link_state(vf); | ||
|
||
netif_carrier_on(netdev); | ||
netif_tx_start_all_queues(netdev); | ||
|
||
return 0; | ||
} | ||
|
||
/** | ||
* ice_repr_stop - Disable port representor's network interface | ||
* @netdev: network interface device structure | ||
* | ||
* The stop entry point is called when a port representor's network | ||
* interface is de-activated by the system. Corresponding | ||
* VF is notified about link status change. | ||
* | ||
* Returns 0 on success | ||
*/ | ||
static int ice_repr_stop(struct net_device *netdev) | ||
{ | ||
struct ice_repr *repr = ice_netdev_to_repr(netdev); | ||
struct ice_vf *vf; | ||
|
||
vf = repr->vf; | ||
vf->link_forced = true; | ||
vf->link_up = false; | ||
ice_vc_notify_vf_link_state(vf); | ||
|
||
netif_carrier_off(netdev); | ||
netif_tx_stop_all_queues(netdev); | ||
|
||
return 0; | ||
} | ||
|
||
static struct devlink_port * | ||
ice_repr_get_devlink_port(struct net_device *netdev) | ||
{ | ||
struct ice_repr *repr = ice_netdev_to_repr(netdev); | ||
|
||
return &repr->vf->devlink_port; | ||
} | ||
|
||
static const struct net_device_ops ice_repr_netdev_ops = { | ||
.ndo_get_phys_port_name = ice_repr_get_phys_port_name, | ||
.ndo_open = ice_repr_open, | ||
.ndo_stop = ice_repr_stop, | ||
.ndo_get_devlink_port = ice_repr_get_devlink_port, | ||
}; | ||
|
||
/** | ||
* ice_is_port_repr_netdev - Check if a given netdevice is a port representor netdev | ||
* @netdev: pointer to netdev | ||
*/ | ||
bool ice_is_port_repr_netdev(struct net_device *netdev) | ||
{ | ||
return netdev && (netdev->netdev_ops == &ice_repr_netdev_ops); | ||
} | ||
|
||
/** | ||
* ice_repr_reg_netdev - register port representor netdev | ||
* @netdev: pointer to port representor netdev | ||
*/ | ||
static int | ||
ice_repr_reg_netdev(struct net_device *netdev) | ||
{ | ||
eth_hw_addr_random(netdev); | ||
netdev->netdev_ops = &ice_repr_netdev_ops; | ||
|
||
netif_carrier_off(netdev); | ||
netif_tx_stop_all_queues(netdev); | ||
|
||
return register_netdev(netdev); | ||
} | ||
|
||
/** | ||
* ice_repr_add - add representor for VF | ||
* @vf: pointer to VF structure | ||
*/ | ||
static int ice_repr_add(struct ice_vf *vf) | ||
{ | ||
struct ice_q_vector *q_vector; | ||
struct ice_netdev_priv *np; | ||
struct ice_repr *repr; | ||
int err; | ||
|
||
repr = kzalloc(sizeof(*repr), GFP_KERNEL); | ||
if (!repr) | ||
return -ENOMEM; | ||
|
||
repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv)); | ||
if (!repr->netdev) { | ||
err = -ENOMEM; | ||
goto err_alloc; | ||
} | ||
|
||
repr->src_vsi = ice_get_vf_vsi(vf); | ||
repr->vf = vf; | ||
vf->repr = repr; | ||
np = netdev_priv(repr->netdev); | ||
np->repr = repr; | ||
|
||
q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL); | ||
if (!q_vector) { | ||
err = -ENOMEM; | ||
goto err_alloc_q_vector; | ||
} | ||
repr->q_vector = q_vector; | ||
|
||
err = ice_devlink_create_vf_port(vf); | ||
if (err) | ||
goto err_devlink; | ||
|
||
err = ice_repr_reg_netdev(repr->netdev); | ||
if (err) | ||
goto err_netdev; | ||
|
||
devlink_port_type_eth_set(&vf->devlink_port, repr->netdev); | ||
|
||
return 0; | ||
|
||
err_netdev: | ||
ice_devlink_destroy_vf_port(vf); | ||
err_devlink: | ||
kfree(repr->q_vector); | ||
vf->repr->q_vector = NULL; | ||
err_alloc_q_vector: | ||
free_netdev(repr->netdev); | ||
repr->netdev = NULL; | ||
err_alloc: | ||
kfree(repr); | ||
vf->repr = NULL; | ||
return err; | ||
} | ||
|
||
/** | ||
* ice_repr_rem - remove representor from VF | ||
* @vf: pointer to VF structure | ||
*/ | ||
static void ice_repr_rem(struct ice_vf *vf) | ||
{ | ||
ice_devlink_destroy_vf_port(vf); | ||
kfree(vf->repr->q_vector); | ||
vf->repr->q_vector = NULL; | ||
unregister_netdev(vf->repr->netdev); | ||
free_netdev(vf->repr->netdev); | ||
vf->repr->netdev = NULL; | ||
kfree(vf->repr); | ||
vf->repr = NULL; | ||
} | ||
|
||
/** | ||
* ice_repr_add_for_all_vfs - add port representor for all VFs | ||
* @pf: pointer to PF structure | ||
*/ | ||
int ice_repr_add_for_all_vfs(struct ice_pf *pf) | ||
{ | ||
int err; | ||
int i; | ||
|
||
ice_for_each_vf(pf, i) { | ||
err = ice_repr_add(&pf->vf[i]); | ||
if (err) | ||
goto err; | ||
} | ||
return 0; | ||
|
||
err: | ||
for (i = i - 1; i >= 0; i--) | ||
ice_repr_rem(&pf->vf[i]); | ||
|
||
return err; | ||
} | ||
|
||
/** | ||
* ice_repr_rem_from_all_vfs - remove port representor for all VFs | ||
* @pf: pointer to PF structure | ||
*/ | ||
void ice_repr_rem_from_all_vfs(struct ice_pf *pf) | ||
{ | ||
int i; | ||
|
||
ice_for_each_vf(pf, i) | ||
ice_repr_rem(&pf->vf[i]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* Copyright (C) 2019-2021, Intel Corporation. */ | ||
|
||
#ifndef _ICE_REPR_H_ | ||
#define _ICE_REPR_H_ | ||
|
||
#include <net/dst_metadata.h> | ||
#include "ice.h" | ||
|
||
struct ice_repr { | ||
struct ice_vsi *src_vsi; | ||
struct ice_vf *vf; | ||
struct ice_q_vector *q_vector; | ||
struct net_device *netdev; | ||
struct metadata_dst *dst; | ||
}; | ||
|
||
int ice_repr_add_for_all_vfs(struct ice_pf *pf); | ||
void ice_repr_rem_from_all_vfs(struct ice_pf *pf); | ||
|
||
struct ice_repr *ice_netdev_to_repr(struct net_device *netdev); | ||
bool ice_is_port_repr_netdev(struct net_device *netdev); | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters