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 
155687eb34SEdward Cree #define EFX_EF100_REP_DRIVER	"efx_ef100_rep"
165687eb34SEdward Cree 
17*e1479556SEdward Cree static int efx_ef100_rep_init_struct(struct efx_nic *efx, struct efx_rep *efv,
18*e1479556SEdward Cree 				     unsigned int i)
1908135eecSEdward Cree {
2008135eecSEdward Cree 	efv->parent = efx;
21*e1479556SEdward Cree 	efv->idx = i;
2208135eecSEdward Cree 	INIT_LIST_HEAD(&efv->list);
2308135eecSEdward Cree 	efv->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE |
2408135eecSEdward Cree 			  NETIF_MSG_LINK | NETIF_MSG_IFDOWN |
2508135eecSEdward Cree 			  NETIF_MSG_IFUP | NETIF_MSG_RX_ERR |
2608135eecSEdward Cree 			  NETIF_MSG_TX_ERR | NETIF_MSG_HW;
2708135eecSEdward Cree 	return 0;
2808135eecSEdward Cree }
2908135eecSEdward Cree 
30*e1479556SEdward Cree static int efx_ef100_rep_get_port_parent_id(struct net_device *dev,
31*e1479556SEdward Cree 					    struct netdev_phys_item_id *ppid)
32*e1479556SEdward Cree {
33*e1479556SEdward Cree 	struct efx_rep *efv = netdev_priv(dev);
34*e1479556SEdward Cree 	struct efx_nic *efx = efv->parent;
35*e1479556SEdward Cree 	struct ef100_nic_data *nic_data;
36*e1479556SEdward Cree 
37*e1479556SEdward Cree 	nic_data = efx->nic_data;
38*e1479556SEdward Cree 	/* nic_data->port_id is a u8[] */
39*e1479556SEdward Cree 	ppid->id_len = sizeof(nic_data->port_id);
40*e1479556SEdward Cree 	memcpy(ppid->id, nic_data->port_id, sizeof(nic_data->port_id));
41*e1479556SEdward Cree 	return 0;
42*e1479556SEdward Cree }
43*e1479556SEdward Cree 
44*e1479556SEdward Cree static int efx_ef100_rep_get_phys_port_name(struct net_device *dev,
45*e1479556SEdward Cree 					    char *buf, size_t len)
46*e1479556SEdward Cree {
47*e1479556SEdward Cree 	struct efx_rep *efv = netdev_priv(dev);
48*e1479556SEdward Cree 	struct efx_nic *efx = efv->parent;
49*e1479556SEdward Cree 	struct ef100_nic_data *nic_data;
50*e1479556SEdward Cree 	int ret;
51*e1479556SEdward Cree 
52*e1479556SEdward Cree 	nic_data = efx->nic_data;
53*e1479556SEdward Cree 	ret = snprintf(buf, len, "p%upf%uvf%u", efx->port_num,
54*e1479556SEdward Cree 		       nic_data->pf_index, efv->idx);
55*e1479556SEdward Cree 	if (ret >= len)
56*e1479556SEdward Cree 		return -EOPNOTSUPP;
57*e1479556SEdward Cree 
58*e1479556SEdward Cree 	return 0;
59*e1479556SEdward Cree }
60*e1479556SEdward Cree 
6108135eecSEdward Cree static const struct net_device_ops efx_ef100_rep_netdev_ops = {
62*e1479556SEdward Cree 	.ndo_get_port_parent_id	= efx_ef100_rep_get_port_parent_id,
63*e1479556SEdward Cree 	.ndo_get_phys_port_name	= efx_ef100_rep_get_phys_port_name,
6408135eecSEdward Cree };
6508135eecSEdward Cree 
665687eb34SEdward Cree static void efx_ef100_rep_get_drvinfo(struct net_device *dev,
675687eb34SEdward Cree 				      struct ethtool_drvinfo *drvinfo)
685687eb34SEdward Cree {
695687eb34SEdward Cree 	strscpy(drvinfo->driver, EFX_EF100_REP_DRIVER, sizeof(drvinfo->driver));
705687eb34SEdward Cree }
715687eb34SEdward Cree 
725687eb34SEdward Cree static u32 efx_ef100_rep_ethtool_get_msglevel(struct net_device *net_dev)
735687eb34SEdward Cree {
745687eb34SEdward Cree 	struct efx_rep *efv = netdev_priv(net_dev);
755687eb34SEdward Cree 
765687eb34SEdward Cree 	return efv->msg_enable;
775687eb34SEdward Cree }
785687eb34SEdward Cree 
795687eb34SEdward Cree static void efx_ef100_rep_ethtool_set_msglevel(struct net_device *net_dev,
805687eb34SEdward Cree 					       u32 msg_enable)
815687eb34SEdward Cree {
825687eb34SEdward Cree 	struct efx_rep *efv = netdev_priv(net_dev);
835687eb34SEdward Cree 
845687eb34SEdward Cree 	efv->msg_enable = msg_enable;
855687eb34SEdward Cree }
865687eb34SEdward Cree 
8708135eecSEdward Cree static const struct ethtool_ops efx_ef100_rep_ethtool_ops = {
885687eb34SEdward Cree 	.get_drvinfo		= efx_ef100_rep_get_drvinfo,
895687eb34SEdward Cree 	.get_msglevel		= efx_ef100_rep_ethtool_get_msglevel,
905687eb34SEdward Cree 	.set_msglevel		= efx_ef100_rep_ethtool_set_msglevel,
9108135eecSEdward Cree };
9208135eecSEdward Cree 
9308135eecSEdward Cree static struct efx_rep *efx_ef100_rep_create_netdev(struct efx_nic *efx,
9408135eecSEdward Cree 						   unsigned int i)
9508135eecSEdward Cree {
9608135eecSEdward Cree 	struct net_device *net_dev;
9708135eecSEdward Cree 	struct efx_rep *efv;
9808135eecSEdward Cree 	int rc;
9908135eecSEdward Cree 
10008135eecSEdward Cree 	net_dev = alloc_etherdev_mq(sizeof(*efv), 1);
10108135eecSEdward Cree 	if (!net_dev)
10208135eecSEdward Cree 		return ERR_PTR(-ENOMEM);
10308135eecSEdward Cree 
10408135eecSEdward Cree 	efv = netdev_priv(net_dev);
105*e1479556SEdward Cree 	rc = efx_ef100_rep_init_struct(efx, efv, i);
10608135eecSEdward Cree 	if (rc)
10708135eecSEdward Cree 		goto fail1;
10808135eecSEdward Cree 	efv->net_dev = net_dev;
10908135eecSEdward Cree 	rtnl_lock();
11008135eecSEdward Cree 	spin_lock_bh(&efx->vf_reps_lock);
11108135eecSEdward Cree 	list_add_tail(&efv->list, &efx->vf_reps);
11208135eecSEdward Cree 	spin_unlock_bh(&efx->vf_reps_lock);
11308135eecSEdward Cree 	netif_carrier_off(net_dev);
11408135eecSEdward Cree 	netif_tx_stop_all_queues(net_dev);
11508135eecSEdward Cree 	rtnl_unlock();
11608135eecSEdward Cree 
11708135eecSEdward Cree 	net_dev->netdev_ops = &efx_ef100_rep_netdev_ops;
11808135eecSEdward Cree 	net_dev->ethtool_ops = &efx_ef100_rep_ethtool_ops;
11908135eecSEdward Cree 	net_dev->min_mtu = EFX_MIN_MTU;
12008135eecSEdward Cree 	net_dev->max_mtu = EFX_MAX_MTU;
12108135eecSEdward Cree 	return efv;
12208135eecSEdward Cree fail1:
12308135eecSEdward Cree 	free_netdev(net_dev);
12408135eecSEdward Cree 	return ERR_PTR(rc);
12508135eecSEdward Cree }
12608135eecSEdward Cree 
12708135eecSEdward Cree static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv)
12808135eecSEdward Cree {
12908135eecSEdward Cree 	struct efx_nic *efx = efv->parent;
13008135eecSEdward Cree 
13108135eecSEdward Cree 	spin_lock_bh(&efx->vf_reps_lock);
13208135eecSEdward Cree 	list_del(&efv->list);
13308135eecSEdward Cree 	spin_unlock_bh(&efx->vf_reps_lock);
13408135eecSEdward Cree 	free_netdev(efv->net_dev);
13508135eecSEdward Cree }
13608135eecSEdward Cree 
13708135eecSEdward Cree int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i)
13808135eecSEdward Cree {
13908135eecSEdward Cree 	struct efx_rep *efv;
14008135eecSEdward Cree 	int rc;
14108135eecSEdward Cree 
14208135eecSEdward Cree 	efv = efx_ef100_rep_create_netdev(efx, i);
14308135eecSEdward Cree 	if (IS_ERR(efv)) {
14408135eecSEdward Cree 		rc = PTR_ERR(efv);
14508135eecSEdward Cree 		pci_err(efx->pci_dev,
14608135eecSEdward Cree 			"Failed to create representor for VF %d, rc %d\n", i,
14708135eecSEdward Cree 			rc);
14808135eecSEdward Cree 		return rc;
14908135eecSEdward Cree 	}
15008135eecSEdward Cree 	rc = register_netdev(efv->net_dev);
15108135eecSEdward Cree 	if (rc) {
15208135eecSEdward Cree 		pci_err(efx->pci_dev,
15308135eecSEdward Cree 			"Failed to register representor for VF %d, rc %d\n",
15408135eecSEdward Cree 			i, rc);
15508135eecSEdward Cree 		goto fail;
15608135eecSEdward Cree 	}
15708135eecSEdward Cree 	pci_dbg(efx->pci_dev, "Representor for VF %d is %s\n", i,
15808135eecSEdward Cree 		efv->net_dev->name);
15908135eecSEdward Cree 	return 0;
16008135eecSEdward Cree fail:
16108135eecSEdward Cree 	efx_ef100_rep_destroy_netdev(efv);
16208135eecSEdward Cree 	return rc;
16308135eecSEdward Cree }
16408135eecSEdward Cree 
16508135eecSEdward Cree void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv)
16608135eecSEdward Cree {
16708135eecSEdward Cree 	struct net_device *rep_dev;
16808135eecSEdward Cree 
16908135eecSEdward Cree 	rep_dev = efv->net_dev;
17008135eecSEdward Cree 	if (!rep_dev)
17108135eecSEdward Cree 		return;
17208135eecSEdward Cree 	netif_dbg(efx, drv, rep_dev, "Removing VF representor\n");
17308135eecSEdward Cree 	unregister_netdev(rep_dev);
17408135eecSEdward Cree 	efx_ef100_rep_destroy_netdev(efv);
17508135eecSEdward Cree }
17608135eecSEdward Cree 
17708135eecSEdward Cree void efx_ef100_fini_vfreps(struct efx_nic *efx)
17808135eecSEdward Cree {
17908135eecSEdward Cree 	struct ef100_nic_data *nic_data = efx->nic_data;
18008135eecSEdward Cree 	struct efx_rep *efv, *next;
18108135eecSEdward Cree 
18208135eecSEdward Cree 	if (!nic_data->grp_mae)
18308135eecSEdward Cree 		return;
18408135eecSEdward Cree 
18508135eecSEdward Cree 	list_for_each_entry_safe(efv, next, &efx->vf_reps, list)
18608135eecSEdward Cree 		efx_ef100_vfrep_destroy(efx, efv);
18708135eecSEdward Cree }
188