xref: /openbmc/linux/drivers/net/ethernet/sfc/ef100_rep.c (revision 5687eb3466a90a72d13f2aab20b4b801289dbda9)
108135eecSEdward Cree // SPDX-License-Identifier: GPL-2.0-only
208135eecSEdward Cree /****************************************************************************
308135eecSEdward Cree  * Driver for Solarflare network controllers and boards
408135eecSEdward Cree  * Copyright 2019 Solarflare Communications Inc.
508135eecSEdward Cree  * Copyright 2020-2022 Xilinx Inc.
608135eecSEdward Cree  *
708135eecSEdward Cree  * This program is free software; you can redistribute it and/or modify it
808135eecSEdward Cree  * under the terms of the GNU General Public License version 2 as published
908135eecSEdward Cree  * by the Free Software Foundation, incorporated herein by reference.
1008135eecSEdward Cree  */
1108135eecSEdward Cree 
1208135eecSEdward Cree #include "ef100_rep.h"
1308135eecSEdward Cree #include "ef100_nic.h"
1408135eecSEdward Cree 
15*5687eb34SEdward Cree #define EFX_EF100_REP_DRIVER	"efx_ef100_rep"
16*5687eb34SEdward Cree 
1708135eecSEdward Cree static int efx_ef100_rep_init_struct(struct efx_nic *efx, struct efx_rep *efv)
1808135eecSEdward Cree {
1908135eecSEdward Cree 	efv->parent = efx;
2008135eecSEdward Cree 	INIT_LIST_HEAD(&efv->list);
2108135eecSEdward Cree 	efv->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE |
2208135eecSEdward Cree 			  NETIF_MSG_LINK | NETIF_MSG_IFDOWN |
2308135eecSEdward Cree 			  NETIF_MSG_IFUP | NETIF_MSG_RX_ERR |
2408135eecSEdward Cree 			  NETIF_MSG_TX_ERR | NETIF_MSG_HW;
2508135eecSEdward Cree 	return 0;
2608135eecSEdward Cree }
2708135eecSEdward Cree 
2808135eecSEdward Cree static const struct net_device_ops efx_ef100_rep_netdev_ops = {
2908135eecSEdward Cree };
3008135eecSEdward Cree 
31*5687eb34SEdward Cree static void efx_ef100_rep_get_drvinfo(struct net_device *dev,
32*5687eb34SEdward Cree 				      struct ethtool_drvinfo *drvinfo)
33*5687eb34SEdward Cree {
34*5687eb34SEdward Cree 	strscpy(drvinfo->driver, EFX_EF100_REP_DRIVER, sizeof(drvinfo->driver));
35*5687eb34SEdward Cree }
36*5687eb34SEdward Cree 
37*5687eb34SEdward Cree static u32 efx_ef100_rep_ethtool_get_msglevel(struct net_device *net_dev)
38*5687eb34SEdward Cree {
39*5687eb34SEdward Cree 	struct efx_rep *efv = netdev_priv(net_dev);
40*5687eb34SEdward Cree 
41*5687eb34SEdward Cree 	return efv->msg_enable;
42*5687eb34SEdward Cree }
43*5687eb34SEdward Cree 
44*5687eb34SEdward Cree static void efx_ef100_rep_ethtool_set_msglevel(struct net_device *net_dev,
45*5687eb34SEdward Cree 					       u32 msg_enable)
46*5687eb34SEdward Cree {
47*5687eb34SEdward Cree 	struct efx_rep *efv = netdev_priv(net_dev);
48*5687eb34SEdward Cree 
49*5687eb34SEdward Cree 	efv->msg_enable = msg_enable;
50*5687eb34SEdward Cree }
51*5687eb34SEdward Cree 
5208135eecSEdward Cree static const struct ethtool_ops efx_ef100_rep_ethtool_ops = {
53*5687eb34SEdward Cree 	.get_drvinfo		= efx_ef100_rep_get_drvinfo,
54*5687eb34SEdward Cree 	.get_msglevel		= efx_ef100_rep_ethtool_get_msglevel,
55*5687eb34SEdward Cree 	.set_msglevel		= efx_ef100_rep_ethtool_set_msglevel,
5608135eecSEdward Cree };
5708135eecSEdward Cree 
5808135eecSEdward Cree static struct efx_rep *efx_ef100_rep_create_netdev(struct efx_nic *efx,
5908135eecSEdward Cree 						   unsigned int i)
6008135eecSEdward Cree {
6108135eecSEdward Cree 	struct net_device *net_dev;
6208135eecSEdward Cree 	struct efx_rep *efv;
6308135eecSEdward Cree 	int rc;
6408135eecSEdward Cree 
6508135eecSEdward Cree 	net_dev = alloc_etherdev_mq(sizeof(*efv), 1);
6608135eecSEdward Cree 	if (!net_dev)
6708135eecSEdward Cree 		return ERR_PTR(-ENOMEM);
6808135eecSEdward Cree 
6908135eecSEdward Cree 	efv = netdev_priv(net_dev);
7008135eecSEdward Cree 	rc = efx_ef100_rep_init_struct(efx, efv);
7108135eecSEdward Cree 	if (rc)
7208135eecSEdward Cree 		goto fail1;
7308135eecSEdward Cree 	efv->net_dev = net_dev;
7408135eecSEdward Cree 	rtnl_lock();
7508135eecSEdward Cree 	spin_lock_bh(&efx->vf_reps_lock);
7608135eecSEdward Cree 	list_add_tail(&efv->list, &efx->vf_reps);
7708135eecSEdward Cree 	spin_unlock_bh(&efx->vf_reps_lock);
7808135eecSEdward Cree 	netif_carrier_off(net_dev);
7908135eecSEdward Cree 	netif_tx_stop_all_queues(net_dev);
8008135eecSEdward Cree 	rtnl_unlock();
8108135eecSEdward Cree 
8208135eecSEdward Cree 	net_dev->netdev_ops = &efx_ef100_rep_netdev_ops;
8308135eecSEdward Cree 	net_dev->ethtool_ops = &efx_ef100_rep_ethtool_ops;
8408135eecSEdward Cree 	net_dev->min_mtu = EFX_MIN_MTU;
8508135eecSEdward Cree 	net_dev->max_mtu = EFX_MAX_MTU;
8608135eecSEdward Cree 	return efv;
8708135eecSEdward Cree fail1:
8808135eecSEdward Cree 	free_netdev(net_dev);
8908135eecSEdward Cree 	return ERR_PTR(rc);
9008135eecSEdward Cree }
9108135eecSEdward Cree 
9208135eecSEdward Cree static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv)
9308135eecSEdward Cree {
9408135eecSEdward Cree 	struct efx_nic *efx = efv->parent;
9508135eecSEdward Cree 
9608135eecSEdward Cree 	spin_lock_bh(&efx->vf_reps_lock);
9708135eecSEdward Cree 	list_del(&efv->list);
9808135eecSEdward Cree 	spin_unlock_bh(&efx->vf_reps_lock);
9908135eecSEdward Cree 	free_netdev(efv->net_dev);
10008135eecSEdward Cree }
10108135eecSEdward Cree 
10208135eecSEdward Cree int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i)
10308135eecSEdward Cree {
10408135eecSEdward Cree 	struct efx_rep *efv;
10508135eecSEdward Cree 	int rc;
10608135eecSEdward Cree 
10708135eecSEdward Cree 	efv = efx_ef100_rep_create_netdev(efx, i);
10808135eecSEdward Cree 	if (IS_ERR(efv)) {
10908135eecSEdward Cree 		rc = PTR_ERR(efv);
11008135eecSEdward Cree 		pci_err(efx->pci_dev,
11108135eecSEdward Cree 			"Failed to create representor for VF %d, rc %d\n", i,
11208135eecSEdward Cree 			rc);
11308135eecSEdward Cree 		return rc;
11408135eecSEdward Cree 	}
11508135eecSEdward Cree 	rc = register_netdev(efv->net_dev);
11608135eecSEdward Cree 	if (rc) {
11708135eecSEdward Cree 		pci_err(efx->pci_dev,
11808135eecSEdward Cree 			"Failed to register representor for VF %d, rc %d\n",
11908135eecSEdward Cree 			i, rc);
12008135eecSEdward Cree 		goto fail;
12108135eecSEdward Cree 	}
12208135eecSEdward Cree 	pci_dbg(efx->pci_dev, "Representor for VF %d is %s\n", i,
12308135eecSEdward Cree 		efv->net_dev->name);
12408135eecSEdward Cree 	return 0;
12508135eecSEdward Cree fail:
12608135eecSEdward Cree 	efx_ef100_rep_destroy_netdev(efv);
12708135eecSEdward Cree 	return rc;
12808135eecSEdward Cree }
12908135eecSEdward Cree 
13008135eecSEdward Cree void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv)
13108135eecSEdward Cree {
13208135eecSEdward Cree 	struct net_device *rep_dev;
13308135eecSEdward Cree 
13408135eecSEdward Cree 	rep_dev = efv->net_dev;
13508135eecSEdward Cree 	if (!rep_dev)
13608135eecSEdward Cree 		return;
13708135eecSEdward Cree 	netif_dbg(efx, drv, rep_dev, "Removing VF representor\n");
13808135eecSEdward Cree 	unregister_netdev(rep_dev);
13908135eecSEdward Cree 	efx_ef100_rep_destroy_netdev(efv);
14008135eecSEdward Cree }
14108135eecSEdward Cree 
14208135eecSEdward Cree void efx_ef100_fini_vfreps(struct efx_nic *efx)
14308135eecSEdward Cree {
14408135eecSEdward Cree 	struct ef100_nic_data *nic_data = efx->nic_data;
14508135eecSEdward Cree 	struct efx_rep *efv, *next;
14608135eecSEdward Cree 
14708135eecSEdward Cree 	if (!nic_data->grp_mae)
14808135eecSEdward Cree 		return;
14908135eecSEdward Cree 
15008135eecSEdward Cree 	list_for_each_entry_safe(efv, next, &efx->vf_reps, list)
15108135eecSEdward Cree 		efx_ef100_vfrep_destroy(efx, efv);
15208135eecSEdward Cree }
153