b378c3bfc1ba9099f50bc73d258a008ef373ac0c
[debian/madwifi.git] / ath / if_ath_pci.c
1 /*-
2  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
3  * Copyright (c) 2004-2005 Atheros Communications, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer,
11  *    without modification.
12  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
13  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
14  *    redistribution must be conditioned upon including a substantially
15  *    similar Disclaimer requirement for further binary redistribution.
16  * 3. Neither the names of the above-listed copyright holders nor the names
17  *    of any contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * Alternatively, this software may be distributed under the terms of the
21  * GNU General Public License ("GPL") version 2 as published by the Free
22  * Software Foundation.
23  *
24  * NO WARRANTY
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
28  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
30  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
33  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGES.
36  *
37  * $Id: if_ath_pci.c 4136 2011-02-02 21:22:31Z proski $
38  */
39 #include "opt_ah.h"
40
41 #ifndef EXPORT_SYMTAB
42 #define EXPORT_SYMTAB
43 #endif
44
45 #if !defined(AUTOCONF_INCLUDED) && !defined(CONFIG_LOCALVERSION)
46 #include <linux/config.h>
47 #endif
48 #include <linux/version.h>
49 #include <linux/module.h>
50 #include <linux/init.h>
51 #include <linux/if.h>
52 #include <linux/if_arp.h>
53 #include <linux/netdevice.h>
54 #include <linux/cache.h>
55
56 #include <linux/pci.h>
57
58 #include <asm/io.h>
59 #include <asm/uaccess.h>
60
61 #include "if_media.h"
62 #include <net80211/ieee80211_var.h>
63
64 #include "if_athvar.h"
65 #include "ah_devid.h"
66 #include "if_ath_pci.h"
67
68 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
69 /*
70  * PCI initialization uses Linux 2.4.x version and
71  * older kernels do not support this
72  */
73 #error Atheros PCI version requires at least Linux kernel version 2.4.0
74 #endif /* kernel < 2.4.0 */
75
76 struct ath_pci_softc {
77         struct ath_softc        aps_sc;
78 #ifdef CONFIG_PM
79         u32     aps_pmstate[16];
80 #endif
81 };
82
83 /*
84  * Module glue.
85  */
86 #include "release.h"
87 static char *version = RELEASE_VERSION;
88 static char *dev_info = "ath_pci";
89
90 #include <linux/ethtool.h>
91
92 /*
93  * User a static table of PCI id's for now.  While this is the
94  * "new way" to do things, we may want to switch back to having
95  * the HAL check them by defining a probe method.
96  */
97 static struct pci_device_id ath_pci_id_table[] __devinitdata = {
98         { 0x168c, 0x0007, PCI_ANY_ID, PCI_ANY_ID },
99         { 0x168c, 0x0012, PCI_ANY_ID, PCI_ANY_ID },
100         { 0x168c, 0x0013, PCI_ANY_ID, PCI_ANY_ID },
101         { 0xa727, 0x0013, PCI_ANY_ID, PCI_ANY_ID }, /* 3com */
102         { 0x10b7, 0x0013, PCI_ANY_ID, PCI_ANY_ID }, /* 3com 3CRDAG675 */
103         { 0x168c, 0x1014, PCI_ANY_ID, PCI_ANY_ID }, /* IBM minipci 5212 */
104         { 0x168c, 0x101a, PCI_ANY_ID, PCI_ANY_ID }, /* some Griffin-Lite */
105         { 0x168c, 0x0015, PCI_ANY_ID, PCI_ANY_ID },
106         { 0x168c, 0x0016, PCI_ANY_ID, PCI_ANY_ID },
107         { 0x168c, 0x0017, PCI_ANY_ID, PCI_ANY_ID },
108         { 0x168c, 0x0018, PCI_ANY_ID, PCI_ANY_ID },
109         { 0x168c, 0x0019, PCI_ANY_ID, PCI_ANY_ID },
110         { 0x168c, 0x001a, PCI_ANY_ID, PCI_ANY_ID },
111         { 0x168c, 0x001b, PCI_ANY_ID, PCI_ANY_ID },
112         { 0x168c, 0x001c, PCI_ANY_ID, PCI_ANY_ID }, /* PCI Express 5424 */
113         { 0x168c, 0x001d, PCI_ANY_ID, PCI_ANY_ID }, /* PCI Express ???  */
114         { 0x168c, 0x9013, PCI_ANY_ID, PCI_ANY_ID }, /* sonicwall */
115         { 0 }
116 };
117
118 static u16 ath_devidmap[][2] = {
119         { 0x9013, 0x0013 }
120 };
121
122 static int
123 ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
124 {
125         unsigned long phymem;
126         void __iomem *mem;
127         struct ath_pci_softc *sc;
128         struct net_device *dev;
129         const char *athname;
130         u_int8_t csz;
131         u32 val;
132         u16 vdevice;
133         int i;
134
135         if (pci_enable_device(pdev))
136                 return -EIO;
137
138         /* XXX 32-bit addressing only */
139         if (pci_set_dma_mask(pdev, 0xffffffff)) {
140                 printk(KERN_ERR "ath_pci: 32-bit DMA not available\n");
141                 goto bad;
142         }
143
144         /*
145          * Cache line size is used to size and align various
146          * structures used to communicate with the hardware.
147          */
148         pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
149         if (csz == 0) {
150                 /*
151                  * Linux 2.4.18 (at least) writes the cache line size
152                  * register as a 16-bit wide register which is wrong.
153                  * We must have this setup properly for rx buffer
154                  * DMA to work so force a reasonable value here if it
155                  * comes up zero.
156                  */
157                 csz = L1_CACHE_BYTES / sizeof(u_int32_t);
158                 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
159         }
160         /*
161          * The default setting of latency timer yields poor results,
162          * set it to the value used by other systems.  It may be worth
163          * tweaking this setting more.
164          */
165         pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
166
167         pci_set_master(pdev);
168
169         /*
170          * Disable the RETRY_TIMEOUT register (0x41) to keep
171          * PCI Tx retries from interfering with C3 CPU state.
172          *
173          * Code taken from ipw2100 driver - jg
174          */
175         pci_read_config_dword(pdev, 0x40, &val);
176         if ((val & 0x0000ff00) != 0)
177                 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
178
179         phymem = pci_resource_start(pdev, 0);
180         if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "ath")) {
181                 printk(KERN_ERR "ath_pci: cannot reserve PCI memory region\n");
182                 goto bad;
183         }
184
185         mem = ioremap(phymem, pci_resource_len(pdev, 0));
186         if (!mem) {
187                 printk(KERN_ERR "ath_pci: cannot remap PCI memory region\n") ;
188                 goto bad1;
189         }
190
191 /*
192  * Reject new MAC revisions if HAL doesn't support AR2425.  Ideally, it could
193  * be done in the PCI ID table, but AR2424 and AR2425 share the same vendor ID
194  * 168c:001c.
195  */
196 #ifndef AH_SUPPORT_2425
197 #define AR5K_SREV               0x4020  /* MAC revision */
198 #define AR5K_SREV_CUTOFF        0xE0    /* Cutoff revision */
199         {
200                 u_int32_t mac_rev = readl(mem + AR5K_SREV);
201                 if (mac_rev > AR5K_SREV_CUTOFF)
202                 {
203                         printk(KERN_ERR "%s: HAL doesn't support MAC revision "
204                                "0x%02x\n", dev_info, mac_rev);
205                         goto bad2;
206                 }
207         }
208 #endif
209
210         dev = alloc_netdev(sizeof(struct ath_pci_softc), "wifi%d", ether_setup);
211         if (dev == NULL) {
212                 printk(KERN_ERR "ath_pci: no memory for device state\n");
213                 goto bad2;
214         }
215         sc = netdev_priv(dev);
216         sc->aps_sc.sc_dev = dev;
217         sc->aps_sc.sc_iobase = mem;
218
219         /*
220          * Mark the device as detached to avoid processing
221          * interrupts until setup is complete.
222          */
223         sc->aps_sc.sc_invalid = 1;
224
225         dev->irq = pdev->irq;
226         /*
227          * Don't leave arp type as ARPHRD_ETHER as this is no eth device
228          */
229         dev->type = ARPHRD_IEEE80211;
230
231         SET_MODULE_OWNER(dev);
232         SET_NETDEV_DEV(dev, &pdev->dev);
233
234         sc->aps_sc.sc_bdev = (void *) pdev;
235
236         pci_set_drvdata(pdev, dev);
237
238         if (request_irq(pdev->irq, ath_intr, IRQF_SHARED, dev->name, dev)) {
239                 printk(KERN_WARNING "%s: request_irq failed\n", dev->name);
240                 goto bad3;
241         }
242
243         /* looking for device type from broken device id */
244         vdevice = id->device;
245         for(i=0;i<sizeof(ath_devidmap)/sizeof(ath_devidmap[0]);i++) {
246                 if(id->device == ath_devidmap[i][0]) {
247                         vdevice = ath_devidmap[i][1];
248                         break;
249                 }
250         }
251
252         /*
253          * Auto-enable soft led processing for IBM cards and for
254          * 5211 minipci cards.  Users can also manually enable/disable
255          * support with a sysctl.
256          */
257         if (vdevice == AR5212_DEVID_IBM || vdevice == AR5211_DEVID) {
258                 sc->aps_sc.sc_softled = 1;
259                 sc->aps_sc.sc_ledpin = 0;
260         }
261
262         /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
263         if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
264                 sc->aps_sc.sc_softled = 1;
265                 sc->aps_sc.sc_ledpin = 1;
266         }
267
268         if (ath_attach(vdevice, dev, NULL) != 0)
269                 goto bad4;
270
271         athname = ath_hal_probe(id->vendor, vdevice);
272         printk(KERN_INFO "%s: %s: mem=0x%lx, irq=%d\n",
273                 dev->name, athname ? athname : "Atheros ???", phymem, dev->irq);
274
275         /* ready to process interrupts */
276         sc->aps_sc.sc_invalid = 0;
277
278         return 0;
279 bad4:
280         free_irq(dev->irq, dev);
281 bad3:
282         free_netdev(dev);
283 bad2:
284         iounmap(mem);
285 bad1:
286         release_mem_region(phymem, pci_resource_len(pdev, 0));
287 bad:
288         pci_disable_device(pdev);
289         return (-ENODEV);
290 }
291
292 static void
293 ath_pci_remove(struct pci_dev *pdev)
294 {
295         struct net_device *dev = pci_get_drvdata(pdev);
296         struct ath_pci_softc *sc = netdev_priv(dev);
297
298         ath_detach(dev);
299         if (dev->irq)
300                 free_irq(dev->irq, dev);
301         iounmap(sc->aps_sc.sc_iobase);
302         release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
303         pci_disable_device(pdev);
304         free_netdev(dev);
305 }
306
307 #ifdef CONFIG_PM
308 static int
309 ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
310 {
311         struct net_device *dev = pci_get_drvdata(pdev);
312
313         ath_suspend(dev);
314         PCI_SAVE_STATE(pdev, ((struct ath_pci_softc *)netdev_priv(dev))->aps_pmstate);
315         pci_disable_device(pdev);
316         return pci_set_power_state(pdev, PCI_D3hot);
317 }
318
319 static int
320 ath_pci_resume(struct pci_dev *pdev)
321 {
322         struct net_device *dev = pci_get_drvdata(pdev);
323         u32 val;
324         int err;
325
326         err = pci_set_power_state(pdev, PCI_D0);
327         if (err)
328                 return err;
329
330         /* XXX - Should this return nonzero on fail? */
331         PCI_RESTORE_STATE(pdev, ((struct ath_pci_softc *)netdev_priv(dev))->aps_pmstate);
332
333         err = pci_enable_device(pdev);
334         if (err)
335                 return err;
336
337         pci_set_master(pdev);
338         /*
339          * Suspend/Resume resets the PCI configuration space, so we have to
340          * re-disable the RETRY_TIMEOUT register (0x41) to keep
341          * PCI Tx retries from interfering with C3 CPU state
342          *
343          * Code taken from ipw2100 driver - jg
344          */
345         pci_read_config_dword(pdev, 0x40, &val);
346         if ((val & 0x0000ff00) != 0)
347                 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
348         ath_resume(dev);
349
350         return 0;
351 }
352 #endif /* CONFIG_PM */
353
354 MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
355
356 static struct pci_driver ath_pci_driver = {
357         .name           = "ath_pci",
358         .id_table       = ath_pci_id_table,
359         .probe          = ath_pci_probe,
360         .remove         = ath_pci_remove,
361 #ifdef CONFIG_PM
362         .suspend        = ath_pci_suspend,
363         .resume         = ath_pci_resume,
364 #endif /* CONFIG_PM */
365         /* Linux 2.4.6 has save_state and enable_wake that are not used here */
366 };
367
368 int
369 ath_ioctl_ethtool(struct ath_softc *sc, int cmd, void __user *addr)
370 {
371         struct ethtool_drvinfo info;
372
373         if (cmd != ETHTOOL_GDRVINFO)
374                 return -EOPNOTSUPP;
375         memset(&info, 0, sizeof(info));
376         info.cmd = cmd;
377         strncpy(info.driver, dev_info, sizeof(info.driver) - 1);
378         strncpy(info.version, version, sizeof(info.version) - 1);
379 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
380         /* include the device name so later versions of kudzu DTRT */
381         strncpy(info.bus_info, pci_name((struct pci_dev *)sc->sc_bdev),
382                 sizeof(info.bus_info) - 1);
383 #endif
384         return copy_to_user(addr, &info, sizeof(info)) ? -EFAULT : 0;
385 }
386
387 MODULE_AUTHOR("Errno Consulting, Sam Leffler");
388 MODULE_DESCRIPTION("Support for Atheros 802.11 wireless LAN cards.");
389 #ifdef MODULE_VERSION
390 MODULE_VERSION(RELEASE_VERSION);
391 #endif
392 MODULE_SUPPORTED_DEVICE("Atheros WLAN cards");
393 #ifdef MODULE_LICENSE
394 MODULE_LICENSE("Dual BSD/GPL");
395 #endif
396
397 static int __init
398 init_ath_pci(void)
399 {
400         printk(KERN_INFO "%s: %s\n", dev_info, version);
401
402         if (pci_register_driver(&ath_pci_driver) < 0) {
403                 printk("ath_pci: No devices found, driver not installed.\n");
404                 return (-ENODEV);
405         }
406         ath_sysctl_register();
407         return (0);
408 }
409 module_init(init_ath_pci);
410
411 static void __exit
412 exit_ath_pci(void)
413 {
414         ath_sysctl_unregister();
415         pci_unregister_driver(&ath_pci_driver);
416
417         printk(KERN_INFO "%s: driver unloaded\n", dev_info);
418 }
419 module_exit(exit_ath_pci);
420
421 /* return bus cachesize in 4B word units */
422 void
423 bus_read_cachesize(struct ath_softc *sc, u_int8_t *csz)
424 {
425         pci_read_config_byte(sc->sc_bdev, PCI_CACHE_LINE_SIZE, csz);
426 }