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_tmd"
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_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA)
0054 #define COR_RESET (0x80)
0055 #define TMD_RESET_TIME (500)
0056
0057
0058
0059
0060 static int orinoco_tmd_cor_reset(struct orinoco_private *priv)
0061 {
0062 struct hermes *hw = &priv->hw;
0063 struct orinoco_pci_card *card = priv->card;
0064 unsigned long timeout;
0065 u16 reg;
0066
0067 iowrite8(COR_VALUE | COR_RESET, card->bridge_io);
0068 mdelay(1);
0069
0070 iowrite8(COR_VALUE, card->bridge_io);
0071 mdelay(1);
0072
0073
0074 timeout = jiffies + msecs_to_jiffies(TMD_RESET_TIME);
0075 reg = hermes_read_regn(hw, CMD);
0076 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
0077 mdelay(1);
0078 reg = hermes_read_regn(hw, CMD);
0079 }
0080
0081
0082 if (reg & HERMES_CMD_BUSY) {
0083 printk(KERN_ERR PFX "Busy timeout\n");
0084 return -ETIMEDOUT;
0085 }
0086
0087 return 0;
0088 }
0089
0090
0091 static int orinoco_tmd_init_one(struct pci_dev *pdev,
0092 const struct pci_device_id *ent)
0093 {
0094 int err;
0095 struct orinoco_private *priv;
0096 struct orinoco_pci_card *card;
0097 void __iomem *hermes_io, *bridge_io;
0098
0099 err = pci_enable_device(pdev);
0100 if (err) {
0101 printk(KERN_ERR PFX "Cannot enable PCI device\n");
0102 return err;
0103 }
0104
0105 err = pci_request_regions(pdev, DRIVER_NAME);
0106 if (err) {
0107 printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
0108 goto fail_resources;
0109 }
0110
0111 bridge_io = pci_iomap(pdev, 1, 0);
0112 if (!bridge_io) {
0113 printk(KERN_ERR PFX "Cannot map bridge registers\n");
0114 err = -EIO;
0115 goto fail_map_bridge;
0116 }
0117
0118 hermes_io = pci_iomap(pdev, 2, 0);
0119 if (!hermes_io) {
0120 printk(KERN_ERR PFX "Cannot map chipset registers\n");
0121 err = -EIO;
0122 goto fail_map_hermes;
0123 }
0124
0125
0126 priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
0127 orinoco_tmd_cor_reset, NULL);
0128 if (!priv) {
0129 printk(KERN_ERR PFX "Cannot allocate network device\n");
0130 err = -ENOMEM;
0131 goto fail_alloc;
0132 }
0133
0134 card = priv->card;
0135 card->bridge_io = bridge_io;
0136
0137 hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
0138
0139 err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
0140 DRIVER_NAME, priv);
0141 if (err) {
0142 printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
0143 err = -EBUSY;
0144 goto fail_irq;
0145 }
0146
0147 err = orinoco_tmd_cor_reset(priv);
0148 if (err) {
0149 printk(KERN_ERR PFX "Initial reset failed\n");
0150 goto fail;
0151 }
0152
0153 err = orinoco_init(priv);
0154 if (err) {
0155 printk(KERN_ERR PFX "orinoco_init() failed\n");
0156 goto fail;
0157 }
0158
0159 err = orinoco_if_add(priv, 0, 0, NULL);
0160 if (err) {
0161 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
0162 goto fail;
0163 }
0164
0165 pci_set_drvdata(pdev, priv);
0166
0167 return 0;
0168
0169 fail:
0170 free_irq(pdev->irq, priv);
0171
0172 fail_irq:
0173 free_orinocodev(priv);
0174
0175 fail_alloc:
0176 pci_iounmap(pdev, hermes_io);
0177
0178 fail_map_hermes:
0179 pci_iounmap(pdev, bridge_io);
0180
0181 fail_map_bridge:
0182 pci_release_regions(pdev);
0183
0184 fail_resources:
0185 pci_disable_device(pdev);
0186
0187 return err;
0188 }
0189
0190 static void orinoco_tmd_remove_one(struct pci_dev *pdev)
0191 {
0192 struct orinoco_private *priv = pci_get_drvdata(pdev);
0193 struct orinoco_pci_card *card = priv->card;
0194
0195 orinoco_if_del(priv);
0196 free_irq(pdev->irq, priv);
0197 free_orinocodev(priv);
0198 pci_iounmap(pdev, priv->hw.iobase);
0199 pci_iounmap(pdev, card->bridge_io);
0200 pci_release_regions(pdev);
0201 pci_disable_device(pdev);
0202 }
0203
0204 static const struct pci_device_id orinoco_tmd_id_table[] = {
0205 {0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,},
0206 {0,},
0207 };
0208
0209 MODULE_DEVICE_TABLE(pci, orinoco_tmd_id_table);
0210
0211 static struct pci_driver orinoco_tmd_driver = {
0212 .name = DRIVER_NAME,
0213 .id_table = orinoco_tmd_id_table,
0214 .probe = orinoco_tmd_init_one,
0215 .remove = orinoco_tmd_remove_one,
0216 .driver.pm = &orinoco_pci_pm_ops,
0217 };
0218
0219 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
0220 " (Joerg Dorchain <joerg@dorchain.net>)";
0221 MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
0222 MODULE_DESCRIPTION("Driver for wireless LAN cards using the TMD7160 PCI bridge");
0223 MODULE_LICENSE("Dual MPL/GPL");
0224
0225 static int __init orinoco_tmd_init(void)
0226 {
0227 printk(KERN_DEBUG "%s\n", version);
0228 return pci_register_driver(&orinoco_tmd_driver);
0229 }
0230
0231 static void __exit orinoco_tmd_exit(void)
0232 {
0233 pci_unregister_driver(&orinoco_tmd_driver);
0234 }
0235
0236 module_init(orinoco_tmd_init);
0237 module_exit(orinoco_tmd_exit);