0cdf4daf54d990d7f6f951a1e4e35e15f5c7a47c
[openwrt.git] / package / mac80211 / patches / 405-ath9k-move-PCI-code-into-separate-file.patch
1 From d95e670cd1395ffd8410bed809b6d060f2183d6b Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Mon, 5 Jan 2009 11:01:09 +0100
4 Subject: [PATCH 05/11] ath9k: move PCI code into separate file
5
6 Now that we have converted all bus specific routines to replaceable, we
7 can move the PCI specific codes into a separate file.
8
9 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
10 Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
11 ---
12  drivers/net/wireless/ath9k/Makefile |    1 +
13  drivers/net/wireless/ath9k/core.h   |   18 ++-
14  drivers/net/wireless/ath9k/main.c   |  299 +++--------------------------------
15  drivers/net/wireless/ath9k/pci.c    |  289 +++++++++++++++++++++++++++++++++
16  4 files changed, 328 insertions(+), 279 deletions(-)
17
18 --- a/drivers/net/wireless/ath9k/Makefile
19 +++ b/drivers/net/wireless/ath9k/Makefile
20 @@ -11,6 +11,7 @@ ath9k-y +=    hw.o \
21                 xmit.o \
22                 rc.o
23  
24 +ath9k-$(CONFIG_PCI) += pci.o
25  ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
26  
27  obj-$(CONFIG_ATH9K) += ath9k.o
28 --- a/drivers/net/wireless/ath9k/core.h
29 +++ b/drivers/net/wireless/ath9k/core.h
30 @@ -18,7 +18,7 @@
31  #define CORE_H
32  
33  #include <linux/etherdevice.h>
34 -#include <linux/pci.h>
35 +#include <linux/device.h>
36  #include <net/mac80211.h>
37  #include <linux/leds.h>
38  #include <linux/rfkill.h>
39 @@ -766,4 +766,20 @@ static inline void ath_bus_cleanup(struc
40         sc->bus_ops->cleanup(sc);
41  }
42  
43 +extern struct ieee80211_ops ath9k_ops;
44 +
45 +irqreturn_t ath_isr(int irq, void *dev);
46 +int ath_attach(u16 devid, struct ath_softc *sc);
47 +void ath_detach(struct ath_softc *sc);
48 +const char *ath_mac_bb_name(u32 mac_bb_version);
49 +const char *ath_rf_name(u16 rf_version);
50 +
51 +#ifdef CONFIG_PCI
52 +int ath_pci_init(void);
53 +void ath_pci_exit(void);
54 +#else
55 +static inline int ath_pci_init(void) { return 0; };
56 +static inline void ath_pci_exit(void) {};
57 +#endif
58 +
59  #endif /* CORE_H */
60 --- a/drivers/net/wireless/ath9k/main.c
61 +++ b/drivers/net/wireless/ath9k/main.c
62 @@ -28,38 +28,6 @@ MODULE_DESCRIPTION("Support for Atheros 
63  MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
64  MODULE_LICENSE("Dual BSD/GPL");
65  
66 -static struct pci_device_id ath_pci_id_table[] __devinitdata = {
67 -       { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
68 -       { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
69 -       { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
70 -       { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
71 -       { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
72 -       { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
73 -       { 0 }
74 -};
75 -
76 -static void ath_detach(struct ath_softc *sc);
77 -
78 -/* return bus cachesize in 4B word units */
79 -
80 -static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
81 -{
82 -       u8 u8tmp;
83 -
84 -       pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
85 -                            (u8 *)&u8tmp);
86 -       *csz = (int)u8tmp;
87 -
88 -       /*
89 -        * This check was put in to avoid "unplesant" consequences if
90 -        * the bootrom has not fully initialized all PCI devices.
91 -        * Sometimes the cache line size register is not set
92 -        */
93 -
94 -       if (*csz == 0)
95 -               *csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
96 -}
97 -
98  static void ath_cache_conf_rate(struct ath_softc *sc,
99                                 struct ieee80211_conf *conf)
100  {
101 @@ -497,7 +465,7 @@ static void ath9k_tasklet(unsigned long 
102         ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
103  }
104  
105 -static irqreturn_t ath_isr(int irq, void *dev)
106 +irqreturn_t ath_isr(int irq, void *dev)
107  {
108         struct ath_softc *sc = dev;
109         struct ath_hal *ah = sc->sc_ah;
110 @@ -1278,7 +1246,7 @@ static int ath_start_rfkill_poll(struct 
111  }
112  #endif /* CONFIG_RFKILL */
113  
114 -static void ath_detach(struct ath_softc *sc)
115 +void ath_detach(struct ath_softc *sc)
116  {
117         struct ieee80211_hw *hw = sc->hw;
118         int i = 0;
119 @@ -1529,7 +1497,7 @@ bad:
120         return error;
121  }
122  
123 -static int ath_attach(u16 devid, struct ath_softc *sc)
124 +int ath_attach(u16 devid, struct ath_softc *sc)
125  {
126         struct ieee80211_hw *hw = sc->hw;
127         int error = 0;
128 @@ -2448,7 +2416,7 @@ static int ath9k_ampdu_action(struct iee
129         return ret;
130  }
131  
132 -static struct ieee80211_ops ath9k_ops = {
133 +struct ieee80211_ops ath9k_ops = {
134         .tx                 = ath9k_tx,
135         .start              = ath9k_start,
136         .stop               = ath9k_stop,
137 @@ -2492,7 +2460,7 @@ static struct {
138  /*
139   * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
140   */
141 -static const char *
142 +const char *
143  ath_mac_bb_name(u32 mac_bb_version)
144  {
145         int i;
146 @@ -2509,7 +2477,7 @@ ath_mac_bb_name(u32 mac_bb_version)
147  /*
148   * Return the RF name. "????" is returned if the RF is unknown.
149   */
150 -static const char *
151 +const char *
152  ath_rf_name(u16 rf_version)
153  {
154         int i;
155 @@ -2523,236 +2491,7 @@ ath_rf_name(u16 rf_version)
156         return "????";
157  }
158  
159 -static void ath_pci_cleanup(struct ath_softc *sc)
160 -{
161 -       struct pci_dev *pdev = to_pci_dev(sc->dev);
162 -
163 -       ath_detach(sc);
164 -       if (pdev->irq)
165 -               free_irq(pdev->irq, sc);
166 -       pci_iounmap(pdev, sc->mem);
167 -       pci_release_region(pdev, 0);
168 -       pci_disable_device(pdev);
169 -       ieee80211_free_hw(sc->hw);
170 -}
171 -
172 -static struct ath_bus_ops ath_pci_bus_ops = {
173 -       .read_cachesize = ath_pci_read_cachesize,
174 -       .cleanup = ath_pci_cleanup,
175 -};
176 -
177 -static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
178 -{
179 -       void __iomem *mem;
180 -       struct ath_softc *sc;
181 -       struct ieee80211_hw *hw;
182 -       u8 csz;
183 -       u32 val;
184 -       int ret = 0;
185 -       struct ath_hal *ah;
186 -
187 -       if (pci_enable_device(pdev))
188 -               return -EIO;
189 -
190 -       ret =  pci_set_dma_mask(pdev, DMA_32BIT_MASK);
191 -
192 -       if (ret) {
193 -               printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
194 -               goto bad;
195 -       }
196 -
197 -       ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
198 -
199 -       if (ret) {
200 -               printk(KERN_ERR "ath9k: 32-bit DMA consistent "
201 -                       "DMA enable failed\n");
202 -               goto bad;
203 -       }
204 -
205 -       /*
206 -        * Cache line size is used to size and align various
207 -        * structures used to communicate with the hardware.
208 -        */
209 -       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
210 -       if (csz == 0) {
211 -               /*
212 -                * Linux 2.4.18 (at least) writes the cache line size
213 -                * register as a 16-bit wide register which is wrong.
214 -                * We must have this setup properly for rx buffer
215 -                * DMA to work so force a reasonable value here if it
216 -                * comes up zero.
217 -                */
218 -               csz = L1_CACHE_BYTES / sizeof(u32);
219 -               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
220 -       }
221 -       /*
222 -        * The default setting of latency timer yields poor results,
223 -        * set it to the value used by other systems. It may be worth
224 -        * tweaking this setting more.
225 -        */
226 -       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
227 -
228 -       pci_set_master(pdev);
229 -
230 -       /*
231 -        * Disable the RETRY_TIMEOUT register (0x41) to keep
232 -        * PCI Tx retries from interfering with C3 CPU state.
233 -        */
234 -       pci_read_config_dword(pdev, 0x40, &val);
235 -       if ((val & 0x0000ff00) != 0)
236 -               pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
237 -
238 -       ret = pci_request_region(pdev, 0, "ath9k");
239 -       if (ret) {
240 -               dev_err(&pdev->dev, "PCI memory region reserve error\n");
241 -               ret = -ENODEV;
242 -               goto bad;
243 -       }
244 -
245 -       mem = pci_iomap(pdev, 0, 0);
246 -       if (!mem) {
247 -               printk(KERN_ERR "PCI memory map error\n") ;
248 -               ret = -EIO;
249 -               goto bad1;
250 -       }
251 -
252 -       hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
253 -       if (hw == NULL) {
254 -               printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
255 -               goto bad2;
256 -       }
257 -
258 -       SET_IEEE80211_DEV(hw, &pdev->dev);
259 -       pci_set_drvdata(pdev, hw);
260 -
261 -       sc = hw->priv;
262 -       sc->hw = hw;
263 -       sc->dev = &pdev->dev;
264 -       sc->mem = mem;
265 -       sc->bus_ops = &ath_pci_bus_ops;
266 -
267 -       if (ath_attach(id->device, sc) != 0) {
268 -               ret = -ENODEV;
269 -               goto bad3;
270 -       }
271 -
272 -       /* setup interrupt service routine */
273 -
274 -       if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
275 -               printk(KERN_ERR "%s: request_irq failed\n",
276 -                       wiphy_name(hw->wiphy));
277 -               ret = -EIO;
278 -               goto bad4;
279 -       }
280 -
281 -       ah = sc->sc_ah;
282 -       printk(KERN_INFO
283 -              "%s: Atheros AR%s MAC/BB Rev:%x "
284 -              "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
285 -              wiphy_name(hw->wiphy),
286 -              ath_mac_bb_name(ah->ah_macVersion),
287 -              ah->ah_macRev,
288 -              ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
289 -              ah->ah_phyRev,
290 -              (unsigned long)mem, pdev->irq);
291 -
292 -       return 0;
293 -bad4:
294 -       ath_detach(sc);
295 -bad3:
296 -       ieee80211_free_hw(hw);
297 -bad2:
298 -       pci_iounmap(pdev, mem);
299 -bad1:
300 -       pci_release_region(pdev, 0);
301 -bad:
302 -       pci_disable_device(pdev);
303 -       return ret;
304 -}
305 -
306 -static void ath_pci_remove(struct pci_dev *pdev)
307 -{
308 -       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
309 -       struct ath_softc *sc = hw->priv;
310 -
311 -       ath_pci_cleanup(sc);
312 -}
313 -
314 -#ifdef CONFIG_PM
315 -
316 -static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
317 -{
318 -       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
319 -       struct ath_softc *sc = hw->priv;
320 -
321 -       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
322 -
323 -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
324 -       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
325 -               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
326 -#endif
327 -
328 -       pci_save_state(pdev);
329 -       pci_disable_device(pdev);
330 -       pci_set_power_state(pdev, 3);
331 -
332 -       return 0;
333 -}
334 -
335 -static int ath_pci_resume(struct pci_dev *pdev)
336 -{
337 -       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
338 -       struct ath_softc *sc = hw->priv;
339 -       u32 val;
340 -       int err;
341 -
342 -       err = pci_enable_device(pdev);
343 -       if (err)
344 -               return err;
345 -       pci_restore_state(pdev);
346 -       /*
347 -        * Suspend/Resume resets the PCI configuration space, so we have to
348 -        * re-disable the RETRY_TIMEOUT register (0x41) to keep
349 -        * PCI Tx retries from interfering with C3 CPU state
350 -        */
351 -       pci_read_config_dword(pdev, 0x40, &val);
352 -       if ((val & 0x0000ff00) != 0)
353 -               pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
354 -
355 -       /* Enable LED */
356 -       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
357 -                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
358 -       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
359 -
360 -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
361 -       /*
362 -        * check the h/w rfkill state on resume
363 -        * and start the rfkill poll timer
364 -        */
365 -       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
366 -               queue_delayed_work(sc->hw->workqueue,
367 -                                  &sc->rf_kill.rfkill_poll, 0);
368 -#endif
369 -
370 -       return 0;
371 -}
372 -
373 -#endif /* CONFIG_PM */
374 -
375 -MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
376 -
377 -static struct pci_driver ath_pci_driver = {
378 -       .name       = "ath9k",
379 -       .id_table   = ath_pci_id_table,
380 -       .probe      = ath_pci_probe,
381 -       .remove     = ath_pci_remove,
382 -#ifdef CONFIG_PM
383 -       .suspend    = ath_pci_suspend,
384 -       .resume     = ath_pci_resume,
385 -#endif /* CONFIG_PM */
386 -};
387 -
388 -static int __init init_ath_pci(void)
389 +static int __init ath9k_init(void)
390  {
391         int error;
392  
393 @@ -2764,26 +2503,30 @@ static int __init init_ath_pci(void)
394                 printk(KERN_ERR
395                         "Unable to register rate control algorithm: %d\n",
396                         error);
397 -               ath_rate_control_unregister();
398 -               return error;
399 +               goto err_out;
400         }
401  
402 -       if (pci_register_driver(&ath_pci_driver) < 0) {
403 +       error = ath_pci_init();
404 +       if (error < 0) {
405                 printk(KERN_ERR
406                         "ath_pci: No devices found, driver not installed.\n");
407 -               ath_rate_control_unregister();
408 -               pci_unregister_driver(&ath_pci_driver);
409 -               return -ENODEV;
410 +               error = -ENODEV;
411 +               goto err_rate_unregister;
412         }
413  
414         return 0;
415 +
416 + err_rate_unregister:
417 +       ath_rate_control_unregister();
418 + err_out:
419 +       return error;
420  }
421 -module_init(init_ath_pci);
422 +module_init(ath9k_init);
423  
424 -static void __exit exit_ath_pci(void)
425 +static void __exit ath9k_exit(void)
426  {
427 +       ath_pci_exit();
428         ath_rate_control_unregister();
429 -       pci_unregister_driver(&ath_pci_driver);
430         printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
431  }
432 -module_exit(exit_ath_pci);
433 +module_exit(ath9k_exit);
434 --- /dev/null
435 +++ b/drivers/net/wireless/ath9k/pci.c
436 @@ -0,0 +1,289 @@
437 +/*
438 + * Copyright (c) 2008 Atheros Communications Inc.
439 + *
440 + * Permission to use, copy, modify, and/or distribute this software for any
441 + * purpose with or without fee is hereby granted, provided that the above
442 + * copyright notice and this permission notice appear in all copies.
443 + *
444 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
445 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
446 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
447 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
448 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
449 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
450 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
451 + */
452 +
453 +#include <linux/nl80211.h>
454 +#include <linux/pci.h>
455 +#include "core.h"
456 +#include "reg.h"
457 +#include "hw.h"
458 +
459 +static struct pci_device_id ath_pci_id_table[] __devinitdata = {
460 +       { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
461 +       { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
462 +       { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
463 +       { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
464 +       { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
465 +       { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
466 +       { 0 }
467 +};
468 +
469 +/* return bus cachesize in 4B word units */
470 +static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
471 +{
472 +       u8 u8tmp;
473 +
474 +       pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
475 +                            (u8 *)&u8tmp);
476 +       *csz = (int)u8tmp;
477 +
478 +       /*
479 +        * This check was put in to avoid "unplesant" consequences if
480 +        * the bootrom has not fully initialized all PCI devices.
481 +        * Sometimes the cache line size register is not set
482 +        */
483 +
484 +       if (*csz == 0)
485 +               *csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
486 +}
487 +
488 +static void ath_pci_cleanup(struct ath_softc *sc)
489 +{
490 +       struct pci_dev *pdev = to_pci_dev(sc->dev);
491 +
492 +       ath_detach(sc);
493 +       if (pdev->irq)
494 +               free_irq(pdev->irq, sc);
495 +       pci_iounmap(pdev, sc->mem);
496 +       pci_release_region(pdev, 0);
497 +       pci_disable_device(pdev);
498 +       ieee80211_free_hw(sc->hw);
499 +}
500 +
501 +static struct ath_bus_ops ath_pci_bus_ops = {
502 +       .read_cachesize = ath_pci_read_cachesize,
503 +       .cleanup = ath_pci_cleanup,
504 +};
505 +
506 +static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
507 +{
508 +       void __iomem *mem;
509 +       struct ath_softc *sc;
510 +       struct ieee80211_hw *hw;
511 +       u8 csz;
512 +       u32 val;
513 +       int ret = 0;
514 +       struct ath_hal *ah;
515 +
516 +       if (pci_enable_device(pdev))
517 +               return -EIO;
518 +
519 +       ret =  pci_set_dma_mask(pdev, DMA_32BIT_MASK);
520 +
521 +       if (ret) {
522 +               printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
523 +               goto bad;
524 +       }
525 +
526 +       ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
527 +
528 +       if (ret) {
529 +               printk(KERN_ERR "ath9k: 32-bit DMA consistent "
530 +                       "DMA enable failed\n");
531 +               goto bad;
532 +       }
533 +
534 +       /*
535 +        * Cache line size is used to size and align various
536 +        * structures used to communicate with the hardware.
537 +        */
538 +       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
539 +       if (csz == 0) {
540 +               /*
541 +                * Linux 2.4.18 (at least) writes the cache line size
542 +                * register as a 16-bit wide register which is wrong.
543 +                * We must have this setup properly for rx buffer
544 +                * DMA to work so force a reasonable value here if it
545 +                * comes up zero.
546 +                */
547 +               csz = L1_CACHE_BYTES / sizeof(u32);
548 +               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
549 +       }
550 +       /*
551 +        * The default setting of latency timer yields poor results,
552 +        * set it to the value used by other systems. It may be worth
553 +        * tweaking this setting more.
554 +        */
555 +       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
556 +
557 +       pci_set_master(pdev);
558 +
559 +       /*
560 +        * Disable the RETRY_TIMEOUT register (0x41) to keep
561 +        * PCI Tx retries from interfering with C3 CPU state.
562 +        */
563 +       pci_read_config_dword(pdev, 0x40, &val);
564 +       if ((val & 0x0000ff00) != 0)
565 +               pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
566 +
567 +       ret = pci_request_region(pdev, 0, "ath9k");
568 +       if (ret) {
569 +               dev_err(&pdev->dev, "PCI memory region reserve error\n");
570 +               ret = -ENODEV;
571 +               goto bad;
572 +       }
573 +
574 +       mem = pci_iomap(pdev, 0, 0);
575 +       if (!mem) {
576 +               printk(KERN_ERR "PCI memory map error\n") ;
577 +               ret = -EIO;
578 +               goto bad1;
579 +       }
580 +
581 +       hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
582 +       if (hw == NULL) {
583 +               printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
584 +               goto bad2;
585 +       }
586 +
587 +       SET_IEEE80211_DEV(hw, &pdev->dev);
588 +       pci_set_drvdata(pdev, hw);
589 +
590 +       sc = hw->priv;
591 +       sc->hw = hw;
592 +       sc->dev = &pdev->dev;
593 +       sc->mem = mem;
594 +       sc->bus_ops = &ath_pci_bus_ops;
595 +
596 +       if (ath_attach(id->device, sc) != 0) {
597 +               ret = -ENODEV;
598 +               goto bad3;
599 +       }
600 +
601 +       /* setup interrupt service routine */
602 +
603 +       if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
604 +               printk(KERN_ERR "%s: request_irq failed\n",
605 +                       wiphy_name(hw->wiphy));
606 +               ret = -EIO;
607 +               goto bad4;
608 +       }
609 +
610 +       ah = sc->sc_ah;
611 +       printk(KERN_INFO
612 +              "%s: Atheros AR%s MAC/BB Rev:%x "
613 +              "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
614 +              wiphy_name(hw->wiphy),
615 +              ath_mac_bb_name(ah->ah_macVersion),
616 +              ah->ah_macRev,
617 +              ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
618 +              ah->ah_phyRev,
619 +              (unsigned long)mem, pdev->irq);
620 +
621 +       return 0;
622 +bad4:
623 +       ath_detach(sc);
624 +bad3:
625 +       ieee80211_free_hw(hw);
626 +bad2:
627 +       pci_iounmap(pdev, mem);
628 +bad1:
629 +       pci_release_region(pdev, 0);
630 +bad:
631 +       pci_disable_device(pdev);
632 +       return ret;
633 +}
634 +
635 +static void ath_pci_remove(struct pci_dev *pdev)
636 +{
637 +       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
638 +       struct ath_softc *sc = hw->priv;
639 +
640 +       ath_pci_cleanup(sc);
641 +}
642 +
643 +#ifdef CONFIG_PM
644 +
645 +static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
646 +{
647 +       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
648 +       struct ath_softc *sc = hw->priv;
649 +
650 +       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
651 +
652 +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
653 +       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
654 +               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
655 +#endif
656 +
657 +       pci_save_state(pdev);
658 +       pci_disable_device(pdev);
659 +       pci_set_power_state(pdev, 3);
660 +
661 +       return 0;
662 +}
663 +
664 +static int ath_pci_resume(struct pci_dev *pdev)
665 +{
666 +       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
667 +       struct ath_softc *sc = hw->priv;
668 +       u32 val;
669 +       int err;
670 +
671 +       err = pci_enable_device(pdev);
672 +       if (err)
673 +               return err;
674 +       pci_restore_state(pdev);
675 +       /*
676 +        * Suspend/Resume resets the PCI configuration space, so we have to
677 +        * re-disable the RETRY_TIMEOUT register (0x41) to keep
678 +        * PCI Tx retries from interfering with C3 CPU state
679 +        */
680 +       pci_read_config_dword(pdev, 0x40, &val);
681 +       if ((val & 0x0000ff00) != 0)
682 +               pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
683 +
684 +       /* Enable LED */
685 +       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
686 +                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
687 +       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
688 +
689 +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
690 +       /*
691 +        * check the h/w rfkill state on resume
692 +        * and start the rfkill poll timer
693 +        */
694 +       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
695 +               queue_delayed_work(sc->hw->workqueue,
696 +                                  &sc->rf_kill.rfkill_poll, 0);
697 +#endif
698 +
699 +       return 0;
700 +}
701 +
702 +#endif /* CONFIG_PM */
703 +
704 +MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
705 +
706 +static struct pci_driver ath_pci_driver = {
707 +       .name       = "ath9k",
708 +       .id_table   = ath_pci_id_table,
709 +       .probe      = ath_pci_probe,
710 +       .remove     = ath_pci_remove,
711 +#ifdef CONFIG_PM
712 +       .suspend    = ath_pci_suspend,
713 +       .resume     = ath_pci_resume,
714 +#endif /* CONFIG_PM */
715 +};
716 +
717 +int __init ath_pci_init(void)
718 +{
719 +       return pci_register_driver(&ath_pci_driver);
720 +}
721 +
722 +void ath_pci_exit(void)
723 +{
724 +       pci_unregister_driver(&ath_pci_driver);
725 +}