@@ -543,7 +543,7 @@ static void ice_dealloc_dynamic_port(struct ice_dynamic_port *dyn_port)
struct ice_pf *pf = dyn_port->pf;
xa_erase(&pf->sf_nums, devlink_port->attrs.pci_sf.sf);
- devl_port_unregister(devlink_port);
+ ice_eswitch_detach_sf(pf, dyn_port);
ice_vsi_free(dyn_port->vsi);
xa_erase(&pf->dyn_ports, dyn_port->vsi->idx);
kfree(dyn_port);
@@ -765,9 +765,9 @@ ice_alloc_dynamic_port(struct ice_pf *pf,
goto unroll_vsi_alloc;
}
- err = ice_devlink_create_sf_port(dyn_port);
+ err = ice_eswitch_attach_sf(pf, dyn_port);
if (err) {
- NL_SET_ERR_MSG_MOD(extack, "Port registration failed");
+ NL_SET_ERR_MSG_MOD(extack, "Failed to attach SF to eswitch");
goto unroll_xa_insert;
}
@@ -525,6 +525,30 @@ int ice_eswitch_attach_vf(struct ice_pf *pf, struct ice_vf *vf)
return err;
}
+/**
+ * ice_eswitch_attach_sf - attach SF to a eswitch
+ * @pf: pointer to PF structure
+ * @sf: pointer to SF structure to be attached
+ *
+ * During attaching port representor for SF is created.
+ *
+ * Return: zero on success or an error code on failure.
+ */
+int ice_eswitch_attach_sf(struct ice_pf *pf, struct ice_dynamic_port *sf)
+{
+ struct ice_repr *repr = ice_repr_create_sf(sf);
+ int err;
+
+ if (IS_ERR(repr))
+ return PTR_ERR(repr);
+
+ err = ice_eswitch_attach(pf, repr, &sf->repr_id);
+ if (err)
+ ice_repr_destroy(repr);
+
+ return err;
+}
+
static void ice_eswitch_detach(struct ice_pf *pf, struct ice_repr *repr)
{
ice_eswitch_stop_reprs(pf);
@@ -568,6 +592,21 @@ void ice_eswitch_detach_vf(struct ice_pf *pf, struct ice_vf *vf)
devl_unlock(devlink);
}
+/**
+ * ice_eswitch_detach_sf - detach SF from a eswitch
+ * @pf: pointer to PF structure
+ * @sf: pointer to SF structure to be detached
+ */
+void ice_eswitch_detach_sf(struct ice_pf *pf, struct ice_dynamic_port *sf)
+{
+ struct ice_repr *repr = xa_load(&pf->eswitch.reprs, sf->repr_id);
+
+ if (!repr)
+ return;
+
+ ice_eswitch_detach(pf, repr);
+}
+
/**
* ice_eswitch_rebuild - rebuild eswitch
* @pf: pointer to PF structure
@@ -9,7 +9,9 @@
#ifdef CONFIG_ICE_SWITCHDEV
void ice_eswitch_detach_vf(struct ice_pf *pf, struct ice_vf *vf);
+void ice_eswitch_detach_sf(struct ice_pf *pf, struct ice_dynamic_port *sf);
int ice_eswitch_attach_vf(struct ice_pf *pf, struct ice_vf *vf);
+int ice_eswitch_attach_sf(struct ice_pf *pf, struct ice_dynamic_port *sf);
void ice_eswitch_rebuild(struct ice_pf *pf);
int ice_eswitch_mode_get(struct devlink *devlink, u16 *mode);
@@ -35,12 +37,21 @@ void ice_eswitch_decfg_vsi(struct ice_vsi *vsi, const u8 *mac);
static inline void
ice_eswitch_detach_vf(struct ice_pf *pf, struct ice_vf *vf) { }
+static inline void
+ice_eswitch_detach_sf(struct ice_pf *pf, struct ice_dynamic_port *sf) { }
+
static inline int
ice_eswitch_attach_vf(struct ice_pf *pf, struct ice_vf *vf)
{
return -EOPNOTSUPP;
}
+static inline int
+ice_eswitch_attach_sf(struct ice_pf *pf, struct ice_dynamic_port *sf)
+{
+ return -EOPNOTSUPP;
+}
+
static inline void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf) { }
static inline void
@@ -302,6 +302,12 @@ static void ice_repr_rem_vf(struct ice_repr *repr)
ice_virtchnl_set_dflt_ops(repr->vf);
}
+static void ice_repr_rem_sf(struct ice_repr *repr)
+{
+ unregister_netdev(repr->netdev);
+ ice_devlink_destroy_sf_port(repr->sf);
+}
+
static void ice_repr_set_tx_topology(struct ice_pf *pf)
{
struct devlink *devlink;
@@ -420,6 +426,52 @@ struct ice_repr *ice_repr_create_vf(struct ice_vf *vf)
return repr;
}
+static int ice_repr_add_sf(struct ice_repr *repr)
+{
+ struct ice_dynamic_port *sf = repr->sf;
+ int err;
+
+ err = ice_devlink_create_sf_port(sf);
+ if (err)
+ return err;
+
+ SET_NETDEV_DEVLINK_PORT(repr->netdev, &sf->devlink_port);
+ err = ice_repr_reg_netdev(repr->netdev);
+ if (err)
+ goto err_netdev;
+
+ return 0;
+
+err_netdev:
+ ice_devlink_destroy_sf_port(sf);
+ return err;
+}
+
+/**
+ * ice_repr_create_sf - add representor for SF VSI
+ * @sf: SF to create port representor on
+ *
+ * Set correct representor type for SF and functions pointer.
+ *
+ * Return: created port representor on success, error otherwise
+ */
+struct ice_repr *ice_repr_create_sf(struct ice_dynamic_port *sf)
+{
+ struct ice_repr *repr = ice_repr_create(sf->vsi);
+
+ if (!repr)
+ return ERR_PTR(-ENOMEM);
+
+ repr->type = ICE_REPR_TYPE_SF;
+ repr->sf = sf;
+ repr->ops.add = ice_repr_add_sf;
+ repr->ops.rem = ice_repr_rem_sf;
+
+ ether_addr_copy(repr->parent_mac, sf->hw_addr);
+
+ return repr;
+}
+
struct ice_repr *ice_repr_get(struct ice_pf *pf, u32 id)
{
return xa_load(&pf->eswitch.reprs, id);
@@ -17,6 +17,7 @@ struct ice_repr_pcpu_stats {
enum ice_repr_type {
ICE_REPR_TYPE_VF,
+ ICE_REPR_TYPE_SF,
};
struct ice_repr {
@@ -28,7 +29,10 @@ struct ice_repr {
u32 id;
u8 parent_mac[ETH_ALEN];
enum ice_repr_type type;
- struct ice_vf *vf;
+ union {
+ struct ice_vf *vf;
+ struct ice_dynamic_port *sf;
+ };
struct {
int (*add)(struct ice_repr *repr);
void (*rem)(struct ice_repr *repr);
@@ -36,6 +40,7 @@ struct ice_repr {
};
struct ice_repr *ice_repr_create_vf(struct ice_vf *vf);
+struct ice_repr *ice_repr_create_sf(struct ice_dynamic_port *sf);
void ice_repr_destroy(struct ice_repr *repr);