1 #define PRISM2_PCI 2 3 /* Host AP driver's support for Intersil Prism2.5 PCI cards is based on 4 * driver patches from Reyk Floeter <reyk@vantronix.net> and 5 * Andy Warner <andyw@pobox.com> */ 6 7 #include <linux/module.h> 8 #include <linux/if.h> 9 #include <linux/skbuff.h> 10 #include <linux/netdevice.h> 11 #include <linux/slab.h> 12 #include <linux/workqueue.h> 13 #include <linux/wireless.h> 14 #include <net/iw_handler.h> 15 16 #include <linux/ioport.h> 17 #include <linux/pci.h> 18 #include <asm/io.h> 19 20 #include "hostap_wlan.h" 21 22 23 static char *dev_info = "hostap_pci"; 24 25 26 MODULE_AUTHOR("Jouni Malinen"); 27 MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN " 28 "PCI cards."); 29 MODULE_SUPPORTED_DEVICE("Intersil Prism2.5-based WLAN PCI cards"); 30 MODULE_LICENSE("GPL"); 31 32 33 /* struct local_info::hw_priv */ 34 struct hostap_pci_priv { 35 void __iomem *mem_start; 36 }; 37 38 39 /* FIX: do we need mb/wmb/rmb with memory operations? */ 40 41 42 static const struct pci_device_id prism2_pci_id_table[] = { 43 /* Intersil Prism3 ISL3872 11Mb/s WLAN Controller */ 44 { 0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID }, 45 /* Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller */ 46 { 0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID }, 47 /* Samsung MagicLAN SWL-2210P */ 48 { 0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID }, 49 { 0 } 50 }; 51 52 53 #ifdef PRISM2_IO_DEBUG 54 55 static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v) 56 { 57 struct hostap_interface *iface; 58 struct hostap_pci_priv *hw_priv; 59 local_info_t *local; 60 unsigned long flags; 61 62 iface = netdev_priv(dev); 63 local = iface->local; 64 hw_priv = local->hw_priv; 65 66 spin_lock_irqsave(&local->lock, flags); 67 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v); 68 writeb(v, hw_priv->mem_start + a); 69 spin_unlock_irqrestore(&local->lock, flags); 70 } 71 72 static inline u8 hfa384x_inb_debug(struct net_device *dev, int a) 73 { 74 struct hostap_interface *iface; 75 struct hostap_pci_priv *hw_priv; 76 local_info_t *local; 77 unsigned long flags; 78 u8 v; 79 80 iface = netdev_priv(dev); 81 local = iface->local; 82 hw_priv = local->hw_priv; 83 84 spin_lock_irqsave(&local->lock, flags); 85 v = readb(hw_priv->mem_start + a); 86 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v); 87 spin_unlock_irqrestore(&local->lock, flags); 88 return v; 89 } 90 91 static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v) 92 { 93 struct hostap_interface *iface; 94 struct hostap_pci_priv *hw_priv; 95 local_info_t *local; 96 unsigned long flags; 97 98 iface = netdev_priv(dev); 99 local = iface->local; 100 hw_priv = local->hw_priv; 101 102 spin_lock_irqsave(&local->lock, flags); 103 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v); 104 writew(v, hw_priv->mem_start + a); 105 spin_unlock_irqrestore(&local->lock, flags); 106 } 107 108 static inline u16 hfa384x_inw_debug(struct net_device *dev, int a) 109 { 110 struct hostap_interface *iface; 111 struct hostap_pci_priv *hw_priv; 112 local_info_t *local; 113 unsigned long flags; 114 u16 v; 115 116 iface = netdev_priv(dev); 117 local = iface->local; 118 hw_priv = local->hw_priv; 119 120 spin_lock_irqsave(&local->lock, flags); 121 v = readw(hw_priv->mem_start + a); 122 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v); 123 spin_unlock_irqrestore(&local->lock, flags); 124 return v; 125 } 126 127 #define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v)) 128 #define HFA384X_INB(a) hfa384x_inb_debug(dev, (a)) 129 #define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v)) 130 #define HFA384X_INW(a) hfa384x_inw_debug(dev, (a)) 131 #define HFA384X_OUTW_DATA(v,a) hfa384x_outw_debug(dev, (a), le16_to_cpu((v))) 132 #define HFA384X_INW_DATA(a) cpu_to_le16(hfa384x_inw_debug(dev, (a))) 133 134 #else /* PRISM2_IO_DEBUG */ 135 136 static inline void hfa384x_outb(struct net_device *dev, int a, u8 v) 137 { 138 struct hostap_interface *iface; 139 struct hostap_pci_priv *hw_priv; 140 iface = netdev_priv(dev); 141 hw_priv = iface->local->hw_priv; 142 writeb(v, hw_priv->mem_start + a); 143 } 144 145 static inline u8 hfa384x_inb(struct net_device *dev, int a) 146 { 147 struct hostap_interface *iface; 148 struct hostap_pci_priv *hw_priv; 149 iface = netdev_priv(dev); 150 hw_priv = iface->local->hw_priv; 151 return readb(hw_priv->mem_start + a); 152 } 153 154 static inline void hfa384x_outw(struct net_device *dev, int a, u16 v) 155 { 156 struct hostap_interface *iface; 157 struct hostap_pci_priv *hw_priv; 158 iface = netdev_priv(dev); 159 hw_priv = iface->local->hw_priv; 160 writew(v, hw_priv->mem_start + a); 161 } 162 163 static inline u16 hfa384x_inw(struct net_device *dev, int a) 164 { 165 struct hostap_interface *iface; 166 struct hostap_pci_priv *hw_priv; 167 iface = netdev_priv(dev); 168 hw_priv = iface->local->hw_priv; 169 return readw(hw_priv->mem_start + a); 170 } 171 172 #define HFA384X_OUTB(v,a) hfa384x_outb(dev, (a), (v)) 173 #define HFA384X_INB(a) hfa384x_inb(dev, (a)) 174 #define HFA384X_OUTW(v,a) hfa384x_outw(dev, (a), (v)) 175 #define HFA384X_INW(a) hfa384x_inw(dev, (a)) 176 #define HFA384X_OUTW_DATA(v,a) hfa384x_outw(dev, (a), le16_to_cpu((v))) 177 #define HFA384X_INW_DATA(a) cpu_to_le16(hfa384x_inw(dev, (a))) 178 179 #endif /* PRISM2_IO_DEBUG */ 180 181 182 static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf, 183 int len) 184 { 185 u16 d_off; 186 __le16 *pos; 187 188 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF; 189 pos = (__le16 *) buf; 190 191 for ( ; len > 1; len -= 2) 192 *pos++ = HFA384X_INW_DATA(d_off); 193 194 if (len & 1) 195 *((char *) pos) = HFA384X_INB(d_off); 196 197 return 0; 198 } 199 200 201 static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) 202 { 203 u16 d_off; 204 __le16 *pos; 205 206 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF; 207 pos = (__le16 *) buf; 208 209 for ( ; len > 1; len -= 2) 210 HFA384X_OUTW_DATA(*pos++, d_off); 211 212 if (len & 1) 213 HFA384X_OUTB(*((char *) pos), d_off); 214 215 return 0; 216 } 217 218 219 /* FIX: This might change at some point.. */ 220 #include "hostap_hw.c" 221 222 static void prism2_pci_cor_sreset(local_info_t *local) 223 { 224 struct net_device *dev = local->dev; 225 u16 reg; 226 227 reg = HFA384X_INB(HFA384X_PCICOR_OFF); 228 printk(KERN_DEBUG "%s: Original COR value: 0x%0x\n", dev->name, reg); 229 230 /* linux-wlan-ng uses extremely long hold and settle times for 231 * COR sreset. A comment in the driver code mentions that the long 232 * delays appear to be necessary. However, at least IBM 22P6901 seems 233 * to work fine with shorter delays. 234 * 235 * Longer delays can be configured by uncommenting following line: */ 236 /* #define PRISM2_PCI_USE_LONG_DELAYS */ 237 238 #ifdef PRISM2_PCI_USE_LONG_DELAYS 239 int i; 240 241 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF); 242 mdelay(250); 243 244 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF); 245 mdelay(500); 246 247 /* Wait for f/w to complete initialization (CMD:BUSY == 0) */ 248 i = 2000000 / 10; 249 while ((HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) && --i) 250 udelay(10); 251 252 #else /* PRISM2_PCI_USE_LONG_DELAYS */ 253 254 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF); 255 mdelay(2); 256 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF); 257 mdelay(2); 258 259 #endif /* PRISM2_PCI_USE_LONG_DELAYS */ 260 261 if (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) { 262 printk(KERN_DEBUG "%s: COR sreset timeout\n", dev->name); 263 } 264 } 265 266 267 static void prism2_pci_genesis_reset(local_info_t *local, int hcr) 268 { 269 struct net_device *dev = local->dev; 270 271 HFA384X_OUTW(0x00C5, HFA384X_PCICOR_OFF); 272 mdelay(10); 273 HFA384X_OUTW(hcr, HFA384X_PCIHCR_OFF); 274 mdelay(10); 275 HFA384X_OUTW(0x0045, HFA384X_PCICOR_OFF); 276 mdelay(10); 277 } 278 279 280 static struct prism2_helper_functions prism2_pci_funcs = 281 { 282 .card_present = NULL, 283 .cor_sreset = prism2_pci_cor_sreset, 284 .genesis_reset = prism2_pci_genesis_reset, 285 .hw_type = HOSTAP_HW_PCI, 286 }; 287 288 289 static int prism2_pci_probe(struct pci_dev *pdev, 290 const struct pci_device_id *id) 291 { 292 unsigned long phymem; 293 void __iomem *mem = NULL; 294 local_info_t *local = NULL; 295 struct net_device *dev = NULL; 296 static int cards_found /* = 0 */; 297 int irq_registered = 0; 298 struct hostap_interface *iface; 299 struct hostap_pci_priv *hw_priv; 300 301 hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL); 302 if (hw_priv == NULL) 303 return -ENOMEM; 304 305 if (pci_enable_device(pdev)) 306 goto err_out_free; 307 308 phymem = pci_resource_start(pdev, 0); 309 310 if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) { 311 printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n"); 312 goto err_out_disable; 313 } 314 315 mem = pci_ioremap_bar(pdev, 0); 316 if (mem == NULL) { 317 printk(KERN_ERR "prism2: Cannot remap PCI memory region\n") ; 318 goto fail; 319 } 320 321 dev = prism2_init_local_data(&prism2_pci_funcs, cards_found, 322 &pdev->dev); 323 if (dev == NULL) 324 goto fail; 325 iface = netdev_priv(dev); 326 local = iface->local; 327 local->hw_priv = hw_priv; 328 cards_found++; 329 330 dev->irq = pdev->irq; 331 hw_priv->mem_start = mem; 332 dev->base_addr = (unsigned long) mem; 333 334 prism2_pci_cor_sreset(local); 335 336 pci_set_drvdata(pdev, dev); 337 338 if (request_irq(dev->irq, prism2_interrupt, IRQF_SHARED, dev->name, 339 dev)) { 340 printk(KERN_WARNING "%s: request_irq failed\n", dev->name); 341 goto fail; 342 } else 343 irq_registered = 1; 344 345 if (!local->pri_only && prism2_hw_config(dev, 1)) { 346 printk(KERN_DEBUG "%s: hardware initialization failed\n", 347 dev_info); 348 goto fail; 349 } 350 351 printk(KERN_INFO "%s: Intersil Prism2.5 PCI: " 352 "mem=0x%lx, irq=%d\n", dev->name, phymem, dev->irq); 353 354 return hostap_hw_ready(dev); 355 356 fail: 357 if (irq_registered && dev) 358 free_irq(dev->irq, dev); 359 360 if (mem) 361 iounmap(mem); 362 363 release_mem_region(phymem, pci_resource_len(pdev, 0)); 364 365 err_out_disable: 366 pci_disable_device(pdev); 367 prism2_free_local_data(dev); 368 369 err_out_free: 370 kfree(hw_priv); 371 372 return -ENODEV; 373 } 374 375 376 static void prism2_pci_remove(struct pci_dev *pdev) 377 { 378 struct net_device *dev; 379 struct hostap_interface *iface; 380 void __iomem *mem_start; 381 struct hostap_pci_priv *hw_priv; 382 383 dev = pci_get_drvdata(pdev); 384 iface = netdev_priv(dev); 385 hw_priv = iface->local->hw_priv; 386 387 /* Reset the hardware, and ensure interrupts are disabled. */ 388 prism2_pci_cor_sreset(iface->local); 389 hfa384x_disable_interrupts(dev); 390 391 if (dev->irq) 392 free_irq(dev->irq, dev); 393 394 mem_start = hw_priv->mem_start; 395 prism2_free_local_data(dev); 396 kfree(hw_priv); 397 398 iounmap(mem_start); 399 400 release_mem_region(pci_resource_start(pdev, 0), 401 pci_resource_len(pdev, 0)); 402 pci_disable_device(pdev); 403 } 404 405 406 #ifdef CONFIG_PM 407 static int prism2_pci_suspend(struct pci_dev *pdev, pm_message_t state) 408 { 409 struct net_device *dev = pci_get_drvdata(pdev); 410 411 if (netif_running(dev)) { 412 netif_stop_queue(dev); 413 netif_device_detach(dev); 414 } 415 prism2_suspend(dev); 416 pci_save_state(pdev); 417 pci_disable_device(pdev); 418 pci_set_power_state(pdev, PCI_D3hot); 419 420 return 0; 421 } 422 423 static int prism2_pci_resume(struct pci_dev *pdev) 424 { 425 struct net_device *dev = pci_get_drvdata(pdev); 426 int err; 427 428 err = pci_enable_device(pdev); 429 if (err) { 430 printk(KERN_ERR "%s: pci_enable_device failed on resume\n", 431 dev->name); 432 return err; 433 } 434 pci_restore_state(pdev); 435 prism2_hw_config(dev, 0); 436 if (netif_running(dev)) { 437 netif_device_attach(dev); 438 netif_start_queue(dev); 439 } 440 441 return 0; 442 } 443 #endif /* CONFIG_PM */ 444 445 446 MODULE_DEVICE_TABLE(pci, prism2_pci_id_table); 447 448 static struct pci_driver prism2_pci_driver = { 449 .name = "hostap_pci", 450 .id_table = prism2_pci_id_table, 451 .probe = prism2_pci_probe, 452 .remove = prism2_pci_remove, 453 #ifdef CONFIG_PM 454 .suspend = prism2_pci_suspend, 455 .resume = prism2_pci_resume, 456 #endif /* CONFIG_PM */ 457 }; 458 459 module_pci_driver(prism2_pci_driver); 460