whci.c 6.4 KB

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