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 15*5687eb34SEdward Cree #define EFX_EF100_REP_DRIVER "efx_ef100_rep" 16*5687eb34SEdward Cree 1708135eecSEdward Cree static int efx_ef100_rep_init_struct(struct efx_nic *efx, struct efx_rep *efv) 1808135eecSEdward Cree { 1908135eecSEdward Cree efv->parent = efx; 2008135eecSEdward Cree INIT_LIST_HEAD(&efv->list); 2108135eecSEdward Cree efv->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE | 2208135eecSEdward Cree NETIF_MSG_LINK | NETIF_MSG_IFDOWN | 2308135eecSEdward Cree NETIF_MSG_IFUP | NETIF_MSG_RX_ERR | 2408135eecSEdward Cree NETIF_MSG_TX_ERR | NETIF_MSG_HW; 2508135eecSEdward Cree return 0; 2608135eecSEdward Cree } 2708135eecSEdward Cree 2808135eecSEdward Cree static const struct net_device_ops efx_ef100_rep_netdev_ops = { 2908135eecSEdward Cree }; 3008135eecSEdward Cree 31*5687eb34SEdward Cree static void efx_ef100_rep_get_drvinfo(struct net_device *dev, 32*5687eb34SEdward Cree struct ethtool_drvinfo *drvinfo) 33*5687eb34SEdward Cree { 34*5687eb34SEdward Cree strscpy(drvinfo->driver, EFX_EF100_REP_DRIVER, sizeof(drvinfo->driver)); 35*5687eb34SEdward Cree } 36*5687eb34SEdward Cree 37*5687eb34SEdward Cree static u32 efx_ef100_rep_ethtool_get_msglevel(struct net_device *net_dev) 38*5687eb34SEdward Cree { 39*5687eb34SEdward Cree struct efx_rep *efv = netdev_priv(net_dev); 40*5687eb34SEdward Cree 41*5687eb34SEdward Cree return efv->msg_enable; 42*5687eb34SEdward Cree } 43*5687eb34SEdward Cree 44*5687eb34SEdward Cree static void efx_ef100_rep_ethtool_set_msglevel(struct net_device *net_dev, 45*5687eb34SEdward Cree u32 msg_enable) 46*5687eb34SEdward Cree { 47*5687eb34SEdward Cree struct efx_rep *efv = netdev_priv(net_dev); 48*5687eb34SEdward Cree 49*5687eb34SEdward Cree efv->msg_enable = msg_enable; 50*5687eb34SEdward Cree } 51*5687eb34SEdward Cree 5208135eecSEdward Cree static const struct ethtool_ops efx_ef100_rep_ethtool_ops = { 53*5687eb34SEdward Cree .get_drvinfo = efx_ef100_rep_get_drvinfo, 54*5687eb34SEdward Cree .get_msglevel = efx_ef100_rep_ethtool_get_msglevel, 55*5687eb34SEdward Cree .set_msglevel = efx_ef100_rep_ethtool_set_msglevel, 5608135eecSEdward Cree }; 5708135eecSEdward Cree 5808135eecSEdward Cree static struct efx_rep *efx_ef100_rep_create_netdev(struct efx_nic *efx, 5908135eecSEdward Cree unsigned int i) 6008135eecSEdward Cree { 6108135eecSEdward Cree struct net_device *net_dev; 6208135eecSEdward Cree struct efx_rep *efv; 6308135eecSEdward Cree int rc; 6408135eecSEdward Cree 6508135eecSEdward Cree net_dev = alloc_etherdev_mq(sizeof(*efv), 1); 6608135eecSEdward Cree if (!net_dev) 6708135eecSEdward Cree return ERR_PTR(-ENOMEM); 6808135eecSEdward Cree 6908135eecSEdward Cree efv = netdev_priv(net_dev); 7008135eecSEdward Cree rc = efx_ef100_rep_init_struct(efx, efv); 7108135eecSEdward Cree if (rc) 7208135eecSEdward Cree goto fail1; 7308135eecSEdward Cree efv->net_dev = net_dev; 7408135eecSEdward Cree rtnl_lock(); 7508135eecSEdward Cree spin_lock_bh(&efx->vf_reps_lock); 7608135eecSEdward Cree list_add_tail(&efv->list, &efx->vf_reps); 7708135eecSEdward Cree spin_unlock_bh(&efx->vf_reps_lock); 7808135eecSEdward Cree netif_carrier_off(net_dev); 7908135eecSEdward Cree netif_tx_stop_all_queues(net_dev); 8008135eecSEdward Cree rtnl_unlock(); 8108135eecSEdward Cree 8208135eecSEdward Cree net_dev->netdev_ops = &efx_ef100_rep_netdev_ops; 8308135eecSEdward Cree net_dev->ethtool_ops = &efx_ef100_rep_ethtool_ops; 8408135eecSEdward Cree net_dev->min_mtu = EFX_MIN_MTU; 8508135eecSEdward Cree net_dev->max_mtu = EFX_MAX_MTU; 8608135eecSEdward Cree return efv; 8708135eecSEdward Cree fail1: 8808135eecSEdward Cree free_netdev(net_dev); 8908135eecSEdward Cree return ERR_PTR(rc); 9008135eecSEdward Cree } 9108135eecSEdward Cree 9208135eecSEdward Cree static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv) 9308135eecSEdward Cree { 9408135eecSEdward Cree struct efx_nic *efx = efv->parent; 9508135eecSEdward Cree 9608135eecSEdward Cree spin_lock_bh(&efx->vf_reps_lock); 9708135eecSEdward Cree list_del(&efv->list); 9808135eecSEdward Cree spin_unlock_bh(&efx->vf_reps_lock); 9908135eecSEdward Cree free_netdev(efv->net_dev); 10008135eecSEdward Cree } 10108135eecSEdward Cree 10208135eecSEdward Cree int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i) 10308135eecSEdward Cree { 10408135eecSEdward Cree struct efx_rep *efv; 10508135eecSEdward Cree int rc; 10608135eecSEdward Cree 10708135eecSEdward Cree efv = efx_ef100_rep_create_netdev(efx, i); 10808135eecSEdward Cree if (IS_ERR(efv)) { 10908135eecSEdward Cree rc = PTR_ERR(efv); 11008135eecSEdward Cree pci_err(efx->pci_dev, 11108135eecSEdward Cree "Failed to create representor for VF %d, rc %d\n", i, 11208135eecSEdward Cree rc); 11308135eecSEdward Cree return rc; 11408135eecSEdward Cree } 11508135eecSEdward Cree rc = register_netdev(efv->net_dev); 11608135eecSEdward Cree if (rc) { 11708135eecSEdward Cree pci_err(efx->pci_dev, 11808135eecSEdward Cree "Failed to register representor for VF %d, rc %d\n", 11908135eecSEdward Cree i, rc); 12008135eecSEdward Cree goto fail; 12108135eecSEdward Cree } 12208135eecSEdward Cree pci_dbg(efx->pci_dev, "Representor for VF %d is %s\n", i, 12308135eecSEdward Cree efv->net_dev->name); 12408135eecSEdward Cree return 0; 12508135eecSEdward Cree fail: 12608135eecSEdward Cree efx_ef100_rep_destroy_netdev(efv); 12708135eecSEdward Cree return rc; 12808135eecSEdward Cree } 12908135eecSEdward Cree 13008135eecSEdward Cree void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv) 13108135eecSEdward Cree { 13208135eecSEdward Cree struct net_device *rep_dev; 13308135eecSEdward Cree 13408135eecSEdward Cree rep_dev = efv->net_dev; 13508135eecSEdward Cree if (!rep_dev) 13608135eecSEdward Cree return; 13708135eecSEdward Cree netif_dbg(efx, drv, rep_dev, "Removing VF representor\n"); 13808135eecSEdward Cree unregister_netdev(rep_dev); 13908135eecSEdward Cree efx_ef100_rep_destroy_netdev(efv); 14008135eecSEdward Cree } 14108135eecSEdward Cree 14208135eecSEdward Cree void efx_ef100_fini_vfreps(struct efx_nic *efx) 14308135eecSEdward Cree { 14408135eecSEdward Cree struct ef100_nic_data *nic_data = efx->nic_data; 14508135eecSEdward Cree struct efx_rep *efv, *next; 14608135eecSEdward Cree 14708135eecSEdward Cree if (!nic_data->grp_mae) 14808135eecSEdward Cree return; 14908135eecSEdward Cree 15008135eecSEdward Cree list_for_each_entry_safe(efv, next, &efx->vf_reps, list) 15108135eecSEdward Cree efx_ef100_vfrep_destroy(efx, efv); 15208135eecSEdward Cree } 153