ath9k_hw: cleanup MCI gpm offset state
authorRajkumar Manoharan <rmanohar@qca.qualcomm.com>
Tue, 12 Jun 2012 14:48:16 +0000 (20:18 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 13 Jun 2012 18:35:58 +0000 (14:35 -0400)
Add utility functions to get and test GPM offset and
remove MCI_STATE*_GPM_OFFSET states.

Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/ar9003_mci.c
drivers/net/wireless/ath/ath9k/ar9003_mci.h
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/mci.c

index c11dbaa..0433f2b 100644 (file)
@@ -593,8 +593,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
                if (!time_out)
                        break;
 
-               offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
-                                         &more_data);
+               offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data);
 
                if (offset == MCI_GPM_INVALID)
                        continue;
@@ -658,8 +657,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
                time_out = 0;
 
        while (more_data == MCI_GPM_MORE) {
-               offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
-                                         &more_data);
+               offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data);
                if (offset == MCI_GPM_INVALID)
                        break;
 
@@ -894,7 +892,7 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
        }
 
        /* Check pending GPM msg before MCI Reset Rx */
-       ar9003_mci_state(ah, MCI_STATE_CHECK_GPM_OFFSET, NULL);
+       ar9003_mci_check_gpm_offset(ah);
 
        regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);
        REG_WRITE(ah, AR_MCI_COMMAND2, regval);
@@ -902,7 +900,7 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
        regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
        REG_WRITE(ah, AR_MCI_COMMAND2, regval);
 
-       ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
+       ar9003_mci_get_next_gpm_offset(ah, true, NULL);
 
        REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
                  (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
@@ -1170,7 +1168,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
-       u32 value = 0, more_gpm = 0, gpm_ptr;
+       u32 value = 0;
        u8 query_type;
 
        switch (state_type) {
@@ -1182,96 +1180,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
                                value = 0;
                }
                value &= AR_BTCOEX_CTRL_MCI_MODE_EN;
-               break;
-       case MCI_STATE_INIT_GPM_OFFSET:
-               value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
-               mci->gpm_idx = value;
-               break;
-       case MCI_STATE_CHECK_GPM_OFFSET:
-               /*
-                * This should only be called before "MAC Warm Reset" or
-                * "MCI Reset Rx".
-                */
-               value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
-               if (mci->gpm_idx == value)
-                       break;
-               ath_dbg(common, MCI,
-                       "GPM cached write pointer mismatch %d %d\n",
-                       mci->gpm_idx, value);
-               mci->query_bt = true;
-               mci->need_flush_btinfo = true;
-               mci->gpm_idx = 0;
-               break;
-       case MCI_STATE_NEXT_GPM_OFFSET:
-       case MCI_STATE_LAST_GPM_OFFSET:
-               /*
-               * This could be useful to avoid new GPM message interrupt which
-               * may lead to spurious interrupt after power sleep, or multiple
-               * entry of ath_mci_intr().
-               * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
-               * alleviate this effect, but clearing GPM RX interrupt bit is
-               * safe, because whether this is called from hw or driver code
-               * there must be an interrupt bit set/triggered initially
-               */
-               REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
-                         AR_MCI_INTERRUPT_RX_MSG_GPM);
-
-               gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
-               value = gpm_ptr;
-
-               if (value == 0)
-                       value = mci->gpm_len - 1;
-               else if (value >= mci->gpm_len) {
-                       if (value != 0xFFFF)
-                               value = 0;
-               } else {
-                       value--;
-               }
-
-               if (value == 0xFFFF) {
-                       value = MCI_GPM_INVALID;
-                       more_gpm = MCI_GPM_NOMORE;
-               } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) {
-                       if (gpm_ptr == mci->gpm_idx) {
-                               value = MCI_GPM_INVALID;
-                               more_gpm = MCI_GPM_NOMORE;
-                       } else {
-                               for (;;) {
-                                       u32 temp_index;
-
-                                       /* skip reserved GPM if any */
-
-                                       if (value != mci->gpm_idx)
-                                               more_gpm = MCI_GPM_MORE;
-                                       else
-                                               more_gpm = MCI_GPM_NOMORE;
-
-                                       temp_index = mci->gpm_idx;
-                                       mci->gpm_idx++;
-
-                                       if (mci->gpm_idx >=
-                                           mci->gpm_len)
-                                               mci->gpm_idx = 0;
-
-                                       if (ar9003_mci_is_gpm_valid(ah,
-                                                                   temp_index)) {
-                                               value = temp_index;
-                                               break;
-                                       }
-
-                                       if (more_gpm == MCI_GPM_NOMORE) {
-                                               value = MCI_GPM_INVALID;
-                                               break;
-                                       }
-                               }
-                       }
-                       if (p_data)
-                               *p_data = more_gpm;
-               }
-
-               if (value != MCI_GPM_INVALID)
-                       value <<= 4;
-
                break;
        case MCI_STATE_LAST_SCHD_MSG_OFFSET:
                value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
@@ -1450,3 +1358,99 @@ void ar9003_mci_set_power_awake(struct ath_hw *ah)
                udelay(50);
        }
 }
+
+void ar9003_mci_check_gpm_offset(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
+       u32 offset;
+
+       /*
+        * This should only be called before "MAC Warm Reset" or "MCI Reset Rx".
+        */
+       offset = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
+       if (mci->gpm_idx == offset)
+               return;
+       ath_dbg(common, MCI, "GPM cached write pointer mismatch %d %d\n",
+               mci->gpm_idx, offset);
+       mci->query_bt = true;
+       mci->need_flush_btinfo = true;
+       mci->gpm_idx = 0;
+}
+
+u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more)
+{
+       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
+       u32 offset, more_gpm = 0, gpm_ptr;
+
+       if (first) {
+               gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
+               mci->gpm_idx = gpm_ptr;
+               return gpm_ptr;
+       }
+
+       /*
+        * This could be useful to avoid new GPM message interrupt which
+        * may lead to spurious interrupt after power sleep, or multiple
+        * entry of ath_mci_intr().
+        * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
+        * alleviate this effect, but clearing GPM RX interrupt bit is
+        * safe, because whether this is called from hw or driver code
+        * there must be an interrupt bit set/triggered initially
+        */
+       REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
+                       AR_MCI_INTERRUPT_RX_MSG_GPM);
+
+       gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
+       offset = gpm_ptr;
+
+       if (!offset)
+               offset = mci->gpm_len - 1;
+       else if (offset >= mci->gpm_len) {
+               if (offset != 0xFFFF)
+                       offset = 0;
+       } else {
+               offset--;
+       }
+
+       if ((offset == 0xFFFF) || (gpm_ptr == mci->gpm_idx)) {
+               offset = MCI_GPM_INVALID;
+               more_gpm = MCI_GPM_NOMORE;
+               goto out;
+       }
+       for (;;) {
+               u32 temp_index;
+
+               /* skip reserved GPM if any */
+
+               if (offset != mci->gpm_idx)
+                       more_gpm = MCI_GPM_MORE;
+               else
+                       more_gpm = MCI_GPM_NOMORE;
+
+               temp_index = mci->gpm_idx;
+               mci->gpm_idx++;
+
+               if (mci->gpm_idx >= mci->gpm_len)
+                       mci->gpm_idx = 0;
+
+               if (ar9003_mci_is_gpm_valid(ah, temp_index)) {
+                       offset = temp_index;
+                       break;
+               }
+
+               if (more_gpm == MCI_GPM_NOMORE) {
+                       offset = MCI_GPM_INVALID;
+                       break;
+               }
+       }
+
+       if (offset != MCI_GPM_INVALID)
+               offset <<= 4;
+out:
+       if (more)
+               *more = more_gpm;
+
+       return offset;
+}
+EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset);
index 8cb3307..163d156 100644 (file)
@@ -189,10 +189,6 @@ enum mci_bt_state {
 /* Type of state query */
 enum mci_state_type {
        MCI_STATE_ENABLE,
-       MCI_STATE_INIT_GPM_OFFSET,
-       MCI_STATE_CHECK_GPM_OFFSET,
-       MCI_STATE_NEXT_GPM_OFFSET,
-       MCI_STATE_LAST_GPM_OFFSET,
        MCI_STATE_BT,
        MCI_STATE_SET_BT_SLEEP,
        MCI_STATE_SET_BT_AWAKE,
@@ -266,6 +262,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
 void ar9003_mci_cleanup(struct ath_hw *ah);
 void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
                              u32 *rx_msg_intr);
+u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more);
 /*
  * These functions are used by ath9k_hw.
  */
@@ -286,6 +283,7 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
 void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked);
 void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah);
 void ar9003_mci_set_power_awake(struct ath_hw *ah);
+void ar9003_mci_check_gpm_offset(struct ath_hw *ah);
 
 #else
 
@@ -329,6 +327,9 @@ static inline void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah)
 static inline void ar9003_mci_set_power_awake(struct ath_hw *ah)
 {
 }
+static inline void ar9003_mci_check_gpm_offset(struct ath_hw *ah)
+{
+}
 #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
 
 #endif
index 4ec496d..784baee 100644 (file)
@@ -1349,7 +1349,7 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
        }
 
        if (ath9k_hw_mci_is_enabled(ah))
-               ar9003_mci_state(ah, MCI_STATE_CHECK_GPM_OFFSET, NULL);
+               ar9003_mci_check_gpm_offset(ah);
 
        REG_WRITE(ah, AR_RTC_RC, rst_flags);
 
index f0c8fa4..9e15231 100644 (file)
@@ -421,7 +421,7 @@ void ath_mci_intr(struct ath_softc *sc)
        ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg);
 
        if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) {
-               ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
+               ar9003_mci_get_next_gpm_offset(ah, true, NULL);
                return;
        }
 
@@ -488,8 +488,8 @@ void ath_mci_intr(struct ath_softc *sc)
                while (more_data == MCI_GPM_MORE) {
 
                        pgpm = mci->gpm_buf.bf_addr;
-                       offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
-                                                 &more_data);
+                       offset = ar9003_mci_get_next_gpm_offset(ah, false,
+                                                               &more_data);
 
                        if (offset == MCI_GPM_INVALID)
                                break;