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 <linux/rhashtable.h> |
13 | #include "ef100_rep.h" |
14 | #include "ef100_netdev.h" |
15 | #include "ef100_nic.h" |
16 | #include "mae.h" |
17 | #include "rx_common.h" |
18 | #include "tc_bindings.h" |
19 | #include "efx_devlink.h" |
20 | |
21 | #define EFX_EF100_REP_DRIVER "efx_ef100_rep" |
22 | |
23 | #define EFX_REP_DEFAULT_PSEUDO_RING_SIZE 64 |
24 | |
25 | static int efx_ef100_rep_poll(struct napi_struct *napi, int weight); |
26 | |
27 | static int efx_ef100_rep_init_struct(struct efx_nic *efx, struct efx_rep *efv, |
28 | unsigned int i) |
29 | { |
30 | efv->parent = efx; |
31 | efv->idx = i; |
32 | INIT_LIST_HEAD(list: &efv->list); |
33 | efv->dflt.fw_id = MC_CMD_MAE_ACTION_RULE_INSERT_OUT_ACTION_RULE_ID_NULL; |
34 | INIT_LIST_HEAD(list: &efv->dflt.acts.list); |
35 | INIT_LIST_HEAD(list: &efv->rx_list); |
36 | spin_lock_init(&efv->rx_lock); |
37 | efv->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE | |
38 | NETIF_MSG_LINK | NETIF_MSG_IFDOWN | |
39 | NETIF_MSG_IFUP | NETIF_MSG_RX_ERR | |
40 | NETIF_MSG_TX_ERR | NETIF_MSG_HW; |
41 | return 0; |
42 | } |
43 | |
44 | static int efx_ef100_rep_open(struct net_device *net_dev) |
45 | { |
46 | struct efx_rep *efv = netdev_priv(dev: net_dev); |
47 | |
48 | netif_napi_add(dev: net_dev, napi: &efv->napi, poll: efx_ef100_rep_poll); |
49 | napi_enable(n: &efv->napi); |
50 | return 0; |
51 | } |
52 | |
53 | static int efx_ef100_rep_close(struct net_device *net_dev) |
54 | { |
55 | struct efx_rep *efv = netdev_priv(dev: net_dev); |
56 | |
57 | napi_disable(n: &efv->napi); |
58 | netif_napi_del(napi: &efv->napi); |
59 | return 0; |
60 | } |
61 | |
62 | static netdev_tx_t efx_ef100_rep_xmit(struct sk_buff *skb, |
63 | struct net_device *dev) |
64 | { |
65 | struct efx_rep *efv = netdev_priv(dev); |
66 | struct efx_nic *efx = efv->parent; |
67 | netdev_tx_t rc; |
68 | |
69 | /* __ef100_hard_start_xmit() will always return success even in the |
70 | * case of TX drops, where it will increment efx's tx_dropped. The |
71 | * efv stats really only count attempted TX, not success/failure. |
72 | */ |
73 | atomic64_inc(v: &efv->stats.tx_packets); |
74 | atomic64_add(i: skb->len, v: &efv->stats.tx_bytes); |
75 | netif_tx_lock(dev: efx->net_dev); |
76 | rc = __ef100_hard_start_xmit(skb, efx, net_dev: dev, efv); |
77 | netif_tx_unlock(dev: efx->net_dev); |
78 | return rc; |
79 | } |
80 | |
81 | static int efx_ef100_rep_get_port_parent_id(struct net_device *dev, |
82 | struct netdev_phys_item_id *ppid) |
83 | { |
84 | struct efx_rep *efv = netdev_priv(dev); |
85 | struct efx_nic *efx = efv->parent; |
86 | struct ef100_nic_data *nic_data; |
87 | |
88 | nic_data = efx->nic_data; |
89 | /* nic_data->port_id is a u8[] */ |
90 | ppid->id_len = sizeof(nic_data->port_id); |
91 | memcpy(ppid->id, nic_data->port_id, sizeof(nic_data->port_id)); |
92 | return 0; |
93 | } |
94 | |
95 | static int efx_ef100_rep_get_phys_port_name(struct net_device *dev, |
96 | char *buf, size_t len) |
97 | { |
98 | struct efx_rep *efv = netdev_priv(dev); |
99 | struct efx_nic *efx = efv->parent; |
100 | struct ef100_nic_data *nic_data; |
101 | int ret; |
102 | |
103 | nic_data = efx->nic_data; |
104 | ret = snprintf(buf, size: len, fmt: "p%upf%uvf%u" , efx->port_num, |
105 | nic_data->pf_index, efv->idx); |
106 | if (ret >= len) |
107 | return -EOPNOTSUPP; |
108 | |
109 | return 0; |
110 | } |
111 | |
112 | static int efx_ef100_rep_setup_tc(struct net_device *net_dev, |
113 | enum tc_setup_type type, void *type_data) |
114 | { |
115 | struct efx_rep *efv = netdev_priv(dev: net_dev); |
116 | struct efx_nic *efx = efv->parent; |
117 | |
118 | if (type == TC_SETUP_CLSFLOWER) |
119 | return efx_tc_flower(efx, net_dev, tc: type_data, efv); |
120 | if (type == TC_SETUP_BLOCK) |
121 | return efx_tc_setup_block(net_dev, efx, tcb: type_data, efv); |
122 | |
123 | return -EOPNOTSUPP; |
124 | } |
125 | |
126 | static void efx_ef100_rep_get_stats64(struct net_device *dev, |
127 | struct rtnl_link_stats64 *stats) |
128 | { |
129 | struct efx_rep *efv = netdev_priv(dev); |
130 | |
131 | stats->rx_packets = atomic64_read(v: &efv->stats.rx_packets); |
132 | stats->tx_packets = atomic64_read(v: &efv->stats.tx_packets); |
133 | stats->rx_bytes = atomic64_read(v: &efv->stats.rx_bytes); |
134 | stats->tx_bytes = atomic64_read(v: &efv->stats.tx_bytes); |
135 | stats->rx_dropped = atomic64_read(v: &efv->stats.rx_dropped); |
136 | stats->tx_errors = atomic64_read(v: &efv->stats.tx_errors); |
137 | } |
138 | |
139 | const struct net_device_ops efx_ef100_rep_netdev_ops = { |
140 | .ndo_open = efx_ef100_rep_open, |
141 | .ndo_stop = efx_ef100_rep_close, |
142 | .ndo_start_xmit = efx_ef100_rep_xmit, |
143 | .ndo_get_port_parent_id = efx_ef100_rep_get_port_parent_id, |
144 | .ndo_get_phys_port_name = efx_ef100_rep_get_phys_port_name, |
145 | .ndo_get_stats64 = efx_ef100_rep_get_stats64, |
146 | .ndo_setup_tc = efx_ef100_rep_setup_tc, |
147 | }; |
148 | |
149 | static void efx_ef100_rep_get_drvinfo(struct net_device *dev, |
150 | struct ethtool_drvinfo *drvinfo) |
151 | { |
152 | strscpy(drvinfo->driver, EFX_EF100_REP_DRIVER, sizeof(drvinfo->driver)); |
153 | } |
154 | |
155 | static u32 efx_ef100_rep_ethtool_get_msglevel(struct net_device *net_dev) |
156 | { |
157 | struct efx_rep *efv = netdev_priv(dev: net_dev); |
158 | |
159 | return efv->msg_enable; |
160 | } |
161 | |
162 | static void efx_ef100_rep_ethtool_set_msglevel(struct net_device *net_dev, |
163 | u32 msg_enable) |
164 | { |
165 | struct efx_rep *efv = netdev_priv(dev: net_dev); |
166 | |
167 | efv->msg_enable = msg_enable; |
168 | } |
169 | |
170 | static void efx_ef100_rep_ethtool_get_ringparam(struct net_device *net_dev, |
171 | struct ethtool_ringparam *ring, |
172 | struct kernel_ethtool_ringparam *kring, |
173 | struct netlink_ext_ack *ext_ack) |
174 | { |
175 | struct efx_rep *efv = netdev_priv(dev: net_dev); |
176 | |
177 | ring->rx_max_pending = U32_MAX; |
178 | ring->rx_pending = efv->rx_pring_size; |
179 | } |
180 | |
181 | static int efx_ef100_rep_ethtool_set_ringparam(struct net_device *net_dev, |
182 | struct ethtool_ringparam *ring, |
183 | struct kernel_ethtool_ringparam *kring, |
184 | struct netlink_ext_ack *ext_ack) |
185 | { |
186 | struct efx_rep *efv = netdev_priv(dev: net_dev); |
187 | |
188 | if (ring->rx_mini_pending || ring->rx_jumbo_pending || ring->tx_pending) |
189 | return -EINVAL; |
190 | |
191 | efv->rx_pring_size = ring->rx_pending; |
192 | return 0; |
193 | } |
194 | |
195 | static const struct ethtool_ops efx_ef100_rep_ethtool_ops = { |
196 | .get_drvinfo = efx_ef100_rep_get_drvinfo, |
197 | .get_msglevel = efx_ef100_rep_ethtool_get_msglevel, |
198 | .set_msglevel = efx_ef100_rep_ethtool_set_msglevel, |
199 | .get_ringparam = efx_ef100_rep_ethtool_get_ringparam, |
200 | .set_ringparam = efx_ef100_rep_ethtool_set_ringparam, |
201 | }; |
202 | |
203 | static struct efx_rep *efx_ef100_rep_create_netdev(struct efx_nic *efx, |
204 | unsigned int i) |
205 | { |
206 | struct net_device *net_dev; |
207 | struct efx_rep *efv; |
208 | int rc; |
209 | |
210 | net_dev = alloc_etherdev_mq(sizeof(*efv), 1); |
211 | if (!net_dev) |
212 | return ERR_PTR(error: -ENOMEM); |
213 | |
214 | efv = netdev_priv(dev: net_dev); |
215 | rc = efx_ef100_rep_init_struct(efx, efv, i); |
216 | if (rc) |
217 | goto fail1; |
218 | efv->net_dev = net_dev; |
219 | rtnl_lock(); |
220 | spin_lock_bh(lock: &efx->vf_reps_lock); |
221 | list_add_tail(new: &efv->list, head: &efx->vf_reps); |
222 | spin_unlock_bh(lock: &efx->vf_reps_lock); |
223 | if (netif_running(dev: efx->net_dev) && efx->state == STATE_NET_UP) { |
224 | netif_device_attach(dev: net_dev); |
225 | netif_carrier_on(dev: net_dev); |
226 | } else { |
227 | netif_carrier_off(dev: net_dev); |
228 | netif_tx_stop_all_queues(dev: net_dev); |
229 | } |
230 | rtnl_unlock(); |
231 | |
232 | net_dev->netdev_ops = &efx_ef100_rep_netdev_ops; |
233 | net_dev->ethtool_ops = &efx_ef100_rep_ethtool_ops; |
234 | net_dev->min_mtu = EFX_MIN_MTU; |
235 | net_dev->max_mtu = EFX_MAX_MTU; |
236 | net_dev->features |= NETIF_F_LLTX; |
237 | net_dev->hw_features |= NETIF_F_LLTX; |
238 | return efv; |
239 | fail1: |
240 | free_netdev(dev: net_dev); |
241 | return ERR_PTR(error: rc); |
242 | } |
243 | |
244 | static int efx_ef100_configure_rep(struct efx_rep *efv) |
245 | { |
246 | struct efx_nic *efx = efv->parent; |
247 | int rc; |
248 | |
249 | efv->rx_pring_size = EFX_REP_DEFAULT_PSEUDO_RING_SIZE; |
250 | /* Look up actual mport ID */ |
251 | rc = efx_mae_lookup_mport(efx, vf: efv->idx, id: &efv->mport); |
252 | if (rc) |
253 | return rc; |
254 | pci_dbg(efx->pci_dev, "VF %u has mport ID %#x\n" , efv->idx, efv->mport); |
255 | /* mport label should fit in 16 bits */ |
256 | WARN_ON(efv->mport >> 16); |
257 | |
258 | return efx_tc_configure_default_rule_rep(efv); |
259 | } |
260 | |
261 | static void efx_ef100_deconfigure_rep(struct efx_rep *efv) |
262 | { |
263 | struct efx_nic *efx = efv->parent; |
264 | |
265 | efx_tc_deconfigure_default_rule(efx, rule: &efv->dflt); |
266 | } |
267 | |
268 | static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv) |
269 | { |
270 | struct efx_nic *efx = efv->parent; |
271 | |
272 | rtnl_lock(); |
273 | spin_lock_bh(lock: &efx->vf_reps_lock); |
274 | list_del(entry: &efv->list); |
275 | spin_unlock_bh(lock: &efx->vf_reps_lock); |
276 | rtnl_unlock(); |
277 | synchronize_rcu(); |
278 | free_netdev(dev: efv->net_dev); |
279 | } |
280 | |
281 | int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i) |
282 | { |
283 | struct efx_rep *efv; |
284 | int rc; |
285 | |
286 | efv = efx_ef100_rep_create_netdev(efx, i); |
287 | if (IS_ERR(ptr: efv)) { |
288 | rc = PTR_ERR(ptr: efv); |
289 | pci_err(efx->pci_dev, |
290 | "Failed to create representor for VF %d, rc %d\n" , i, |
291 | rc); |
292 | return rc; |
293 | } |
294 | rc = efx_ef100_configure_rep(efv); |
295 | if (rc) { |
296 | pci_err(efx->pci_dev, |
297 | "Failed to configure representor for VF %d, rc %d\n" , |
298 | i, rc); |
299 | goto fail1; |
300 | } |
301 | ef100_rep_set_devlink_port(efv); |
302 | rc = register_netdev(dev: efv->net_dev); |
303 | if (rc) { |
304 | pci_err(efx->pci_dev, |
305 | "Failed to register representor for VF %d, rc %d\n" , |
306 | i, rc); |
307 | goto fail2; |
308 | } |
309 | pci_dbg(efx->pci_dev, "Representor for VF %d is %s\n" , i, |
310 | efv->net_dev->name); |
311 | return 0; |
312 | fail2: |
313 | ef100_rep_unset_devlink_port(efv); |
314 | efx_ef100_deconfigure_rep(efv); |
315 | fail1: |
316 | efx_ef100_rep_destroy_netdev(efv); |
317 | return rc; |
318 | } |
319 | |
320 | void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv) |
321 | { |
322 | struct net_device *rep_dev; |
323 | |
324 | rep_dev = efv->net_dev; |
325 | if (!rep_dev) |
326 | return; |
327 | netif_dbg(efx, drv, rep_dev, "Removing VF representor\n" ); |
328 | unregister_netdev(dev: rep_dev); |
329 | ef100_rep_unset_devlink_port(efv); |
330 | efx_ef100_deconfigure_rep(efv); |
331 | efx_ef100_rep_destroy_netdev(efv); |
332 | } |
333 | |
334 | void efx_ef100_fini_vfreps(struct efx_nic *efx) |
335 | { |
336 | struct ef100_nic_data *nic_data = efx->nic_data; |
337 | struct efx_rep *efv, *next; |
338 | |
339 | if (!nic_data->grp_mae) |
340 | return; |
341 | |
342 | list_for_each_entry_safe(efv, next, &efx->vf_reps, list) |
343 | efx_ef100_vfrep_destroy(efx, efv); |
344 | } |
345 | |
346 | static bool ef100_mport_is_pcie_vnic(struct mae_mport_desc *mport_desc) |
347 | { |
348 | return mport_desc->mport_type == MAE_MPORT_DESC_MPORT_TYPE_VNIC && |
349 | mport_desc->vnic_client_type == MAE_MPORT_DESC_VNIC_CLIENT_TYPE_FUNCTION; |
350 | } |
351 | |
352 | bool ef100_mport_on_local_intf(struct efx_nic *efx, |
353 | struct mae_mport_desc *mport_desc) |
354 | { |
355 | struct ef100_nic_data *nic_data = efx->nic_data; |
356 | bool pcie_func; |
357 | |
358 | pcie_func = ef100_mport_is_pcie_vnic(mport_desc); |
359 | |
360 | return nic_data->have_local_intf && pcie_func && |
361 | mport_desc->interface_idx == nic_data->local_mae_intf; |
362 | } |
363 | |
364 | bool ef100_mport_is_vf(struct mae_mport_desc *mport_desc) |
365 | { |
366 | bool pcie_func; |
367 | |
368 | pcie_func = ef100_mport_is_pcie_vnic(mport_desc); |
369 | return pcie_func && (mport_desc->vf_idx != MAE_MPORT_DESC_VF_IDX_NULL); |
370 | } |
371 | |
372 | void efx_ef100_init_reps(struct efx_nic *efx) |
373 | { |
374 | struct ef100_nic_data *nic_data = efx->nic_data; |
375 | int rc; |
376 | |
377 | nic_data->have_local_intf = false; |
378 | rc = efx_mae_enumerate_mports(efx); |
379 | if (rc) |
380 | pci_warn(efx->pci_dev, |
381 | "Could not enumerate mports (rc=%d), are we admin?" , |
382 | rc); |
383 | } |
384 | |
385 | void efx_ef100_fini_reps(struct efx_nic *efx) |
386 | { |
387 | struct efx_mae *mae = efx->mae; |
388 | |
389 | rhashtable_free_and_destroy(ht: &mae->mports_ht, free_fn: efx_mae_remove_mport, |
390 | NULL); |
391 | } |
392 | |
393 | static int efx_ef100_rep_poll(struct napi_struct *napi, int weight) |
394 | { |
395 | struct efx_rep *efv = container_of(napi, struct efx_rep, napi); |
396 | unsigned int read_index; |
397 | struct list_head head; |
398 | struct sk_buff *skb; |
399 | bool need_resched; |
400 | int spent = 0; |
401 | |
402 | INIT_LIST_HEAD(list: &head); |
403 | /* Grab up to 'weight' pending SKBs */ |
404 | spin_lock_bh(lock: &efv->rx_lock); |
405 | read_index = efv->write_index; |
406 | while (spent < weight && !list_empty(head: &efv->rx_list)) { |
407 | skb = list_first_entry(&efv->rx_list, struct sk_buff, list); |
408 | list_del(entry: &skb->list); |
409 | list_add_tail(new: &skb->list, head: &head); |
410 | spent++; |
411 | } |
412 | spin_unlock_bh(lock: &efv->rx_lock); |
413 | /* Receive them */ |
414 | netif_receive_skb_list(head: &head); |
415 | if (spent < weight) |
416 | if (napi_complete_done(n: napi, work_done: spent)) { |
417 | spin_lock_bh(lock: &efv->rx_lock); |
418 | efv->read_index = read_index; |
419 | /* If write_index advanced while we were doing the |
420 | * RX, then storing our read_index won't re-prime the |
421 | * fake-interrupt. In that case, we need to schedule |
422 | * NAPI again to consume the additional packet(s). |
423 | */ |
424 | need_resched = efv->write_index != read_index; |
425 | spin_unlock_bh(lock: &efv->rx_lock); |
426 | if (need_resched) |
427 | napi_schedule(n: &efv->napi); |
428 | } |
429 | return spent; |
430 | } |
431 | |
432 | void efx_ef100_rep_rx_packet(struct efx_rep *efv, struct efx_rx_buffer *rx_buf) |
433 | { |
434 | u8 *eh = efx_rx_buf_va(buf: rx_buf); |
435 | struct sk_buff *skb; |
436 | bool primed; |
437 | |
438 | /* Don't allow too many queued SKBs to build up, as they consume |
439 | * GFP_ATOMIC memory. If we overrun, just start dropping. |
440 | */ |
441 | if (efv->write_index - READ_ONCE(efv->read_index) > efv->rx_pring_size) { |
442 | atomic64_inc(v: &efv->stats.rx_dropped); |
443 | if (net_ratelimit()) |
444 | netif_dbg(efv->parent, rx_err, efv->net_dev, |
445 | "nodesc-dropped packet of length %u\n" , |
446 | rx_buf->len); |
447 | return; |
448 | } |
449 | |
450 | skb = netdev_alloc_skb(dev: efv->net_dev, length: rx_buf->len); |
451 | if (!skb) { |
452 | atomic64_inc(v: &efv->stats.rx_dropped); |
453 | if (net_ratelimit()) |
454 | netif_dbg(efv->parent, rx_err, efv->net_dev, |
455 | "noskb-dropped packet of length %u\n" , |
456 | rx_buf->len); |
457 | return; |
458 | } |
459 | memcpy(skb->data, eh, rx_buf->len); |
460 | __skb_put(skb, len: rx_buf->len); |
461 | |
462 | skb_record_rx_queue(skb, rx_queue: 0); /* rep is single-queue */ |
463 | |
464 | /* Move past the ethernet header */ |
465 | skb->protocol = eth_type_trans(skb, dev: efv->net_dev); |
466 | |
467 | skb_checksum_none_assert(skb); |
468 | |
469 | atomic64_inc(v: &efv->stats.rx_packets); |
470 | atomic64_add(i: rx_buf->len, v: &efv->stats.rx_bytes); |
471 | |
472 | /* Add it to the rx list */ |
473 | spin_lock_bh(lock: &efv->rx_lock); |
474 | primed = efv->read_index == efv->write_index; |
475 | list_add_tail(new: &skb->list, head: &efv->rx_list); |
476 | efv->write_index++; |
477 | spin_unlock_bh(lock: &efv->rx_lock); |
478 | /* Trigger rx work */ |
479 | if (primed) |
480 | napi_schedule(n: &efv->napi); |
481 | } |
482 | |
483 | struct efx_rep *efx_ef100_find_rep_by_mport(struct efx_nic *efx, u16 mport) |
484 | { |
485 | struct efx_rep *efv, *out = NULL; |
486 | |
487 | /* spinlock guards against list mutation while we're walking it; |
488 | * but caller must also hold rcu_read_lock() to ensure the netdev |
489 | * isn't freed after we drop the spinlock. |
490 | */ |
491 | spin_lock_bh(lock: &efx->vf_reps_lock); |
492 | list_for_each_entry(efv, &efx->vf_reps, list) |
493 | if (efv->mport == mport) { |
494 | out = efv; |
495 | break; |
496 | } |
497 | spin_unlock_bh(lock: &efx->vf_reps_lock); |
498 | return out; |
499 | } |
500 | |