aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2013-12-24 00:14:19 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-01-03 15:36:57 -0500
commit990de2b2e48ac377fb40842a9b04fd940ba78e1b (patch)
tree61c8d466c704157aaa1d082c7bacac7b1409a6fa /drivers/net
parent4598702d1b3e0b6aa6694f4c786313a999afbdc9 (diff)
ath9k: Add HW callbacks for MAC/BB hang checks
This is required for adding separate hang check routines for AR9002 and AR9003. Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c72
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c70
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h3
4 files changed, 85 insertions, 70 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index f1d3c4aa2396..75a6d85d6ee9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -892,6 +892,77 @@ static void ar9003_hw_init_hang_checks(struct ath_hw *ah)
892 ah->bb_watchdog_timeout_ms = 25; 892 ah->bb_watchdog_timeout_ms = 25;
893} 893}
894 894
895static bool ath9k_hw_check_dcs(u32 dma_dbg, u32 num_dcu_states,
896 int *hang_state, int *hang_pos)
897{
898 static u32 dcu_chain_state[] = {5, 6, 9}; /* DCU chain stuck states */
899 u32 chain_state, dcs_pos, i;
900
901 for (dcs_pos = 0; dcs_pos < num_dcu_states; dcs_pos++) {
902 chain_state = (dma_dbg >> (5 * dcs_pos)) & 0x1f;
903 for (i = 0; i < 3; i++) {
904 if (chain_state == dcu_chain_state[i]) {
905 *hang_state = chain_state;
906 *hang_pos = dcs_pos;
907 return true;
908 }
909 }
910 }
911 return false;
912}
913
914#define DCU_COMPLETE_STATE 1
915#define DCU_COMPLETE_STATE_MASK 0x3
916#define NUM_STATUS_READS 50
917
918static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah)
919{
920 u32 chain_state, comp_state, dcs_reg = AR_DMADBG_4;
921 u32 i, hang_pos, hang_state, num_state = 6;
922
923 comp_state = REG_READ(ah, AR_DMADBG_6);
924
925 if ((comp_state & DCU_COMPLETE_STATE_MASK) != DCU_COMPLETE_STATE) {
926 ath_dbg(ath9k_hw_common(ah), RESET,
927 "MAC Hang signature not found at DCU complete\n");
928 return false;
929 }
930
931 chain_state = REG_READ(ah, dcs_reg);
932 if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos))
933 goto hang_check_iter;
934
935 dcs_reg = AR_DMADBG_5;
936 num_state = 4;
937 chain_state = REG_READ(ah, dcs_reg);
938 if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos))
939 goto hang_check_iter;
940
941 ath_dbg(ath9k_hw_common(ah), RESET,
942 "MAC Hang signature 1 not found\n");
943 return false;
944
945hang_check_iter:
946 ath_dbg(ath9k_hw_common(ah), RESET,
947 "DCU registers: chain %08x complete %08x Hang: state %d pos %d\n",
948 chain_state, comp_state, hang_state, hang_pos);
949
950 for (i = 0; i < NUM_STATUS_READS; i++) {
951 chain_state = REG_READ(ah, dcs_reg);
952 chain_state = (chain_state >> (5 * hang_pos)) & 0x1f;
953 comp_state = REG_READ(ah, AR_DMADBG_6);
954
955 if (((comp_state & DCU_COMPLETE_STATE_MASK) !=
956 DCU_COMPLETE_STATE) ||
957 (chain_state != hang_state))
958 return false;
959 }
960
961 ath_dbg(ath9k_hw_common(ah), RESET, "MAC Hang signature 1 found\n");
962
963 return true;
964}
965
895/* Sets up the AR9003 hardware familiy callbacks */ 966/* Sets up the AR9003 hardware familiy callbacks */
896void ar9003_hw_attach_ops(struct ath_hw *ah) 967void ar9003_hw_attach_ops(struct ath_hw *ah)
897{ 968{
@@ -901,6 +972,7 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
901 ar9003_hw_init_mode_regs(ah); 972 ar9003_hw_init_mode_regs(ah);
902 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; 973 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
903 priv_ops->init_hang_checks = ar9003_hw_init_hang_checks; 974 priv_ops->init_hang_checks = ar9003_hw_init_hang_checks;
975 priv_ops->detect_mac_hang = ar9003_hw_detect_mac_hang;
904 976
905 ops->config_pci_powersave = ar9003_hw_configpcipowersave; 977 ops->config_pci_powersave = ar9003_hw_configpcipowersave;
906 978
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index bd95eae37d90..0b2550a91c7c 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -112,6 +112,16 @@ static inline void ath9k_hw_init_hang_checks(struct ath_hw *ah)
112 ath9k_hw_private_ops(ah)->init_hang_checks(ah); 112 ath9k_hw_private_ops(ah)->init_hang_checks(ah);
113} 113}
114 114
115static inline bool ath9k_hw_detect_mac_hang(struct ath_hw *ah)
116{
117 return ath9k_hw_private_ops(ah)->detect_mac_hang(ah);
118}
119
120static inline bool ath9k_hw_detect_bb_hang(struct ath_hw *ah)
121{
122 return ath9k_hw_private_ops(ah)->detect_bb_hang(ah);
123}
124
115/* PHY ops */ 125/* PHY ops */
116 126
117static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah, 127static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 51c4edd07659..708388063a6b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1529,76 +1529,6 @@ static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
1529 } 1529 }
1530} 1530}
1531 1531
1532static bool ath9k_hw_check_dcs(u32 dma_dbg, u32 num_dcu_states,
1533 int *hang_state, int *hang_pos)
1534{
1535 static u32 dcu_chain_state[] = {5, 6, 9}; /* DCU chain stuck states */
1536 u32 chain_state, dcs_pos, i;
1537
1538 for (dcs_pos = 0; dcs_pos < num_dcu_states; dcs_pos++) {
1539 chain_state = (dma_dbg >> (5 * dcs_pos)) & 0x1f;
1540 for (i = 0; i < 3; i++) {
1541 if (chain_state == dcu_chain_state[i]) {
1542 *hang_state = chain_state;
1543 *hang_pos = dcs_pos;
1544 return true;
1545 }
1546 }
1547 }
1548 return false;
1549}
1550
1551#define DCU_COMPLETE_STATE 1
1552#define DCU_COMPLETE_STATE_MASK 0x3
1553#define NUM_STATUS_READS 50
1554static bool ath9k_hw_detect_mac_hang(struct ath_hw *ah)
1555{
1556 u32 chain_state, comp_state, dcs_reg = AR_DMADBG_4;
1557 u32 i, hang_pos, hang_state, num_state = 6;
1558
1559 comp_state = REG_READ(ah, AR_DMADBG_6);
1560
1561 if ((comp_state & DCU_COMPLETE_STATE_MASK) != DCU_COMPLETE_STATE) {
1562 ath_dbg(ath9k_hw_common(ah), RESET,
1563 "MAC Hang signature not found at DCU complete\n");
1564 return false;
1565 }
1566
1567 chain_state = REG_READ(ah, dcs_reg);
1568 if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos))
1569 goto hang_check_iter;
1570
1571 dcs_reg = AR_DMADBG_5;
1572 num_state = 4;
1573 chain_state = REG_READ(ah, dcs_reg);
1574 if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos))
1575 goto hang_check_iter;
1576
1577 ath_dbg(ath9k_hw_common(ah), RESET,
1578 "MAC Hang signature 1 not found\n");
1579 return false;
1580
1581hang_check_iter:
1582 ath_dbg(ath9k_hw_common(ah), RESET,
1583 "DCU registers: chain %08x complete %08x Hang: state %d pos %d\n",
1584 chain_state, comp_state, hang_state, hang_pos);
1585
1586 for (i = 0; i < NUM_STATUS_READS; i++) {
1587 chain_state = REG_READ(ah, dcs_reg);
1588 chain_state = (chain_state >> (5 * hang_pos)) & 0x1f;
1589 comp_state = REG_READ(ah, AR_DMADBG_6);
1590
1591 if (((comp_state & DCU_COMPLETE_STATE_MASK) !=
1592 DCU_COMPLETE_STATE) ||
1593 (chain_state != hang_state))
1594 return false;
1595 }
1596
1597 ath_dbg(ath9k_hw_common(ah), RESET, "MAC Hang signature 1 found\n");
1598
1599 return true;
1600}
1601
1602void ath9k_hw_check_nav(struct ath_hw *ah) 1532void ath9k_hw_check_nav(struct ath_hw *ah)
1603{ 1533{
1604 struct ath_common *common = ath9k_hw_common(ah); 1534 struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 0a3cfc537859..cb930d680392 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -585,6 +585,9 @@ struct ath_hw_radar_conf {
585 */ 585 */
586struct ath_hw_private_ops { 586struct ath_hw_private_ops {
587 void (*init_hang_checks)(struct ath_hw *ah); 587 void (*init_hang_checks)(struct ath_hw *ah);
588 bool (*detect_mac_hang)(struct ath_hw *ah);
589 bool (*detect_bb_hang)(struct ath_hw *ah);
590
588 /* Calibration ops */ 591 /* Calibration ops */
589 void (*init_cal_settings)(struct ath_hw *ah); 592 void (*init_cal_settings)(struct ath_hw *ah);
590 bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan); 593 bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);