Back to home page

OSCL-LXR

 
 

    


0001 /* orinoco_plx.c
0002  *
0003  * Driver for Prism II devices which would usually be driven by orinoco_cs,
0004  * but are connected to the PCI bus by a PLX9052.
0005  *
0006  * Current maintainers are:
0007  *  Pavel Roskin <proski AT gnu.org>
0008  * and  David Gibson <hermes AT gibson.dropbear.id.au>
0009  *
0010  * (C) Copyright David Gibson, IBM Corp. 2001-2003.
0011  * Copyright (C) 2001 Daniel Barlow
0012  *
0013  * The contents of this file are subject to the Mozilla Public License
0014  * Version 1.1 (the "License"); you may not use this file except in
0015  * compliance with the License. You may obtain a copy of the License
0016  * at http://www.mozilla.org/MPL/
0017  *
0018  * Software distributed under the License is distributed on an "AS IS"
0019  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
0020  * the License for the specific language governing rights and
0021  * limitations under the License.
0022  *
0023  * Alternatively, the contents of this file may be used under the
0024  * terms of the GNU General Public License version 2 (the "GPL"), in
0025  * which case the provisions of the GPL are applicable instead of the
0026  * above.  If you wish to allow the use of your version of this file
0027  * only under the terms of the GPL and not to allow others to use your
0028  * version of this file under the MPL, indicate your decision by
0029  * deleting the provisions above and replace them with the notice and
0030  * other provisions required by the GPL.  If you do not delete the
0031  * provisions above, a recipient may use your version of this file
0032  * under either the MPL or the GPL.
0033  *
0034  * Here's the general details on how the PLX9052 adapter works:
0035  *
0036  * - Two PCI I/O address spaces, one 0x80 long which contains the
0037  * PLX9052 registers, and one that's 0x40 long mapped to the PCMCIA
0038  * slot I/O address space.
0039  *
0040  * - One PCI memory address space, mapped to the PCMCIA attribute space
0041  * (containing the CIS).
0042  *
0043  * Using the later, you can read through the CIS data to make sure the
0044  * card is compatible with the driver. Keep in mind that the PCMCIA
0045  * spec specifies the CIS as the lower 8 bits of each word read from
0046  * the CIS, so to read the bytes of the CIS, read every other byte
0047  * (0,2,4,...). Passing that test, you need to enable the I/O address
0048  * space on the PCMCIA card via the PCMCIA COR register. This is the
0049  * first byte following the CIS. In my case (which may not have any
0050  * relation to what's on the PRISM2 cards), COR was at offset 0x800
0051  * within the PCI memory space. Write 0x41 to the COR register to
0052  * enable I/O mode and to select level triggered interrupts. To
0053  * confirm you actually succeeded, read the COR register back and make
0054  * sure it actually got set to 0x41, in case you have an unexpected
0055  * card inserted.
0056  *
0057  * Following that, you can treat the second PCI I/O address space (the
0058  * one that's not 0x80 in length) as the PCMCIA I/O space.
0059  *
0060  * Note that in the Eumitcom's source for their drivers, they register
0061  * the interrupt as edge triggered when registering it with the
0062  * Windows kernel. I don't recall how to register edge triggered on
0063  * Linux (if it can be done at all). But in some experimentation, I
0064  * don't see much operational difference between using either
0065  * interrupt mode. Don't mess with the interrupt mode in the COR
0066  * register though, as the PLX9052 wants level triggers with the way
0067  * the serial EEPROM configures it on the WL11000.
0068  *
0069  * There's some other little quirks related to timing that I bumped
0070  * into, but I don't recall right now. Also, there's two variants of
0071  * the WL11000 I've seen, revision A1 and T2. These seem to differ
0072  * slightly in the timings configured in the wait-state generator in
0073  * the PLX9052. There have also been some comments from Eumitcom that
0074  * cards shouldn't be hot swapped, apparently due to risk of cooking
0075  * the PLX9052. I'm unsure why they believe this, as I can't see
0076  * anything in the design that would really cause a problem, except
0077  * for crashing drivers not written to expect it. And having developed
0078  * drivers for the WL11000, I'd say it's quite tricky to write code
0079  * that will successfully deal with a hot unplug. Very odd things
0080  * happen on the I/O side of things. But anyway, be warned. Despite
0081  * that, I've hot-swapped a number of times during debugging and
0082  * driver development for various reasons (stuck WAIT# line after the
0083  * radio card's firmware locks up).
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) /* COR attribute offset of Prism2 PC card */
0100 #define COR_VALUE   (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
0101 #define COR_RESET     (0x80)    /* reset bit in the COR register */
0102 #define PLX_RESET_TIME  (500)   /* milliseconds */
0103 
0104 #define PLX_INTCSR      0x4c /* Interrupt Control & Status Register */
0105 #define PLX_INTCSR_INTEN    (1 << 6) /* Interrupt Enable bit */
0106 
0107 /*
0108  * Do a soft reset of the card using the Configuration Option Register
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     /* Just in case, wait more until the card is no longer busy */
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     /* Still busy? */
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     /* Verify whether a supported PC card is present */
0154     /* FIXME: we probably need to be smarted about this */
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     /* bjoern: We need to tell the card to enable interrupts, in
0164        case the serial eprom didn't do this already.  See the
0165        PLX9052 data book, p8-1 and 8-24 for reference. */
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     /* Allocate network device */
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,},  /* Siemens SpeedStream SS1023 */
0316     {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,},  /* Netgear MA301 */
0317     {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},  /* Correga  - does this work? */
0318     {0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},  /* SMC EZConnect SMC2602W,
0319                                Eumitcom PCI WL11000,
0320                                Addtron AWA-100 */
0321     {0x16ab, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},  /* Global Sun Tech GL24110P */
0322     {0x16ab, 0x1101, PCI_ANY_ID, PCI_ANY_ID,},  /* Reported working, but unknown */
0323     {0x16ab, 0x1102, PCI_ANY_ID, PCI_ANY_ID,},  /* Linksys WDT11 */
0324     {0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,},  /* USR 2415 */
0325     {0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,},  /* Belkin F5D6000 tested by
0326                                Brendan W. McAdams <rit AT jacked-in.org> */
0327     {0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,},  /* 3Com AirConnect PCI tested by
0328                                Damien Persohn <damien AT persohn.net> */
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);