1 /*- 2 * Copyright (c) 2016 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * This software was jointly developed between OKTET Labs (under contract 6 * for Solarflare) and Solarflare Communications, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <rte_dev.h> 31 #include <rte_ethdev.h> 32 #include <rte_pci.h> 33 34 #include "efx.h" 35 36 #include "sfc.h" 37 #include "sfc_debug.h" 38 #include "sfc_log.h" 39 #include "sfc_kvargs.h" 40 #include "sfc_ev.h" 41 42 43 static void 44 sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) 45 { 46 struct sfc_adapter *sa = dev->data->dev_private; 47 48 sfc_log_init(sa, "entry"); 49 50 dev_info->pci_dev = RTE_DEV_TO_PCI(dev->device); 51 dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX; 52 53 /* By default packets are dropped if no descriptors are available */ 54 dev_info->default_rxconf.rx_drop_en = 1; 55 56 dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS; 57 dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS; 58 /* The RXQ hardware requires that the descriptor count is a power 59 * of 2, but rx_desc_lim cannot properly describe that constraint. 60 */ 61 dev_info->rx_desc_lim.nb_align = EFX_RXQ_MINNDESCS; 62 } 63 64 static int 65 sfc_dev_configure(struct rte_eth_dev *dev) 66 { 67 struct rte_eth_dev_data *dev_data = dev->data; 68 struct sfc_adapter *sa = dev_data->dev_private; 69 int rc; 70 71 sfc_log_init(sa, "entry n_rxq=%u n_txq=%u", 72 dev_data->nb_rx_queues, dev_data->nb_tx_queues); 73 74 sfc_adapter_lock(sa); 75 switch (sa->state) { 76 case SFC_ADAPTER_CONFIGURED: 77 sfc_close(sa); 78 SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED); 79 /* FALLTHROUGH */ 80 case SFC_ADAPTER_INITIALIZED: 81 rc = sfc_configure(sa); 82 break; 83 default: 84 sfc_err(sa, "unexpected adapter state %u to configure", 85 sa->state); 86 rc = EINVAL; 87 break; 88 } 89 sfc_adapter_unlock(sa); 90 91 sfc_log_init(sa, "done %d", rc); 92 SFC_ASSERT(rc >= 0); 93 return -rc; 94 } 95 96 static int 97 sfc_dev_start(struct rte_eth_dev *dev) 98 { 99 struct sfc_adapter *sa = dev->data->dev_private; 100 int rc; 101 102 sfc_log_init(sa, "entry"); 103 104 sfc_adapter_lock(sa); 105 rc = sfc_start(sa); 106 sfc_adapter_unlock(sa); 107 108 sfc_log_init(sa, "done %d", rc); 109 SFC_ASSERT(rc >= 0); 110 return -rc; 111 } 112 113 static int 114 sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete) 115 { 116 struct sfc_adapter *sa = dev->data->dev_private; 117 struct rte_eth_link *dev_link = &dev->data->dev_link; 118 struct rte_eth_link old_link; 119 struct rte_eth_link current_link; 120 121 sfc_log_init(sa, "entry"); 122 123 if (sa->state != SFC_ADAPTER_STARTED) 124 return 0; 125 126 retry: 127 EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t)); 128 *(int64_t *)&old_link = rte_atomic64_read((rte_atomic64_t *)dev_link); 129 130 if (wait_to_complete) { 131 efx_link_mode_t link_mode; 132 133 efx_port_poll(sa->nic, &link_mode); 134 sfc_port_link_mode_to_info(link_mode, ¤t_link); 135 136 if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link, 137 *(uint64_t *)&old_link, 138 *(uint64_t *)¤t_link)) 139 goto retry; 140 } else { 141 sfc_ev_mgmt_qpoll(sa); 142 *(int64_t *)¤t_link = 143 rte_atomic64_read((rte_atomic64_t *)dev_link); 144 } 145 146 if (old_link.link_status != current_link.link_status) 147 sfc_info(sa, "Link status is %s", 148 current_link.link_status ? "UP" : "DOWN"); 149 150 return old_link.link_status == current_link.link_status ? 0 : -1; 151 } 152 153 static void 154 sfc_dev_stop(struct rte_eth_dev *dev) 155 { 156 struct sfc_adapter *sa = dev->data->dev_private; 157 158 sfc_log_init(sa, "entry"); 159 160 sfc_adapter_lock(sa); 161 sfc_stop(sa); 162 sfc_adapter_unlock(sa); 163 164 sfc_log_init(sa, "done"); 165 } 166 167 static void 168 sfc_dev_close(struct rte_eth_dev *dev) 169 { 170 struct sfc_adapter *sa = dev->data->dev_private; 171 172 sfc_log_init(sa, "entry"); 173 174 sfc_adapter_lock(sa); 175 switch (sa->state) { 176 case SFC_ADAPTER_STARTED: 177 sfc_stop(sa); 178 SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED); 179 /* FALLTHROUGH */ 180 case SFC_ADAPTER_CONFIGURED: 181 sfc_close(sa); 182 SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED); 183 /* FALLTHROUGH */ 184 case SFC_ADAPTER_INITIALIZED: 185 break; 186 default: 187 sfc_err(sa, "unexpected adapter state %u on close", sa->state); 188 break; 189 } 190 sfc_adapter_unlock(sa); 191 192 sfc_log_init(sa, "done"); 193 } 194 195 static const struct eth_dev_ops sfc_eth_dev_ops = { 196 .dev_configure = sfc_dev_configure, 197 .dev_start = sfc_dev_start, 198 .dev_stop = sfc_dev_stop, 199 .dev_close = sfc_dev_close, 200 .link_update = sfc_dev_link_update, 201 .dev_infos_get = sfc_dev_infos_get, 202 }; 203 204 static int 205 sfc_eth_dev_init(struct rte_eth_dev *dev) 206 { 207 struct sfc_adapter *sa = dev->data->dev_private; 208 struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(dev); 209 int rc; 210 const efx_nic_cfg_t *encp; 211 const struct ether_addr *from; 212 213 /* Required for logging */ 214 sa->eth_dev = dev; 215 216 /* Copy PCI device info to the dev->data */ 217 rte_eth_copy_pci_info(dev, pci_dev); 218 219 rc = sfc_kvargs_parse(sa); 220 if (rc != 0) 221 goto fail_kvargs_parse; 222 223 rc = sfc_kvargs_process(sa, SFC_KVARG_DEBUG_INIT, 224 sfc_kvarg_bool_handler, &sa->debug_init); 225 if (rc != 0) 226 goto fail_kvarg_debug_init; 227 228 sfc_log_init(sa, "entry"); 229 230 dev->data->mac_addrs = rte_zmalloc("sfc", ETHER_ADDR_LEN, 0); 231 if (dev->data->mac_addrs == NULL) { 232 rc = ENOMEM; 233 goto fail_mac_addrs; 234 } 235 236 sfc_adapter_lock_init(sa); 237 sfc_adapter_lock(sa); 238 239 sfc_log_init(sa, "attaching"); 240 rc = sfc_attach(sa); 241 if (rc != 0) 242 goto fail_attach; 243 244 encp = efx_nic_cfg_get(sa->nic); 245 246 /* 247 * The arguments are really reverse order in comparison to 248 * Linux kernel. Copy from NIC config to Ethernet device data. 249 */ 250 from = (const struct ether_addr *)(encp->enc_mac_addr); 251 ether_addr_copy(from, &dev->data->mac_addrs[0]); 252 253 dev->dev_ops = &sfc_eth_dev_ops; 254 255 sfc_adapter_unlock(sa); 256 257 sfc_log_init(sa, "done"); 258 return 0; 259 260 fail_attach: 261 sfc_adapter_unlock(sa); 262 sfc_adapter_lock_fini(sa); 263 rte_free(dev->data->mac_addrs); 264 dev->data->mac_addrs = NULL; 265 266 fail_mac_addrs: 267 fail_kvarg_debug_init: 268 sfc_kvargs_cleanup(sa); 269 270 fail_kvargs_parse: 271 sfc_log_init(sa, "failed %d", rc); 272 SFC_ASSERT(rc > 0); 273 return -rc; 274 } 275 276 static int 277 sfc_eth_dev_uninit(struct rte_eth_dev *dev) 278 { 279 struct sfc_adapter *sa = dev->data->dev_private; 280 281 sfc_log_init(sa, "entry"); 282 283 sfc_adapter_lock(sa); 284 285 sfc_detach(sa); 286 287 rte_free(dev->data->mac_addrs); 288 dev->data->mac_addrs = NULL; 289 290 dev->dev_ops = NULL; 291 292 sfc_kvargs_cleanup(sa); 293 294 sfc_adapter_unlock(sa); 295 sfc_adapter_lock_fini(sa); 296 297 sfc_log_init(sa, "done"); 298 299 /* Required for logging, so cleanup last */ 300 sa->eth_dev = NULL; 301 return 0; 302 } 303 304 static const struct rte_pci_id pci_id_sfc_efx_map[] = { 305 { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_FARMINGDALE) }, 306 { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_GREENPORT) }, 307 { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_MEDFORD) }, 308 { .vendor_id = 0 /* sentinel */ } 309 }; 310 311 static struct eth_driver sfc_efx_pmd = { 312 .pci_drv = { 313 .id_table = pci_id_sfc_efx_map, 314 .drv_flags = 315 RTE_PCI_DRV_NEED_MAPPING, 316 .probe = rte_eth_dev_pci_probe, 317 .remove = rte_eth_dev_pci_remove, 318 }, 319 .eth_dev_init = sfc_eth_dev_init, 320 .eth_dev_uninit = sfc_eth_dev_uninit, 321 .dev_private_size = sizeof(struct sfc_adapter), 322 }; 323 324 RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv); 325 RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map); 326 RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx, 327 SFC_KVARG_DEBUG_INIT "=" SFC_KVARG_VALUES_BOOL); 328