00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "opt_ah.h"
00041
00042 #ifndef EXPORT_SYMTAB
00043 #define EXPORT_SYMTAB
00044 #endif
00045
00046 #include <linux/config.h>
00047 #include <linux/version.h>
00048 #include <linux/module.h>
00049 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
00050 #include <linux/moduleparam.h>
00051 #endif
00052 #include <linux/init.h>
00053 #include <linux/if.h>
00054 #include <linux/netdevice.h>
00055 #include <linux/cache.h>
00056
00057 #include <linux/pci.h>
00058
00059 #include <asm/uaccess.h>
00060 #include "if_athvar.h"
00061 #include "if_ath_pci.h"
00062
00063
00064 static char *ifname = "ath";
00065 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
00066 MODULE_PARM(ifname, "s");
00067 #else
00068 module_param(ifname, charp, 0);
00069 #endif
00070
00071 MODULE_PARM_DESC(ifname, "Interface name prefix (default: ath)");
00072
00073 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
00074
00075
00076
00077
00078 #error Atheros PCI version requires at least Linux kernel version 2.4.0
00079 #endif
00080
00081 struct ath_pci_softc {
00082 struct ath_softc aps_sc;
00083 #ifdef CONFIG_PM
00084 u32 aps_pmstate[16];
00085 #endif
00086 };
00087
00088
00089
00090
00091
00092
00093 static struct pci_device_id ath_pci_id_table[] __devinitdata = {
00094 { 0x168c, 0x0007, PCI_ANY_ID, PCI_ANY_ID },
00095 { 0x168c, 0x0012, PCI_ANY_ID, PCI_ANY_ID },
00096 { 0x168c, 0x0013, PCI_ANY_ID, PCI_ANY_ID },
00097 { 0xa727, 0x0013, PCI_ANY_ID, PCI_ANY_ID },
00098 { 0x10b7, 0x0013, PCI_ANY_ID, PCI_ANY_ID },
00099 { 0x168c, 0x1014, PCI_ANY_ID, PCI_ANY_ID },
00100 { 0x168c, 0x0015, PCI_ANY_ID, PCI_ANY_ID },
00101 { 0x168c, 0x0016, PCI_ANY_ID, PCI_ANY_ID },
00102 { 0x168c, 0x0017, PCI_ANY_ID, PCI_ANY_ID },
00103 { 0x168c, 0x0018, PCI_ANY_ID, PCI_ANY_ID },
00104 { 0x168c, 0x0019, PCI_ANY_ID, PCI_ANY_ID },
00105 { 0x168c, 0x001a, PCI_ANY_ID, PCI_ANY_ID },
00106 { 0 }
00107 };
00108
00109 static int
00110 ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
00111 {
00112 unsigned long phymem;
00113 unsigned long mem;
00114 struct ath_pci_softc *sc;
00115 struct net_device *dev;
00116 const char *athname;
00117 u_int8_t csz;
00118 u32 val;
00119
00120 if (pci_enable_device(pdev))
00121 return (-EIO);
00122
00123
00124 if (pci_set_dma_mask(pdev, 0xffffffff)) {
00125 printk(KERN_ERR "ath_pci: 32-bit DMA not available\n");
00126 goto bad;
00127 }
00128
00129
00130
00131
00132
00133 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
00134 if (csz == 0) {
00135
00136
00137
00138
00139
00140
00141
00142 csz = L1_CACHE_BYTES / sizeof(u_int32_t);
00143 printk("ath_pci: cache line size not set; forcing %u\n", csz);
00144 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
00145 }
00146
00147
00148
00149
00150
00151 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
00152
00153 pci_set_master(pdev);
00154
00155
00156
00157
00158
00159
00160
00161 pci_read_config_dword(pdev, 0x40, &val);
00162 if ((val & 0x0000ff00) != 0)
00163 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
00164
00165
00166 phymem = pci_resource_start(pdev, 0);
00167 if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "ath")) {
00168 printk(KERN_ERR "ath_pci: cannot reserve PCI memory region\n");
00169 goto bad;
00170 }
00171
00172 mem = (unsigned long) ioremap(phymem, pci_resource_len(pdev, 0));
00173 if (!mem) {
00174 printk(KERN_ERR "ath_pci: cannot remap PCI memory region\n") ;
00175 release_mem_region(phymem, pci_resource_len(pdev, 0));
00176 goto bad1;
00177 }
00178
00179 sc = kmalloc(sizeof(struct ath_pci_softc), GFP_KERNEL);
00180 if (sc == NULL) {
00181 printk(KERN_ERR "ath_pci: no memory for device state\n");
00182 goto bad2;
00183 }
00184 memset(sc, 0, sizeof(struct ath_pci_softc));
00185
00186 dev = &sc->aps_sc.dev;
00187 memcpy(dev->name, "ath%d", sizeof("ath%d"));
00188
00189 dev->irq = pdev->irq;
00190 dev->mem_start = mem;
00191 dev->mem_end = mem + pci_resource_len(pdev, 0);
00192 dev->priv = sc;
00193
00194 SET_MODULE_OWNER(dev);
00195 SET_NETDEV_DEV(dev, &pdev->dev);
00196
00197
00198 sc->aps_sc.sc_bdev = (void *) pdev;
00199
00200 pci_set_drvdata(pdev, dev);
00201
00202 if (request_irq(dev->irq, ath_intr, SA_SHIRQ, dev->name, dev)) {
00203 printk(KERN_WARNING "%s: request_irq failed\n", dev->name);
00204 goto bad3;
00205 }
00206
00207
00208
00209
00210
00211 sc->aps_sc.sc_invalid = 0;
00212
00213 if (ath_attach(id->device, dev) != 0)
00214 goto bad4;
00215
00216 athname = ath_hal_probe(id->vendor, id->device);
00217 printk(KERN_INFO "%s: %s: mem=0x%lx, irq=%d\n",
00218 dev->name, athname ? athname : "Atheros ???", phymem, dev->irq);
00219
00220 return 0;
00221 bad4:
00222 free_irq(dev->irq, dev);
00223 bad3:
00224 kfree(sc);
00225 bad2:
00226 iounmap((void *) mem);
00227 bad1:
00228 release_mem_region(phymem, pci_resource_len(pdev, 0));
00229 bad:
00230 pci_disable_device(pdev);
00231 return (-ENODEV);
00232 }
00233
00234 static void
00235 ath_pci_remove(struct pci_dev *pdev)
00236 {
00237 struct net_device *dev = pci_get_drvdata(pdev);
00238
00239 ath_detach(dev);
00240 if (dev->irq)
00241 free_irq(dev->irq, dev);
00242 iounmap((void *) dev->mem_start);
00243 release_mem_region(pci_resource_start(pdev, 0),
00244 pci_resource_len(pdev, 0));
00245 pci_disable_device(pdev);
00246
00247 #ifdef HAVE_FREE_NETDEV
00248 free_netdev(dev);
00249 #endif
00250 }
00251
00252 #ifdef CONFIG_PM
00253 static int
00254 ath_pci_suspend(struct pci_dev *pdev, u32 state)
00255 {
00256 struct net_device *dev = pci_get_drvdata(pdev);
00257
00258 ath_suspend(dev);
00259 PCI_SAVE_STATE(pdev,
00260 ((struct ath_pci_softc *)dev->priv)->aps_pmstate);
00261 pci_disable_device(pdev);
00262 pci_set_power_state(pdev, 3);
00263
00264 return (0);
00265 }
00266
00267 static int
00268 ath_pci_resume(struct pci_dev *pdev)
00269 {
00270 struct net_device *dev = pci_get_drvdata(pdev);
00271 u32 val;
00272
00273 pci_enable_device(pdev);
00274 PCI_RESTORE_STATE(pdev,
00275 ((struct ath_pci_softc *)dev->priv)->aps_pmstate);
00276
00277
00278
00279
00280
00281
00282
00283 pci_read_config_dword(pdev, 0x40, &val);
00284 if ((val & 0x0000ff00) != 0)
00285 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
00286 ath_resume(dev);
00287
00288 return (0);
00289 }
00290 #endif
00291
00292 MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
00293
00294 static struct pci_driver ath_pci_drv_id = {
00295 .name = "ath_pci",
00296 .id_table = ath_pci_id_table,
00297 .probe = ath_pci_probe,
00298 .remove = ath_pci_remove,
00299 #ifdef CONFIG_PM
00300 .suspend = ath_pci_suspend,
00301 .resume = ath_pci_resume,
00302 #endif
00303
00304 };
00305
00306
00307
00308
00309 #include "release.h"
00310 #include "version.h"
00311
00312 char *version = ATH_PCI_VERSION " " RELEASE_TYPE;
00313 char *dev_info = "ath_pci";
00314
00315 #include <linux/ethtool.h>
00316
00317 int
00318 ath_ioctl_ethtool(struct ath_softc *sc, int cmd, void *addr)
00319 {
00320 struct ethtool_drvinfo info;
00321
00322 if (cmd != ETHTOOL_GDRVINFO)
00323 return -EOPNOTSUPP;
00324 memset(&info, 0, sizeof(info));
00325 info.cmd = cmd;
00326 strncpy(info.driver, dev_info, sizeof(info.driver)-1);
00327 strncpy(info.version, version, sizeof(info.version)-1);
00328 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
00329
00330 strncpy(info.bus_info, pci_name((struct pci_dev *)sc->sc_bdev),
00331 sizeof(info.bus_info)-1);
00332 #endif
00333
00334 return copy_to_user(addr, &info, sizeof(info)) ? -EFAULT : 0;
00335 }
00336 MODULE_AUTHOR("Errno Consulting, Sam Leffler");
00337 MODULE_DESCRIPTION("Support for Atheros 802.11 wireless LAN cards.");
00338 MODULE_SUPPORTED_DEVICE("Atheros WLAN cards");
00339 #ifdef MODULE_LICENSE
00340 MODULE_LICENSE("Dual BSD/GPL");
00341 #endif
00342
00343 static int __init
00344 init_ath_pci(void)
00345 {
00346 printk(KERN_INFO "%s: %s\n", dev_info, version);
00347
00348 if (pci_register_driver(&ath_pci_drv_id) < 0) {
00349 printk("ath_pci: No devices found, driver not installed.\n");
00350 pci_unregister_driver(&ath_pci_drv_id);
00351 return (-ENODEV);
00352 }
00353 #ifdef CONFIG_SYSCTL
00354 ath_sysctl_register();
00355 #endif
00356 return (0);
00357 }
00358 module_init(init_ath_pci);
00359
00360 static void __exit
00361 exit_ath_pci(void)
00362 {
00363 #ifdef CONFIG_SYSCTL
00364 ath_sysctl_unregister();
00365 #endif
00366
00367 pci_unregister_driver(&ath_pci_drv_id);
00368
00369 printk(KERN_INFO "%s: driver unloaded\n", dev_info);
00370 }
00371 module_exit(exit_ath_pci);
00372
00373
00374 void
00375 bus_read_cachesize(struct ath_softc *sc, u_int8_t *csz)
00376 {
00377 pci_read_config_byte(sc->sc_bdev, PCI_CACHE_LINE_SIZE, csz);
00378 }
00379
00380