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 "ef100_rep.h" 13 #include "ef100_netdev.h" 14 #include "ef100_nic.h" 15 #include "mae.h" 16 17 #define EFX_EF100_REP_DRIVER "efx_ef100_rep" 18 19 static int efx_ef100_rep_init_struct(struct efx_nic *efx, struct efx_rep *efv, 20 unsigned int i) 21 { 22 efv->parent = efx; 23 efv->idx = i; 24 INIT_LIST_HEAD(&efv->list); 25 efv->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE | 26 NETIF_MSG_LINK | NETIF_MSG_IFDOWN | 27 NETIF_MSG_IFUP | NETIF_MSG_RX_ERR | 28 NETIF_MSG_TX_ERR | NETIF_MSG_HW; 29 return 0; 30 } 31 32 static netdev_tx_t efx_ef100_rep_xmit(struct sk_buff *skb, 33 struct net_device *dev) 34 { 35 struct efx_rep *efv = netdev_priv(dev); 36 struct efx_nic *efx = efv->parent; 37 netdev_tx_t rc; 38 39 /* __ef100_hard_start_xmit() will always return success even in the 40 * case of TX drops, where it will increment efx's tx_dropped. The 41 * efv stats really only count attempted TX, not success/failure. 42 */ 43 atomic64_inc(&efv->stats.tx_packets); 44 atomic64_add(skb->len, &efv->stats.tx_bytes); 45 netif_tx_lock(efx->net_dev); 46 rc = __ef100_hard_start_xmit(skb, efx, dev, efv); 47 netif_tx_unlock(efx->net_dev); 48 return rc; 49 } 50 51 static int efx_ef100_rep_get_port_parent_id(struct net_device *dev, 52 struct netdev_phys_item_id *ppid) 53 { 54 struct efx_rep *efv = netdev_priv(dev); 55 struct efx_nic *efx = efv->parent; 56 struct ef100_nic_data *nic_data; 57 58 nic_data = efx->nic_data; 59 /* nic_data->port_id is a u8[] */ 60 ppid->id_len = sizeof(nic_data->port_id); 61 memcpy(ppid->id, nic_data->port_id, sizeof(nic_data->port_id)); 62 return 0; 63 } 64 65 static int efx_ef100_rep_get_phys_port_name(struct net_device *dev, 66 char *buf, size_t len) 67 { 68 struct efx_rep *efv = netdev_priv(dev); 69 struct efx_nic *efx = efv->parent; 70 struct ef100_nic_data *nic_data; 71 int ret; 72 73 nic_data = efx->nic_data; 74 ret = snprintf(buf, len, "p%upf%uvf%u", efx->port_num, 75 nic_data->pf_index, efv->idx); 76 if (ret >= len) 77 return -EOPNOTSUPP; 78 79 return 0; 80 } 81 82 static const struct net_device_ops efx_ef100_rep_netdev_ops = { 83 .ndo_start_xmit = efx_ef100_rep_xmit, 84 .ndo_get_port_parent_id = efx_ef100_rep_get_port_parent_id, 85 .ndo_get_phys_port_name = efx_ef100_rep_get_phys_port_name, 86 }; 87 88 static void efx_ef100_rep_get_drvinfo(struct net_device *dev, 89 struct ethtool_drvinfo *drvinfo) 90 { 91 strscpy(drvinfo->driver, EFX_EF100_REP_DRIVER, sizeof(drvinfo->driver)); 92 } 93 94 static u32 efx_ef100_rep_ethtool_get_msglevel(struct net_device *net_dev) 95 { 96 struct efx_rep *efv = netdev_priv(net_dev); 97 98 return efv->msg_enable; 99 } 100 101 static void efx_ef100_rep_ethtool_set_msglevel(struct net_device *net_dev, 102 u32 msg_enable) 103 { 104 struct efx_rep *efv = netdev_priv(net_dev); 105 106 efv->msg_enable = msg_enable; 107 } 108 109 static const struct ethtool_ops efx_ef100_rep_ethtool_ops = { 110 .get_drvinfo = efx_ef100_rep_get_drvinfo, 111 .get_msglevel = efx_ef100_rep_ethtool_get_msglevel, 112 .set_msglevel = efx_ef100_rep_ethtool_set_msglevel, 113 }; 114 115 static struct efx_rep *efx_ef100_rep_create_netdev(struct efx_nic *efx, 116 unsigned int i) 117 { 118 struct net_device *net_dev; 119 struct efx_rep *efv; 120 int rc; 121 122 net_dev = alloc_etherdev_mq(sizeof(*efv), 1); 123 if (!net_dev) 124 return ERR_PTR(-ENOMEM); 125 126 efv = netdev_priv(net_dev); 127 rc = efx_ef100_rep_init_struct(efx, efv, i); 128 if (rc) 129 goto fail1; 130 efv->net_dev = net_dev; 131 rtnl_lock(); 132 spin_lock_bh(&efx->vf_reps_lock); 133 list_add_tail(&efv->list, &efx->vf_reps); 134 spin_unlock_bh(&efx->vf_reps_lock); 135 if (netif_running(efx->net_dev) && efx->state == STATE_NET_UP) { 136 netif_device_attach(net_dev); 137 netif_carrier_on(net_dev); 138 } else { 139 netif_carrier_off(net_dev); 140 netif_tx_stop_all_queues(net_dev); 141 } 142 rtnl_unlock(); 143 144 net_dev->netdev_ops = &efx_ef100_rep_netdev_ops; 145 net_dev->ethtool_ops = &efx_ef100_rep_ethtool_ops; 146 net_dev->min_mtu = EFX_MIN_MTU; 147 net_dev->max_mtu = EFX_MAX_MTU; 148 net_dev->features |= NETIF_F_LLTX; 149 net_dev->hw_features |= NETIF_F_LLTX; 150 return efv; 151 fail1: 152 free_netdev(net_dev); 153 return ERR_PTR(rc); 154 } 155 156 static int efx_ef100_configure_rep(struct efx_rep *efv) 157 { 158 struct efx_nic *efx = efv->parent; 159 u32 selector; 160 int rc; 161 162 /* Construct mport selector for corresponding VF */ 163 efx_mae_mport_vf(efx, efv->idx, &selector); 164 /* Look up actual mport ID */ 165 rc = efx_mae_lookup_mport(efx, selector, &efv->mport); 166 if (rc) 167 return rc; 168 pci_dbg(efx->pci_dev, "VF %u has mport ID %#x\n", efv->idx, efv->mport); 169 /* mport label should fit in 16 bits */ 170 WARN_ON(efv->mport >> 16); 171 172 return 0; 173 } 174 175 static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv) 176 { 177 struct efx_nic *efx = efv->parent; 178 179 rtnl_lock(); 180 spin_lock_bh(&efx->vf_reps_lock); 181 list_del(&efv->list); 182 spin_unlock_bh(&efx->vf_reps_lock); 183 rtnl_unlock(); 184 free_netdev(efv->net_dev); 185 } 186 187 int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i) 188 { 189 struct efx_rep *efv; 190 int rc; 191 192 efv = efx_ef100_rep_create_netdev(efx, i); 193 if (IS_ERR(efv)) { 194 rc = PTR_ERR(efv); 195 pci_err(efx->pci_dev, 196 "Failed to create representor for VF %d, rc %d\n", i, 197 rc); 198 return rc; 199 } 200 rc = efx_ef100_configure_rep(efv); 201 if (rc) { 202 pci_err(efx->pci_dev, 203 "Failed to configure representor for VF %d, rc %d\n", 204 i, rc); 205 goto fail; 206 } 207 rc = register_netdev(efv->net_dev); 208 if (rc) { 209 pci_err(efx->pci_dev, 210 "Failed to register representor for VF %d, rc %d\n", 211 i, rc); 212 goto fail; 213 } 214 pci_dbg(efx->pci_dev, "Representor for VF %d is %s\n", i, 215 efv->net_dev->name); 216 return 0; 217 fail: 218 efx_ef100_rep_destroy_netdev(efv); 219 return rc; 220 } 221 222 void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv) 223 { 224 struct net_device *rep_dev; 225 226 rep_dev = efv->net_dev; 227 if (!rep_dev) 228 return; 229 netif_dbg(efx, drv, rep_dev, "Removing VF representor\n"); 230 unregister_netdev(rep_dev); 231 efx_ef100_rep_destroy_netdev(efv); 232 } 233 234 void efx_ef100_fini_vfreps(struct efx_nic *efx) 235 { 236 struct ef100_nic_data *nic_data = efx->nic_data; 237 struct efx_rep *efv, *next; 238 239 if (!nic_data->grp_mae) 240 return; 241 242 list_for_each_entry_safe(efv, next, &efx->vf_reps, list) 243 efx_ef100_vfrep_destroy(efx, efv); 244 } 245