1 From 957a60be8a6b55da588df12e160ac53e3b36238e Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Fri, 2 Jan 2009 16:10:25 +0100
4 Subject: [RFC 05/12] ath9k: move PCI code into separate file
6 Convert 'struct pci_dev' to 'struct device' to make it usable on the AHB
9 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
10 Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
12 drivers/net/wireless/ath9k/Makefile | 1 +
13 drivers/net/wireless/ath9k/core.h | 16 ++
14 drivers/net/wireless/ath9k/main.c | 368 ++---------------------------------
15 drivers/net/wireless/ath9k/pci.c | 357 +++++++++++++++++++++++++++++++++
16 4 files changed, 395 insertions(+), 347 deletions(-)
18 --- a/drivers/net/wireless/ath9k/Makefile
19 +++ b/drivers/net/wireless/ath9k/Makefile
20 @@ -11,6 +11,7 @@ ath9k-y += hw.o \
24 +ath9k-$(CONFIG_PCI) += pci.o
25 ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
27 obj-$(CONFIG_ATH9K) += ath9k.o
28 --- a/drivers/net/wireless/ath9k/core.h
29 +++ b/drivers/net/wireless/ath9k/core.h
30 @@ -857,4 +857,20 @@ static inline void ath_bus_cleanup(struc
31 sc->bus_ops->cleanup(sc);
34 +extern struct ieee80211_ops ath9k_ops;
36 +irqreturn_t ath_isr(int irq, void *dev);
37 +int ath_attach(u16 devid, struct ath_softc *sc);
38 +void ath_detach(struct ath_softc *sc);
39 +const char *ath_mac_bb_name(u32 mac_bb_version);
40 +const char *ath_rf_name(u16 rf_version);
43 +int ath_pci_init(void);
44 +void ath_pci_exit(void);
46 +static inline int ath_pci_init(void) { return 0; };
47 +static inline void ath_pci_exit(void) {};
51 --- a/drivers/net/wireless/ath9k/main.c
52 +++ b/drivers/net/wireless/ath9k/main.c
53 @@ -28,37 +28,6 @@ MODULE_DESCRIPTION("Support for Atheros
54 MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
55 MODULE_LICENSE("Dual BSD/GPL");
57 -static struct pci_device_id ath_pci_id_table[] __devinitdata = {
58 - { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
59 - { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
60 - { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
61 - { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
62 - { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
63 - { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
67 -static void ath_detach(struct ath_softc *sc);
69 -/* return bus cachesize in 4B word units */
70 -static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
74 - pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp);
78 - * This check was put in to avoid "unplesant" consequences if
79 - * the bootrom has not fully initialized all PCI devices.
80 - * Sometimes the cache line size register is not set
84 - *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
88 static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
90 sc->cur_rate_table = sc->hw_rate_table[mode];
91 @@ -499,7 +468,7 @@ static void ath9k_tasklet(unsigned long
92 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
95 -static irqreturn_t ath_isr(int irq, void *dev)
96 +irqreturn_t ath_isr(int irq, void *dev)
98 struct ath_softc *sc = dev;
99 struct ath_hal *ah = sc->sc_ah;
100 @@ -1287,7 +1256,7 @@ static int ath_start_rfkill_poll(struct
102 #endif /* CONFIG_RFKILL */
104 -static void ath_detach(struct ath_softc *sc)
105 +void ath_detach(struct ath_softc *sc)
107 struct ieee80211_hw *hw = sc->hw;
109 @@ -1538,7 +1507,7 @@ bad:
113 -static int ath_attach(u16 devid, struct ath_softc *sc)
114 +int ath_attach(u16 devid, struct ath_softc *sc)
116 struct ieee80211_hw *hw = sc->hw;
118 @@ -2466,7 +2435,7 @@ static int ath9k_ampdu_action(struct iee
122 -static struct ieee80211_ops ath9k_ops = {
123 +struct ieee80211_ops ath9k_ops = {
125 .start = ath9k_start,
127 @@ -2510,7 +2479,7 @@ static struct {
129 * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
133 ath_mac_bb_name(u32 mac_bb_version)
136 @@ -2527,7 +2496,7 @@ ath_mac_bb_name(u32 mac_bb_version)
138 * Return the RF name. "????" is returned if the RF is unknown.
142 ath_rf_name(u16 rf_version)
145 @@ -2541,306 +2510,7 @@ ath_rf_name(u16 rf_version)
149 -static dma_addr_t ath_pci_map_single_to_device(struct ath_softc *sc,
150 - void *p, size_t size)
152 - return pci_map_single(sc->pdev, p, size, PCI_DMA_TODEVICE);
155 -static void ath_pci_unmap_single_to_device(struct ath_softc *sc,
156 - dma_addr_t da, size_t size)
158 - pci_unmap_single(sc->pdev, da, size, PCI_DMA_TODEVICE);
161 -static dma_addr_t ath_pci_map_single_from_device(struct ath_softc *sc,
162 - void *p, size_t size)
164 - return pci_map_single(sc->pdev, p, size, PCI_DMA_FROMDEVICE);
167 -static void ath_pci_unmap_single_from_device(struct ath_softc *sc,
168 - dma_addr_t da, size_t size)
170 - pci_unmap_single(sc->pdev, da, size, PCI_DMA_FROMDEVICE);
173 -static int ath_pci_dma_mapping_error(struct ath_softc *sc, dma_addr_t da)
175 - return pci_dma_mapping_error(sc->pdev, da);
178 -static void ath_pci_sync_single_for_cpu(struct ath_softc *sc, dma_addr_t da,
181 - pci_dma_sync_single_for_cpu(sc->pdev, da, size,
182 - PCI_DMA_FROMDEVICE);
185 -static void *ath_pci_dma_alloc(struct ath_softc *sc, size_t size,
188 - return pci_alloc_consistent(sc->pdev, size, pda);
191 -static void ath_pci_dma_free(struct ath_softc *sc, size_t size,
192 - void *p, dma_addr_t da)
194 - pci_free_consistent(sc->pdev, size, p, da);
197 -static u32 ath_pci_reg_read(struct ath_hal *ah, unsigned reg)
199 - return ioread32(ah->ah_sh + reg);
202 -static void ath_pci_reg_write(struct ath_hal *ah, unsigned reg, u32 val)
204 - iowrite32(val, ah->ah_sh + reg);
207 -static void ath_pci_cleanup(struct ath_softc *sc)
211 - free_irq(sc->pdev->irq, sc);
212 - pci_iounmap(sc->pdev, sc->mem);
213 - pci_release_region(sc->pdev, 0);
214 - pci_disable_device(sc->pdev);
215 - ieee80211_free_hw(sc->hw);
218 -static struct ath_bus_ops ath_pci_bus_ops = {
219 - .dma_map_single_to_device = ath_pci_map_single_to_device,
220 - .dma_unmap_single_to_device = ath_pci_unmap_single_to_device,
221 - .dma_map_single_from_device = ath_pci_map_single_from_device,
222 - .dma_unmap_single_from_device = ath_pci_unmap_single_from_device,
223 - .dma_map_single_to_device = ath_pci_map_single_to_device,
224 - .dma_mapping_error = ath_pci_dma_mapping_error,
225 - .dma_sync_single_for_cpu = ath_pci_sync_single_for_cpu,
226 - .dma_alloc = ath_pci_dma_alloc,
227 - .dma_free = ath_pci_dma_free,
229 - .reg_read = ath_pci_reg_read,
230 - .reg_write = ath_pci_reg_write,
232 - .read_cachesize = ath_pci_read_cachesize,
234 - .cleanup = ath_pci_cleanup,
237 -static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
240 - struct ath_softc *sc;
241 - struct ieee80211_hw *hw;
245 - struct ath_hal *ah;
247 - if (pci_enable_device(pdev))
250 - ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
253 - printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
257 - ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
260 - printk(KERN_ERR "ath9k: 32-bit DMA consistent "
261 - "DMA enable failed\n");
266 - * Cache line size is used to size and align various
267 - * structures used to communicate with the hardware.
269 - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
272 - * Linux 2.4.18 (at least) writes the cache line size
273 - * register as a 16-bit wide register which is wrong.
274 - * We must have this setup properly for rx buffer
275 - * DMA to work so force a reasonable value here if it
278 - csz = L1_CACHE_BYTES / sizeof(u32);
279 - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
282 - * The default setting of latency timer yields poor results,
283 - * set it to the value used by other systems. It may be worth
284 - * tweaking this setting more.
286 - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
288 - pci_set_master(pdev);
291 - * Disable the RETRY_TIMEOUT register (0x41) to keep
292 - * PCI Tx retries from interfering with C3 CPU state.
294 - pci_read_config_dword(pdev, 0x40, &val);
295 - if ((val & 0x0000ff00) != 0)
296 - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
298 - ret = pci_request_region(pdev, 0, "ath9k");
300 - dev_err(&pdev->dev, "PCI memory region reserve error\n");
305 - mem = pci_iomap(pdev, 0, 0);
307 - printk(KERN_ERR "PCI memory map error\n") ;
312 - hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
314 - printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
318 - SET_IEEE80211_DEV(hw, &pdev->dev);
319 - pci_set_drvdata(pdev, hw);
325 - sc->bus_ops = &ath_pci_bus_ops;
327 - if (ath_attach(id->device, sc) != 0) {
332 - /* setup interrupt service routine */
334 - if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
335 - printk(KERN_ERR "%s: request_irq failed\n",
336 - wiphy_name(hw->wiphy));
343 - "%s: Atheros AR%s MAC/BB Rev:%x "
344 - "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
345 - wiphy_name(hw->wiphy),
346 - ath_mac_bb_name(ah->ah_macVersion),
348 - ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
350 - (unsigned long)mem, pdev->irq);
356 - ieee80211_free_hw(hw);
358 - pci_iounmap(pdev, mem);
360 - pci_release_region(pdev, 0);
362 - pci_disable_device(pdev);
366 -static void ath_pci_remove(struct pci_dev *pdev)
368 - struct ieee80211_hw *hw = pci_get_drvdata(pdev);
369 - struct ath_softc *sc = hw->priv;
371 - ath_pci_cleanup(sc);
376 -static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
378 - struct ieee80211_hw *hw = pci_get_drvdata(pdev);
379 - struct ath_softc *sc = hw->priv;
381 - ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
383 -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
384 - if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
385 - cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
388 - pci_save_state(pdev);
389 - pci_disable_device(pdev);
390 - pci_set_power_state(pdev, 3);
395 -static int ath_pci_resume(struct pci_dev *pdev)
397 - struct ieee80211_hw *hw = pci_get_drvdata(pdev);
398 - struct ath_softc *sc = hw->priv;
402 - err = pci_enable_device(pdev);
405 - pci_restore_state(pdev);
407 - * Suspend/Resume resets the PCI configuration space, so we have to
408 - * re-disable the RETRY_TIMEOUT register (0x41) to keep
409 - * PCI Tx retries from interfering with C3 CPU state
411 - pci_read_config_dword(pdev, 0x40, &val);
412 - if ((val & 0x0000ff00) != 0)
413 - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
416 - ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
417 - AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
418 - ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
420 -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
422 - * check the h/w rfkill state on resume
423 - * and start the rfkill poll timer
425 - if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
426 - queue_delayed_work(sc->hw->workqueue,
427 - &sc->rf_kill.rfkill_poll, 0);
433 -#endif /* CONFIG_PM */
435 -MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
437 -static struct pci_driver ath_pci_driver = {
439 - .id_table = ath_pci_id_table,
440 - .probe = ath_pci_probe,
441 - .remove = ath_pci_remove,
443 - .suspend = ath_pci_suspend,
444 - .resume = ath_pci_resume,
445 -#endif /* CONFIG_PM */
448 -static int __init init_ath_pci(void)
449 +static int __init ath9k_init(void)
453 @@ -2852,26 +2522,30 @@ static int __init init_ath_pci(void)
455 "Unable to register rate control algorithm: %d\n",
457 - ath_rate_control_unregister();
462 - if (pci_register_driver(&ath_pci_driver) < 0) {
463 + error = ath_pci_init();
466 "ath_pci: No devices found, driver not installed.\n");
467 - ath_rate_control_unregister();
468 - pci_unregister_driver(&ath_pci_driver);
471 + goto err_rate_unregister;
476 + err_rate_unregister:
477 + ath_rate_control_unregister();
481 -module_init(init_ath_pci);
482 +module_init(ath9k_init);
484 -static void __exit exit_ath_pci(void)
485 +static void __exit ath9k_exit(void)
488 ath_rate_control_unregister();
489 - pci_unregister_driver(&ath_pci_driver);
490 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
492 -module_exit(exit_ath_pci);
493 +module_exit(ath9k_exit);
495 +++ b/drivers/net/wireless/ath9k/pci.c
498 + * Copyright (c) 2008 Atheros Communications Inc.
500 + * Permission to use, copy, modify, and/or distribute this software for any
501 + * purpose with or without fee is hereby granted, provided that the above
502 + * copyright notice and this permission notice appear in all copies.
504 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
505 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
506 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
507 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
508 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
509 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
510 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
513 +#include <linux/nl80211.h>
518 +static struct pci_device_id ath_pci_id_table[] __devinitdata = {
519 + { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
520 + { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
521 + { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
522 + { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
523 + { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
524 + { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
528 +/* return bus cachesize in 4B word units */
529 +static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
533 + pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp);
537 + * This check was put in to avoid "unplesant" consequences if
538 + * the bootrom has not fully initialized all PCI devices.
539 + * Sometimes the cache line size register is not set
543 + *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
546 +static dma_addr_t ath_pci_map_single_to_device(struct ath_softc *sc,
547 + void *p, size_t size)
549 + return pci_map_single(sc->pdev, p, size, PCI_DMA_TODEVICE);
552 +static void ath_pci_unmap_single_to_device(struct ath_softc *sc,
553 + dma_addr_t da, size_t size)
555 + pci_unmap_single(sc->pdev, da, size, PCI_DMA_TODEVICE);
558 +static dma_addr_t ath_pci_map_single_from_device(struct ath_softc *sc,
559 + void *p, size_t size)
561 + return pci_map_single(sc->pdev, p, size, PCI_DMA_FROMDEVICE);
564 +static void ath_pci_unmap_single_from_device(struct ath_softc *sc,
565 + dma_addr_t da, size_t size)
567 + pci_unmap_single(sc->pdev, da, size, PCI_DMA_FROMDEVICE);
570 +static int ath_pci_dma_mapping_error(struct ath_softc *sc, dma_addr_t da)
572 + return pci_dma_mapping_error(sc->pdev, da);
575 +static void ath_pci_sync_single_for_cpu(struct ath_softc *sc, dma_addr_t da,
578 + pci_dma_sync_single_for_cpu(sc->pdev, da, size,
579 + PCI_DMA_FROMDEVICE);
582 +static void *ath_pci_dma_alloc(struct ath_softc *sc, size_t size,
585 + return pci_alloc_consistent(sc->pdev, size, pda);
588 +static void ath_pci_dma_free(struct ath_softc *sc, size_t size,
589 + void *p, dma_addr_t da)
591 + pci_free_consistent(sc->pdev, size, p, da);
594 +static u32 ath_pci_reg_read(struct ath_hal *ah, unsigned reg)
596 + return ioread32(ah->ah_sh + reg);
599 +static void ath_pci_reg_write(struct ath_hal *ah, unsigned reg, u32 val)
601 + iowrite32(val, ah->ah_sh + reg);
604 +static void ath_pci_cleanup(struct ath_softc *sc)
608 + free_irq(sc->pdev->irq, sc);
609 + pci_iounmap(sc->pdev, sc->mem);
610 + pci_release_region(sc->pdev, 0);
611 + pci_disable_device(sc->pdev);
612 + ieee80211_free_hw(sc->hw);
615 +static struct ath_bus_ops ath_pci_bus_ops = {
616 + .dma_map_single_to_device = ath_pci_map_single_to_device,
617 + .dma_unmap_single_to_device = ath_pci_unmap_single_to_device,
618 + .dma_map_single_from_device = ath_pci_map_single_from_device,
619 + .dma_unmap_single_from_device = ath_pci_unmap_single_from_device,
620 + .dma_map_single_to_device = ath_pci_map_single_to_device,
621 + .dma_mapping_error = ath_pci_dma_mapping_error,
622 + .dma_sync_single_for_cpu = ath_pci_sync_single_for_cpu,
623 + .dma_alloc = ath_pci_dma_alloc,
624 + .dma_free = ath_pci_dma_free,
626 + .reg_read = ath_pci_reg_read,
627 + .reg_write = ath_pci_reg_write,
629 + .read_cachesize = ath_pci_read_cachesize,
631 + .cleanup = ath_pci_cleanup,
634 +static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
637 + struct ath_softc *sc;
638 + struct ieee80211_hw *hw;
642 + struct ath_hal *ah;
644 + if (pci_enable_device(pdev))
647 + ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
650 + printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
654 + ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
657 + printk(KERN_ERR "ath9k: 32-bit DMA consistent "
658 + "DMA enable failed\n");
663 + * Cache line size is used to size and align various
664 + * structures used to communicate with the hardware.
666 + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
669 + * Linux 2.4.18 (at least) writes the cache line size
670 + * register as a 16-bit wide register which is wrong.
671 + * We must have this setup properly for rx buffer
672 + * DMA to work so force a reasonable value here if it
675 + csz = L1_CACHE_BYTES / sizeof(u32);
676 + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
679 + * The default setting of latency timer yields poor results,
680 + * set it to the value used by other systems. It may be worth
681 + * tweaking this setting more.
683 + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
685 + pci_set_master(pdev);
688 + * Disable the RETRY_TIMEOUT register (0x41) to keep
689 + * PCI Tx retries from interfering with C3 CPU state.
691 + pci_read_config_dword(pdev, 0x40, &val);
692 + if ((val & 0x0000ff00) != 0)
693 + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
695 + ret = pci_request_region(pdev, 0, "ath9k");
697 + dev_err(&pdev->dev, "PCI memory region reserve error\n");
702 + mem = pci_iomap(pdev, 0, 0);
704 + printk(KERN_ERR "PCI memory map error\n") ;
709 + hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
711 + printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
715 + SET_IEEE80211_DEV(hw, &pdev->dev);
716 + pci_set_drvdata(pdev, hw);
722 + sc->bus_ops = &ath_pci_bus_ops;
724 + if (ath_attach(id->device, sc) != 0) {
729 + /* setup interrupt service routine */
731 + if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
732 + printk(KERN_ERR "%s: request_irq failed\n",
733 + wiphy_name(hw->wiphy));
740 + "%s: Atheros AR%s MAC/BB Rev:%x "
741 + "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
742 + wiphy_name(hw->wiphy),
743 + ath_mac_bb_name(ah->ah_macVersion),
745 + ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
747 + (unsigned long)mem, pdev->irq);
753 + ieee80211_free_hw(hw);
755 + pci_iounmap(pdev, mem);
757 + pci_release_region(pdev, 0);
759 + pci_disable_device(pdev);
763 +static void ath_pci_remove(struct pci_dev *pdev)
765 + struct ieee80211_hw *hw = pci_get_drvdata(pdev);
766 + struct ath_softc *sc = hw->priv;
768 + ath_pci_cleanup(sc);
773 +static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
775 + struct ieee80211_hw *hw = pci_get_drvdata(pdev);
776 + struct ath_softc *sc = hw->priv;
778 + ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
780 +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
781 + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
782 + cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
785 + pci_save_state(pdev);
786 + pci_disable_device(pdev);
787 + pci_set_power_state(pdev, 3);
792 +static int ath_pci_resume(struct pci_dev *pdev)
794 + struct ieee80211_hw *hw = pci_get_drvdata(pdev);
795 + struct ath_softc *sc = hw->priv;
799 + err = pci_enable_device(pdev);
802 + pci_restore_state(pdev);
804 + * Suspend/Resume resets the PCI configuration space, so we have to
805 + * re-disable the RETRY_TIMEOUT register (0x41) to keep
806 + * PCI Tx retries from interfering with C3 CPU state
808 + pci_read_config_dword(pdev, 0x40, &val);
809 + if ((val & 0x0000ff00) != 0)
810 + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
813 + ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
814 + AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
815 + ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
817 +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
819 + * check the h/w rfkill state on resume
820 + * and start the rfkill poll timer
822 + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
823 + queue_delayed_work(sc->hw->workqueue,
824 + &sc->rf_kill.rfkill_poll, 0);
830 +#endif /* CONFIG_PM */
832 +MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
834 +static struct pci_driver ath_pci_driver = {
836 + .id_table = ath_pci_id_table,
837 + .probe = ath_pci_probe,
838 + .remove = ath_pci_remove,
840 + .suspend = ath_pci_suspend,
841 + .resume = ath_pci_resume,
842 +#endif /* CONFIG_PM */
845 +int __init ath_pci_init(void)
847 + return pci_register_driver(&ath_pci_driver);
850 +void ath_pci_exit(void)
852 + pci_unregister_driver(&ath_pci_driver);