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
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 #define DRIVER_NAME "orinoco_plx"
0087 #define PFX DRIVER_NAME ": "
0088
0089 #include <linux/module.h>
0090 #include <linux/kernel.h>
0091 #include <linux/init.h>
0092 #include <linux/delay.h>
0093 #include <linux/pci.h>
0094 #include <pcmcia/cisreg.h>
0095
0096 #include "orinoco.h"
0097 #include "orinoco_pci.h"
0098
0099 #define COR_OFFSET (0x3e0)
0100 #define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA)
0101 #define COR_RESET (0x80)
0102 #define PLX_RESET_TIME (500)
0103
0104 #define PLX_INTCSR 0x4c
0105 #define PLX_INTCSR_INTEN (1 << 6)
0106
0107
0108
0109
0110 static int orinoco_plx_cor_reset(struct orinoco_private *priv)
0111 {
0112 struct hermes *hw = &priv->hw;
0113 struct orinoco_pci_card *card = priv->card;
0114 unsigned long timeout;
0115 u16 reg;
0116
0117 iowrite8(COR_VALUE | COR_RESET, card->attr_io + COR_OFFSET);
0118 mdelay(1);
0119
0120 iowrite8(COR_VALUE, card->attr_io + COR_OFFSET);
0121 mdelay(1);
0122
0123
0124 timeout = jiffies + msecs_to_jiffies(PLX_RESET_TIME);
0125 reg = hermes_read_regn(hw, CMD);
0126 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
0127 mdelay(1);
0128 reg = hermes_read_regn(hw, CMD);
0129 }
0130
0131
0132 if (reg & HERMES_CMD_BUSY) {
0133 printk(KERN_ERR PFX "Busy timeout\n");
0134 return -ETIMEDOUT;
0135 }
0136
0137 return 0;
0138 }
0139
0140 static int orinoco_plx_hw_init(struct orinoco_pci_card *card)
0141 {
0142 int i;
0143 u32 csr_reg;
0144 static const u8 cis_magic[] = {
0145 0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67
0146 };
0147
0148 printk(KERN_DEBUG PFX "CIS: ");
0149 for (i = 0; i < 16; i++)
0150 printk("%02X:", ioread8(card->attr_io + (i << 1)));
0151 printk("\n");
0152
0153
0154
0155 for (i = 0; i < sizeof(cis_magic); i++) {
0156 if (cis_magic[i] != ioread8(card->attr_io + (i << 1))) {
0157 printk(KERN_ERR PFX "The CIS value of Prism2 PC "
0158 "card is unexpected\n");
0159 return -ENODEV;
0160 }
0161 }
0162
0163
0164
0165
0166 csr_reg = ioread32(card->bridge_io + PLX_INTCSR);
0167 if (!(csr_reg & PLX_INTCSR_INTEN)) {
0168 csr_reg |= PLX_INTCSR_INTEN;
0169 iowrite32(csr_reg, card->bridge_io + PLX_INTCSR);
0170 csr_reg = ioread32(card->bridge_io + PLX_INTCSR);
0171 if (!(csr_reg & PLX_INTCSR_INTEN)) {
0172 printk(KERN_ERR PFX "Cannot enable interrupts\n");
0173 return -EIO;
0174 }
0175 }
0176
0177 return 0;
0178 }
0179
0180 static int orinoco_plx_init_one(struct pci_dev *pdev,
0181 const struct pci_device_id *ent)
0182 {
0183 int err;
0184 struct orinoco_private *priv;
0185 struct orinoco_pci_card *card;
0186 void __iomem *hermes_io, *attr_io, *bridge_io;
0187
0188 err = pci_enable_device(pdev);
0189 if (err) {
0190 printk(KERN_ERR PFX "Cannot enable PCI device\n");
0191 return err;
0192 }
0193
0194 err = pci_request_regions(pdev, DRIVER_NAME);
0195 if (err) {
0196 printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
0197 goto fail_resources;
0198 }
0199
0200 bridge_io = pci_iomap(pdev, 1, 0);
0201 if (!bridge_io) {
0202 printk(KERN_ERR PFX "Cannot map bridge registers\n");
0203 err = -EIO;
0204 goto fail_map_bridge;
0205 }
0206
0207 attr_io = pci_iomap(pdev, 2, 0);
0208 if (!attr_io) {
0209 printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n");
0210 err = -EIO;
0211 goto fail_map_attr;
0212 }
0213
0214 hermes_io = pci_iomap(pdev, 3, 0);
0215 if (!hermes_io) {
0216 printk(KERN_ERR PFX "Cannot map chipset registers\n");
0217 err = -EIO;
0218 goto fail_map_hermes;
0219 }
0220
0221
0222 priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
0223 orinoco_plx_cor_reset, NULL);
0224 if (!priv) {
0225 printk(KERN_ERR PFX "Cannot allocate network device\n");
0226 err = -ENOMEM;
0227 goto fail_alloc;
0228 }
0229
0230 card = priv->card;
0231 card->bridge_io = bridge_io;
0232 card->attr_io = attr_io;
0233
0234 hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
0235
0236 err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
0237 DRIVER_NAME, priv);
0238 if (err) {
0239 printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
0240 err = -EBUSY;
0241 goto fail_irq;
0242 }
0243
0244 err = orinoco_plx_hw_init(card);
0245 if (err) {
0246 printk(KERN_ERR PFX "Hardware initialization failed\n");
0247 goto fail;
0248 }
0249
0250 err = orinoco_plx_cor_reset(priv);
0251 if (err) {
0252 printk(KERN_ERR PFX "Initial reset failed\n");
0253 goto fail;
0254 }
0255
0256 err = orinoco_init(priv);
0257 if (err) {
0258 printk(KERN_ERR PFX "orinoco_init() failed\n");
0259 goto fail;
0260 }
0261
0262 err = orinoco_if_add(priv, 0, 0, NULL);
0263 if (err) {
0264 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
0265 goto fail_wiphy;
0266 }
0267
0268 pci_set_drvdata(pdev, priv);
0269
0270 return 0;
0271
0272 fail_wiphy:
0273 wiphy_unregister(priv_to_wiphy(priv));
0274 fail:
0275 free_irq(pdev->irq, priv);
0276
0277 fail_irq:
0278 free_orinocodev(priv);
0279
0280 fail_alloc:
0281 pci_iounmap(pdev, hermes_io);
0282
0283 fail_map_hermes:
0284 pci_iounmap(pdev, attr_io);
0285
0286 fail_map_attr:
0287 pci_iounmap(pdev, bridge_io);
0288
0289 fail_map_bridge:
0290 pci_release_regions(pdev);
0291
0292 fail_resources:
0293 pci_disable_device(pdev);
0294
0295 return err;
0296 }
0297
0298 static void orinoco_plx_remove_one(struct pci_dev *pdev)
0299 {
0300 struct orinoco_private *priv = pci_get_drvdata(pdev);
0301 struct orinoco_pci_card *card = priv->card;
0302
0303 orinoco_if_del(priv);
0304 wiphy_unregister(priv_to_wiphy(priv));
0305 free_irq(pdev->irq, priv);
0306 free_orinocodev(priv);
0307 pci_iounmap(pdev, priv->hw.iobase);
0308 pci_iounmap(pdev, card->attr_io);
0309 pci_iounmap(pdev, card->bridge_io);
0310 pci_release_regions(pdev);
0311 pci_disable_device(pdev);
0312 }
0313
0314 static const struct pci_device_id orinoco_plx_id_table[] = {
0315 {0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,},
0316 {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,},
0317 {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},
0318 {0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},
0319
0320
0321 {0x16ab, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},
0322 {0x16ab, 0x1101, PCI_ANY_ID, PCI_ANY_ID,},
0323 {0x16ab, 0x1102, PCI_ANY_ID, PCI_ANY_ID,},
0324 {0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,},
0325 {0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,},
0326
0327 {0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,},
0328
0329 {0,},
0330 };
0331
0332 MODULE_DEVICE_TABLE(pci, orinoco_plx_id_table);
0333
0334 static struct pci_driver orinoco_plx_driver = {
0335 .name = DRIVER_NAME,
0336 .id_table = orinoco_plx_id_table,
0337 .probe = orinoco_plx_init_one,
0338 .remove = orinoco_plx_remove_one,
0339 .driver.pm = &orinoco_pci_pm_ops,
0340 };
0341
0342 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
0343 " (Pavel Roskin <proski@gnu.org>,"
0344 " David Gibson <hermes@gibson.dropbear.id.au>,"
0345 " Daniel Barlow <dan@telent.net>)";
0346 MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
0347 MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
0348 MODULE_LICENSE("Dual MPL/GPL");
0349
0350 static int __init orinoco_plx_init(void)
0351 {
0352 printk(KERN_DEBUG "%s\n", version);
0353 return pci_register_driver(&orinoco_plx_driver);
0354 }
0355
0356 static void __exit orinoco_plx_exit(void)
0357 {
0358 pci_unregister_driver(&orinoco_plx_driver);
0359 }
0360
0361 module_init(orinoco_plx_init);
0362 module_exit(orinoco_plx_exit);