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