Add support for MCI BT coex
cover Add support for MCI BT coex
From: Mohammed Shafi Shajakhan <[email protected]>
Add support for MCI BT-Coex for AR9462. with AR9462 we have WLAN and BT coexists via MCI protocol(Message Coexistence Interface) WLAN and BT exchanges GPM, SCHED messages and few other messages for coexistence.
*thanks to Senthil Balasubramanian <[email protected]> for his technical support
*thanks to Wilson Tsao <[email protected]> who being the core author of MCI, for his valuable help and documents
*thanks a lot to Rajkumar Manoharan <[email protected]> for his suggestions, review comments, code cleanups, and modifications in design.
bug fixes and few miscellaneous cleanups will be added then and there
Mohammed Shafi Shajakhan (18):
ath9k_hw: add definitions to support MCI h/w code
ath9k_hw: add GPIO output MUX related macros
ath9k_hw: Add MCI h/w specific structure
ath9k_hw: initialize MCI parameters
ath9k_hw: Add MCI h/w code and state machine
ath9k: Add MCI interrupt to interrupt mask
ath9k_hw: take care of enabling MCI interrupts
ath9k_hw: check for asynchronous MCI interrupt pending
ath9k_hw: check for MCI interrupt in get_isr
ath9k: add MCI specific definitions and structures
ath9k: Add functions to allocate/free buffers for MCI
ath9k_hw: MCI related changes in chip management
ath9k_hw: MCI related changes in set_reset_reg
ath9k_hw: Add support for MCI WLAN calibration
ath9k_hw: Add MCI related changes in chip reset
ath9k: make ath_reset non-static
ath9k: MCI state machine based on MCI interrupt
ath9k: fix a typo
drivers/net/wireless/ath/ath9k/Makefile | 3 +- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 43 + drivers/net/wireless/ath/ath9k/ar9003_mac.c | 36 +- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 1464 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_mci.h | 102 ++ drivers/net/wireless/ath/ath9k/ar9003_phy.h | 3 + drivers/net/wireless/ath/ath9k/ath9k.h | 2 + drivers/net/wireless/ath/ath9k/btcoex.c | 2 +- drivers/net/wireless/ath/ath9k/btcoex.h | 31 + drivers/net/wireless/ath/ath9k/hw.c | 174 +++- drivers/net/wireless/ath/ath9k/hw.h | 182 +++ drivers/net/wireless/ath/ath9k/init.c | 33 + drivers/net/wireless/ath/ath9k/mac.c | 17 +- drivers/net/wireless/ath/ath9k/main.c | 11 +- drivers/net/wireless/ath/ath9k/mci.c | 419 +++++++ drivers/net/wireless/ath/ath9k/mci.h | 20 + drivers/net/wireless/ath/ath9k/reg.h | 306 +++++- 17 files changed, 2807 insertions(+), 41 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_mci.c create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_mci.h
PATCH 1/18 ath9k_hw: add definitions to support MCI h/w code
From: Mohammed Shafi Shajakhan <[email protected]>
these definitions will be used by MCI state machine and the corresponding hardware code
--- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 102 +++++++++ drivers/net/wireless/ath/ath9k/ar9003_phy.h | 3 + drivers/net/wireless/ath/ath9k/hw.h | 146 +++++++++++++ drivers/net/wireless/ath/ath9k/reg.h | 304 ++++++++++++++++++++++++--- 4 files changed, 529 insertions(+), 26 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_mci.h
drivers/net/wireless/ath/ath9k/ar9003_mci.h new file +102 -0
@@ -0,0 +1,102 @@ +/* +* Copyright (c) 2010-2011 Atheros Communications Inc. +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef AR9003_MCI_H +#define AR9003_MCI_H + +#define MCI_FLAG_DISABLE_TIMESTAMP 0x00000001/* Disable time stamp */ + +/* Default remote BT device MCI COEX version */ +#define MCI_GPM_COEX_MAJOR_VERSION_DEFAULT 3 +#define MCI_GPM_COEX_MINOR_VERSION_DEFAULT 0 + +/* Local WLAN MCI COEX version */ +#define MCI_GPM_COEX_MAJOR_VERSION_WLAN 3 +#define MCI_GPM_COEX_MINOR_VERSION_WLAN 0 + +enum mci_gpm_coex_query_type { +MCI_GPM_COEX_QUERY_BT_ALL_INFO =BIT (0 ), +MCI_GPM_COEX_QUERY_BT_TOPOLOGY =BIT (1 ), +MCI_GPM_COEX_QUERY_BT_DEBUG =BIT (2 ), +}; + +enum mci_gpm_coex_halt_bt_gpm { +MCI_GPM_COEX_BT_GPM_UNHALT , +MCI_GPM_COEX_BT_GPM_HALT +}; + +enum mci_gpm_coex_bt_update_flags_op { +MCI_GPM_COEX_BT_FLAGS_READ , +MCI_GPM_COEX_BT_FLAGS_SET , +MCI_GPM_COEX_BT_FLAGS_CLEAR +}; + +#define MCI_NUM_BT_CHANNELS 79 + +#define MCI_BT_MCI_FLAGS_UPDATE_CORR 0x00000002 +#define MCI_BT_MCI_FLAGS_UPDATE_HDR 0x00000004 +#define MCI_BT_MCI_FLAGS_UPDATE_PLD 0x00000008 +#define MCI_BT_MCI_FLAGS_LNA_CTRL 0x00000010 +#define MCI_BT_MCI_FLAGS_DEBUG 0x00000020 +#define MCI_BT_MCI_FLAGS_SCHED_MSG 0x00000040 +#define MCI_BT_MCI_FLAGS_CONT_MSG 0x00000080 +#define MCI_BT_MCI_FLAGS_COEX_GPM 0x00000100 +#define MCI_BT_MCI_FLAGS_CPU_INT_MSG 0x00000200 +#define MCI_BT_MCI_FLAGS_MCI_MODE 0x00000400 +#define MCI_BT_MCI_FLAGS_AR9462_MODE 0x00001000 +#define MCI_BT_MCI_FLAGS_OTHER 0x00010000 + +#define MCI_DEFAULT_BT_MCI_FLAGS 0x00011dde + +#define MCI_TOGGLE_BT_MCI_FLAGS (MCI_BT_MCI_FLAGS_UPDATE_CORR | \ + MCI_BT_MCI_FLAGS_UPDATE_HDR | \ + MCI_BT_MCI_FLAGS_UPDATE_PLD | \ + MCI_BT_MCI_FLAGS_MCI_MODE) + +#define MCI_2G_FLAGS_CLEAR_MASK 0x00000000 +#define MCI_2G_FLAGS_SET_MASK MCI_TOGGLE_BT_MCI_FLAGS +#define MCI_2G_FLAGS MCI_DEFAULT_BT_MCI_FLAGS + +#define MCI_5G_FLAGS_CLEAR_MASK MCI_TOGGLE_BT_MCI_FLAGS +#define MCI_5G_FLAGS_SET_MASK 0x00000000 +#define MCI_5G_FLAGS (MCI_DEFAULT_BT_MCI_FLAGS & \ + ~MCI_TOGGLE_BT_MCI_FLAGS) + +/* +* Default value for AR9462 is 0x00002201 +*/ +#define ATH_MCI_CONFIG_CONCUR_TX 0x00000003 +#define ATH_MCI_CONFIG_MCI_OBS_MCI 0x00000004 +#define ATH_MCI_CONFIG_MCI_OBS_TXRX 0x00000008 +#define ATH_MCI_CONFIG_MCI_OBS_BT 0x00000010 +#define ATH_MCI_CONFIG_DISABLE_MCI_CAL 0x00000020 +#define ATH_MCI_CONFIG_DISABLE_OSLA 0x00000040 +#define ATH_MCI_CONFIG_DISABLE_FTP_STOMP 0x00000080 +#define ATH_MCI_CONFIG_AGGR_THRESH 0x00000700 +#define ATH_MCI_CONFIG_AGGR_THRESH_S 8 +#define ATH_MCI_CONFIG_DISABLE_AGGR_THRESH 0x00000800 +#define ATH_MCI_CONFIG_CLK_DIV 0x00003000 +#define ATH_MCI_CONFIG_CLK_DIV_S 12 +#define ATH_MCI_CONFIG_DISABLE_TUNING 0x00004000 +#define ATH_MCI_CONFIG_MCI_WEIGHT_DBG 0x40000000 +#define ATH_MCI_CONFIG_DISABLE_MCI 0x80000000 + +#define ATH_MCI_CONFIG_MCI_OBS_MASK (ATH_MCI_CONFIG_MCI_OBS_MCI | \ + ATH_MCI_CONFIG_MCI_OBS_TXRX | \ + ATH_MCI_CONFIG_MCI_OBS_BT) +#define ATH_MCI_CONFIG_MCI_OBS_GPIO 0x0000002F + +#endif
drivers/net/wireless/ath/ath9k/ar9003_phy.h +3 -0
@@ -490,6 +490,8 @@#define AR_PHY_TEST_CTL_TSTADC_EN_S 8#define AR_PHY_TEST_CTL_RX_OBS_SEL 0x3C00#define AR_PHY_TEST_CTL_RX_OBS_SEL_S 10 +#define AR_PHY_TEST_CTL_DEBUGPORT_SEL 0xe0000000 +#define AR_PHY_TEST_CTL_DEBUGPORT_SEL_S 29#define AR_PHY_TSTDAC (AR_SM_BASE + 0x168)
@@ -1001,6 +1003,7 @@/* GLB Registers */ #define AR_GLB_BASE 0x20000 +#define AR_GLB_GPIO_CONTROL (AR_GLB_BASE)#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44)#define AR_GLB_SCRATCH (_ah) (AR_GLB_BASE + \ (AR_SREV_9462_20(_ah) ? 0x4c : 0x50))
drivers/net/wireless/ath/ath9k/hw.h +146 -0
164 lines not on this page · raw message
drivers/net/wireless/ath/ath9k/reg.h +278 -26
333 lines not on this page · raw message
Signature · 1 line
1.7.0.4
PATCH 2/18 ath9k_hw: add GPIO output MUX related macros
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
--- drivers/net/wireless/ath/ath9k/hw.h | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath9k/hw.h +10 -0
@@ -126,6 +126,16 @@#define AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL 4#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6 +#define AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA 0x16 +#define AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK 0x17 +#define AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA 0x18 +#define AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK 0x19 +#define AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX 0x14 +#define AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX 0x13 +#define AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX 9 +#define AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX 8 +#define AR_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE 0x1d +#define AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA 0x1e#define AR_GPIOD_MASK 0x00001FFF#define AR_GPIO_BIT (_gpio) (1 << (_gpio))
Signature · 1 line
1.7.0.4
PATCH 3/18 ath9k_hw: Add MCI h/w specific structure
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
--- drivers/net/wireless/ath/ath9k/btcoex.h | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath9k/btcoex.h +31 -0
@@ -54,8 +54,39 @@ enum ath_btcoex_scheme { ATH_BTCOEX_CFG_MCI, }; +struct ath9k_hw_mci { +u32 raw_intr; +u32 rx_msg_intr; +u32 cont_status; +u32 gpm_addr; +u32 gpm_len; +u32 gpm_idx; +u32 sched_addr; +u32 wlan_channels[4 ]; +u32 wlan_cal_seq; +u32 wlan_cal_done; +u32 config; +u8 *gpm_buf; +u8 *sched_buf; +bool ready; +bool update_2g5g; +bool is_2g; +bool query_bt; +bool unhalt_bt_gpm;/* need send UNHALT */ +bool halted_bt_gpm;/* HALT sent */ +bool need_flush_btinfo; +bool bt_version_known; +bool wlan_channels_update; +u8 wlan_ver_major; +u8 wlan_ver_minor; +u8 bt_ver_major; +u8 bt_ver_minor; +u8 bt_state; +}; +struct ath_btcoex_hw {enum ath_btcoex_scheme scheme; +struct ath9k_hw_mci mci;bool enabled;u8 wlanactive_gpio;u8 btactive_gpio;
Signature · 1 line
1.7.0.4
PATCH 4/18 ath9k_hw: initialize MCI parameters
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
these parameter will be utilized and modified in the MCI hardware codes state machine
--- drivers/net/wireless/ath/ath9k/init.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath9k/init.c +22 -0
@@ -408,6 +408,7 @@ fail:static int ath9k_init_btcoex (struct ath_softc *sc) {struct ath_txq *txq; +struct ath_hw *ah = sc->sc_ah;int r;switch (sc->sc_ah->btcoex_hw.scheme) {
@@ -426,6 +427,27 @@ static int ath9k_init_btcoex(struct ath_softc *sc) sc->btcoex.bt_stomp_type =ATH_BTCOEX_STOMP_LOW ; sc->btcoex.duty_cycle =ATH_BTCOEX_DEF_DUTY_CYCLE ;INIT_LIST_HEAD (&sc->btcoex.mci.info); +if (sc->sc_ah->caps.hw_caps &ATH9K_HW_CAP_MCI ) { + ah->btcoex_hw.mci.ready = false; + ah->btcoex_hw.mci.bt_state =0 ; + ah->btcoex_hw.mci.bt_ver_major =3 ; + ah->btcoex_hw.mci.bt_ver_minor =0 ; + ah->btcoex_hw.mci.bt_version_known = false; + ah->btcoex_hw.mci.update_2g5g = true; + ah->btcoex_hw.mci.is_2g = true; + ah->btcoex_hw.mci.wlan_channels_update = false; + ah->btcoex_hw.mci.wlan_channels[0 ] =0x00000000 ; + ah->btcoex_hw.mci.wlan_channels[1 ] =0xffffffff ; + ah->btcoex_hw.mci.wlan_channels[2 ] =0xffffffff ; + ah->btcoex_hw.mci.wlan_channels[3 ] =0x7fffffff ; + ah->btcoex_hw.mci.query_bt = true; + ah->btcoex_hw.mci.unhalt_bt_gpm = true; + ah->btcoex_hw.mci.halted_bt_gpm = false; + ah->btcoex_hw.mci.need_flush_btinfo = false; + ah->btcoex_hw.mci.wlan_cal_seq =0 ; + ah->btcoex_hw.mci.wlan_cal_done =0 ; + ah->btcoex_hw.mci.config =0x2201 ; + }break ;default :WARN_ON (1 );
Signature · 1 line
1.7.0.4
PATCH 5/18 ath9k_hw: Add MCI h/w code and state machine
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
--- drivers/net/wireless/ath/ath9k/Makefile | 3 +- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 1464 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 26 + 3 files changed, 1492 insertions(+), 1 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_mci.c
drivers/net/wireless/ath/ath9k/Makefile +2 -1
@@ -34,7 +34,8 @@ ath9k_hw-y:= \ ar9002_mac.o \ ar9003_mac.o \ ar9003_eeprom.o \ - ar9003_paprd.o + ar9003_paprd.o \ + ar9003_mci.o obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
drivers/net/wireless/ath/ath9k/ar9003_mci.c new file +1464 -0
1,464 lines not on this page · raw message
drivers/net/wireless/ath/ath9k/hw.h +26 -0
@@ -1203,6 +1203,32 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);void ath9k_hw_proc_mib_event (struct ath_hw *ah);void ath9k_hw_ani_monitor (struct ath_hw *ah,struct ath9k_channel *chan); +bool ar9003_mci_send_message (struct ath_hw *ah,u8 header,u32 flag, +u32 *payload,u8 len,bool wait_done, +bool check_bt); +void ar9003_mci_mute_bt (struct ath_hw *ah); +u32 ar9003_mci_state (struct ath_hw *ah,u32 state_type,u32 *p_data); +void ar9003_mci_setup (struct ath_hw *ah,u32 gpm_addr,void *gpm_buf, +u16 len,u32 sched_addr); +void ar9003_mci_cleanup (struct ath_hw *ah); +void ar9003_mci_send_coex_halt_bt_gpm (struct ath_hw *ah,bool halt, +bool wait_done); +u32 ar9003_mci_wait_for_gpm (struct ath_hw *ah,u8 gpm_type, +u8 gpm_opcode,int time_out); +void ar9003_mci_2g5g_changed (struct ath_hw *ah,bool is_2g); +void ar9003_mci_disable_interrupt (struct ath_hw *ah); +void ar9003_mci_enable_interrupt (struct ath_hw *ah); +void ar9003_mci_2g5g_switch (struct ath_hw *ah,bool wait_done); +void ar9003_mci_reset (struct ath_hw *ah,bool en_int,bool is_2g, +bool is_full_sleep); +bool ar9003_mci_check_int (struct ath_hw *ah,u32 ints); +void ar9003_mci_remote_reset (struct ath_hw *ah,bool wait_done); +void ar9003_mci_send_sys_waking (struct ath_hw *ah,bool wait_done); +void ar9003_mci_send_lna_transfer (struct ath_hw *ah,bool wait_done); +void ar9003_mci_sync_bt_state (struct ath_hw *ah); +void ar9003_mci_get_interrupt (struct ath_hw *ah,u32 *raw_intr, +u32 *rx_msg_intr); +#define ATH9K_CLOCK_RATE_CCK 22#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
Signature · 1 line
1.7.0.4
PATCH 6/18 ath9k: Add MCI interrupt to interrupt mask
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
--- drivers/net/wireless/ath/ath9k/main.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/net/wireless/ath/ath9k/main.c +5 -1
@@ -764,7 +764,8 @@ irqreturn_t ath_isr(int irq, void *dev)ATH9K_INT_BMISS | \ATH9K_INT_CST | \ATH9K_INT_TSFOOR | \ - ATH9K_INT_GENTIMER) +ATH9K_INT_GENTIMER | \ + ATH9K_INT_MCI) struct ath_softc *sc = dev;struct ath_hw *ah = sc->sc_ah;
@@ -1119,6 +1120,9 @@ static int ath9k_start(struct ieee80211_hw *hw)if (ah->caps.hw_caps &ATH9K_HW_CAP_HT ) ah->imask |=ATH9K_INT_CST ; +if (ah->caps.hw_caps &ATH9K_HW_CAP_MCI ) + ah->imask |=ATH9K_INT_MCI ; + sc->sc_flags &= ~SC_OP_INVALID ; sc->sc_ah->is_monitoring = false;
Signature · 1 line
1.7.0.4
PATCH 7/18 ath9k_hw: take care of enabling MCI interrupts
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
enable MCI interrupt when ath9k_hw_enable_interrupts is called, like during the completion of chip_reset before which the interrupts are disabled
--- drivers/net/wireless/ath/ath9k/mac.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-)
drivers/net/wireless/ath/ath9k/mac.c +8 -4
@@ -798,6 +798,7 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) {struct ath_common *common =ath9k_hw_common (ah);u32 sync_default =AR_INTR_SYNC_DEFAULT ; +u32 async_mask;if (!(ah->imask &ATH9K_INT_GLOBAL ))return ;
@@ -812,13 +813,16 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)if (AR_SREV_9340 (ah)) sync_default &= ~AR_INTR_SYNC_HOST1_FATAL ; + async_mask =AR_INTR_MAC_IRQ ; + +if (ah->imask &ATH9K_INT_MCI ) + async_mask |=AR_INTR_ASYNC_MASK_MCI ; +ath_dbg (common,ATH_DBG_INTERRUPT ,"enable IER\n" );REG_WRITE (ah,AR_IER ,AR_IER_ENABLE );if (!AR_SREV_9100 (ah)) { -REG_WRITE (ah,AR_INTR_ASYNC_ENABLE , -AR_INTR_MAC_IRQ ); -REG_WRITE (ah,AR_INTR_ASYNC_MASK ,AR_INTR_MAC_IRQ ); - +REG_WRITE (ah,AR_INTR_ASYNC_ENABLE , async_mask); +REG_WRITE (ah,AR_INTR_ASYNC_MASK , async_mask);REG_WRITE (ah,AR_INTR_SYNC_ENABLE , sync_default);REG_WRITE (ah,AR_INTR_SYNC_MASK , sync_default);
Signature · 1 line
1.7.0.4
PATCH 8/18 ath9k_hw: check for asynchronous MCI interrupt pending
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
MCI interrupt is an asynchronous one, so take care of it by having a check in ath9k_hw_intrpend, which actually decides whether the interrupt is really for the driver from ath_isr
--- drivers/net/wireless/ath/ath9k/mac.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
drivers/net/wireless/ath/ath9k/mac.c +4 -1
@@ -760,7 +760,10 @@ bool ath9k_hw_intrpend(struct ath_hw *ah)return true; host_isr =REG_READ (ah,AR_INTR_ASYNC_CAUSE ); -if ((host_isr &AR_INTR_MAC_IRQ ) && (host_isr !=AR_INTR_SPURIOUS )) + +if (((host_isr &AR_INTR_MAC_IRQ ) || + (host_isr &AR_INTR_ASYNC_MASK_MCI )) && + (host_isr !=AR_INTR_SPURIOUS ))return true; host_isr =REG_READ (ah,AR_INTR_SYNC_CAUSE );
Signature · 1 line
1.7.0.4
PATCH 9/18 ath9k_hw: check for MCI interrupt in get_isr
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
check for the condition of MCI interrupt being triggered and appropriately obtain the values of MCI_INTERRUPT_RX_MSG_RAW and MCI_INTERRUPT_RAW
--- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 36 +++++++++++++++++++++++++- 1 files changed, 34 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/ar9003_mac.c +34 -2
@@ -175,15 +175,47 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)u32 isr =0 ;u32 mask2 =0 ;struct ath9k_hw_capabilities *pCap = &ah->caps; -u32 sync_cause =0 ;struct ath_common *common =ath9k_hw_common (ah); +struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; +u32 sync_cause =0 , async_cause; -if (REG_READ (ah,AR_INTR_ASYNC_CAUSE ) &AR_INTR_MAC_IRQ ) { + async_cause =REG_READ (ah,AR_INTR_ASYNC_CAUSE ); + +if (async_cause & (AR_INTR_MAC_IRQ |AR_INTR_ASYNC_MASK_MCI )) {if ((REG_READ (ah,AR_RTC_STATUS ) &AR_RTC_STATUS_M ) ==AR_RTC_STATUS_ON ) isr =REG_READ (ah,AR_ISR ); } +if (async_cause &AR_INTR_ASYNC_MASK_MCI ) { +u32 raw_intr, rx_msg_intr; + + rx_msg_intr =REG_READ (ah,AR_MCI_INTERRUPT_RX_MSG_RAW ); + raw_intr =REG_READ (ah,AR_MCI_INTERRUPT_RAW ); + +if ((raw_intr ==0xdeadbeef ) || (rx_msg_intr ==0xdeadbeef )) +ath_dbg (common,ATH_DBG_MCI , +"MCI gets 0xdeadbeef during MCI int processing" +"new raw_intr=0x%08x, new rx_msg_raw=0x%08x, " +"raw_intr=0x%08x, rx_msg_raw=0x%08x\n" , + raw_intr, rx_msg_intr, mci->raw_intr, + mci->rx_msg_intr); +else { + mci->rx_msg_intr |= rx_msg_intr; + mci->raw_intr |= raw_intr; + *masked |=ATH9K_INT_MCI ; + +if (rx_msg_intr &AR_MCI_INTERRUPT_RX_MSG_CONT_INFO ) + mci->cont_status = +REG_READ (ah,AR_MCI_CONT_STATUS ); + +REG_WRITE (ah,AR_MCI_INTERRUPT_RX_MSG_RAW , rx_msg_intr); +REG_WRITE (ah,AR_MCI_INTERRUPT_RAW , raw_intr); +ath_dbg (common,ATH_DBG_MCI ,"AR_INTR_SYNC_MCI\n" ); + + } + } + sync_cause =REG_READ (ah,AR_INTR_SYNC_CAUSE ) &AR_INTR_SYNC_DEFAULT ; *masked =0 ;
Signature · 1 line
1.7.0.4
PATCH 10/18 ath9k: add MCI specific definitions and structures
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
--- drivers/net/wireless/ath/ath9k/mci.h | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath9k/mci.h +17 -0
@@ -17,6 +17,9 @@#ifndef MCI_H #define MCI_H +#define ATH_MCI_SCHED_BUF_SIZE (16 * 16)/* 16 entries, 4 dword each */ +#define ATH_MCI_GPM_MAX_ENTRY 16 +#define ATH_MCI_GPM_BUF_SIZE (ATH_MCI_GPM_MAX_ENTRY * 16)#define ATH_MCI_DEF_BT_PERIOD 40#define ATH_MCI_BDR_DUTY_CYCLE 20#define ATH_MCI_MAX_DUTY_CYCLE 90
@@ -110,6 +113,20 @@ struct ath_mci_profile {u8 num_bdr; }; + +struct ath_mci_buf { +void *bf_addr;/* virtual addr of desc */ +dma_addr_t bf_paddr;/* physical addr of buffer */ +u32 bf_len;/* len of data */ +}; + +struct ath_mci_coex { +atomic_t mci_cal_flag; +struct ath_mci_buf sched_buf; +struct ath_mci_buf gpm_buf; +u32 bt_cal_start; +}; +void ath_mci_flush_profile (struct ath_mci_profile *mci);void ath_mci_process_profile (struct ath_softc *sc,struct ath_mci_profile_info *info);
Signature · 1 line
1.7.0.4
PATCH 11/18 ath9k: Add functions to allocate/free buffers for MCI
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
required buffers and dma allocation is done for GPM and SCHED messages
--- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/mci.c | 78 ++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/mci.h | 2 + 3 files changed, 81 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath9k/ath9k.h +1 -0
@@ -647,6 +647,7 @@ struct ath_softc {struct delayed_work tx_complete_work;struct delayed_work hw_pll_work;struct ath_btcoex btcoex; +struct ath_mci_coex mci_coex;struct ath_descdma txsdma;
drivers/net/wireless/ath/ath9k/mci.c +78 -0
87 lines not on this page · raw message
drivers/net/wireless/ath/ath9k/mci.h +2 -0
@@ -132,4 +132,6 @@ void ath_mci_process_profile(struct ath_softc *sc, struct ath_mci_profile_info *info);void ath_mci_process_status (struct ath_softc *sc,struct ath_mci_profile_status *status); +int ath_mci_setup (struct ath_softc *sc); +void ath_mci_cleanup (struct ath_softc *sc);#endif
Signature · 1 line
1.7.0.4
PATCH 12/18 ath9k_hw: MCI related changes in chip management
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
send halt BT GPM if the chip is in network sleep and BT state is awake
--- drivers/net/wireless/ath/ath9k/hw.c | 24 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/reg.h | 2 ++ 2 files changed, 26 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath9k/hw.c +24 -0
@@ -1933,6 +1933,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)bool ath9k_hw_setpower (struct ath_hw *ah,enum ath9k_power_mode mode) {struct ath_common *common =ath9k_hw_common (ah); +struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;int status = true, setChip = true;static const char *modes[] = {"AWAKE" ,
@@ -1950,12 +1951,35 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)switch (mode) {case ATH9K_PM_AWAKE : status =ath9k_hw_set_power_awake (ah, setChip); + +if (ah->caps.hw_caps &ATH9K_HW_CAP_MCI ) +REG_WRITE (ah,AR_RTC_KEEP_AWAKE ,0x2 ); +break ;case ATH9K_PM_FULL_SLEEP : + +if (ah->caps.hw_caps &ATH9K_HW_CAP_MCI ) { +if (ar9003_mci_state (ah,MCI_STATE_ENABLE ,NULL ) && + (mci->bt_state !=MCI_BT_SLEEP ) && + !mci->halted_bt_gpm) { +ath_dbg (common,ATH_DBG_MCI ,"MCI halt BT GPM" +"(full_sleep)" ); +ar9003_mci_send_coex_halt_bt_gpm (ah, + true, true); + } + + mci->ready = false; +REG_WRITE (ah,AR_RTC_KEEP_AWAKE ,0x2 ); + } +ath9k_set_power_sleep (ah, setChip); ah->chip_fullsleep = true;break ;case ATH9K_PM_NETWORK_SLEEP : + +if (ah->caps.hw_caps &ATH9K_HW_CAP_MCI ) +REG_WRITE (ah,AR_RTC_KEEP_AWAKE ,0x2 ); +ath9k_set_power_network_sleep (ah, setChip);break ;default :
drivers/net/wireless/ath/ath9k/reg.h +2 -0
@@ -1279,6 +1279,8 @@ enum {#define AR_RTC_INTR_MASK \ ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058) +#define AR_RTC_KEEP_AWAKE 0x7034 +/* RTC_DERIVED_* - only for AR9100 */ #define AR_RTC_DERIVED_CLK \
Signature · 1 line
1.7.0.4
PATCH 13/18 ath9k_hw: MCI related changes in set_reset_reg
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
--- drivers/net/wireless/ath/ath9k/hw.c | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-)
drivers/net/wireless/ath/ath9k/hw.c +11 -3
@@ -1350,6 +1350,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)static bool ath9k_hw_set_reset_reg (struct ath_hw *ah,u32 type) { +bool ret = false;if (AR_SREV_9300_20_OR_LATER (ah)) {REG_WRITE (ah,AR_WA , ah->WARegVal);
@@ -1361,13 +1362,20 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)switch (type) {case ATH9K_RESET_POWER_ON : -return ath9k_hw_set_reset_power_on (ah); + ret =ath9k_hw_set_reset_power_on (ah); +break ;case ATH9K_RESET_WARM :case ATH9K_RESET_COLD : -return ath9k_hw_set_reset (ah, type); + ret =ath9k_hw_set_reset (ah, type); +break ;default : -return false; +break ; } + +if (ah->caps.hw_caps &ATH9K_HW_CAP_MCI ) +REG_WRITE (ah,AR_RTC_KEEP_AWAKE ,0x2 ); + +return ret; } static bool ath9k_hw_chip_reset(struct ath_hw *ah,
Signature · 1 line
1.7.0.4
PATCH 14/18 ath9k_hw: Add support for MCI WLAN calibration
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
WLAN communicates with BT for its calibration by sending WLAN_CAL_REQ, waits for BT_CAL_GRANT. This is done with the help of GPM messages. also WLAN_CAL_DONE messages is sent once WLAN calibration is done.
--- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 43 +++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath9k/ar9003_calib.c +43 -0
@@ -18,6 +18,7 @@#include "hw-ops.h" #include "ar9003_phy.h" #include "ar9003_rtt.h" +#include "ar9003_mci.h" #define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT#define MAX_MAG_DELTA 11
@@ -934,10 +935,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, {struct ath_common *common =ath9k_hw_common (ah);struct ath9k_hw_cal_data *caldata = ah->caldata; +struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;bool txiqcal_done = false, txclcal_done = false;bool is_reusable = true, status = true;bool run_rtt_cal = false, run_agc_cal;bool rtt = !!(ah->caps.hw_caps &ATH9K_HW_CAP_RTT ); +bool mci = !!(ah->caps.hw_caps &ATH9K_HW_CAP_MCI );u32 agc_ctrl =0 , agc_supp_cals =AR_PHY_AGC_CONTROL_OFFSET_CAL |AR_PHY_AGC_CONTROL_FLTR_CAL |AR_PHY_AGC_CONTROL_PKDET_CAL ;
@@ -1005,6 +1008,31 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, }else if (caldata && !caldata->done_txiqcal_once) run_agc_cal = true; +if (mci &&IS_CHAN_2GHZ (chan) && + (mci_hw->bt_state ==MCI_BT_AWAKE ) && + run_agc_cal && + !(mci_hw->config &ATH_MCI_CONFIG_DISABLE_MCI_CAL )) { + +u32 pld[4 ] = {0 ,0 ,0 ,0 }; + +/* send CAL_REQ only when BT is AWAKE. */ +ath_dbg (common,ATH_DBG_MCI ,"MCI send WLAN_CAL_REQ 0x%x\n" , + mci_hw->wlan_cal_seq); +MCI_GPM_SET_CAL_TYPE (pld,MCI_GPM_WLAN_CAL_REQ ); + pld[MCI_GPM_WLAN_CAL_W_SEQUENCE ] = mci_hw->wlan_cal_seq++; +ar9003_mci_send_message (ah,MCI_GPM ,0 , pld,16 , true, false); + +/* Wait BT_CAL_GRANT for 50ms */ +ath_dbg (common,ATH_DBG_MCI ,"MCI wait for BT_CAL_GRANT" ); + +if (ar9003_mci_wait_for_gpm (ah,MCI_GPM_BT_CAL_GRANT ,0 ,50000 )) +ath_dbg (common,ATH_DBG_MCI ,"MCI got BT_CAL_GRANT" ); +else { + is_reusable = false; +ath_dbg (common,ATH_DBG_MCI ,"\nMCI BT is not responding" ); + } + } + txiqcal_done =ar9003_hw_tx_iq_cal_run (ah);REG_WRITE (ah,AR_PHY_ACTIVE ,AR_PHY_ACTIVE_DIS );udelay (5 );
@@ -1022,6 +1050,21 @@ skip_tx_iqcal:AR_PHY_AGC_CONTROL_CAL , 0, AH_WAIT_TIMEOUT); } + +if (mci &&IS_CHAN_2GHZ (chan) && + (mci_hw->bt_state ==MCI_BT_AWAKE ) && + run_agc_cal && + !(mci_hw->config &ATH_MCI_CONFIG_DISABLE_MCI_CAL )) { + +u32 pld[4 ] = {0 ,0 ,0 ,0 }; + +ath_dbg (common,ATH_DBG_MCI ,"MCI Send WLAN_CAL_DONE 0x%x\n" , + mci_hw->wlan_cal_done); +MCI_GPM_SET_CAL_TYPE (pld,MCI_GPM_WLAN_CAL_DONE ); + pld[MCI_GPM_WLAN_CAL_W_SEQUENCE ] = mci_hw->wlan_cal_done++; +ar9003_mci_send_message (ah,MCI_GPM ,0 , pld,16 , true, false); + } +if (rtt && !run_rtt_cal) { agc_ctrl |= agc_supp_cals;REG_WRITE (ah,AR_PHY_AGC_CONTROL , agc_ctrl);
Signature · 1 line
1.7.0.4
PATCH 15/18 ath9k_hw: Add MCI related changes in chip reset
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
here we check for BT state and if BT calibration has started, give 25ms for BT Calibration to finish. we also take care of 2G/5G switch and LNA transfer incase WLAN is operating in 5G. in case the BT state is awake when we do WLAN calibration re-calibrate and we reset the message exchange between WLAN and BT. BT is given preference when simultaneous CAL request happens. calibration for WLAN/BT is done assuming that the other co-existing module is in awake state, if not we continue to do calibration while if the other module's state changes we need to do restart the calibration handshake
--- drivers/net/wireless/ath/ath9k/hw.c | 132 +++++++++++++++++++++++++++++++++++ 1 files changed, 132 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath9k/hw.c +132 -0
@@ -1514,6 +1514,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, struct ath9k_hw_cal_data *caldata, bool bChannelChange) {struct ath_common *common =ath9k_hw_common (ah); +struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;u32 saveLedState;struct ath9k_channel *curchan = ah->curchan;u32 saveDefAntenna;
@@ -1521,6 +1522,53 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,u64 tsf =0 ;int i, r;bool allow_fbs = false; +bool mci = !!(ah->caps.hw_caps &ATH9K_HW_CAP_MCI ); +bool save_fullsleep = ah->chip_fullsleep; + +if (mci) { + +ar9003_mci_2g5g_changed (ah,IS_CHAN_2GHZ (chan)); + +if (mci_hw->bt_state ==MCI_BT_CAL_START ) { +u32 payload[4 ] = {0 ,0 ,0 ,0 }; + +ath_dbg (common,ATH_DBG_MCI ,"MCI stop rx for BT CAL" ); + + mci_hw->bt_state =MCI_BT_CAL ; + +/* +* MCI FIX: disable mci interrupt here. This is to avoid +* SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and +* lead to mci_intr reentry. +*/ + +ar9003_mci_disable_interrupt (ah); + +ath_dbg (common,ATH_DBG_MCI ,"send WLAN_CAL_GRANT" ); +MCI_GPM_SET_CAL_TYPE (payload,MCI_GPM_WLAN_CAL_GRANT ); +ar9003_mci_send_message (ah,MCI_GPM ,0 , payload, +16 , true, false); + +ath_dbg (common,ATH_DBG_MCI ,"\nMCI BT is calibrating" ); + +/* Wait BT calibration to be completed for 25ms */ + +if (ar9003_mci_wait_for_gpm (ah,MCI_GPM_BT_CAL_DONE , +0 ,25000 )) +ath_dbg (common,ATH_DBG_MCI , +"MCI got BT_CAL_DONE\n" ); +else +ath_dbg (common,ATH_DBG_MCI , +"MCI ### BT cal takes to long, force" +"bt_state to be bt_awake\n" ); + mci_hw->bt_state =MCI_BT_AWAKE ; +/* MCI FIX: enable mci interrupt here */ +ar9003_mci_enable_interrupt (ah); + +return true; + } + } +if (!ath9k_hw_setpower (ah,ATH9K_PM_AWAKE ))return -EIO ;
@@ -1558,12 +1606,29 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,if (ath9k_hw_channel_change (ah, chan)) {ath9k_hw_loadnf (ah, ah->curchan);ath9k_hw_start_nfcal (ah, true); +if (mci && mci_hw->ready) +ar9003_mci_2g5g_switch (ah, true); +if (AR_SREV_9271 (ah))ar9002_hw_load_ani_reg (ah, chan);return 0 ; } } +if (mci) { +ar9003_mci_disable_interrupt (ah); + +if (mci_hw->ready && !save_fullsleep) { +ar9003_mci_mute_bt (ah); +udelay (20 ); +REG_WRITE (ah,AR_BTCOEX_CTRL ,0 ); + } + + mci_hw->bt_state =MCI_BT_SLEEP ; + mci_hw->ready = false; + } + + saveDefAntenna =REG_READ (ah,AR_DEF_ANTENNA );if (saveDefAntenna ==0 ) saveDefAntenna =1 ;
@@ -1619,6 +1684,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,if (r)return r; +if (mci) +ar9003_mci_reset (ah, false,IS_CHAN_2GHZ (chan), save_fullsleep); +/* * Some AR91xx SoC devices frequently fail to accept TSF writes * right after the chip reset. When that happens, write a new
@@ -1736,6 +1804,55 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,ath9k_hw_loadnf (ah, chan);ath9k_hw_start_nfcal (ah, true); +if (mci && mci_hw->ready) { + +if (IS_CHAN_2GHZ (chan) && + (mci_hw->bt_state ==MCI_BT_SLEEP )) { + +if (ar9003_mci_check_int (ah, +AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET ) || +ar9003_mci_check_int (ah, +AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE )) { + +/* +* BT is sleeping. Check if BT wakes up during +* WLAN calibration. If BT wakes up during +* WLAN calibration, need to go through all +* message exchanges again and recal. +*/ + +ath_dbg (common,ATH_DBG_MCI ,"MCI BT wakes up" +"during WLAN calibration\n" ); + +REG_WRITE (ah,AR_MCI_INTERRUPT_RX_MSG_RAW , +AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | +AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE ); +ath_dbg (common,ATH_DBG_MCI ,"MCI send" +"REMOTE_RESET\n" ); +ar9003_mci_remote_reset (ah, true); +ar9003_mci_send_sys_waking (ah, true); +udelay (1 ); +if (IS_CHAN_2GHZ (chan)) +ar9003_mci_send_lna_transfer (ah, true); + + mci_hw->bt_state =MCI_BT_AWAKE ; + +ath_dbg (common,ATH_DBG_MCI ,"MCI re-cal\n" ); + +if (caldata) { + caldata->done_txiqcal_once = false; + caldata->done_txclcal_once = false; + caldata->rtt_hist.num_readings =0 ; + } + +if (!ath9k_hw_init_cal (ah, chan)) +return -EIO ; + + } + } +ar9003_mci_enable_interrupt (ah); + } +ENABLE_REGWRITE_BUFFER (ah);ath9k_hw_restore_chainmask (ah);
@@ -1778,6 +1895,21 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,if (ah->btcoex_hw.enabled)ath9k_hw_btcoex_enable (ah); +if (mci && mci_hw->ready) { +/* +* check BT state again to make +* sure it's not changed. +*/ + +ar9003_mci_sync_bt_state (ah); +ar9003_mci_2g5g_switch (ah, true); + +if ((mci_hw->bt_state ==MCI_BT_AWAKE ) && + (mci_hw->query_bt == true)) { + mci_hw->need_flush_btinfo = true; + } + } +if (AR_SREV_9300_20_OR_LATER (ah)) {ar9003_hw_bb_watchdog_config (ah);
Signature · 1 line
1.7.0.4
PATCH 16/18 ath9k: make ath_reset non-static
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
to be used by MCI specific changes
--- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 2 +- 2 files changed, 2 insertions(+), 1 deletions(-)
drivers/net/wireless/ath/ath9k/ath9k.h +1 -0
@@ -424,6 +424,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);#define ATH_PAPRD_TIMEOUT 100/* msecs */ +int ath_reset (struct ath_softc *sc,bool retry_tx);void ath_reset_work (struct work_struct *work);void ath_hw_check (struct work_struct *work);void ath_hw_pll_work (struct work_struct *work);
drivers/net/wireless/ath/ath9k/main.c +1 -1
@@ -959,7 +959,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)ath9k_ps_restore (sc); } -static int ath_reset (struct ath_softc *sc,bool retry_tx) +int ath_reset (struct ath_softc *sc,bool retry_tx) {int r;
Signature · 1 line
1.7.0.4
PATCH 16/18 ath9k: make ath_reset non-static
Quoted 8 lines · Mohammed Shafi Shajakhan
From: Mohammed Shafi Shajakhan <[email protected]>
to be used by MCI specific changes
Cc Wilson Tsao <[email protected]>Cc Senthil Balasubramanian <[email protected]>Signed-off-by Rajkumar Manoharan <[email protected]>Signed-off-by Mohammed Shafi Shajakhan <[email protected]>
NACK. ath_reset can no longer be called in tasklet context (which you seem to be doing in the next patch).
Replace your ath_reset() call with:
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
- Felix
PATCH 16/18 ath9k: make ath_reset non-static
Hi Felix,
thanks for your review.
Quoted 9 lines · Felix Fietkau
Quoted 8 lines · Mohammed Shafi Shajakhan
From: Mohammed Shafi Shajakhan<[email protected]>
to be used by MCI specific changes
Cc Wilson Tsao<[email protected]>Cc Senthil Balasubramanian<[email protected]>Signed-off-by Rajkumar Manoharan<[email protected]>Signed-off-by Mohammed Shafi Shajakhan<[email protected]>
Quoted 6 lines
NACK.
ath_resetcan no longer be called in tasklet context (which you seem to be doing in the next patch).
Replace yourath_reset()call with:ieee80211_queue_work(sc->hw,&sc->hw_reset_work);- Felix
just like in ath9k_flush, i like to have the chip reset immediately rather than queuing at as a work.
in chip reset we have:
*we have BT calibration
*sync up with BT state
*2g_5g change
*LNA transfer
and few other things
when BT asks for calibration i understand we have to immediately give preference to it.
please let me know if i had missed something and also if queuing ath_reset actually helps us in some way.
i will revert this back once i test queue_work does no harm.
Signature · 2 lines
thanks, shafi
PATCH 16/18 ath9k: make ath_reset non-static
Quoted 29 lines · Mohammed Shafi Shajakhan
Hi Felix,
thanks for your review.
Quoted 9 lines · Felix Fietkau
Quoted 8 lines · Mohammed Shafi Shajakhan
From: Mohammed Shafi Shajakhan<[email protected]>
to be used by MCI specific changes
Cc Wilson Tsao<[email protected]>Cc Senthil Balasubramanian<[email protected]>Signed-off-by Rajkumar Manoharan<[email protected]>Signed-off-by Mohammed Shafi Shajakhan<[email protected]>Quoted 6 lines
NACK.
ath_resetcan no longer be called in tasklet context (which you seem to be doing in the next patch).
Replace yourath_reset()call with:ieee80211_queue_work(sc->hw,&sc->hw_reset_work);- Felix
just like in
ath9k_flush, i like to have the chip reset immediately rather than queuing at as a work.
in chip reset we have:
*we have BT calibration
*sync up with BT state
*2g_5g change
*LNA transfer
and few other things
Quoted 5 lines
when BT asks for calibration i understand we have to immediately give preference to it.
please let me know if i had missed something and also if queuingath_resetactually helps us in some way.
i will revert this back once i testqueue_workdoes no harm.
Doing reset from tasklet context created several nasty stability issues that were hard to track down, and the potential gain from doing reset 'immediately' that way is purely theoretical. Resets should be rare in normal operation, as they're also expensive.
The main problem when running reset from a tasklet is that there is no way of gracefully shutting down ongoing workqueue activity, so the result of the reset could be that the work items mess up the state right after the reset is done.
- Felix
PATCH 16/18 ath9k: make ath_reset non-static
Quoted 8 lines · Felix Fietkau
Doing reset from tasklet context created several nasty stability issues that were hard to track down, and the potential gain from doing reset 'immediately' that way is purely theoretical. Resets should be rare in normal operation, as they're also expensive.
The main problem when running reset from a tasklet is that there is no way of gracefully shutting down ongoing workqueue activity, so the result of the reset could be that the work items mess up the state right after the reset is done.
thanks, true in this case ath_reset is called from tasklet context. i will send a v2 for using queue_work.
Quoted 2 lines
- Felix
Signature · 2 lines
thanks, shafi
PATCH 17/18 ath9k: MCI state machine based on MCI interrupt
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
--- drivers/net/wireless/ath/ath9k/hw.c | 4 +- drivers/net/wireless/ath/ath9k/init.c | 11 + drivers/net/wireless/ath/ath9k/main.c | 3 + drivers/net/wireless/ath/ath9k/mci.c | 341 +++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/mci.h | 1 + 5 files changed, 359 insertions(+), 1 deletions(-)
drivers/net/wireless/ath/ath9k/hw.c +3 -1
@@ -2397,7 +2397,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->hw_caps |=ATH9K_HW_CAP_4KB_SPLITTRANS ;if (common->btcoex_enabled) { -if (AR_SREV_9300_20_OR_LATER (ah)) { +if (AR_SREV_9462 (ah)) + btcoex_hw->scheme =ATH_BTCOEX_CFG_MCI ; +else if (AR_SREV_9300_20_OR_LATER (ah)) { btcoex_hw->scheme =ATH_BTCOEX_CFG_3WIRE ; btcoex_hw->btactive_gpio =ATH_BTACTIVE_GPIO_9300 ; btcoex_hw->wlanactive_gpio =ATH_WLANACTIVE_GPIO_9300 ;
drivers/net/wireless/ath/ath9k/init.c +11 -0
@@ -425,8 +425,16 @@ static int ath9k_init_btcoex(struct ath_softc *sc) txq = sc->tx.txq_map[WME_AC_BE ];ath9k_hw_init_btcoex_hw (sc->sc_ah, txq->axq_qnum); sc->btcoex.bt_stomp_type =ATH_BTCOEX_STOMP_LOW ; +break ; +case ATH_BTCOEX_CFG_MCI : + sc->btcoex.bt_stomp_type =ATH_BTCOEX_STOMP_LOW ; sc->btcoex.duty_cycle =ATH_BTCOEX_DEF_DUTY_CYCLE ;INIT_LIST_HEAD (&sc->btcoex.mci.info); + + r =ath_mci_setup (sc); +if (r) +return r; +if (sc->sc_ah->caps.hw_caps &ATH9K_HW_CAP_MCI ) { ah->btcoex_hw.mci.ready = false; ah->btcoex_hw.mci.bt_state =0 ;
@@ -861,6 +869,9 @@ static void ath9k_deinit_softc(struct ath_softc *sc) sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)ath_gen_timer_free (sc->sc_ah, sc->btcoex.no_stomp_timer); +if (sc->sc_ah->btcoex_hw.scheme ==ATH_BTCOEX_CFG_MCI ) +ath_mci_cleanup (sc); +for (i =0 ; i <ATH9K_NUM_TX_QUEUES ; i++)if (ATH_TXQ_SETUP (sc, i))ath_tx_cleanupq (sc, &sc->tx.txq[i]);
drivers/net/wireless/ath/ath9k/main.c +3 -0
@@ -742,6 +742,9 @@ void ath9k_tasklet(unsigned long data)if (status &ATH9K_INT_GENTIMER )ath_gen_timer_isr (sc->sc_ah); +if (status &ATH9K_INT_MCI ) +ath_mci_intr (sc); + out:/* re-enable hardware interrupt */ ath9k_hw_enable_interrupts (ah);
drivers/net/wireless/ath/ath9k/mci.c +341 -0
356 lines not on this page · raw message
drivers/net/wireless/ath/ath9k/mci.h +1 -0
@@ -134,4 +134,5 @@ void ath_mci_process_status(struct ath_softc *sc, struct ath_mci_profile_status *status);int ath_mci_setup (struct ath_softc *sc);void ath_mci_cleanup (struct ath_softc *sc); +void ath_mci_intr (struct ath_softc *sc);#endif
Signature · 1 line
1.7.0.4
PATCH 18/18 ath9k: fix a typo
In reply to Mohammed Shafi ShajakhanFrom: Mohammed Shafi Shajakhan <[email protected]>
--- drivers/net/wireless/ath/ath9k/btcoex.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/ath/ath9k/btcoex.c +1 -1
@@ -21,7 +21,7 @@ enum ath_bt_mode {ATH_BT_COEX_MODE_LEGACY ,/* legacy rx_clear mode */ ATH_BT_COEX_MODE_UNSLOTTED ,/* untimed/unslotted mode */ ATH_BT_COEX_MODE_SLOTTED ,/* slotted mode */ - ATH_BT_COEX_MODE_DISALBED, /* coexistence disabled */ + ATH_BT_COEX_MODE_DISABLED, /* coexistence disabled */ }; struct ath_btcoex_config {
Signature · 1 line
1.7.0.4