xref: /openbmc/linux/drivers/net/ethernet/sfc/ef100_rep.c (revision 08135eecd07fbf48e819bdf3ec2a7717e76346ee)
1*08135eecSEdward Cree // SPDX-License-Identifier: GPL-2.0-only
2*08135eecSEdward Cree /****************************************************************************
3*08135eecSEdward Cree  * Driver for Solarflare network controllers and boards
4*08135eecSEdward Cree  * Copyright 2019 Solarflare Communications Inc.
5*08135eecSEdward Cree  * Copyright 2020-2022 Xilinx Inc.
6*08135eecSEdward Cree  *
7*08135eecSEdward Cree  * This program is free software; you can redistribute it and/or modify it
8*08135eecSEdward Cree  * under the terms of the GNU General Public License version 2 as published
9*08135eecSEdward Cree  * by the Free Software Foundation, incorporated herein by reference.
10*08135eecSEdward Cree  */
11*08135eecSEdward Cree 
12*08135eecSEdward Cree #include "ef100_rep.h"
13*08135eecSEdward Cree #include "ef100_nic.h"
14*08135eecSEdward Cree 
15*08135eecSEdward Cree static int efx_ef100_rep_init_struct(struct efx_nic *efx, struct efx_rep *efv)
16*08135eecSEdward Cree {
17*08135eecSEdward Cree 	efv->parent = efx;
18*08135eecSEdward Cree 	INIT_LIST_HEAD(&efv->list);
19*08135eecSEdward Cree 	efv->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE |
20*08135eecSEdward Cree 			  NETIF_MSG_LINK | NETIF_MSG_IFDOWN |
21*08135eecSEdward Cree 			  NETIF_MSG_IFUP | NETIF_MSG_RX_ERR |
22*08135eecSEdward Cree 			  NETIF_MSG_TX_ERR | NETIF_MSG_HW;
23*08135eecSEdward Cree 	return 0;
24*08135eecSEdward Cree }
25*08135eecSEdward Cree 
26*08135eecSEdward Cree static const struct net_device_ops efx_ef100_rep_netdev_ops = {
27*08135eecSEdward Cree };
28*08135eecSEdward Cree 
29*08135eecSEdward Cree static const struct ethtool_ops efx_ef100_rep_ethtool_ops = {
30*08135eecSEdward Cree };
31*08135eecSEdward Cree 
32*08135eecSEdward Cree static struct efx_rep *efx_ef100_rep_create_netdev(struct efx_nic *efx,
33*08135eecSEdward Cree 						   unsigned int i)
34*08135eecSEdward Cree {
35*08135eecSEdward Cree 	struct net_device *net_dev;
36*08135eecSEdward Cree 	struct efx_rep *efv;
37*08135eecSEdward Cree 	int rc;
38*08135eecSEdward Cree 
39*08135eecSEdward Cree 	net_dev = alloc_etherdev_mq(sizeof(*efv), 1);
40*08135eecSEdward Cree 	if (!net_dev)
41*08135eecSEdward Cree 		return ERR_PTR(-ENOMEM);
42*08135eecSEdward Cree 
43*08135eecSEdward Cree 	efv = netdev_priv(net_dev);
44*08135eecSEdward Cree 	rc = efx_ef100_rep_init_struct(efx, efv);
45*08135eecSEdward Cree 	if (rc)
46*08135eecSEdward Cree 		goto fail1;
47*08135eecSEdward Cree 	efv->net_dev = net_dev;
48*08135eecSEdward Cree 	rtnl_lock();
49*08135eecSEdward Cree 	spin_lock_bh(&efx->vf_reps_lock);
50*08135eecSEdward Cree 	list_add_tail(&efv->list, &efx->vf_reps);
51*08135eecSEdward Cree 	spin_unlock_bh(&efx->vf_reps_lock);
52*08135eecSEdward Cree 	netif_carrier_off(net_dev);
53*08135eecSEdward Cree 	netif_tx_stop_all_queues(net_dev);
54*08135eecSEdward Cree 	rtnl_unlock();
55*08135eecSEdward Cree 
56*08135eecSEdward Cree 	net_dev->netdev_ops = &efx_ef100_rep_netdev_ops;
57*08135eecSEdward Cree 	net_dev->ethtool_ops = &efx_ef100_rep_ethtool_ops;
58*08135eecSEdward Cree 	net_dev->min_mtu = EFX_MIN_MTU;
59*08135eecSEdward Cree 	net_dev->max_mtu = EFX_MAX_MTU;
60*08135eecSEdward Cree 	return efv;
61*08135eecSEdward Cree fail1:
62*08135eecSEdward Cree 	free_netdev(net_dev);
63*08135eecSEdward Cree 	return ERR_PTR(rc);
64*08135eecSEdward Cree }
65*08135eecSEdward Cree 
66*08135eecSEdward Cree static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv)
67*08135eecSEdward Cree {
68*08135eecSEdward Cree 	struct efx_nic *efx = efv->parent;
69*08135eecSEdward Cree 
70*08135eecSEdward Cree 	spin_lock_bh(&efx->vf_reps_lock);
71*08135eecSEdward Cree 	list_del(&efv->list);
72*08135eecSEdward Cree 	spin_unlock_bh(&efx->vf_reps_lock);
73*08135eecSEdward Cree 	free_netdev(efv->net_dev);
74*08135eecSEdward Cree }
75*08135eecSEdward Cree 
76*08135eecSEdward Cree int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i)
77*08135eecSEdward Cree {
78*08135eecSEdward Cree 	struct efx_rep *efv;
79*08135eecSEdward Cree 	int rc;
80*08135eecSEdward Cree 
81*08135eecSEdward Cree 	efv = efx_ef100_rep_create_netdev(efx, i);
82*08135eecSEdward Cree 	if (IS_ERR(efv)) {
83*08135eecSEdward Cree 		rc = PTR_ERR(efv);
84*08135eecSEdward Cree 		pci_err(efx->pci_dev,
85*08135eecSEdward Cree 			"Failed to create representor for VF %d, rc %d\n", i,
86*08135eecSEdward Cree 			rc);
87*08135eecSEdward Cree 		return rc;
88*08135eecSEdward Cree 	}
89*08135eecSEdward Cree 	rc = register_netdev(efv->net_dev);
90*08135eecSEdward Cree 	if (rc) {
91*08135eecSEdward Cree 		pci_err(efx->pci_dev,
92*08135eecSEdward Cree 			"Failed to register representor for VF %d, rc %d\n",
93*08135eecSEdward Cree 			i, rc);
94*08135eecSEdward Cree 		goto fail;
95*08135eecSEdward Cree 	}
96*08135eecSEdward Cree 	pci_dbg(efx->pci_dev, "Representor for VF %d is %s\n", i,
97*08135eecSEdward Cree 		efv->net_dev->name);
98*08135eecSEdward Cree 	return 0;
99*08135eecSEdward Cree fail:
100*08135eecSEdward Cree 	efx_ef100_rep_destroy_netdev(efv);
101*08135eecSEdward Cree 	return rc;
102*08135eecSEdward Cree }
103*08135eecSEdward Cree 
104*08135eecSEdward Cree void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv)
105*08135eecSEdward Cree {
106*08135eecSEdward Cree 	struct net_device *rep_dev;
107*08135eecSEdward Cree 
108*08135eecSEdward Cree 	rep_dev = efv->net_dev;
109*08135eecSEdward Cree 	if (!rep_dev)
110*08135eecSEdward Cree 		return;
111*08135eecSEdward Cree 	netif_dbg(efx, drv, rep_dev, "Removing VF representor\n");
112*08135eecSEdward Cree 	unregister_netdev(rep_dev);
113*08135eecSEdward Cree 	efx_ef100_rep_destroy_netdev(efv);
114*08135eecSEdward Cree }
115*08135eecSEdward Cree 
116*08135eecSEdward Cree void efx_ef100_fini_vfreps(struct efx_nic *efx)
117*08135eecSEdward Cree {
118*08135eecSEdward Cree 	struct ef100_nic_data *nic_data = efx->nic_data;
119*08135eecSEdward Cree 	struct efx_rep *efv, *next;
120*08135eecSEdward Cree 
121*08135eecSEdward Cree 	if (!nic_data->grp_mae)
122*08135eecSEdward Cree 		return;
123*08135eecSEdward Cree 
124*08135eecSEdward Cree 	list_for_each_entry_safe(efv, next, &efx->vf_reps, list)
125*08135eecSEdward Cree 		efx_ef100_vfrep_destroy(efx, efv);
126*08135eecSEdward Cree }
127