0001
0002 #define PRISM2_PCI
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/if.h>
0010 #include <linux/skbuff.h>
0011 #include <linux/netdevice.h>
0012 #include <linux/slab.h>
0013 #include <linux/workqueue.h>
0014 #include <linux/wireless.h>
0015 #include <net/iw_handler.h>
0016
0017 #include <linux/ioport.h>
0018 #include <linux/pci.h>
0019 #include <asm/io.h>
0020
0021 #include "hostap_wlan.h"
0022
0023
0024 static char *dev_info = "hostap_pci";
0025
0026
0027 MODULE_AUTHOR("Jouni Malinen");
0028 MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN "
0029 "PCI cards.");
0030 MODULE_LICENSE("GPL");
0031
0032
0033
0034 struct hostap_pci_priv {
0035 void __iomem *mem_start;
0036 };
0037
0038
0039
0040
0041
0042 static const struct pci_device_id prism2_pci_id_table[] = {
0043
0044 { 0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID },
0045
0046 { 0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID },
0047
0048 { 0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID },
0049 { 0 }
0050 };
0051
0052
0053 #ifdef PRISM2_IO_DEBUG
0054
0055 static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
0056 {
0057 struct hostap_interface *iface;
0058 struct hostap_pci_priv *hw_priv;
0059 local_info_t *local;
0060 unsigned long flags;
0061
0062 iface = netdev_priv(dev);
0063 local = iface->local;
0064 hw_priv = local->hw_priv;
0065
0066 spin_lock_irqsave(&local->lock, flags);
0067 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
0068 writeb(v, hw_priv->mem_start + a);
0069 spin_unlock_irqrestore(&local->lock, flags);
0070 }
0071
0072 static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
0073 {
0074 struct hostap_interface *iface;
0075 struct hostap_pci_priv *hw_priv;
0076 local_info_t *local;
0077 unsigned long flags;
0078 u8 v;
0079
0080 iface = netdev_priv(dev);
0081 local = iface->local;
0082 hw_priv = local->hw_priv;
0083
0084 spin_lock_irqsave(&local->lock, flags);
0085 v = readb(hw_priv->mem_start + a);
0086 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
0087 spin_unlock_irqrestore(&local->lock, flags);
0088 return v;
0089 }
0090
0091 static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
0092 {
0093 struct hostap_interface *iface;
0094 struct hostap_pci_priv *hw_priv;
0095 local_info_t *local;
0096 unsigned long flags;
0097
0098 iface = netdev_priv(dev);
0099 local = iface->local;
0100 hw_priv = local->hw_priv;
0101
0102 spin_lock_irqsave(&local->lock, flags);
0103 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
0104 writew(v, hw_priv->mem_start + a);
0105 spin_unlock_irqrestore(&local->lock, flags);
0106 }
0107
0108 static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
0109 {
0110 struct hostap_interface *iface;
0111 struct hostap_pci_priv *hw_priv;
0112 local_info_t *local;
0113 unsigned long flags;
0114 u16 v;
0115
0116 iface = netdev_priv(dev);
0117 local = iface->local;
0118 hw_priv = local->hw_priv;
0119
0120 spin_lock_irqsave(&local->lock, flags);
0121 v = readw(hw_priv->mem_start + a);
0122 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
0123 spin_unlock_irqrestore(&local->lock, flags);
0124 return v;
0125 }
0126
0127 #define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
0128 #define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
0129 #define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
0130 #define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
0131 #define HFA384X_OUTW_DATA(v,a) hfa384x_outw_debug(dev, (a), le16_to_cpu((v)))
0132 #define HFA384X_INW_DATA(a) cpu_to_le16(hfa384x_inw_debug(dev, (a)))
0133
0134 #else
0135
0136 static inline void hfa384x_outb(struct net_device *dev, int a, u8 v)
0137 {
0138 struct hostap_interface *iface;
0139 struct hostap_pci_priv *hw_priv;
0140 iface = netdev_priv(dev);
0141 hw_priv = iface->local->hw_priv;
0142 writeb(v, hw_priv->mem_start + a);
0143 }
0144
0145 static inline u8 hfa384x_inb(struct net_device *dev, int a)
0146 {
0147 struct hostap_interface *iface;
0148 struct hostap_pci_priv *hw_priv;
0149 iface = netdev_priv(dev);
0150 hw_priv = iface->local->hw_priv;
0151 return readb(hw_priv->mem_start + a);
0152 }
0153
0154 static inline void hfa384x_outw(struct net_device *dev, int a, u16 v)
0155 {
0156 struct hostap_interface *iface;
0157 struct hostap_pci_priv *hw_priv;
0158 iface = netdev_priv(dev);
0159 hw_priv = iface->local->hw_priv;
0160 writew(v, hw_priv->mem_start + a);
0161 }
0162
0163 static inline u16 hfa384x_inw(struct net_device *dev, int a)
0164 {
0165 struct hostap_interface *iface;
0166 struct hostap_pci_priv *hw_priv;
0167 iface = netdev_priv(dev);
0168 hw_priv = iface->local->hw_priv;
0169 return readw(hw_priv->mem_start + a);
0170 }
0171
0172 #define HFA384X_OUTB(v,a) hfa384x_outb(dev, (a), (v))
0173 #define HFA384X_INB(a) hfa384x_inb(dev, (a))
0174 #define HFA384X_OUTW(v,a) hfa384x_outw(dev, (a), (v))
0175 #define HFA384X_INW(a) hfa384x_inw(dev, (a))
0176 #define HFA384X_OUTW_DATA(v,a) hfa384x_outw(dev, (a), le16_to_cpu((v)))
0177 #define HFA384X_INW_DATA(a) cpu_to_le16(hfa384x_inw(dev, (a)))
0178
0179 #endif
0180
0181
0182 static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
0183 int len)
0184 {
0185 u16 d_off;
0186 __le16 *pos;
0187
0188 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
0189 pos = (__le16 *) buf;
0190
0191 for ( ; len > 1; len -= 2)
0192 *pos++ = HFA384X_INW_DATA(d_off);
0193
0194 if (len & 1)
0195 *((char *) pos) = HFA384X_INB(d_off);
0196
0197 return 0;
0198 }
0199
0200
0201 static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
0202 {
0203 u16 d_off;
0204 __le16 *pos;
0205
0206 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
0207 pos = (__le16 *) buf;
0208
0209 for ( ; len > 1; len -= 2)
0210 HFA384X_OUTW_DATA(*pos++, d_off);
0211
0212 if (len & 1)
0213 HFA384X_OUTB(*((char *) pos), d_off);
0214
0215 return 0;
0216 }
0217
0218
0219
0220 #include "hostap_hw.c"
0221
0222 static void prism2_pci_cor_sreset(local_info_t *local)
0223 {
0224 struct net_device *dev = local->dev;
0225 u16 reg;
0226
0227 reg = HFA384X_INB(HFA384X_PCICOR_OFF);
0228 printk(KERN_DEBUG "%s: Original COR value: 0x%0x\n", dev->name, reg);
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238 #ifdef PRISM2_PCI_USE_LONG_DELAYS
0239 int i;
0240
0241 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF);
0242 mdelay(250);
0243
0244 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF);
0245 mdelay(500);
0246
0247
0248 i = 2000000 / 10;
0249 while ((HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) && --i)
0250 udelay(10);
0251
0252 #else
0253
0254 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF);
0255 mdelay(2);
0256 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF);
0257 mdelay(2);
0258
0259 #endif
0260
0261 if (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) {
0262 printk(KERN_DEBUG "%s: COR sreset timeout\n", dev->name);
0263 }
0264 }
0265
0266
0267 static void prism2_pci_genesis_reset(local_info_t *local, int hcr)
0268 {
0269 struct net_device *dev = local->dev;
0270
0271 HFA384X_OUTW(0x00C5, HFA384X_PCICOR_OFF);
0272 mdelay(10);
0273 HFA384X_OUTW(hcr, HFA384X_PCIHCR_OFF);
0274 mdelay(10);
0275 HFA384X_OUTW(0x0045, HFA384X_PCICOR_OFF);
0276 mdelay(10);
0277 }
0278
0279
0280 static struct prism2_helper_functions prism2_pci_funcs =
0281 {
0282 .card_present = NULL,
0283 .cor_sreset = prism2_pci_cor_sreset,
0284 .genesis_reset = prism2_pci_genesis_reset,
0285 .hw_type = HOSTAP_HW_PCI,
0286 };
0287
0288
0289 static int prism2_pci_probe(struct pci_dev *pdev,
0290 const struct pci_device_id *id)
0291 {
0292 unsigned long phymem;
0293 void __iomem *mem = NULL;
0294 local_info_t *local = NULL;
0295 struct net_device *dev = NULL;
0296 static int cards_found ;
0297 int irq_registered = 0;
0298 struct hostap_interface *iface;
0299 struct hostap_pci_priv *hw_priv;
0300
0301 hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
0302 if (hw_priv == NULL)
0303 return -ENOMEM;
0304
0305 if (pci_enable_device(pdev))
0306 goto err_out_free;
0307
0308 phymem = pci_resource_start(pdev, 0);
0309
0310 if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) {
0311 printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n");
0312 goto err_out_disable;
0313 }
0314
0315 mem = pci_ioremap_bar(pdev, 0);
0316 if (mem == NULL) {
0317 printk(KERN_ERR "prism2: Cannot remap PCI memory region\n") ;
0318 goto fail;
0319 }
0320
0321 dev = prism2_init_local_data(&prism2_pci_funcs, cards_found,
0322 &pdev->dev);
0323 if (dev == NULL)
0324 goto fail;
0325 iface = netdev_priv(dev);
0326 local = iface->local;
0327 local->hw_priv = hw_priv;
0328 cards_found++;
0329
0330 dev->irq = pdev->irq;
0331 hw_priv->mem_start = mem;
0332 dev->base_addr = (unsigned long) mem;
0333
0334 prism2_pci_cor_sreset(local);
0335
0336 pci_set_drvdata(pdev, dev);
0337
0338 if (request_irq(dev->irq, prism2_interrupt, IRQF_SHARED, dev->name,
0339 dev)) {
0340 printk(KERN_WARNING "%s: request_irq failed\n", dev->name);
0341 goto fail;
0342 } else
0343 irq_registered = 1;
0344
0345 if (!local->pri_only && prism2_hw_config(dev, 1)) {
0346 printk(KERN_DEBUG "%s: hardware initialization failed\n",
0347 dev_info);
0348 goto fail;
0349 }
0350
0351 printk(KERN_INFO "%s: Intersil Prism2.5 PCI: "
0352 "mem=0x%lx, irq=%d\n", dev->name, phymem, dev->irq);
0353
0354 return hostap_hw_ready(dev);
0355
0356 fail:
0357 if (irq_registered && dev)
0358 free_irq(dev->irq, dev);
0359
0360 if (mem)
0361 iounmap(mem);
0362
0363 release_mem_region(phymem, pci_resource_len(pdev, 0));
0364
0365 err_out_disable:
0366 pci_disable_device(pdev);
0367 prism2_free_local_data(dev);
0368
0369 err_out_free:
0370 kfree(hw_priv);
0371
0372 return -ENODEV;
0373 }
0374
0375
0376 static void prism2_pci_remove(struct pci_dev *pdev)
0377 {
0378 struct net_device *dev;
0379 struct hostap_interface *iface;
0380 void __iomem *mem_start;
0381 struct hostap_pci_priv *hw_priv;
0382
0383 dev = pci_get_drvdata(pdev);
0384 iface = netdev_priv(dev);
0385 hw_priv = iface->local->hw_priv;
0386
0387
0388 prism2_pci_cor_sreset(iface->local);
0389 hfa384x_disable_interrupts(dev);
0390
0391 if (dev->irq)
0392 free_irq(dev->irq, dev);
0393
0394 mem_start = hw_priv->mem_start;
0395 prism2_free_local_data(dev);
0396 kfree(hw_priv);
0397
0398 iounmap(mem_start);
0399
0400 release_mem_region(pci_resource_start(pdev, 0),
0401 pci_resource_len(pdev, 0));
0402 pci_disable_device(pdev);
0403 }
0404
0405 static int __maybe_unused prism2_pci_suspend(struct device *dev_d)
0406 {
0407 struct net_device *dev = dev_get_drvdata(dev_d);
0408
0409 if (netif_running(dev)) {
0410 netif_stop_queue(dev);
0411 netif_device_detach(dev);
0412 }
0413 prism2_suspend(dev);
0414
0415 return 0;
0416 }
0417
0418 static int __maybe_unused prism2_pci_resume(struct device *dev_d)
0419 {
0420 struct net_device *dev = dev_get_drvdata(dev_d);
0421
0422 prism2_hw_config(dev, 0);
0423 if (netif_running(dev)) {
0424 netif_device_attach(dev);
0425 netif_start_queue(dev);
0426 }
0427
0428 return 0;
0429 }
0430
0431 MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
0432
0433 static SIMPLE_DEV_PM_OPS(prism2_pci_pm_ops,
0434 prism2_pci_suspend,
0435 prism2_pci_resume);
0436
0437 static struct pci_driver prism2_pci_driver = {
0438 .name = "hostap_pci",
0439 .id_table = prism2_pci_id_table,
0440 .probe = prism2_pci_probe,
0441 .remove = prism2_pci_remove,
0442 .driver.pm = &prism2_pci_pm_ops,
0443 };
0444
0445 module_pci_driver(prism2_pci_driver);