0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #define DRIVER_NAME "orinoco_nortel"
0041 #define PFX DRIVER_NAME ": "
0042
0043 #include <linux/module.h>
0044 #include <linux/kernel.h>
0045 #include <linux/init.h>
0046 #include <linux/delay.h>
0047 #include <linux/pci.h>
0048 #include <pcmcia/cisreg.h>
0049
0050 #include "orinoco.h"
0051 #include "orinoco_pci.h"
0052
0053 #define COR_OFFSET (0xe0)
0054 #define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA)
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 static int orinoco_nortel_cor_reset(struct orinoco_private *priv)
0066 {
0067 struct orinoco_pci_card *card = priv->card;
0068
0069
0070 iowrite16(8, card->bridge_io + 2);
0071 ioread16(card->attr_io + COR_OFFSET);
0072 iowrite16(0x80, card->attr_io + COR_OFFSET);
0073 mdelay(1);
0074
0075
0076 iowrite16(0, card->attr_io + COR_OFFSET);
0077 iowrite16(0, card->attr_io + COR_OFFSET);
0078 mdelay(1);
0079
0080
0081 iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
0082 iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
0083 mdelay(1);
0084
0085 iowrite16(0x228, card->bridge_io + 2);
0086
0087 return 0;
0088 }
0089
0090 static int orinoco_nortel_hw_init(struct orinoco_pci_card *card)
0091 {
0092 int i;
0093 u32 reg;
0094
0095
0096 if (ioread16(card->bridge_io) & 1) {
0097 printk(KERN_ERR PFX "brg1 answer1 wrong\n");
0098 return -EBUSY;
0099 }
0100 iowrite16(0x118, card->bridge_io + 2);
0101 iowrite16(0x108, card->bridge_io + 2);
0102 mdelay(30);
0103 iowrite16(0x8, card->bridge_io + 2);
0104 for (i = 0; i < 30; i++) {
0105 mdelay(30);
0106 if (ioread16(card->bridge_io) & 0x10)
0107 break;
0108 }
0109 if (i == 30) {
0110 printk(KERN_ERR PFX "brg1 timed out\n");
0111 return -EBUSY;
0112 }
0113 if (ioread16(card->attr_io + COR_OFFSET) & 1) {
0114 printk(KERN_ERR PFX "brg2 answer1 wrong\n");
0115 return -EBUSY;
0116 }
0117 if (ioread16(card->attr_io + COR_OFFSET + 2) & 1) {
0118 printk(KERN_ERR PFX "brg2 answer2 wrong\n");
0119 return -EBUSY;
0120 }
0121 if (ioread16(card->attr_io + COR_OFFSET + 4) & 1) {
0122 printk(KERN_ERR PFX "brg2 answer3 wrong\n");
0123 return -EBUSY;
0124 }
0125
0126
0127 iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
0128 mdelay(1);
0129 reg = ioread16(card->attr_io + COR_OFFSET);
0130 if (reg != COR_VALUE) {
0131 printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n",
0132 reg);
0133 return -EBUSY;
0134 }
0135
0136
0137 iowrite16(1, card->bridge_io + 10);
0138 return 0;
0139 }
0140
0141 static int orinoco_nortel_init_one(struct pci_dev *pdev,
0142 const struct pci_device_id *ent)
0143 {
0144 int err;
0145 struct orinoco_private *priv;
0146 struct orinoco_pci_card *card;
0147 void __iomem *hermes_io, *bridge_io, *attr_io;
0148
0149 err = pci_enable_device(pdev);
0150 if (err) {
0151 printk(KERN_ERR PFX "Cannot enable PCI device\n");
0152 return err;
0153 }
0154
0155 err = pci_request_regions(pdev, DRIVER_NAME);
0156 if (err) {
0157 printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
0158 goto fail_resources;
0159 }
0160
0161 bridge_io = pci_iomap(pdev, 0, 0);
0162 if (!bridge_io) {
0163 printk(KERN_ERR PFX "Cannot map bridge registers\n");
0164 err = -EIO;
0165 goto fail_map_bridge;
0166 }
0167
0168 attr_io = pci_iomap(pdev, 1, 0);
0169 if (!attr_io) {
0170 printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n");
0171 err = -EIO;
0172 goto fail_map_attr;
0173 }
0174
0175 hermes_io = pci_iomap(pdev, 2, 0);
0176 if (!hermes_io) {
0177 printk(KERN_ERR PFX "Cannot map chipset registers\n");
0178 err = -EIO;
0179 goto fail_map_hermes;
0180 }
0181
0182
0183 priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
0184 orinoco_nortel_cor_reset, NULL);
0185 if (!priv) {
0186 printk(KERN_ERR PFX "Cannot allocate network device\n");
0187 err = -ENOMEM;
0188 goto fail_alloc;
0189 }
0190
0191 card = priv->card;
0192 card->bridge_io = bridge_io;
0193 card->attr_io = attr_io;
0194
0195 hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
0196
0197 err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
0198 DRIVER_NAME, priv);
0199 if (err) {
0200 printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
0201 err = -EBUSY;
0202 goto fail_irq;
0203 }
0204
0205 err = orinoco_nortel_hw_init(card);
0206 if (err) {
0207 printk(KERN_ERR PFX "Hardware initialization failed\n");
0208 goto fail;
0209 }
0210
0211 err = orinoco_nortel_cor_reset(priv);
0212 if (err) {
0213 printk(KERN_ERR PFX "Initial reset failed\n");
0214 goto fail;
0215 }
0216
0217 err = orinoco_init(priv);
0218 if (err) {
0219 printk(KERN_ERR PFX "orinoco_init() failed\n");
0220 goto fail;
0221 }
0222
0223 err = orinoco_if_add(priv, 0, 0, NULL);
0224 if (err) {
0225 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
0226 goto fail_wiphy;
0227 }
0228
0229 pci_set_drvdata(pdev, priv);
0230
0231 return 0;
0232
0233 fail_wiphy:
0234 wiphy_unregister(priv_to_wiphy(priv));
0235 fail:
0236 free_irq(pdev->irq, priv);
0237
0238 fail_irq:
0239 free_orinocodev(priv);
0240
0241 fail_alloc:
0242 pci_iounmap(pdev, hermes_io);
0243
0244 fail_map_hermes:
0245 pci_iounmap(pdev, attr_io);
0246
0247 fail_map_attr:
0248 pci_iounmap(pdev, bridge_io);
0249
0250 fail_map_bridge:
0251 pci_release_regions(pdev);
0252
0253 fail_resources:
0254 pci_disable_device(pdev);
0255
0256 return err;
0257 }
0258
0259 static void orinoco_nortel_remove_one(struct pci_dev *pdev)
0260 {
0261 struct orinoco_private *priv = pci_get_drvdata(pdev);
0262 struct orinoco_pci_card *card = priv->card;
0263
0264
0265 iowrite16(0, card->bridge_io + 10);
0266
0267 orinoco_if_del(priv);
0268 wiphy_unregister(priv_to_wiphy(priv));
0269 free_irq(pdev->irq, priv);
0270 free_orinocodev(priv);
0271 pci_iounmap(pdev, priv->hw.iobase);
0272 pci_iounmap(pdev, card->attr_io);
0273 pci_iounmap(pdev, card->bridge_io);
0274 pci_release_regions(pdev);
0275 pci_disable_device(pdev);
0276 }
0277
0278 static const struct pci_device_id orinoco_nortel_id_table[] = {
0279
0280 {0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
0281
0282 {0x1562, 0x0001, PCI_ANY_ID, PCI_ANY_ID,},
0283 {0,},
0284 };
0285
0286 MODULE_DEVICE_TABLE(pci, orinoco_nortel_id_table);
0287
0288 static struct pci_driver orinoco_nortel_driver = {
0289 .name = DRIVER_NAME,
0290 .id_table = orinoco_nortel_id_table,
0291 .probe = orinoco_nortel_init_one,
0292 .remove = orinoco_nortel_remove_one,
0293 .driver.pm = &orinoco_pci_pm_ops,
0294 };
0295
0296 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
0297 " (Tobias Hoffmann & Christoph Jungegger <disdos@traum404.de>)";
0298 MODULE_AUTHOR("Christoph Jungegger <disdos@traum404.de>");
0299 MODULE_DESCRIPTION("Driver for wireless LAN cards using the Nortel PCI bridge");
0300 MODULE_LICENSE("Dual MPL/GPL");
0301
0302 static int __init orinoco_nortel_init(void)
0303 {
0304 printk(KERN_DEBUG "%s\n", version);
0305 return pci_register_driver(&orinoco_nortel_driver);
0306 }
0307
0308 static void __exit orinoco_nortel_exit(void)
0309 {
0310 pci_unregister_driver(&orinoco_nortel_driver);
0311 }
0312
0313 module_init(orinoco_nortel_init);
0314 module_exit(orinoco_nortel_exit);