xref: /linux/drivers/net/ethernet/sfc/ef100_rep.c (revision 6ecf206d602fafd077811b6033c183deb0c0a9c8)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3  * Driver for Solarflare network controllers and boards
4  * Copyright 2019 Solarflare Communications Inc.
5  * Copyright 2020-2022 Xilinx Inc.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 as published
9  * by the Free Software Foundation, incorporated herein by reference.
10  */
11 
12 #include "ef100_rep.h"
13 #include "ef100_netdev.h"
14 #include "ef100_nic.h"
15 #include "mae.h"
16 
17 #define EFX_EF100_REP_DRIVER	"efx_ef100_rep"
18 
19 static int efx_ef100_rep_init_struct(struct efx_nic *efx, struct efx_rep *efv,
20 				     unsigned int i)
21 {
22 	efv->parent = efx;
23 	efv->idx = i;
24 	INIT_LIST_HEAD(&efv->list);
25 	efv->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE |
26 			  NETIF_MSG_LINK | NETIF_MSG_IFDOWN |
27 			  NETIF_MSG_IFUP | NETIF_MSG_RX_ERR |
28 			  NETIF_MSG_TX_ERR | NETIF_MSG_HW;
29 	return 0;
30 }
31 
32 static netdev_tx_t efx_ef100_rep_xmit(struct sk_buff *skb,
33 				      struct net_device *dev)
34 {
35 	struct efx_rep *efv = netdev_priv(dev);
36 	struct efx_nic *efx = efv->parent;
37 	netdev_tx_t rc;
38 
39 	/* __ef100_hard_start_xmit() will always return success even in the
40 	 * case of TX drops, where it will increment efx's tx_dropped.  The
41 	 * efv stats really only count attempted TX, not success/failure.
42 	 */
43 	atomic64_inc(&efv->stats.tx_packets);
44 	atomic64_add(skb->len, &efv->stats.tx_bytes);
45 	netif_tx_lock(efx->net_dev);
46 	rc = __ef100_hard_start_xmit(skb, efx, dev, efv);
47 	netif_tx_unlock(efx->net_dev);
48 	return rc;
49 }
50 
51 static int efx_ef100_rep_get_port_parent_id(struct net_device *dev,
52 					    struct netdev_phys_item_id *ppid)
53 {
54 	struct efx_rep *efv = netdev_priv(dev);
55 	struct efx_nic *efx = efv->parent;
56 	struct ef100_nic_data *nic_data;
57 
58 	nic_data = efx->nic_data;
59 	/* nic_data->port_id is a u8[] */
60 	ppid->id_len = sizeof(nic_data->port_id);
61 	memcpy(ppid->id, nic_data->port_id, sizeof(nic_data->port_id));
62 	return 0;
63 }
64 
65 static int efx_ef100_rep_get_phys_port_name(struct net_device *dev,
66 					    char *buf, size_t len)
67 {
68 	struct efx_rep *efv = netdev_priv(dev);
69 	struct efx_nic *efx = efv->parent;
70 	struct ef100_nic_data *nic_data;
71 	int ret;
72 
73 	nic_data = efx->nic_data;
74 	ret = snprintf(buf, len, "p%upf%uvf%u", efx->port_num,
75 		       nic_data->pf_index, efv->idx);
76 	if (ret >= len)
77 		return -EOPNOTSUPP;
78 
79 	return 0;
80 }
81 
82 static const struct net_device_ops efx_ef100_rep_netdev_ops = {
83 	.ndo_start_xmit		= efx_ef100_rep_xmit,
84 	.ndo_get_port_parent_id	= efx_ef100_rep_get_port_parent_id,
85 	.ndo_get_phys_port_name	= efx_ef100_rep_get_phys_port_name,
86 };
87 
88 static void efx_ef100_rep_get_drvinfo(struct net_device *dev,
89 				      struct ethtool_drvinfo *drvinfo)
90 {
91 	strscpy(drvinfo->driver, EFX_EF100_REP_DRIVER, sizeof(drvinfo->driver));
92 }
93 
94 static u32 efx_ef100_rep_ethtool_get_msglevel(struct net_device *net_dev)
95 {
96 	struct efx_rep *efv = netdev_priv(net_dev);
97 
98 	return efv->msg_enable;
99 }
100 
101 static void efx_ef100_rep_ethtool_set_msglevel(struct net_device *net_dev,
102 					       u32 msg_enable)
103 {
104 	struct efx_rep *efv = netdev_priv(net_dev);
105 
106 	efv->msg_enable = msg_enable;
107 }
108 
109 static const struct ethtool_ops efx_ef100_rep_ethtool_ops = {
110 	.get_drvinfo		= efx_ef100_rep_get_drvinfo,
111 	.get_msglevel		= efx_ef100_rep_ethtool_get_msglevel,
112 	.set_msglevel		= efx_ef100_rep_ethtool_set_msglevel,
113 };
114 
115 static struct efx_rep *efx_ef100_rep_create_netdev(struct efx_nic *efx,
116 						   unsigned int i)
117 {
118 	struct net_device *net_dev;
119 	struct efx_rep *efv;
120 	int rc;
121 
122 	net_dev = alloc_etherdev_mq(sizeof(*efv), 1);
123 	if (!net_dev)
124 		return ERR_PTR(-ENOMEM);
125 
126 	efv = netdev_priv(net_dev);
127 	rc = efx_ef100_rep_init_struct(efx, efv, i);
128 	if (rc)
129 		goto fail1;
130 	efv->net_dev = net_dev;
131 	rtnl_lock();
132 	spin_lock_bh(&efx->vf_reps_lock);
133 	list_add_tail(&efv->list, &efx->vf_reps);
134 	spin_unlock_bh(&efx->vf_reps_lock);
135 	if (netif_running(efx->net_dev) && efx->state == STATE_NET_UP) {
136 		netif_device_attach(net_dev);
137 		netif_carrier_on(net_dev);
138 	} else {
139 		netif_carrier_off(net_dev);
140 		netif_tx_stop_all_queues(net_dev);
141 	}
142 	rtnl_unlock();
143 
144 	net_dev->netdev_ops = &efx_ef100_rep_netdev_ops;
145 	net_dev->ethtool_ops = &efx_ef100_rep_ethtool_ops;
146 	net_dev->min_mtu = EFX_MIN_MTU;
147 	net_dev->max_mtu = EFX_MAX_MTU;
148 	net_dev->features |= NETIF_F_LLTX;
149 	net_dev->hw_features |= NETIF_F_LLTX;
150 	return efv;
151 fail1:
152 	free_netdev(net_dev);
153 	return ERR_PTR(rc);
154 }
155 
156 static int efx_ef100_configure_rep(struct efx_rep *efv)
157 {
158 	struct efx_nic *efx = efv->parent;
159 	u32 selector;
160 	int rc;
161 
162 	/* Construct mport selector for corresponding VF */
163 	efx_mae_mport_vf(efx, efv->idx, &selector);
164 	/* Look up actual mport ID */
165 	rc = efx_mae_lookup_mport(efx, selector, &efv->mport);
166 	if (rc)
167 		return rc;
168 	pci_dbg(efx->pci_dev, "VF %u has mport ID %#x\n", efv->idx, efv->mport);
169 	/* mport label should fit in 16 bits */
170 	WARN_ON(efv->mport >> 16);
171 
172 	return 0;
173 }
174 
175 static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv)
176 {
177 	struct efx_nic *efx = efv->parent;
178 
179 	rtnl_lock();
180 	spin_lock_bh(&efx->vf_reps_lock);
181 	list_del(&efv->list);
182 	spin_unlock_bh(&efx->vf_reps_lock);
183 	rtnl_unlock();
184 	free_netdev(efv->net_dev);
185 }
186 
187 int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i)
188 {
189 	struct efx_rep *efv;
190 	int rc;
191 
192 	efv = efx_ef100_rep_create_netdev(efx, i);
193 	if (IS_ERR(efv)) {
194 		rc = PTR_ERR(efv);
195 		pci_err(efx->pci_dev,
196 			"Failed to create representor for VF %d, rc %d\n", i,
197 			rc);
198 		return rc;
199 	}
200 	rc = efx_ef100_configure_rep(efv);
201 	if (rc) {
202 		pci_err(efx->pci_dev,
203 			"Failed to configure representor for VF %d, rc %d\n",
204 			i, rc);
205 		goto fail;
206 	}
207 	rc = register_netdev(efv->net_dev);
208 	if (rc) {
209 		pci_err(efx->pci_dev,
210 			"Failed to register representor for VF %d, rc %d\n",
211 			i, rc);
212 		goto fail;
213 	}
214 	pci_dbg(efx->pci_dev, "Representor for VF %d is %s\n", i,
215 		efv->net_dev->name);
216 	return 0;
217 fail:
218 	efx_ef100_rep_destroy_netdev(efv);
219 	return rc;
220 }
221 
222 void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv)
223 {
224 	struct net_device *rep_dev;
225 
226 	rep_dev = efv->net_dev;
227 	if (!rep_dev)
228 		return;
229 	netif_dbg(efx, drv, rep_dev, "Removing VF representor\n");
230 	unregister_netdev(rep_dev);
231 	efx_ef100_rep_destroy_netdev(efv);
232 }
233 
234 void efx_ef100_fini_vfreps(struct efx_nic *efx)
235 {
236 	struct ef100_nic_data *nic_data = efx->nic_data;
237 	struct efx_rep *efv, *next;
238 
239 	if (!nic_data->grp_mae)
240 		return;
241 
242 	list_for_each_entry_safe(efv, next, &efx->vf_reps, list)
243 		efx_ef100_vfrep_destroy(efx, efv);
244 }
245