brintos

brintos / linux-shallow public Read only

0
0
Text · 13.4 KiB · e923e17 Raw
500 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/****************************************************************************3 * Driver for Solarflare network controllers and boards4 * 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 it8 * under the terms of the GNU General Public License version 2 as published9 * 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	6424 25static int efx_ef100_rep_poll(struct napi_struct *napi, int weight);26 27static 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(&efv->list);33	efv->dflt.fw_id = MC_CMD_MAE_ACTION_RULE_INSERT_OUT_ACTION_RULE_ID_NULL;34	INIT_LIST_HEAD(&efv->dflt.acts.list);35	INIT_LIST_HEAD(&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 44static int efx_ef100_rep_open(struct net_device *net_dev)45{46	struct efx_rep *efv = netdev_priv(net_dev);47 48	netif_napi_add(net_dev, &efv->napi, efx_ef100_rep_poll);49	napi_enable(&efv->napi);50	return 0;51}52 53static int efx_ef100_rep_close(struct net_device *net_dev)54{55	struct efx_rep *efv = netdev_priv(net_dev);56 57	napi_disable(&efv->napi);58	netif_napi_del(&efv->napi);59	return 0;60}61 62static 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 the70	 * case of TX drops, where it will increment efx's tx_dropped.  The71	 * efv stats really only count attempted TX, not success/failure.72	 */73	atomic64_inc(&efv->stats.tx_packets);74	atomic64_add(skb->len, &efv->stats.tx_bytes);75	netif_tx_lock(efx->net_dev);76	rc = __ef100_hard_start_xmit(skb, efx, dev, efv);77	netif_tx_unlock(efx->net_dev);78	return rc;79}80 81static 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 95static 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, len, "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 112static 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(net_dev);116	struct efx_nic *efx = efv->parent;117 118	if (type == TC_SETUP_CLSFLOWER)119		return efx_tc_flower(efx, net_dev, type_data, efv);120	if (type == TC_SETUP_BLOCK)121		return efx_tc_setup_block(net_dev, efx, type_data, efv);122 123	return -EOPNOTSUPP;124}125 126static 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(&efv->stats.rx_packets);132	stats->tx_packets = atomic64_read(&efv->stats.tx_packets);133	stats->rx_bytes = atomic64_read(&efv->stats.rx_bytes);134	stats->tx_bytes = atomic64_read(&efv->stats.tx_bytes);135	stats->rx_dropped = atomic64_read(&efv->stats.rx_dropped);136	stats->tx_errors = atomic64_read(&efv->stats.tx_errors);137}138 139const 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 149static 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 155static u32 efx_ef100_rep_ethtool_get_msglevel(struct net_device *net_dev)156{157	struct efx_rep *efv = netdev_priv(net_dev);158 159	return efv->msg_enable;160}161 162static void efx_ef100_rep_ethtool_set_msglevel(struct net_device *net_dev,163					       u32 msg_enable)164{165	struct efx_rep *efv = netdev_priv(net_dev);166 167	efv->msg_enable = msg_enable;168}169 170static 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(net_dev);176 177	ring->rx_max_pending = U32_MAX;178	ring->rx_pending = efv->rx_pring_size;179}180 181static 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(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 195static 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 203static 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(-ENOMEM);213 214	efv = netdev_priv(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(&efx->vf_reps_lock);221	list_add_tail(&efv->list, &efx->vf_reps);222	spin_unlock_bh(&efx->vf_reps_lock);223	if (netif_running(efx->net_dev) && efx->state == STATE_NET_UP) {224		netif_device_attach(net_dev);225		netif_carrier_on(net_dev);226	} else {227		netif_carrier_off(net_dev);228		netif_tx_stop_all_queues(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->lltx = true;237 238	return efv;239fail1:240	free_netdev(net_dev);241	return ERR_PTR(rc);242}243 244static 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, efv->idx, &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 261static 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, &efv->dflt);266}267 268static 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(&efx->vf_reps_lock);274	list_del(&efv->list);275	spin_unlock_bh(&efx->vf_reps_lock);276	rtnl_unlock();277	synchronize_rcu();278	free_netdev(efv->net_dev);279}280 281int 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(efv)) {288		rc = PTR_ERR(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(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;312fail2:313	ef100_rep_unset_devlink_port(efv);314	efx_ef100_deconfigure_rep(efv);315fail1:316	efx_ef100_rep_destroy_netdev(efv);317	return rc;318}319 320void 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(rep_dev);329	ef100_rep_unset_devlink_port(efv);330	efx_ef100_deconfigure_rep(efv);331	efx_ef100_rep_destroy_netdev(efv);332}333 334void 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 346static 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 352bool 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 364bool 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 372void 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 385void efx_ef100_fini_reps(struct efx_nic *efx)386{387	struct efx_mae *mae = efx->mae;388 389	rhashtable_free_and_destroy(&mae->mports_ht, efx_mae_remove_mport,390				    NULL);391}392 393static 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(&head);403	/* Grab up to 'weight' pending SKBs */404	spin_lock_bh(&efv->rx_lock);405	read_index = efv->write_index;406	while (spent < weight && !list_empty(&efv->rx_list)) {407		skb = list_first_entry(&efv->rx_list, struct sk_buff, list);408		list_del(&skb->list);409		list_add_tail(&skb->list, &head);410		spent++;411	}412	spin_unlock_bh(&efv->rx_lock);413	/* Receive them */414	netif_receive_skb_list(&head);415	if (spent < weight)416		if (napi_complete_done(napi, spent)) {417			spin_lock_bh(&efv->rx_lock);418			efv->read_index = read_index;419			/* If write_index advanced while we were doing the420			 * RX, then storing our read_index won't re-prime the421			 * fake-interrupt.  In that case, we need to schedule422			 * NAPI again to consume the additional packet(s).423			 */424			need_resched = efv->write_index != read_index;425			spin_unlock_bh(&efv->rx_lock);426			if (need_resched)427				napi_schedule(&efv->napi);428		}429	return spent;430}431 432void efx_ef100_rep_rx_packet(struct efx_rep *efv, struct efx_rx_buffer *rx_buf)433{434	u8 *eh = efx_rx_buf_va(rx_buf);435	struct sk_buff *skb;436	bool primed;437 438	/* Don't allow too many queued SKBs to build up, as they consume439	 * 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(&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(efv->net_dev, rx_buf->len);451	if (!skb) {452		atomic64_inc(&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, rx_buf->len);461 462	skb_record_rx_queue(skb, 0); /* rep is single-queue */463 464	/* Move past the ethernet header */465	skb->protocol = eth_type_trans(skb, efv->net_dev);466 467	skb_checksum_none_assert(skb);468 469	atomic64_inc(&efv->stats.rx_packets);470	atomic64_add(rx_buf->len, &efv->stats.rx_bytes);471 472	/* Add it to the rx list */473	spin_lock_bh(&efv->rx_lock);474	primed = efv->read_index == efv->write_index;475	list_add_tail(&skb->list, &efv->rx_list);476	efv->write_index++;477	spin_unlock_bh(&efv->rx_lock);478	/* Trigger rx work */479	if (primed)480		napi_schedule(&efv->napi);481}482 483struct 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 netdev489	 * isn't freed after we drop the spinlock.490	 */491	spin_lock_bh(&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(&efx->vf_reps_lock);498	return out;499}500