[package] mac80211: add preliminary support for the AR913x SoCs
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 405-ath9k-move-PCI-code-into-separate-file.patch
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
5
6 Convert 'struct pci_dev' to 'struct device' to make it usable on the AHB
7 bus as well.
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 | 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(-)
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 @@ -857,4 +857,20 @@ static inline void ath_bus_cleanup(struc
31 sc->bus_ops->cleanup(sc);
32 }
33
34 +extern struct ieee80211_ops ath9k_ops;
35 +
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);
41 +
42 +#ifdef CONFIG_PCI
43 +int ath_pci_init(void);
44 +void ath_pci_exit(void);
45 +#else
46 +static inline int ath_pci_init(void) { return 0; };
47 +static inline void ath_pci_exit(void) {};
48 +#endif
49 +
50 #endif /* CORE_H */
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");
56
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 */
64 - { 0 }
65 -};
66 -
67 -static void ath_detach(struct ath_softc *sc);
68 -
69 -/* return bus cachesize in 4B word units */
70 -static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
71 -{
72 - u8 u8tmp;
73 -
74 - pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp);
75 - *csz = (int)u8tmp;
76 -
77 - /*
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
81 - */
82 -
83 - if (*csz == 0)
84 - *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
85 -}
86 -
87 -
88 static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
89 {
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);
93 }
94
95 -static irqreturn_t ath_isr(int irq, void *dev)
96 +irqreturn_t ath_isr(int irq, void *dev)
97 {
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
101 }
102 #endif /* CONFIG_RFKILL */
103
104 -static void ath_detach(struct ath_softc *sc)
105 +void ath_detach(struct ath_softc *sc)
106 {
107 struct ieee80211_hw *hw = sc->hw;
108 int i = 0;
109 @@ -1538,7 +1507,7 @@ bad:
110 return error;
111 }
112
113 -static int ath_attach(u16 devid, struct ath_softc *sc)
114 +int ath_attach(u16 devid, struct ath_softc *sc)
115 {
116 struct ieee80211_hw *hw = sc->hw;
117 int error = 0;
118 @@ -2466,7 +2435,7 @@ static int ath9k_ampdu_action(struct iee
119 return ret;
120 }
121
122 -static struct ieee80211_ops ath9k_ops = {
123 +struct ieee80211_ops ath9k_ops = {
124 .tx = ath9k_tx,
125 .start = ath9k_start,
126 .stop = ath9k_stop,
127 @@ -2510,7 +2479,7 @@ static struct {
128 /*
129 * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
130 */
131 -static const char *
132 +const char *
133 ath_mac_bb_name(u32 mac_bb_version)
134 {
135 int i;
136 @@ -2527,7 +2496,7 @@ ath_mac_bb_name(u32 mac_bb_version)
137 /*
138 * Return the RF name. "????" is returned if the RF is unknown.
139 */
140 -static const char *
141 +const char *
142 ath_rf_name(u16 rf_version)
143 {
144 int i;
145 @@ -2541,306 +2510,7 @@ ath_rf_name(u16 rf_version)
146 return "????";
147 }
148
149 -static dma_addr_t ath_pci_map_single_to_device(struct ath_softc *sc,
150 - void *p, size_t size)
151 -{
152 - return pci_map_single(sc->pdev, p, size, PCI_DMA_TODEVICE);
153 -}
154 -
155 -static void ath_pci_unmap_single_to_device(struct ath_softc *sc,
156 - dma_addr_t da, size_t size)
157 -{
158 - pci_unmap_single(sc->pdev, da, size, PCI_DMA_TODEVICE);
159 -}
160 -
161 -static dma_addr_t ath_pci_map_single_from_device(struct ath_softc *sc,
162 - void *p, size_t size)
163 -{
164 - return pci_map_single(sc->pdev, p, size, PCI_DMA_FROMDEVICE);
165 -}
166 -
167 -static void ath_pci_unmap_single_from_device(struct ath_softc *sc,
168 - dma_addr_t da, size_t size)
169 -{
170 - pci_unmap_single(sc->pdev, da, size, PCI_DMA_FROMDEVICE);
171 -}
172 -
173 -static int ath_pci_dma_mapping_error(struct ath_softc *sc, dma_addr_t da)
174 -{
175 - return pci_dma_mapping_error(sc->pdev, da);
176 -}
177 -
178 -static void ath_pci_sync_single_for_cpu(struct ath_softc *sc, dma_addr_t da,
179 - size_t size)
180 -{
181 - pci_dma_sync_single_for_cpu(sc->pdev, da, size,
182 - PCI_DMA_FROMDEVICE);
183 -}
184 -
185 -static void *ath_pci_dma_alloc(struct ath_softc *sc, size_t size,
186 - dma_addr_t *pda)
187 -{
188 - return pci_alloc_consistent(sc->pdev, size, pda);
189 -}
190 -
191 -static void ath_pci_dma_free(struct ath_softc *sc, size_t size,
192 - void *p, dma_addr_t da)
193 -{
194 - pci_free_consistent(sc->pdev, size, p, da);
195 -}
196 -
197 -static u32 ath_pci_reg_read(struct ath_hal *ah, unsigned reg)
198 -{
199 - return ioread32(ah->ah_sh + reg);
200 -}
201 -
202 -static void ath_pci_reg_write(struct ath_hal *ah, unsigned reg, u32 val)
203 -{
204 - iowrite32(val, ah->ah_sh + reg);
205 -}
206 -
207 -static void ath_pci_cleanup(struct ath_softc *sc)
208 -{
209 - ath_detach(sc);
210 - if (sc->pdev->irq)
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);
216 -}
217 -
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,
228 -
229 - .reg_read = ath_pci_reg_read,
230 - .reg_write = ath_pci_reg_write,
231 -
232 - .read_cachesize = ath_pci_read_cachesize,
233 -
234 - .cleanup = ath_pci_cleanup,
235 -};
236 -
237 -static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
238 -{
239 - void __iomem *mem;
240 - struct ath_softc *sc;
241 - struct ieee80211_hw *hw;
242 - u8 csz;
243 - u32 val;
244 - int ret = 0;
245 - struct ath_hal *ah;
246 -
247 - if (pci_enable_device(pdev))
248 - return -EIO;
249 -
250 - ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
251 -
252 - if (ret) {
253 - printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
254 - goto bad;
255 - }
256 -
257 - ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
258 -
259 - if (ret) {
260 - printk(KERN_ERR "ath9k: 32-bit DMA consistent "
261 - "DMA enable failed\n");
262 - goto bad;
263 - }
264 -
265 - /*
266 - * Cache line size is used to size and align various
267 - * structures used to communicate with the hardware.
268 - */
269 - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
270 - if (csz == 0) {
271 - /*
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
276 - * comes up zero.
277 - */
278 - csz = L1_CACHE_BYTES / sizeof(u32);
279 - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
280 - }
281 - /*
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.
285 - */
286 - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
287 -
288 - pci_set_master(pdev);
289 -
290 - /*
291 - * Disable the RETRY_TIMEOUT register (0x41) to keep
292 - * PCI Tx retries from interfering with C3 CPU state.
293 - */
294 - pci_read_config_dword(pdev, 0x40, &val);
295 - if ((val & 0x0000ff00) != 0)
296 - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
297 -
298 - ret = pci_request_region(pdev, 0, "ath9k");
299 - if (ret) {
300 - dev_err(&pdev->dev, "PCI memory region reserve error\n");
301 - ret = -ENODEV;
302 - goto bad;
303 - }
304 -
305 - mem = pci_iomap(pdev, 0, 0);
306 - if (!mem) {
307 - printk(KERN_ERR "PCI memory map error\n") ;
308 - ret = -EIO;
309 - goto bad1;
310 - }
311 -
312 - hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
313 - if (hw == NULL) {
314 - printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
315 - goto bad2;
316 - }
317 -
318 - SET_IEEE80211_DEV(hw, &pdev->dev);
319 - pci_set_drvdata(pdev, hw);
320 -
321 - sc = hw->priv;
322 - sc->hw = hw;
323 - sc->pdev = pdev;
324 - sc->mem = mem;
325 - sc->bus_ops = &ath_pci_bus_ops;
326 -
327 - if (ath_attach(id->device, sc) != 0) {
328 - ret = -ENODEV;
329 - goto bad3;
330 - }
331 -
332 - /* setup interrupt service routine */
333 -
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));
337 - ret = -EIO;
338 - goto bad4;
339 - }
340 -
341 - ah = sc->sc_ah;
342 - printk(KERN_INFO
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),
347 - ah->ah_macRev,
348 - ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
349 - ah->ah_phyRev,
350 - (unsigned long)mem, pdev->irq);
351 -
352 - return 0;
353 -bad4:
354 - ath_detach(sc);
355 -bad3:
356 - ieee80211_free_hw(hw);
357 -bad2:
358 - pci_iounmap(pdev, mem);
359 -bad1:
360 - pci_release_region(pdev, 0);
361 -bad:
362 - pci_disable_device(pdev);
363 - return ret;
364 -}
365 -
366 -static void ath_pci_remove(struct pci_dev *pdev)
367 -{
368 - struct ieee80211_hw *hw = pci_get_drvdata(pdev);
369 - struct ath_softc *sc = hw->priv;
370 -
371 - ath_pci_cleanup(sc);
372 -}
373 -
374 -#ifdef CONFIG_PM
375 -
376 -static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
377 -{
378 - struct ieee80211_hw *hw = pci_get_drvdata(pdev);
379 - struct ath_softc *sc = hw->priv;
380 -
381 - ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
382 -
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);
386 -#endif
387 -
388 - pci_save_state(pdev);
389 - pci_disable_device(pdev);
390 - pci_set_power_state(pdev, 3);
391 -
392 - return 0;
393 -}
394 -
395 -static int ath_pci_resume(struct pci_dev *pdev)
396 -{
397 - struct ieee80211_hw *hw = pci_get_drvdata(pdev);
398 - struct ath_softc *sc = hw->priv;
399 - u32 val;
400 - int err;
401 -
402 - err = pci_enable_device(pdev);
403 - if (err)
404 - return err;
405 - pci_restore_state(pdev);
406 - /*
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
410 - */
411 - pci_read_config_dword(pdev, 0x40, &val);
412 - if ((val & 0x0000ff00) != 0)
413 - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
414 -
415 - /* Enable LED */
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);
419 -
420 -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
421 - /*
422 - * check the h/w rfkill state on resume
423 - * and start the rfkill poll timer
424 - */
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);
428 -#endif
429 -
430 - return 0;
431 -}
432 -
433 -#endif /* CONFIG_PM */
434 -
435 -MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
436 -
437 -static struct pci_driver ath_pci_driver = {
438 - .name = "ath9k",
439 - .id_table = ath_pci_id_table,
440 - .probe = ath_pci_probe,
441 - .remove = ath_pci_remove,
442 -#ifdef CONFIG_PM
443 - .suspend = ath_pci_suspend,
444 - .resume = ath_pci_resume,
445 -#endif /* CONFIG_PM */
446 -};
447 -
448 -static int __init init_ath_pci(void)
449 +static int __init ath9k_init(void)
450 {
451 int error;
452
453 @@ -2852,26 +2522,30 @@ static int __init init_ath_pci(void)
454 printk(KERN_ERR
455 "Unable to register rate control algorithm: %d\n",
456 error);
457 - ath_rate_control_unregister();
458 - return error;
459 + goto err_out;
460 }
461
462 - if (pci_register_driver(&ath_pci_driver) < 0) {
463 + error = ath_pci_init();
464 + if (error < 0) {
465 printk(KERN_ERR
466 "ath_pci: No devices found, driver not installed.\n");
467 - ath_rate_control_unregister();
468 - pci_unregister_driver(&ath_pci_driver);
469 - return -ENODEV;
470 + error = -ENODEV;
471 + goto err_rate_unregister;
472 }
473
474 return 0;
475 +
476 + err_rate_unregister:
477 + ath_rate_control_unregister();
478 + err_out:
479 + return error;
480 }
481 -module_init(init_ath_pci);
482 +module_init(ath9k_init);
483
484 -static void __exit exit_ath_pci(void)
485 +static void __exit ath9k_exit(void)
486 {
487 + ath_pci_exit();
488 ath_rate_control_unregister();
489 - pci_unregister_driver(&ath_pci_driver);
490 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
491 }
492 -module_exit(exit_ath_pci);
493 +module_exit(ath9k_exit);
494 --- /dev/null
495 +++ b/drivers/net/wireless/ath9k/pci.c
496 @@ -0,0 +1,357 @@
497 +/*
498 + * Copyright (c) 2008 Atheros Communications Inc.
499 + *
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.
503 + *
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.
511 + */
512 +
513 +#include <linux/nl80211.h>
514 +#include "core.h"
515 +#include "reg.h"
516 +#include "hw.h"
517 +
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 */
525 + { 0 }
526 +};
527 +
528 +/* return bus cachesize in 4B word units */
529 +static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
530 +{
531 + u8 u8tmp;
532 +
533 + pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp);
534 + *csz = (int)u8tmp;
535 +
536 + /*
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
540 + */
541 +
542 + if (*csz == 0)
543 + *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
544 +}
545 +
546 +static dma_addr_t ath_pci_map_single_to_device(struct ath_softc *sc,
547 + void *p, size_t size)
548 +{
549 + return pci_map_single(sc->pdev, p, size, PCI_DMA_TODEVICE);
550 +}
551 +
552 +static void ath_pci_unmap_single_to_device(struct ath_softc *sc,
553 + dma_addr_t da, size_t size)
554 +{
555 + pci_unmap_single(sc->pdev, da, size, PCI_DMA_TODEVICE);
556 +}
557 +
558 +static dma_addr_t ath_pci_map_single_from_device(struct ath_softc *sc,
559 + void *p, size_t size)
560 +{
561 + return pci_map_single(sc->pdev, p, size, PCI_DMA_FROMDEVICE);
562 +}
563 +
564 +static void ath_pci_unmap_single_from_device(struct ath_softc *sc,
565 + dma_addr_t da, size_t size)
566 +{
567 + pci_unmap_single(sc->pdev, da, size, PCI_DMA_FROMDEVICE);
568 +}
569 +
570 +static int ath_pci_dma_mapping_error(struct ath_softc *sc, dma_addr_t da)
571 +{
572 + return pci_dma_mapping_error(sc->pdev, da);
573 +}
574 +
575 +static void ath_pci_sync_single_for_cpu(struct ath_softc *sc, dma_addr_t da,
576 + size_t size)
577 +{
578 + pci_dma_sync_single_for_cpu(sc->pdev, da, size,
579 + PCI_DMA_FROMDEVICE);
580 +}
581 +
582 +static void *ath_pci_dma_alloc(struct ath_softc *sc, size_t size,
583 + dma_addr_t *pda)
584 +{
585 + return pci_alloc_consistent(sc->pdev, size, pda);
586 +}
587 +
588 +static void ath_pci_dma_free(struct ath_softc *sc, size_t size,
589 + void *p, dma_addr_t da)
590 +{
591 + pci_free_consistent(sc->pdev, size, p, da);
592 +}
593 +
594 +static u32 ath_pci_reg_read(struct ath_hal *ah, unsigned reg)
595 +{
596 + return ioread32(ah->ah_sh + reg);
597 +}
598 +
599 +static void ath_pci_reg_write(struct ath_hal *ah, unsigned reg, u32 val)
600 +{
601 + iowrite32(val, ah->ah_sh + reg);
602 +}
603 +
604 +static void ath_pci_cleanup(struct ath_softc *sc)
605 +{
606 + ath_detach(sc);
607 + if (sc->pdev->irq)
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);
613 +}
614 +
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,
625 +
626 + .reg_read = ath_pci_reg_read,
627 + .reg_write = ath_pci_reg_write,
628 +
629 + .read_cachesize = ath_pci_read_cachesize,
630 +
631 + .cleanup = ath_pci_cleanup,
632 +};
633 +
634 +static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
635 +{
636 + void __iomem *mem;
637 + struct ath_softc *sc;
638 + struct ieee80211_hw *hw;
639 + u8 csz;
640 + u32 val;
641 + int ret = 0;
642 + struct ath_hal *ah;
643 +
644 + if (pci_enable_device(pdev))
645 + return -EIO;
646 +
647 + ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
648 +
649 + if (ret) {
650 + printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
651 + goto bad;
652 + }
653 +
654 + ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
655 +
656 + if (ret) {
657 + printk(KERN_ERR "ath9k: 32-bit DMA consistent "
658 + "DMA enable failed\n");
659 + goto bad;
660 + }
661 +
662 + /*
663 + * Cache line size is used to size and align various
664 + * structures used to communicate with the hardware.
665 + */
666 + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
667 + if (csz == 0) {
668 + /*
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
673 + * comes up zero.
674 + */
675 + csz = L1_CACHE_BYTES / sizeof(u32);
676 + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
677 + }
678 + /*
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.
682 + */
683 + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
684 +
685 + pci_set_master(pdev);
686 +
687 + /*
688 + * Disable the RETRY_TIMEOUT register (0x41) to keep
689 + * PCI Tx retries from interfering with C3 CPU state.
690 + */
691 + pci_read_config_dword(pdev, 0x40, &val);
692 + if ((val & 0x0000ff00) != 0)
693 + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
694 +
695 + ret = pci_request_region(pdev, 0, "ath9k");
696 + if (ret) {
697 + dev_err(&pdev->dev, "PCI memory region reserve error\n");
698 + ret = -ENODEV;
699 + goto bad;
700 + }
701 +
702 + mem = pci_iomap(pdev, 0, 0);
703 + if (!mem) {
704 + printk(KERN_ERR "PCI memory map error\n") ;
705 + ret = -EIO;
706 + goto bad1;
707 + }
708 +
709 + hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
710 + if (hw == NULL) {
711 + printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
712 + goto bad2;
713 + }
714 +
715 + SET_IEEE80211_DEV(hw, &pdev->dev);
716 + pci_set_drvdata(pdev, hw);
717 +
718 + sc = hw->priv;
719 + sc->hw = hw;
720 + sc->pdev = pdev;
721 + sc->mem = mem;
722 + sc->bus_ops = &ath_pci_bus_ops;
723 +
724 + if (ath_attach(id->device, sc) != 0) {
725 + ret = -ENODEV;
726 + goto bad3;
727 + }
728 +
729 + /* setup interrupt service routine */
730 +
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));
734 + ret = -EIO;
735 + goto bad4;
736 + }
737 +
738 + ah = sc->sc_ah;
739 + printk(KERN_INFO
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),
744 + ah->ah_macRev,
745 + ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
746 + ah->ah_phyRev,
747 + (unsigned long)mem, pdev->irq);
748 +
749 + return 0;
750 +bad4:
751 + ath_detach(sc);
752 +bad3:
753 + ieee80211_free_hw(hw);
754 +bad2:
755 + pci_iounmap(pdev, mem);
756 +bad1:
757 + pci_release_region(pdev, 0);
758 +bad:
759 + pci_disable_device(pdev);
760 + return ret;
761 +}
762 +
763 +static void ath_pci_remove(struct pci_dev *pdev)
764 +{
765 + struct ieee80211_hw *hw = pci_get_drvdata(pdev);
766 + struct ath_softc *sc = hw->priv;
767 +
768 + ath_pci_cleanup(sc);
769 +}
770 +
771 +#ifdef CONFIG_PM
772 +
773 +static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
774 +{
775 + struct ieee80211_hw *hw = pci_get_drvdata(pdev);
776 + struct ath_softc *sc = hw->priv;
777 +
778 + ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
779 +
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);
783 +#endif
784 +
785 + pci_save_state(pdev);
786 + pci_disable_device(pdev);
787 + pci_set_power_state(pdev, 3);
788 +
789 + return 0;
790 +}
791 +
792 +static int ath_pci_resume(struct pci_dev *pdev)
793 +{
794 + struct ieee80211_hw *hw = pci_get_drvdata(pdev);
795 + struct ath_softc *sc = hw->priv;
796 + u32 val;
797 + int err;
798 +
799 + err = pci_enable_device(pdev);
800 + if (err)
801 + return err;
802 + pci_restore_state(pdev);
803 + /*
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
807 + */
808 + pci_read_config_dword(pdev, 0x40, &val);
809 + if ((val & 0x0000ff00) != 0)
810 + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
811 +
812 + /* Enable LED */
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);
816 +
817 +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
818 + /*
819 + * check the h/w rfkill state on resume
820 + * and start the rfkill poll timer
821 + */
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);
825 +#endif
826 +
827 + return 0;
828 +}
829 +
830 +#endif /* CONFIG_PM */
831 +
832 +MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
833 +
834 +static struct pci_driver ath_pci_driver = {
835 + .name = "ath9k",
836 + .id_table = ath_pci_id_table,
837 + .probe = ath_pci_probe,
838 + .remove = ath_pci_remove,
839 +#ifdef CONFIG_PM
840 + .suspend = ath_pci_suspend,
841 + .resume = ath_pci_resume,
842 +#endif /* CONFIG_PM */
843 +};
844 +
845 +int __init ath_pci_init(void)
846 +{
847 + return pci_register_driver(&ath_pci_driver);
848 +}
849 +
850 +void ath_pci_exit(void)
851 +{
852 + pci_unregister_driver(&ath_pci_driver);
853 +}