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