1 /* 2 * Copyright (c) 2010-2011 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 MCI_H 18 #define MCI_H 19 20 #include "ar9003_mci.h" 21 22 #define ATH_MCI_SCHED_BUF_SIZE (16 * 16) /* 16 entries, 4 dword each */ 23 #define ATH_MCI_GPM_MAX_ENTRY 16 24 #define ATH_MCI_GPM_BUF_SIZE (ATH_MCI_GPM_MAX_ENTRY * 16) 25 #define ATH_MCI_DEF_BT_PERIOD 40 26 #define ATH_MCI_BDR_DUTY_CYCLE 20 27 #define ATH_MCI_MAX_DUTY_CYCLE 90 28 29 #define ATH_MCI_DEF_AGGR_LIMIT 6 /* in 0.24 ms */ 30 #define ATH_MCI_MAX_ACL_PROFILE 7 31 #define ATH_MCI_MAX_SCO_PROFILE 1 32 #define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\ 33 ATH_MCI_MAX_SCO_PROFILE) 34 35 #define ATH_MCI_INQUIRY_PRIO 62 36 #define ATH_MCI_HI_PRIO 60 37 #define ATH_MCI_NUM_BT_CHANNELS 79 38 #define ATH_MCI_CONCUR_TX_SWITCH 5 39 40 #define MCI_GPM_SET_CHANNEL_BIT(_p_gpm, _bt_chan) \ 41 do { \ 42 if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) { \ 43 *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \ 44 (_bt_chan / 8)) |= (1 << (_bt_chan & 7)); \ 45 } \ 46 } while (0) 47 48 #define MCI_GPM_CLR_CHANNEL_BIT(_p_gpm, _bt_chan) \ 49 do { \ 50 if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) { \ 51 *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \ 52 (_bt_chan / 8)) &= ~(1 << (_bt_chan & 7));\ 53 } \ 54 } while (0) 55 56 #define INC_PROF(_mci, _info) do { \ 57 switch (_info->type) { \ 58 case MCI_GPM_COEX_PROFILE_RFCOMM:\ 59 _mci->num_other_acl++; \ 60 break; \ 61 case MCI_GPM_COEX_PROFILE_A2DP: \ 62 _mci->num_a2dp++; \ 63 if (!_info->edr) \ 64 _mci->num_bdr++; \ 65 break; \ 66 case MCI_GPM_COEX_PROFILE_HID: \ 67 _mci->num_hid++; \ 68 break; \ 69 case MCI_GPM_COEX_PROFILE_BNEP: \ 70 _mci->num_pan++; \ 71 break; \ 72 case MCI_GPM_COEX_PROFILE_VOICE: \ 73 case MCI_GPM_COEX_PROFILE_A2DPVO:\ 74 _mci->num_sco++; \ 75 break; \ 76 default: \ 77 break; \ 78 } \ 79 } while (0) 80 81 #define DEC_PROF(_mci, _info) do { \ 82 switch (_info->type) { \ 83 case MCI_GPM_COEX_PROFILE_RFCOMM:\ 84 _mci->num_other_acl--; \ 85 break; \ 86 case MCI_GPM_COEX_PROFILE_A2DP: \ 87 _mci->num_a2dp--; \ 88 if (!_info->edr) \ 89 _mci->num_bdr--; \ 90 break; \ 91 case MCI_GPM_COEX_PROFILE_HID: \ 92 _mci->num_hid--; \ 93 break; \ 94 case MCI_GPM_COEX_PROFILE_BNEP: \ 95 _mci->num_pan--; \ 96 break; \ 97 case MCI_GPM_COEX_PROFILE_VOICE: \ 98 case MCI_GPM_COEX_PROFILE_A2DPVO:\ 99 _mci->num_sco--; \ 100 break; \ 101 default: \ 102 break; \ 103 } \ 104 } while (0) 105 106 #define NUM_PROF(_mci) (_mci->num_other_acl + _mci->num_a2dp + \ 107 _mci->num_hid + _mci->num_pan + _mci->num_sco) 108 109 struct ath_mci_profile_info { 110 u8 type; 111 u8 conn_handle; 112 bool start; 113 bool master; 114 bool edr; 115 u8 voice_type; 116 u16 T; /* Voice: Tvoice, HID: Tsniff, in slots */ 117 u8 W; /* Voice: Wvoice, HID: Sniff timeout, in slots */ 118 u8 A; /* HID: Sniff attempt, in slots */ 119 struct list_head list; 120 }; 121 122 struct ath_mci_profile_status { 123 bool is_critical; 124 bool is_link; 125 u8 conn_handle; 126 }; 127 128 struct ath_mci_profile { 129 struct list_head info; 130 DECLARE_BITMAP(status, ATH_MCI_MAX_PROFILE); 131 u16 aggr_limit; 132 u8 num_mgmt; 133 u8 num_sco; 134 u8 num_a2dp; 135 u8 num_hid; 136 u8 num_pan; 137 u8 num_other_acl; 138 u8 num_bdr; 139 u8 voice_priority; 140 }; 141 142 struct ath_mci_buf { 143 void *bf_addr; /* virtual addr of desc */ 144 dma_addr_t bf_paddr; /* physical addr of buffer */ 145 u32 bf_len; /* len of data */ 146 }; 147 148 struct ath_mci_coex { 149 struct ath_mci_buf sched_buf; 150 struct ath_mci_buf gpm_buf; 151 }; 152 153 void ath_mci_flush_profile(struct ath_mci_profile *mci); 154 int ath_mci_setup(struct ath_softc *sc); 155 void ath_mci_cleanup(struct ath_softc *sc); 156 void ath_mci_intr(struct ath_softc *sc); 157 void ath9k_mci_update_rssi(struct ath_softc *sc); 158 159 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 160 void ath_mci_enable(struct ath_softc *sc); 161 void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all); 162 void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, 163 bool concur_tx); 164 #else 165 static inline void ath_mci_enable(struct ath_softc *sc) 166 { 167 } 168 static inline void ath9k_mci_update_wlan_channels(struct ath_softc *sc, 169 bool allow_all) 170 { 171 } 172 static inline void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, 173 bool concur_tx) 174 { 175 } 176 #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ 177 178 #endif /* MCI_H*/ 179