0cdf4daf54d990d7f6f951a1e4e35e15f5c7a47c
[openwrt/svn-archive/archive.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 +}