root/drivers/staging/uwb/whci.c

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

DEFINITIONS

This source file includes following definitions.
  1. whci_capdata_quirks
  2. whci_wait_for
  3. whci_add_cap
  4. whci_del_cap
  5. whci_n_caps
  6. whci_probe
  7. whci_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * WHCI UWB Multi-interface Controller enumerator.
   4  *
   5  * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
   6  */
   7 #include <linux/delay.h>
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/pci.h>
  11 #include <linux/dma-mapping.h>
  12 #include <linux/slab.h>
  13 #include "include/whci.h"
  14 #include "include/umc.h"
  15 
  16 struct whci_card {
  17         struct pci_dev *pci;
  18         void __iomem *uwbbase;
  19         u8 n_caps;
  20         struct umc_dev *devs[0];
  21 };
  22 
  23 
  24 /* Fix faulty HW :( */
  25 static
  26 u64 whci_capdata_quirks(struct whci_card *card, u64 capdata)
  27 {
  28         u64 capdata_orig = capdata;
  29         struct pci_dev *pci_dev = card->pci;
  30         if (pci_dev->vendor == PCI_VENDOR_ID_INTEL
  31             && (pci_dev->device == 0x0c3b || pci_dev->device == 0004)
  32             && pci_dev->class == 0x0d1010) {
  33                 switch (UWBCAPDATA_TO_CAP_ID(capdata)) {
  34                         /* WLP capability has 0x100 bytes of aperture */
  35                 case 0x80:
  36                         capdata |= 0x40 << 8; break;
  37                         /* WUSB capability has 0x80 bytes of aperture
  38                          * and ID is 1 */
  39                 case 0x02:
  40                         capdata &= ~0xffff;
  41                         capdata |= 0x2001;
  42                         break;
  43                 }
  44         }
  45         if (capdata_orig != capdata)
  46                 dev_warn(&pci_dev->dev,
  47                          "PCI v%04x d%04x c%06x#%02x: "
  48                          "corrected capdata from %016Lx to %016Lx\n",
  49                          pci_dev->vendor, pci_dev->device, pci_dev->class,
  50                          (unsigned)UWBCAPDATA_TO_CAP_ID(capdata),
  51                          (unsigned long long)capdata_orig,
  52                          (unsigned long long)capdata);
  53         return capdata;
  54 }
  55 
  56 
  57 /**
  58  * whci_wait_for - wait for a WHCI register to be set
  59  *
  60  * Polls (for at most @max_ms ms) until '*@reg & @mask == @result'.
  61  */
  62 int whci_wait_for(struct device *dev, u32 __iomem *reg, u32 mask, u32 result,
  63         unsigned long max_ms, const char *tag)
  64 {
  65         unsigned t = 0;
  66         u32 val;
  67         for (;;) {
  68                 val = le_readl(reg);
  69                 if ((val & mask) == result)
  70                         break;
  71                 if (t >= max_ms) {
  72                         dev_err(dev, "%s timed out\n", tag);
  73                         return -ETIMEDOUT;
  74                 }
  75                 msleep(10);
  76                 t += 10;
  77         }
  78         return 0;
  79 }
  80 EXPORT_SYMBOL_GPL(whci_wait_for);
  81 
  82 
  83 /*
  84  * NOTE: the capinfo and capdata registers are slightly different
  85  *       (size and cap-id fields). So for cap #0, we need to fill
  86  *       in. Size comes from the size of the register block
  87  *       (statically calculated); cap_id comes from nowhere, we use
  88  *       zero, that is reserved, for the radio controller, because
  89  *       none was defined at the spec level.
  90  */
  91 static int whci_add_cap(struct whci_card *card, int n)
  92 {
  93         struct umc_dev *umc;
  94         u64 capdata;
  95         int bar, err;
  96 
  97         umc = umc_device_create(&card->pci->dev, n);
  98         if (umc == NULL)
  99                 return -ENOMEM;
 100 
 101         capdata = le_readq(card->uwbbase + UWBCAPDATA(n));
 102 
 103         bar = UWBCAPDATA_TO_BAR(capdata) << 1;
 104 
 105         capdata = whci_capdata_quirks(card, capdata);
 106         /* Capability 0 is the radio controller. It's size is 32
 107          * bytes (WHCI0.95[2.3, T2-9]). */
 108         umc->version         = UWBCAPDATA_TO_VERSION(capdata);
 109         umc->cap_id          = n == 0 ? 0 : UWBCAPDATA_TO_CAP_ID(capdata);
 110         umc->bar             = bar;
 111         umc->resource.start  = pci_resource_start(card->pci, bar)
 112                 + UWBCAPDATA_TO_OFFSET(capdata);
 113         umc->resource.end    = umc->resource.start
 114                 + (n == 0 ? 0x20 : UWBCAPDATA_TO_SIZE(capdata)) - 1;
 115         umc->resource.name   = dev_name(&umc->dev);
 116         umc->resource.flags  = card->pci->resource[bar].flags;
 117         umc->resource.parent = &card->pci->resource[bar];
 118         umc->irq             = card->pci->irq;
 119 
 120         err = umc_device_register(umc);
 121         if (err < 0)
 122                 goto error;
 123         card->devs[n] = umc;
 124         return 0;
 125 
 126 error:
 127         kfree(umc);
 128         return err;
 129 }
 130 
 131 static void whci_del_cap(struct whci_card *card, int n)
 132 {
 133         struct umc_dev *umc = card->devs[n];
 134 
 135         umc_device_unregister(umc);
 136 }
 137 
 138 static int whci_n_caps(struct pci_dev *pci)
 139 {
 140         void __iomem *uwbbase;
 141         u64 capinfo;
 142 
 143         uwbbase = pci_iomap(pci, 0, 8);
 144         if (!uwbbase)
 145                 return -ENOMEM;
 146         capinfo = le_readq(uwbbase + UWBCAPINFO);
 147         pci_iounmap(pci, uwbbase);
 148 
 149         return UWBCAPINFO_TO_N_CAPS(capinfo);
 150 }
 151 
 152 static int whci_probe(struct pci_dev *pci, const struct pci_device_id *id)
 153 {
 154         struct whci_card *card;
 155         int err, n_caps, n;
 156 
 157         err = pci_enable_device(pci);
 158         if (err < 0)
 159                 goto error;
 160         pci_enable_msi(pci);
 161         pci_set_master(pci);
 162         err = -ENXIO;
 163         if (!pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
 164                 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
 165         else if (!pci_set_dma_mask(pci, DMA_BIT_MASK(32)))
 166                 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
 167         else
 168                 goto error_dma;
 169 
 170         err = n_caps = whci_n_caps(pci);
 171         if (n_caps < 0)
 172                 goto error_ncaps;
 173 
 174         err = -ENOMEM;
 175         card = kzalloc(sizeof(struct whci_card)
 176                        + sizeof(struct umc_dev *) * (n_caps + 1),
 177                        GFP_KERNEL);
 178         if (card == NULL)
 179                 goto error_kzalloc;
 180         card->pci = pci;
 181         card->n_caps = n_caps;
 182 
 183         err = -EBUSY;
 184         if (!request_mem_region(pci_resource_start(pci, 0),
 185                                 UWBCAPDATA_SIZE(card->n_caps),
 186                                 "whci (capability data)"))
 187                 goto error_request_memregion;
 188         err = -ENOMEM;
 189         card->uwbbase = pci_iomap(pci, 0, UWBCAPDATA_SIZE(card->n_caps));
 190         if (!card->uwbbase)
 191                 goto error_iomap;
 192 
 193         /* Add each capability. */
 194         for (n = 0; n <= card->n_caps; n++) {
 195                 err = whci_add_cap(card, n);
 196                 if (err < 0 && n == 0) {
 197                         dev_err(&pci->dev, "cannot bind UWB radio controller:"
 198                                 " %d\n", err);
 199                         goto error_bind;
 200                 }
 201                 if (err < 0)
 202                         dev_warn(&pci->dev, "warning: cannot bind capability "
 203                                  "#%u: %d\n", n, err);
 204         }
 205         pci_set_drvdata(pci, card);
 206         return 0;
 207 
 208 error_bind:
 209         pci_iounmap(pci, card->uwbbase);
 210 error_iomap:
 211         release_mem_region(pci_resource_start(pci, 0), UWBCAPDATA_SIZE(card->n_caps));
 212 error_request_memregion:
 213         kfree(card);
 214 error_kzalloc:
 215 error_ncaps:
 216 error_dma:
 217         pci_disable_msi(pci);
 218         pci_disable_device(pci);
 219 error:
 220         return err;
 221 }
 222 
 223 static void whci_remove(struct pci_dev *pci)
 224 {
 225         struct whci_card *card = pci_get_drvdata(pci);
 226         int n;
 227 
 228         pci_set_drvdata(pci, NULL);
 229         /* Unregister each capability in reverse (so the master device
 230          * is unregistered last). */
 231         for (n = card->n_caps; n >= 0 ; n--)
 232                 whci_del_cap(card, n);
 233         pci_iounmap(pci, card->uwbbase);
 234         release_mem_region(pci_resource_start(pci, 0), UWBCAPDATA_SIZE(card->n_caps));
 235         kfree(card);
 236         pci_disable_msi(pci);
 237         pci_disable_device(pci);
 238 }
 239 
 240 static struct pci_device_id whci_id_table[] = {
 241         { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) },
 242         { 0 },
 243 };
 244 MODULE_DEVICE_TABLE(pci, whci_id_table);
 245 
 246 
 247 static struct pci_driver whci_driver = {
 248         .name     = "whci",
 249         .id_table = whci_id_table,
 250         .probe    = whci_probe,
 251         .remove   = whci_remove,
 252 };
 253 
 254 module_pci_driver(whci_driver);
 255 MODULE_DESCRIPTION("WHCI UWB Multi-interface Controller enumerator");
 256 MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
 257 MODULE_LICENSE("GPL");

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