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