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