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