0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/module.h>
0021 #include <linux/pci.h>
0022
0023 #include "ctucanfd.h"
0024
0025 #ifndef PCI_DEVICE_DATA
0026 #define PCI_DEVICE_DATA(vend, dev, data) \
0027 .vendor = PCI_VENDOR_ID_##vend, \
0028 .device = PCI_DEVICE_ID_##vend##_##dev, \
0029 .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0, \
0030 .driver_data = (kernel_ulong_t)(data)
0031 #endif
0032
0033 #ifndef PCI_VENDOR_ID_TEDIA
0034 #define PCI_VENDOR_ID_TEDIA 0x1760
0035 #endif
0036
0037 #ifndef PCI_DEVICE_ID_TEDIA_CTUCAN_VER21
0038 #define PCI_DEVICE_ID_TEDIA_CTUCAN_VER21 0xff00
0039 #endif
0040
0041 #define CTUCAN_BAR0_CTUCAN_ID 0x0000
0042 #define CTUCAN_BAR0_CRA_BASE 0x4000
0043 #define CYCLONE_IV_CRA_A2P_IE (0x0050)
0044
0045 #define CTUCAN_WITHOUT_CTUCAN_ID 0
0046 #define CTUCAN_WITH_CTUCAN_ID 1
0047
0048 struct ctucan_pci_board_data {
0049 void __iomem *bar0_base;
0050 void __iomem *cra_base;
0051 void __iomem *bar1_base;
0052 struct list_head ndev_list_head;
0053 int use_msi;
0054 };
0055
0056 static struct ctucan_pci_board_data *ctucan_pci_get_bdata(struct pci_dev *pdev)
0057 {
0058 return (struct ctucan_pci_board_data *)pci_get_drvdata(pdev);
0059 }
0060
0061 static void ctucan_pci_set_drvdata(struct device *dev,
0062 struct net_device *ndev)
0063 {
0064 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
0065 struct ctucan_priv *priv = netdev_priv(ndev);
0066 struct ctucan_pci_board_data *bdata = ctucan_pci_get_bdata(pdev);
0067
0068 list_add(&priv->peers_on_pdev, &bdata->ndev_list_head);
0069 priv->irq_flags = IRQF_SHARED;
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 static int ctucan_pci_probe(struct pci_dev *pdev,
0083 const struct pci_device_id *ent)
0084 {
0085 struct device *dev = &pdev->dev;
0086 unsigned long driver_data = ent->driver_data;
0087 struct ctucan_pci_board_data *bdata;
0088 void __iomem *addr;
0089 void __iomem *cra_addr;
0090 void __iomem *bar0_base;
0091 u32 cra_a2p_ie;
0092 u32 ctucan_id = 0;
0093 int ret;
0094 unsigned int ntxbufs;
0095 unsigned int num_cores = 1;
0096 unsigned int core_i = 0;
0097 int irq;
0098 int msi_ok = 0;
0099
0100 ret = pci_enable_device(pdev);
0101 if (ret) {
0102 dev_err(dev, "pci_enable_device FAILED\n");
0103 goto err;
0104 }
0105
0106 ret = pci_request_regions(pdev, KBUILD_MODNAME);
0107 if (ret) {
0108 dev_err(dev, "pci_request_regions FAILED\n");
0109 goto err_disable_device;
0110 }
0111
0112 ret = pci_enable_msi(pdev);
0113 if (!ret) {
0114 dev_info(dev, "MSI enabled\n");
0115 pci_set_master(pdev);
0116 msi_ok = 1;
0117 }
0118
0119 dev_info(dev, "ctucan BAR0 0x%08llx 0x%08llx\n",
0120 (long long)pci_resource_start(pdev, 0),
0121 (long long)pci_resource_len(pdev, 0));
0122
0123 dev_info(dev, "ctucan BAR1 0x%08llx 0x%08llx\n",
0124 (long long)pci_resource_start(pdev, 1),
0125 (long long)pci_resource_len(pdev, 1));
0126
0127 addr = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
0128 if (!addr) {
0129 dev_err(dev, "PCI BAR 1 cannot be mapped\n");
0130 ret = -ENOMEM;
0131 goto err_release_regions;
0132 }
0133
0134
0135 bar0_base = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
0136 if (!bar0_base) {
0137 dev_err(dev, "PCI BAR 0 cannot be mapped\n");
0138 ret = -EIO;
0139 goto err_pci_iounmap_bar1;
0140 }
0141
0142 if (driver_data == CTUCAN_WITHOUT_CTUCAN_ID) {
0143 cra_addr = bar0_base;
0144 num_cores = 2;
0145 } else {
0146 cra_addr = bar0_base + CTUCAN_BAR0_CRA_BASE;
0147 ctucan_id = ioread32(bar0_base + CTUCAN_BAR0_CTUCAN_ID);
0148 dev_info(dev, "ctucan_id 0x%08lx\n", (unsigned long)ctucan_id);
0149 num_cores = ctucan_id & 0xf;
0150 }
0151
0152 irq = pdev->irq;
0153
0154 ntxbufs = 4;
0155
0156 bdata = kzalloc(sizeof(*bdata), GFP_KERNEL);
0157 if (!bdata) {
0158 ret = -ENOMEM;
0159 goto err_pci_iounmap_bar0;
0160 }
0161
0162 INIT_LIST_HEAD(&bdata->ndev_list_head);
0163 bdata->bar0_base = bar0_base;
0164 bdata->cra_base = cra_addr;
0165 bdata->bar1_base = addr;
0166 bdata->use_msi = msi_ok;
0167
0168 pci_set_drvdata(pdev, bdata);
0169
0170 ret = ctucan_probe_common(dev, addr, irq, ntxbufs, 100000000,
0171 0, ctucan_pci_set_drvdata);
0172 if (ret < 0)
0173 goto err_free_board;
0174
0175 core_i++;
0176
0177 while (core_i < num_cores) {
0178 addr += 0x4000;
0179 ret = ctucan_probe_common(dev, addr, irq, ntxbufs, 100000000,
0180 0, ctucan_pci_set_drvdata);
0181 if (ret < 0) {
0182 dev_info(dev, "CTU CAN FD core %d initialization failed\n",
0183 core_i);
0184 break;
0185 }
0186 core_i++;
0187 }
0188
0189
0190
0191
0192 cra_a2p_ie = ioread32(cra_addr + CYCLONE_IV_CRA_A2P_IE);
0193 dev_info(dev, "cra_a2p_ie 0x%08x\n", cra_a2p_ie);
0194 cra_a2p_ie |= 1;
0195 iowrite32(cra_a2p_ie, cra_addr + CYCLONE_IV_CRA_A2P_IE);
0196 cra_a2p_ie = ioread32(cra_addr + CYCLONE_IV_CRA_A2P_IE);
0197 dev_info(dev, "cra_a2p_ie 0x%08x\n", cra_a2p_ie);
0198
0199 return 0;
0200
0201 err_free_board:
0202 pci_set_drvdata(pdev, NULL);
0203 kfree(bdata);
0204 err_pci_iounmap_bar0:
0205 pci_iounmap(pdev, cra_addr);
0206 err_pci_iounmap_bar1:
0207 pci_iounmap(pdev, addr);
0208 err_release_regions:
0209 if (msi_ok) {
0210 pci_disable_msi(pdev);
0211 pci_clear_master(pdev);
0212 }
0213 pci_release_regions(pdev);
0214 err_disable_device:
0215 pci_disable_device(pdev);
0216 err:
0217 return ret;
0218 }
0219
0220
0221
0222
0223
0224
0225
0226
0227 static void ctucan_pci_remove(struct pci_dev *pdev)
0228 {
0229 struct net_device *ndev;
0230 struct ctucan_priv *priv = NULL;
0231 struct ctucan_pci_board_data *bdata = ctucan_pci_get_bdata(pdev);
0232
0233 dev_dbg(&pdev->dev, "ctucan_remove");
0234
0235 if (!bdata) {
0236 dev_err(&pdev->dev, "%s: no list of devices\n", __func__);
0237 return;
0238 }
0239
0240
0241
0242
0243 if (bdata->cra_base)
0244 iowrite32(0, bdata->cra_base + CYCLONE_IV_CRA_A2P_IE);
0245
0246 while ((priv = list_first_entry_or_null(&bdata->ndev_list_head, struct ctucan_priv,
0247 peers_on_pdev)) != NULL) {
0248 ndev = priv->can.dev;
0249
0250 unregister_candev(ndev);
0251
0252 netif_napi_del(&priv->napi);
0253
0254 list_del_init(&priv->peers_on_pdev);
0255 free_candev(ndev);
0256 }
0257
0258 pci_iounmap(pdev, bdata->bar1_base);
0259
0260 if (bdata->use_msi) {
0261 pci_disable_msi(pdev);
0262 pci_clear_master(pdev);
0263 }
0264
0265 pci_release_regions(pdev);
0266 pci_disable_device(pdev);
0267
0268 pci_iounmap(pdev, bdata->bar0_base);
0269
0270 pci_set_drvdata(pdev, NULL);
0271 kfree(bdata);
0272 }
0273
0274 static SIMPLE_DEV_PM_OPS(ctucan_pci_pm_ops, ctucan_suspend, ctucan_resume);
0275
0276 static const struct pci_device_id ctucan_pci_tbl[] = {
0277 {PCI_DEVICE_DATA(TEDIA, CTUCAN_VER21,
0278 CTUCAN_WITH_CTUCAN_ID)},
0279 {},
0280 };
0281
0282 static struct pci_driver ctucan_pci_driver = {
0283 .name = KBUILD_MODNAME,
0284 .id_table = ctucan_pci_tbl,
0285 .probe = ctucan_pci_probe,
0286 .remove = ctucan_pci_remove,
0287 .driver.pm = &ctucan_pci_pm_ops,
0288 };
0289
0290 module_pci_driver(ctucan_pci_driver);
0291
0292 MODULE_LICENSE("GPL");
0293 MODULE_AUTHOR("Pavel Pisa <pisa@cmp.felk.cvut.cz>");
0294 MODULE_DESCRIPTION("CTU CAN FD for PCI bus");