aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2010-04-15 17:38:06 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-16 15:32:01 -0400
commitd70357d56942fa587e39505547cb69e10a8d59a0 (patch)
treeeb715d856b4ef48fd63805b0845f35024e1e8faa /drivers/net/wireless
parentac1a474d71d6cbf94bf26889da5768f5f2b0ca2b (diff)
ath9k_hw: start building an abstraction layer for hardware routines
ath9k supports the AR5008, AR9001 and AR9002 family of Atheros chipsets, all 802.11n. The new breed of 802.11n chips, the AR9003 family will be supported as well soon. To help with its support we're going to add a few callbacks for hardware routines which differ considerably instead of adding branch checks for the revision at runtime. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h31
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c125
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h47
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c7
5 files changed, 166 insertions, 45 deletions
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 72a835d9e97f..1a87283a0941 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -20,6 +20,7 @@
20#include "../debug.h" 20#include "../debug.h"
21 21
22#include "hw.h" 22#include "hw.h"
23#include "hw-ops.h"
23 24
24/* Common header for Atheros 802.11n base driver cores */ 25/* Common header for Atheros 802.11n base driver cores */
25 26
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
new file mode 100644
index 000000000000..ee33146cda15
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef ATH9K_HW_OPS_H
18#define ATH9K_HW_OPS_H
19
20#include "hw.h"
21
22/* Hardware core and driver accessible callbacks */
23
24static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
25 int restore,
26 int power_off)
27{
28 ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off);
29}
30
31#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 3b9f4c1f8d4e..a55db3bc13e6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -18,6 +18,7 @@
18#include <asm/unaligned.h> 18#include <asm/unaligned.h>
19 19
20#include "hw.h" 20#include "hw.h"
21#include "hw-ops.h"
21#include "rc.h" 22#include "rc.h"
22#include "initvals.h" 23#include "initvals.h"
23 24
@@ -25,6 +26,8 @@
25#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 26#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
26#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 27#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
27 28
29static void ar9002_hw_attach_ops(struct ath_hw *ah);
30
28static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); 31static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
29static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan); 32static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan);
30 33
@@ -45,6 +48,25 @@ static void __exit ath9k_exit(void)
45} 48}
46module_exit(ath9k_exit); 49module_exit(ath9k_exit);
47 50
51/* Private hardware callbacks */
52
53static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
54{
55 ath9k_hw_private_ops(ah)->init_cal_settings(ah);
56}
57
58static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
59{
60 ath9k_hw_private_ops(ah)->init_mode_regs(ah);
61}
62
63static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
64{
65 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
66
67 return priv_ops->macversion_supported(ah->hw_version.macVersion);
68}
69
48/********************/ 70/********************/
49/* Helper Functions */ 71/* Helper Functions */
50/********************/ 72/********************/
@@ -368,7 +390,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
368 if (num_possible_cpus() > 1) 390 if (num_possible_cpus() > 1)
369 ah->config.serialize_regmode = SER_REG_MODE_AUTO; 391 ah->config.serialize_regmode = SER_REG_MODE_AUTO;
370} 392}
371EXPORT_SYMBOL(ath9k_hw_init);
372 393
373static void ath9k_hw_init_defaults(struct ath_hw *ah) 394static void ath9k_hw_init_defaults(struct ath_hw *ah)
374{ 395{
@@ -532,27 +553,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
532 return 0; 553 return 0;
533} 554}
534 555
535static bool ath9k_hw_devid_supported(u16 devid) 556static bool ar9002_hw_macversion_supported(u32 macversion)
536{
537 switch (devid) {
538 case AR5416_DEVID_PCI:
539 case AR5416_DEVID_PCIE:
540 case AR5416_AR9100_DEVID:
541 case AR9160_DEVID_PCI:
542 case AR9280_DEVID_PCI:
543 case AR9280_DEVID_PCIE:
544 case AR9285_DEVID_PCIE:
545 case AR5416_DEVID_AR9287_PCI:
546 case AR5416_DEVID_AR9287_PCIE:
547 case AR2427_DEVID_PCIE:
548 return true;
549 default:
550 break;
551 }
552 return false;
553}
554
555static bool ath9k_hw_macversion_supported(u32 macversion)
556{ 557{
557 switch (macversion) { 558 switch (macversion) {
558 case AR_SREV_VERSION_5416_PCI: 559 case AR_SREV_VERSION_5416_PCI:
@@ -570,7 +571,7 @@ static bool ath9k_hw_macversion_supported(u32 macversion)
570 return false; 571 return false;
571} 572}
572 573
573static void ath9k_hw_init_cal_settings(struct ath_hw *ah) 574static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
574{ 575{
575 if (AR_SREV_9160_10_OR_LATER(ah)) { 576 if (AR_SREV_9160_10_OR_LATER(ah)) {
576 if (AR_SREV_9280_10_OR_LATER(ah)) { 577 if (AR_SREV_9280_10_OR_LATER(ah)) {
@@ -594,7 +595,7 @@ static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
594 } 595 }
595} 596}
596 597
597static void ath9k_hw_init_mode_regs(struct ath_hw *ah) 598static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
598{ 599{
599 if (AR_SREV_9271(ah)) { 600 if (AR_SREV_9271(ah)) {
600 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271, 601 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
@@ -854,20 +855,12 @@ static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
854 "needs fixup for AR_AN_TOP2 register\n"); 855 "needs fixup for AR_AN_TOP2 register\n");
855} 856}
856 857
857int ath9k_hw_init(struct ath_hw *ah) 858/* Called for all hardware families */
859static int __ath9k_hw_init(struct ath_hw *ah)
858{ 860{
859 struct ath_common *common = ath9k_hw_common(ah); 861 struct ath_common *common = ath9k_hw_common(ah);
860 int r = 0; 862 int r = 0;
861 863
862 if (common->bus_ops->ath_bus_type != ATH_USB) {
863 if (!ath9k_hw_devid_supported(ah->hw_version.devid)) {
864 ath_print(common, ATH_DBG_FATAL,
865 "Unsupported device ID: 0x%0x\n",
866 ah->hw_version.devid);
867 return -EOPNOTSUPP;
868 }
869 }
870
871 ath9k_hw_init_defaults(ah); 864 ath9k_hw_init_defaults(ah);
872 ath9k_hw_init_config(ah); 865 ath9k_hw_init_config(ah);
873 866
@@ -877,6 +870,8 @@ int ath9k_hw_init(struct ath_hw *ah)
877 return -EIO; 870 return -EIO;
878 } 871 }
879 872
873 ar9002_hw_attach_ops(ah);
874
880 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { 875 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
881 ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n"); 876 ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
882 return -EIO; 877 return -EIO;
@@ -901,7 +896,7 @@ int ath9k_hw_init(struct ath_hw *ah)
901 else 896 else
902 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; 897 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
903 898
904 if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) { 899 if (!ath9k_hw_macversion_supported(ah)) {
905 ath_print(common, ATH_DBG_FATAL, 900 ath_print(common, ATH_DBG_FATAL,
906 "Mac Chip Rev 0x%02x.%x is not supported by " 901 "Mac Chip Rev 0x%02x.%x is not supported by "
907 "this driver\n", ah->hw_version.macVersion, 902 "this driver\n", ah->hw_version.macVersion,
@@ -918,6 +913,7 @@ int ath9k_hw_init(struct ath_hw *ah)
918 if (AR_SREV_9271(ah)) 913 if (AR_SREV_9271(ah))
919 ah->is_pciexpress = false; 914 ah->is_pciexpress = false;
920 915
916 /* XXX: move this to its own hw op */
921 ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); 917 ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
922 918
923 ath9k_hw_init_cal_settings(ah); 919 ath9k_hw_init_cal_settings(ah);
@@ -979,6 +975,45 @@ int ath9k_hw_init(struct ath_hw *ah)
979 return 0; 975 return 0;
980} 976}
981 977
978int ath9k_hw_init(struct ath_hw *ah)
979{
980 int ret;
981 struct ath_common *common = ath9k_hw_common(ah);
982
983 /* These are all the AR5008/AR9001/AR9002 hardware family of chipsets */
984 switch (ah->hw_version.devid) {
985 case AR5416_DEVID_PCI:
986 case AR5416_DEVID_PCIE:
987 case AR5416_AR9100_DEVID:
988 case AR9160_DEVID_PCI:
989 case AR9280_DEVID_PCI:
990 case AR9280_DEVID_PCIE:
991 case AR9285_DEVID_PCIE:
992 case AR5416_DEVID_AR9287_PCI:
993 case AR5416_DEVID_AR9287_PCIE:
994 case AR2427_DEVID_PCIE:
995 break;
996 default:
997 if (common->bus_ops->ath_bus_type == ATH_USB)
998 break;
999 ath_print(common, ATH_DBG_FATAL,
1000 "Hardware device ID 0x%04x not supported\n",
1001 ah->hw_version.devid);
1002 return -EOPNOTSUPP;
1003 }
1004
1005 ret = __ath9k_hw_init(ah);
1006 if (ret) {
1007 ath_print(common, ATH_DBG_FATAL,
1008 "Unable to initialize hardware; "
1009 "initialization status: %d\n", ret);
1010 return ret;
1011 }
1012
1013 return 0;
1014}
1015EXPORT_SYMBOL(ath9k_hw_init);
1016
982static void ath9k_hw_init_bb(struct ath_hw *ah, 1017static void ath9k_hw_init_bb(struct ath_hw *ah,
983 struct ath9k_channel *chan) 1018 struct ath9k_channel *chan)
984{ 1019{
@@ -2500,7 +2535,9 @@ EXPORT_SYMBOL(ath9k_hw_setpower);
2500 * Programming the SerDes must go through the same 288 bit serial shift 2535 * Programming the SerDes must go through the same 288 bit serial shift
2501 * register as the other analog registers. Hence the 9 writes. 2536 * register as the other analog registers. Hence the 9 writes.
2502 */ 2537 */
2503void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off) 2538static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
2539 int restore,
2540 int power_off)
2504{ 2541{
2505 u8 i; 2542 u8 i;
2506 u32 val; 2543 u32 val;
@@ -2518,7 +2555,7 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
2518 /* 2555 /*
2519 * AR9280 2.0 or later chips use SerDes values from the 2556 * AR9280 2.0 or later chips use SerDes values from the
2520 * initvals.h initialized depending on chipset during 2557 * initvals.h initialized depending on chipset during
2521 * ath9k_hw_init() 2558 * __ath9k_hw_init()
2522 */ 2559 */
2523 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) { 2560 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
2524 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), 2561 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
@@ -2622,7 +2659,6 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
2622 } 2659 }
2623 } 2660 }
2624} 2661}
2625EXPORT_SYMBOL(ath9k_hw_configpcipowersave);
2626 2662
2627/**********************/ 2663/**********************/
2628/* Interrupt Handling */ 2664/* Interrupt Handling */
@@ -3917,3 +3953,16 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len)
3917 hw_name[used] = '\0'; 3953 hw_name[used] = '\0';
3918} 3954}
3919EXPORT_SYMBOL(ath9k_hw_name); 3955EXPORT_SYMBOL(ath9k_hw_name);
3956
3957/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
3958static void ar9002_hw_attach_ops(struct ath_hw *ah)
3959{
3960 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
3961 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
3962
3963 priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
3964 priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
3965 priv_ops->macversion_supported = ar9002_hw_macversion_supported;
3966
3967 ops->config_pci_powersave = ar9002_hw_configpcipowersave;
3968}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f4821cf33b87..dfe8502866bb 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -440,6 +440,36 @@ struct ath_gen_timer_table {
440 } timer_mask; 440 } timer_mask;
441}; 441};
442 442
443/**
444 * struct ath_hw_private_ops - callbacks used internally by hardware code
445 *
446 * This structure contains private callbacks designed to only be used internally
447 * by the hardware core.
448 *
449 * @init_cal_settings: Initializes calibration settings
450 * @init_mode_regs: Initializes mode registers
451 * @macversion_supported: If this specific mac revision is supported
452 */
453struct ath_hw_private_ops {
454 void (*init_cal_settings)(struct ath_hw *ah);
455 void (*init_mode_regs)(struct ath_hw *ah);
456 bool (*macversion_supported)(u32 macversion);
457};
458
459/**
460 * struct ath_hw_ops - callbacks used by hardware code and driver code
461 *
462 * This structure contains callbacks designed to to be used internally by
463 * hardware code and also by the lower level driver.
464 *
465 * @config_pci_powersave:
466 */
467struct ath_hw_ops {
468 void (*config_pci_powersave)(struct ath_hw *ah,
469 int restore,
470 int power_off);
471};
472
443struct ath_hw { 473struct ath_hw {
444 struct ieee80211_hw *hw; 474 struct ieee80211_hw *hw;
445 struct ath_common common; 475 struct ath_common common;
@@ -540,6 +570,11 @@ struct ath_hw {
540 void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah, 570 void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah,
541 struct ath9k_channel *chan); 571 struct ath9k_channel *chan);
542 572
573 /* Private to hardware code */
574 struct ath_hw_private_ops private_ops;
575 /* Accessed by the lower level driver */
576 struct ath_hw_ops ops;
577
543 /* Used to program the radio on non single-chip devices */ 578 /* Used to program the radio on non single-chip devices */
544 u32 *analogBank0Data; 579 u32 *analogBank0Data;
545 u32 *analogBank1Data; 580 u32 *analogBank1Data;
@@ -619,6 +654,16 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
619 return &(ath9k_hw_common(ah)->regulatory); 654 return &(ath9k_hw_common(ah)->regulatory);
620} 655}
621 656
657static inline struct ath_hw_private_ops *ath9k_hw_private_ops(struct ath_hw *ah)
658{
659 return &ah->private_ops;
660}
661
662static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
663{
664 return &ah->ops;
665}
666
622/* Initialization, Detach, Reset */ 667/* Initialization, Detach, Reset */
623const char *ath9k_hw_probe(u16 vendorid, u16 devid); 668const char *ath9k_hw_probe(u16 vendorid, u16 devid);
624void ath9k_hw_deinit(struct ath_hw *ah); 669void ath9k_hw_deinit(struct ath_hw *ah);
@@ -681,8 +726,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
681 726
682bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); 727bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
683 728
684void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off);
685
686/* Interrupt Handling */ 729/* Interrupt Handling */
687bool ath9k_hw_intrpend(struct ath_hw *ah); 730bool ath9k_hw_intrpend(struct ath_hw *ah);
688bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked); 731bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 6063f5463708..62682cc2e216 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -566,13 +566,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
566 ath_read_cachesize(common, &csz); 566 ath_read_cachesize(common, &csz);
567 common->cachelsz = csz << 2; /* convert to bytes */ 567 common->cachelsz = csz << 2; /* convert to bytes */
568 568
569 /* Initializes the hardware for all supported chipsets */
569 ret = ath9k_hw_init(ah); 570 ret = ath9k_hw_init(ah);
570 if (ret) { 571 if (ret)
571 ath_print(common, ATH_DBG_FATAL,
572 "Unable to initialize hardware; "
573 "initialization status: %d\n", ret);
574 goto err_hw; 572 goto err_hw;
575 }
576 573
577 ret = ath9k_init_debug(ah); 574 ret = ath9k_init_debug(ah);
578 if (ret) { 575 if (ret) {