1 /* 2 * Copyright (C) 2015 Netronome Systems, Inc. 3 * 4 * This software is dual licensed under the GNU General License Version 2, 5 * June 1991 as shown in the file COPYING in the top-level directory of this 6 * source tree or the BSD 2-Clause License provided below. You have the 7 * option to license this software under the complete terms of either license. 8 * 9 * The BSD 2-Clause License: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * 1. Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * 2. Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 */ 33 34 /* 35 * nfp_netvf_main.c 36 * Netronome virtual function network device driver: Main entry point 37 * Author: Jason McMullan <jason.mcmullan@netronome.com> 38 * Rolf Neugebauer <rolf.neugebauer@netronome.com> 39 */ 40 41 #include <linux/module.h> 42 #include <linux/kernel.h> 43 #include <linux/init.h> 44 #include <linux/etherdevice.h> 45 46 #include "nfp_net_ctrl.h" 47 #include "nfp_net.h" 48 49 const char nfp_net_driver_name[] = "nfp_netvf"; 50 const char nfp_net_driver_version[] = "0.1"; 51 #define PCI_DEVICE_NFP6000VF 0x6003 52 static const struct pci_device_id nfp_netvf_pci_device_ids[] = { 53 { PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_NFP6000VF, 54 PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID, 55 PCI_ANY_ID, 0, 56 }, 57 { 0, } /* Required last entry. */ 58 }; 59 MODULE_DEVICE_TABLE(pci, nfp_netvf_pci_device_ids); 60 61 static void nfp_netvf_get_mac_addr(struct nfp_net *nn) 62 { 63 u8 mac_addr[ETH_ALEN]; 64 65 put_unaligned_be32(nn_readl(nn, NFP_NET_CFG_MACADDR + 0), &mac_addr[0]); 66 /* We can't do readw for NFP-3200 compatibility */ 67 put_unaligned_be16(nn_readl(nn, NFP_NET_CFG_MACADDR + 4) >> 16, 68 &mac_addr[4]); 69 70 if (!is_valid_ether_addr(mac_addr)) { 71 eth_hw_addr_random(nn->netdev); 72 return; 73 } 74 75 ether_addr_copy(nn->netdev->dev_addr, mac_addr); 76 ether_addr_copy(nn->netdev->perm_addr, mac_addr); 77 } 78 79 static int nfp_netvf_pci_probe(struct pci_dev *pdev, 80 const struct pci_device_id *pci_id) 81 { 82 struct nfp_net_fw_version fw_ver; 83 int max_tx_rings, max_rx_rings; 84 u32 tx_bar_off, rx_bar_off; 85 u32 tx_bar_sz, rx_bar_sz; 86 int tx_bar_no, rx_bar_no; 87 u8 __iomem *ctrl_bar; 88 struct nfp_net *nn; 89 int is_nfp3200; 90 u32 startq; 91 int stride; 92 int err; 93 94 err = pci_enable_device_mem(pdev); 95 if (err) 96 return err; 97 98 err = pci_request_regions(pdev, nfp_net_driver_name); 99 if (err) { 100 dev_err(&pdev->dev, "Unable to allocate device memory.\n"); 101 goto err_pci_disable; 102 } 103 104 switch (pdev->device) { 105 case PCI_DEVICE_NFP6000VF: 106 is_nfp3200 = 0; 107 break; 108 default: 109 err = -ENODEV; 110 goto err_pci_regions; 111 } 112 113 pci_set_master(pdev); 114 115 err = dma_set_mask_and_coherent(&pdev->dev, 116 DMA_BIT_MASK(NFP_NET_MAX_DMA_BITS)); 117 if (err) 118 goto err_pci_regions; 119 120 /* Map the Control BAR. 121 * 122 * Irrespective of the advertised BAR size we only map the 123 * first NFP_NET_CFG_BAR_SZ of the BAR. This keeps the code 124 * the identical for PF and VF drivers. 125 */ 126 ctrl_bar = ioremap_nocache(pci_resource_start(pdev, NFP_NET_CTRL_BAR), 127 NFP_NET_CFG_BAR_SZ); 128 if (!ctrl_bar) { 129 dev_err(&pdev->dev, 130 "Failed to map resource %d\n", NFP_NET_CTRL_BAR); 131 err = -EIO; 132 goto err_pci_regions; 133 } 134 135 nfp_net_get_fw_version(&fw_ver, ctrl_bar); 136 if (fw_ver.resv || fw_ver.class != NFP_NET_CFG_VERSION_CLASS_GENERIC) { 137 dev_err(&pdev->dev, "Unknown Firmware ABI %d.%d.%d.%d\n", 138 fw_ver.resv, fw_ver.class, fw_ver.major, fw_ver.minor); 139 err = -EINVAL; 140 goto err_ctrl_unmap; 141 } 142 143 /* Determine stride */ 144 if (nfp_net_fw_ver_eq(&fw_ver, 0, 0, 0, 1)) { 145 stride = 2; 146 tx_bar_no = NFP_NET_Q0_BAR; 147 rx_bar_no = NFP_NET_Q1_BAR; 148 dev_warn(&pdev->dev, "OBSOLETE Firmware detected - VF isolation not available\n"); 149 } else { 150 switch (fw_ver.major) { 151 case 1 ... 4: 152 if (is_nfp3200) { 153 stride = 2; 154 tx_bar_no = NFP_NET_Q0_BAR; 155 rx_bar_no = NFP_NET_Q1_BAR; 156 } else { 157 stride = 4; 158 tx_bar_no = NFP_NET_Q0_BAR; 159 rx_bar_no = tx_bar_no; 160 } 161 break; 162 default: 163 dev_err(&pdev->dev, "Unsupported Firmware ABI %d.%d.%d.%d\n", 164 fw_ver.resv, fw_ver.class, 165 fw_ver.major, fw_ver.minor); 166 err = -EINVAL; 167 goto err_ctrl_unmap; 168 } 169 } 170 171 /* Find out how many rings are supported */ 172 max_tx_rings = readl(ctrl_bar + NFP_NET_CFG_MAX_TXRINGS); 173 max_rx_rings = readl(ctrl_bar + NFP_NET_CFG_MAX_RXRINGS); 174 175 tx_bar_sz = NFP_QCP_QUEUE_ADDR_SZ * max_tx_rings * stride; 176 rx_bar_sz = NFP_QCP_QUEUE_ADDR_SZ * max_rx_rings * stride; 177 178 /* Sanity checks */ 179 if (tx_bar_sz > pci_resource_len(pdev, tx_bar_no)) { 180 dev_err(&pdev->dev, 181 "TX BAR too small for number of TX rings. Adjusting\n"); 182 tx_bar_sz = pci_resource_len(pdev, tx_bar_no); 183 max_tx_rings = (tx_bar_sz / NFP_QCP_QUEUE_ADDR_SZ) / 2; 184 } 185 if (rx_bar_sz > pci_resource_len(pdev, rx_bar_no)) { 186 dev_err(&pdev->dev, 187 "RX BAR too small for number of RX rings. Adjusting\n"); 188 rx_bar_sz = pci_resource_len(pdev, rx_bar_no); 189 max_rx_rings = (rx_bar_sz / NFP_QCP_QUEUE_ADDR_SZ) / 2; 190 } 191 192 /* XXX Implement a workaround for THB-350 here. Ideally, we 193 * have a different PCI ID for A rev VFs. 194 */ 195 switch (pdev->device) { 196 case PCI_DEVICE_NFP6000VF: 197 startq = readl(ctrl_bar + NFP_NET_CFG_START_TXQ); 198 tx_bar_off = NFP_PCIE_QUEUE(startq); 199 startq = readl(ctrl_bar + NFP_NET_CFG_START_RXQ); 200 rx_bar_off = NFP_PCIE_QUEUE(startq); 201 break; 202 default: 203 err = -ENODEV; 204 goto err_ctrl_unmap; 205 } 206 207 /* Allocate and initialise the netdev */ 208 nn = nfp_net_netdev_alloc(pdev, max_tx_rings, max_rx_rings); 209 if (IS_ERR(nn)) { 210 err = PTR_ERR(nn); 211 goto err_ctrl_unmap; 212 } 213 214 nn->fw_ver = fw_ver; 215 nn->ctrl_bar = ctrl_bar; 216 nn->is_vf = 1; 217 nn->is_nfp3200 = is_nfp3200; 218 nn->stride_tx = stride; 219 nn->stride_rx = stride; 220 221 if (rx_bar_no == tx_bar_no) { 222 u32 bar_off, bar_sz; 223 resource_size_t map_addr; 224 225 /* Make a single overlapping BAR mapping */ 226 if (tx_bar_off < rx_bar_off) 227 bar_off = tx_bar_off; 228 else 229 bar_off = rx_bar_off; 230 231 if ((tx_bar_off + tx_bar_sz) > (rx_bar_off + rx_bar_sz)) 232 bar_sz = (tx_bar_off + tx_bar_sz) - bar_off; 233 else 234 bar_sz = (rx_bar_off + rx_bar_sz) - bar_off; 235 236 map_addr = pci_resource_start(pdev, tx_bar_no) + bar_off; 237 nn->q_bar = ioremap_nocache(map_addr, bar_sz); 238 if (!nn->q_bar) { 239 nn_err(nn, "Failed to map resource %d\n", tx_bar_no); 240 err = -EIO; 241 goto err_netdev_free; 242 } 243 244 /* TX queues */ 245 nn->tx_bar = nn->q_bar + (tx_bar_off - bar_off); 246 /* RX queues */ 247 nn->rx_bar = nn->q_bar + (rx_bar_off - bar_off); 248 } else { 249 resource_size_t map_addr; 250 251 /* TX queues */ 252 map_addr = pci_resource_start(pdev, tx_bar_no) + tx_bar_off; 253 nn->tx_bar = ioremap_nocache(map_addr, tx_bar_sz); 254 if (!nn->tx_bar) { 255 nn_err(nn, "Failed to map resource %d\n", tx_bar_no); 256 err = -EIO; 257 goto err_netdev_free; 258 } 259 260 /* RX queues */ 261 map_addr = pci_resource_start(pdev, rx_bar_no) + rx_bar_off; 262 nn->rx_bar = ioremap_nocache(map_addr, rx_bar_sz); 263 if (!nn->rx_bar) { 264 nn_err(nn, "Failed to map resource %d\n", rx_bar_no); 265 err = -EIO; 266 goto err_unmap_tx; 267 } 268 } 269 270 nfp_netvf_get_mac_addr(nn); 271 272 err = nfp_net_irqs_alloc(nn); 273 if (!err) { 274 nn_warn(nn, "Unable to allocate MSI-X Vectors. Exiting\n"); 275 err = -EIO; 276 goto err_unmap_rx; 277 } 278 279 /* Get ME clock frequency from ctrl BAR 280 * XXX for now frequency is hardcoded until we figure out how 281 * to get the value from nfp-hwinfo into ctrl bar 282 */ 283 nn->me_freq_mhz = 1200; 284 285 err = nfp_net_netdev_init(nn->netdev); 286 if (err) 287 goto err_irqs_disable; 288 289 pci_set_drvdata(pdev, nn); 290 291 nfp_net_info(nn); 292 nfp_net_debugfs_adapter_add(nn); 293 294 return 0; 295 296 err_irqs_disable: 297 nfp_net_irqs_disable(nn); 298 err_unmap_rx: 299 if (!nn->q_bar) 300 iounmap(nn->rx_bar); 301 err_unmap_tx: 302 if (!nn->q_bar) 303 iounmap(nn->tx_bar); 304 else 305 iounmap(nn->q_bar); 306 err_netdev_free: 307 pci_set_drvdata(pdev, NULL); 308 nfp_net_netdev_free(nn); 309 err_ctrl_unmap: 310 iounmap(ctrl_bar); 311 err_pci_regions: 312 pci_release_regions(pdev); 313 err_pci_disable: 314 pci_disable_device(pdev); 315 return err; 316 } 317 318 static void nfp_netvf_pci_remove(struct pci_dev *pdev) 319 { 320 struct nfp_net *nn = pci_get_drvdata(pdev); 321 322 /* Note, the order is slightly different from above as we need 323 * to keep the nn pointer around till we have freed everything. 324 */ 325 nfp_net_debugfs_adapter_del(nn); 326 327 nfp_net_netdev_clean(nn->netdev); 328 329 nfp_net_irqs_disable(nn); 330 331 if (!nn->q_bar) { 332 iounmap(nn->rx_bar); 333 iounmap(nn->tx_bar); 334 } else { 335 iounmap(nn->q_bar); 336 } 337 iounmap(nn->ctrl_bar); 338 339 pci_set_drvdata(pdev, NULL); 340 341 nfp_net_netdev_free(nn); 342 343 pci_release_regions(pdev); 344 pci_disable_device(pdev); 345 } 346 347 static struct pci_driver nfp_netvf_pci_driver = { 348 .name = nfp_net_driver_name, 349 .id_table = nfp_netvf_pci_device_ids, 350 .probe = nfp_netvf_pci_probe, 351 .remove = nfp_netvf_pci_remove, 352 }; 353 354 static int __init nfp_netvf_init(void) 355 { 356 int err; 357 358 pr_info("%s: NFP VF Network driver, Copyright (C) 2014-2015 Netronome Systems\n", 359 nfp_net_driver_name); 360 361 nfp_net_debugfs_create(); 362 err = pci_register_driver(&nfp_netvf_pci_driver); 363 if (err) { 364 nfp_net_debugfs_destroy(); 365 return err; 366 } 367 368 return 0; 369 } 370 371 static void __exit nfp_netvf_exit(void) 372 { 373 pci_unregister_driver(&nfp_netvf_pci_driver); 374 nfp_net_debugfs_destroy(); 375 } 376 377 module_init(nfp_netvf_init); 378 module_exit(nfp_netvf_exit); 379 380 MODULE_AUTHOR("Netronome Systems <oss-drivers@netronome.com>"); 381 MODULE_LICENSE("GPL"); 382 MODULE_DESCRIPTION("NFP VF network device driver"); 383