root/drivers/crypto/ccp/sp-pci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sp_get_msix_irqs
  2. sp_get_msi_irq
  3. sp_get_irqs
  4. sp_free_irqs
  5. sp_pci_is_master
  6. psp_set_master
  7. psp_get_master
  8. sp_pci_probe
  9. sp_pci_remove
  10. sp_pci_suspend
  11. sp_pci_resume
  12. sp_pci_init
  13. sp_pci_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * AMD Secure Processor device driver
   4  *
   5  * Copyright (C) 2013,2018 Advanced Micro Devices, Inc.
   6  *
   7  * Author: Tom Lendacky <thomas.lendacky@amd.com>
   8  * Author: Gary R Hook <gary.hook@amd.com>
   9  */
  10 
  11 #include <linux/module.h>
  12 #include <linux/kernel.h>
  13 #include <linux/device.h>
  14 #include <linux/pci.h>
  15 #include <linux/pci_ids.h>
  16 #include <linux/dma-mapping.h>
  17 #include <linux/kthread.h>
  18 #include <linux/sched.h>
  19 #include <linux/interrupt.h>
  20 #include <linux/spinlock.h>
  21 #include <linux/delay.h>
  22 #include <linux/ccp.h>
  23 
  24 #include "ccp-dev.h"
  25 #include "psp-dev.h"
  26 
  27 #define MSIX_VECTORS                    2
  28 
  29 struct sp_pci {
  30         int msix_count;
  31         struct msix_entry msix_entry[MSIX_VECTORS];
  32 };
  33 static struct sp_device *sp_dev_master;
  34 
  35 static int sp_get_msix_irqs(struct sp_device *sp)
  36 {
  37         struct sp_pci *sp_pci = sp->dev_specific;
  38         struct device *dev = sp->dev;
  39         struct pci_dev *pdev = to_pci_dev(dev);
  40         int v, ret;
  41 
  42         for (v = 0; v < ARRAY_SIZE(sp_pci->msix_entry); v++)
  43                 sp_pci->msix_entry[v].entry = v;
  44 
  45         ret = pci_enable_msix_range(pdev, sp_pci->msix_entry, 1, v);
  46         if (ret < 0)
  47                 return ret;
  48 
  49         sp_pci->msix_count = ret;
  50         sp->use_tasklet = true;
  51 
  52         sp->psp_irq = sp_pci->msix_entry[0].vector;
  53         sp->ccp_irq = (sp_pci->msix_count > 1) ? sp_pci->msix_entry[1].vector
  54                                                : sp_pci->msix_entry[0].vector;
  55         return 0;
  56 }
  57 
  58 static int sp_get_msi_irq(struct sp_device *sp)
  59 {
  60         struct device *dev = sp->dev;
  61         struct pci_dev *pdev = to_pci_dev(dev);
  62         int ret;
  63 
  64         ret = pci_enable_msi(pdev);
  65         if (ret)
  66                 return ret;
  67 
  68         sp->ccp_irq = pdev->irq;
  69         sp->psp_irq = pdev->irq;
  70 
  71         return 0;
  72 }
  73 
  74 static int sp_get_irqs(struct sp_device *sp)
  75 {
  76         struct device *dev = sp->dev;
  77         int ret;
  78 
  79         ret = sp_get_msix_irqs(sp);
  80         if (!ret)
  81                 return 0;
  82 
  83         /* Couldn't get MSI-X vectors, try MSI */
  84         dev_notice(dev, "could not enable MSI-X (%d), trying MSI\n", ret);
  85         ret = sp_get_msi_irq(sp);
  86         if (!ret)
  87                 return 0;
  88 
  89         /* Couldn't get MSI interrupt */
  90         dev_notice(dev, "could not enable MSI (%d)\n", ret);
  91 
  92         return ret;
  93 }
  94 
  95 static void sp_free_irqs(struct sp_device *sp)
  96 {
  97         struct sp_pci *sp_pci = sp->dev_specific;
  98         struct device *dev = sp->dev;
  99         struct pci_dev *pdev = to_pci_dev(dev);
 100 
 101         if (sp_pci->msix_count)
 102                 pci_disable_msix(pdev);
 103         else if (sp->psp_irq)
 104                 pci_disable_msi(pdev);
 105 
 106         sp->ccp_irq = 0;
 107         sp->psp_irq = 0;
 108 }
 109 
 110 static bool sp_pci_is_master(struct sp_device *sp)
 111 {
 112         struct device *dev_cur, *dev_new;
 113         struct pci_dev *pdev_cur, *pdev_new;
 114 
 115         dev_new = sp->dev;
 116         dev_cur = sp_dev_master->dev;
 117 
 118         pdev_new = to_pci_dev(dev_new);
 119         pdev_cur = to_pci_dev(dev_cur);
 120 
 121         if (pdev_new->bus->number < pdev_cur->bus->number)
 122                 return true;
 123 
 124         if (PCI_SLOT(pdev_new->devfn) < PCI_SLOT(pdev_cur->devfn))
 125                 return true;
 126 
 127         if (PCI_FUNC(pdev_new->devfn) < PCI_FUNC(pdev_cur->devfn))
 128                 return true;
 129 
 130         return false;
 131 }
 132 
 133 static void psp_set_master(struct sp_device *sp)
 134 {
 135         if (!sp_dev_master) {
 136                 sp_dev_master = sp;
 137                 return;
 138         }
 139 
 140         if (sp_pci_is_master(sp))
 141                 sp_dev_master = sp;
 142 }
 143 
 144 static struct sp_device *psp_get_master(void)
 145 {
 146         return sp_dev_master;
 147 }
 148 
 149 static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 150 {
 151         struct sp_device *sp;
 152         struct sp_pci *sp_pci;
 153         struct device *dev = &pdev->dev;
 154         void __iomem * const *iomap_table;
 155         int bar_mask;
 156         int ret;
 157 
 158         ret = -ENOMEM;
 159         sp = sp_alloc_struct(dev);
 160         if (!sp)
 161                 goto e_err;
 162 
 163         sp_pci = devm_kzalloc(dev, sizeof(*sp_pci), GFP_KERNEL);
 164         if (!sp_pci)
 165                 goto e_err;
 166 
 167         sp->dev_specific = sp_pci;
 168         sp->dev_vdata = (struct sp_dev_vdata *)id->driver_data;
 169         if (!sp->dev_vdata) {
 170                 ret = -ENODEV;
 171                 dev_err(dev, "missing driver data\n");
 172                 goto e_err;
 173         }
 174 
 175         ret = pcim_enable_device(pdev);
 176         if (ret) {
 177                 dev_err(dev, "pcim_enable_device failed (%d)\n", ret);
 178                 goto e_err;
 179         }
 180 
 181         bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
 182         ret = pcim_iomap_regions(pdev, bar_mask, "ccp");
 183         if (ret) {
 184                 dev_err(dev, "pcim_iomap_regions failed (%d)\n", ret);
 185                 goto e_err;
 186         }
 187 
 188         iomap_table = pcim_iomap_table(pdev);
 189         if (!iomap_table) {
 190                 dev_err(dev, "pcim_iomap_table failed\n");
 191                 ret = -ENOMEM;
 192                 goto e_err;
 193         }
 194 
 195         sp->io_map = iomap_table[sp->dev_vdata->bar];
 196         if (!sp->io_map) {
 197                 dev_err(dev, "ioremap failed\n");
 198                 ret = -ENOMEM;
 199                 goto e_err;
 200         }
 201 
 202         ret = sp_get_irqs(sp);
 203         if (ret)
 204                 goto e_err;
 205 
 206         pci_set_master(pdev);
 207         sp->set_psp_master_device = psp_set_master;
 208         sp->get_psp_master_device = psp_get_master;
 209 
 210         ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
 211         if (ret) {
 212                 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 213                 if (ret) {
 214                         dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n",
 215                                 ret);
 216                         goto e_err;
 217                 }
 218         }
 219 
 220         dev_set_drvdata(dev, sp);
 221 
 222         ret = sp_init(sp);
 223         if (ret)
 224                 goto e_err;
 225 
 226         return 0;
 227 
 228 e_err:
 229         dev_notice(dev, "initialization failed\n");
 230         return ret;
 231 }
 232 
 233 static void sp_pci_remove(struct pci_dev *pdev)
 234 {
 235         struct device *dev = &pdev->dev;
 236         struct sp_device *sp = dev_get_drvdata(dev);
 237 
 238         if (!sp)
 239                 return;
 240 
 241         sp_destroy(sp);
 242 
 243         sp_free_irqs(sp);
 244 }
 245 
 246 #ifdef CONFIG_PM
 247 static int sp_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 248 {
 249         struct device *dev = &pdev->dev;
 250         struct sp_device *sp = dev_get_drvdata(dev);
 251 
 252         return sp_suspend(sp, state);
 253 }
 254 
 255 static int sp_pci_resume(struct pci_dev *pdev)
 256 {
 257         struct device *dev = &pdev->dev;
 258         struct sp_device *sp = dev_get_drvdata(dev);
 259 
 260         return sp_resume(sp);
 261 }
 262 #endif
 263 
 264 #ifdef CONFIG_CRYPTO_DEV_SP_PSP
 265 static const struct psp_vdata pspv1 = {
 266         .cmdresp_reg            = 0x10580,
 267         .cmdbuff_addr_lo_reg    = 0x105e0,
 268         .cmdbuff_addr_hi_reg    = 0x105e4,
 269         .feature_reg            = 0x105fc,
 270         .inten_reg              = 0x10610,
 271         .intsts_reg             = 0x10614,
 272 };
 273 
 274 static const struct psp_vdata pspv2 = {
 275         .cmdresp_reg            = 0x10980,
 276         .cmdbuff_addr_lo_reg    = 0x109e0,
 277         .cmdbuff_addr_hi_reg    = 0x109e4,
 278         .feature_reg            = 0x109fc,
 279         .inten_reg              = 0x10690,
 280         .intsts_reg             = 0x10694,
 281 };
 282 #endif
 283 
 284 static const struct sp_dev_vdata dev_vdata[] = {
 285         {       /* 0 */
 286                 .bar = 2,
 287 #ifdef CONFIG_CRYPTO_DEV_SP_CCP
 288                 .ccp_vdata = &ccpv3,
 289 #endif
 290         },
 291         {       /* 1 */
 292                 .bar = 2,
 293 #ifdef CONFIG_CRYPTO_DEV_SP_CCP
 294                 .ccp_vdata = &ccpv5a,
 295 #endif
 296 #ifdef CONFIG_CRYPTO_DEV_SP_PSP
 297                 .psp_vdata = &pspv1,
 298 #endif
 299         },
 300         {       /* 2 */
 301                 .bar = 2,
 302 #ifdef CONFIG_CRYPTO_DEV_SP_CCP
 303                 .ccp_vdata = &ccpv5b,
 304 #endif
 305         },
 306         {       /* 3 */
 307                 .bar = 2,
 308 #ifdef CONFIG_CRYPTO_DEV_SP_CCP
 309                 .ccp_vdata = &ccpv5a,
 310 #endif
 311 #ifdef CONFIG_CRYPTO_DEV_SP_PSP
 312                 .psp_vdata = &pspv2,
 313 #endif
 314         },
 315 };
 316 static const struct pci_device_id sp_pci_table[] = {
 317         { PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)&dev_vdata[0] },
 318         { PCI_VDEVICE(AMD, 0x1456), (kernel_ulong_t)&dev_vdata[1] },
 319         { PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)&dev_vdata[2] },
 320         { PCI_VDEVICE(AMD, 0x1486), (kernel_ulong_t)&dev_vdata[3] },
 321         /* Last entry must be zero */
 322         { 0, }
 323 };
 324 MODULE_DEVICE_TABLE(pci, sp_pci_table);
 325 
 326 static struct pci_driver sp_pci_driver = {
 327         .name = "ccp",
 328         .id_table = sp_pci_table,
 329         .probe = sp_pci_probe,
 330         .remove = sp_pci_remove,
 331 #ifdef CONFIG_PM
 332         .suspend = sp_pci_suspend,
 333         .resume = sp_pci_resume,
 334 #endif
 335 };
 336 
 337 int sp_pci_init(void)
 338 {
 339         return pci_register_driver(&sp_pci_driver);
 340 }
 341 
 342 void sp_pci_exit(void)
 343 {
 344         pci_unregister_driver(&sp_pci_driver);
 345 }

/* [<][>][^][v][top][bottom][index][help] */