1 /****************************************************************************** 2 * 3 * Copyright(c) 2009-2013 Realtek Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * The full GNU General Public License is included in this distribution in the 15 * file called LICENSE. 16 * 17 * Contact Information: 18 * wlanfae <wlanfae@realtek.com> 19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 20 * Hsinchu 300, Taiwan. 21 * 22 * Larry Finger <Larry.Finger@lwfinger.net> 23 * 24 *****************************************************************************/ 25 #include "../wifi.h" 26 #include <linux/vmalloc.h> 27 #include <linux/module.h> 28 29 #include "rtl_btc.h" 30 #include "halbt_precomp.h" 31 32 static struct rtl_btc_ops rtl_btc_operation = { 33 .btc_init_variables = rtl_btc_init_variables, 34 .btc_init_hal_vars = rtl_btc_init_hal_vars, 35 .btc_init_hw_config = rtl_btc_init_hw_config, 36 .btc_ips_notify = rtl_btc_ips_notify, 37 .btc_lps_notify = rtl_btc_lps_notify, 38 .btc_scan_notify = rtl_btc_scan_notify, 39 .btc_connect_notify = rtl_btc_connect_notify, 40 .btc_mediastatus_notify = rtl_btc_mediastatus_notify, 41 .btc_periodical = rtl_btc_periodical, 42 .btc_halt_notify = rtl_btc_halt_notify, 43 .btc_btinfo_notify = rtl_btc_btinfo_notify, 44 .btc_is_limited_dig = rtl_btc_is_limited_dig, 45 .btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo, 46 .btc_is_bt_disabled = rtl_btc_is_bt_disabled, 47 .btc_special_packet_notify = rtl_btc_special_packet_notify, 48 .btc_record_pwr_mode = rtl_btc_record_pwr_mode, 49 .btc_get_lps_val = rtl_btc_get_lps_val, 50 .btc_get_rpwm_val = rtl_btc_get_rpwm_val, 51 .btc_is_bt_ctrl_lps = rtl_btc_is_bt_ctrl_lps, 52 .btc_is_bt_lps_on = rtl_btc_is_bt_lps_on, 53 .btc_get_ampdu_cfg = rtl_btc_get_ampdu_cfg, 54 }; 55 56 void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len) 57 { 58 u8 safe_len; 59 60 safe_len = sizeof(gl_bt_coexist.pwr_mode_val); 61 62 if (safe_len > len) 63 safe_len = len; 64 65 memcpy(gl_bt_coexist.pwr_mode_val, buf, safe_len); 66 } 67 68 u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv) 69 { 70 return gl_bt_coexist.bt_info.lps_val; 71 } 72 73 u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv) 74 { 75 return gl_bt_coexist.bt_info.rpwm_val; 76 } 77 78 bool rtl_btc_is_bt_ctrl_lps(struct rtl_priv *rtlpriv) 79 { 80 return gl_bt_coexist.bt_info.bt_ctrl_lps; 81 } 82 83 bool rtl_btc_is_bt_lps_on(struct rtl_priv *rtlpriv) 84 { 85 return gl_bt_coexist.bt_info.bt_lps_on; 86 } 87 88 void rtl_btc_get_ampdu_cfg(struct rtl_priv *rtlpriv, u8 *reject_agg, 89 u8 *ctrl_agg_size, u8 *agg_size) 90 { 91 if (reject_agg) 92 *reject_agg = gl_bt_coexist.bt_info.reject_agg_pkt; 93 if (ctrl_agg_size) 94 *ctrl_agg_size = gl_bt_coexist.bt_info.bt_ctrl_agg_buf_size; 95 if (agg_size) 96 *agg_size = gl_bt_coexist.bt_info.agg_buf_size; 97 } 98 99 void rtl_btc_init_variables(struct rtl_priv *rtlpriv) 100 { 101 exhalbtc_initlize_variables(); 102 exhalbtc_bind_bt_coex_withadapter(rtlpriv); 103 } 104 105 void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv) 106 { 107 /* move ant_num, bt_type and single_ant_path to 108 * exhalbtc_bind_bt_coex_withadapter() 109 */ 110 } 111 112 void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv) 113 { 114 u8 bt_exist; 115 116 bt_exist = rtl_get_hwpg_bt_exist(rtlpriv); 117 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, 118 "%s, bt_exist is %d\n", __func__, bt_exist); 119 120 exhalbtc_init_hw_config(&gl_bt_coexist, !bt_exist); 121 exhalbtc_init_coex_dm(&gl_bt_coexist); 122 } 123 124 void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type) 125 { 126 exhalbtc_ips_notify(&gl_bt_coexist, type); 127 } 128 129 void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type) 130 { 131 exhalbtc_lps_notify(&gl_bt_coexist, type); 132 } 133 134 void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype) 135 { 136 exhalbtc_scan_notify(&gl_bt_coexist, scantype); 137 } 138 139 void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action) 140 { 141 exhalbtc_connect_notify(&gl_bt_coexist, action); 142 } 143 144 void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, 145 enum rt_media_status mstatus) 146 { 147 exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus); 148 } 149 150 void rtl_btc_periodical(struct rtl_priv *rtlpriv) 151 { 152 /*rtl_bt_dm_monitor();*/ 153 exhalbtc_periodical(&gl_bt_coexist); 154 } 155 156 void rtl_btc_halt_notify(void) 157 { 158 struct btc_coexist *btcoexist = &gl_bt_coexist; 159 160 exhalbtc_halt_notify(btcoexist); 161 } 162 163 void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length) 164 { 165 exhalbtc_bt_info_notify(&gl_bt_coexist, tmp_buf, length); 166 } 167 168 bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv) 169 { 170 return gl_bt_coexist.bt_info.limited_dig; 171 } 172 173 bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv) 174 { 175 bool bt_change_edca = false; 176 u32 cur_edca_val; 177 u32 edca_bt_hs_uplink = 0x5ea42b, edca_bt_hs_downlink = 0x5ea42b; 178 u32 edca_hs; 179 u32 edca_addr = 0x504; 180 181 cur_edca_val = rtl_read_dword(rtlpriv, edca_addr); 182 if (halbtc_is_wifi_uplink(rtlpriv)) { 183 if (cur_edca_val != edca_bt_hs_uplink) { 184 edca_hs = edca_bt_hs_uplink; 185 bt_change_edca = true; 186 } 187 } else { 188 if (cur_edca_val != edca_bt_hs_downlink) { 189 edca_hs = edca_bt_hs_downlink; 190 bt_change_edca = true; 191 } 192 } 193 194 if (bt_change_edca) 195 rtl_write_dword(rtlpriv, edca_addr, edca_hs); 196 197 return true; 198 } 199 200 bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv) 201 { 202 /* It seems 'bt_disabled' is never be initialized or set. */ 203 if (gl_bt_coexist.bt_info.bt_disabled) 204 return true; 205 else 206 return false; 207 } 208 209 void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type) 210 { 211 return exhalbtc_special_packet_notify(&gl_bt_coexist, pkt_type); 212 } 213 214 struct rtl_btc_ops *rtl_btc_get_ops_pointer(void) 215 { 216 return &rtl_btc_operation; 217 } 218 EXPORT_SYMBOL(rtl_btc_get_ops_pointer); 219 220 221 enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw) 222 { 223 struct rtl_priv *rtlpriv = rtl_priv(hw); 224 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 225 enum rt_media_status m_status = RT_MEDIA_DISCONNECT; 226 227 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; 228 229 if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) 230 m_status = RT_MEDIA_CONNECT; 231 232 return m_status; 233 } 234 235 u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv) 236 { 237 return rtlpriv->btcoexist.btc_info.btcoexist; 238 } 239 240 MODULE_AUTHOR("Page He <page_he@realsil.com.cn>"); 241 MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); 242 MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>"); 243 MODULE_LICENSE("GPL"); 244 MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); 245 246 static int __init rtl_btcoexist_module_init(void) 247 { 248 return 0; 249 } 250 251 static void __exit rtl_btcoexist_module_exit(void) 252 { 253 return; 254 } 255 256 module_init(rtl_btcoexist_module_init); 257 module_exit(rtl_btcoexist_module_exit); 258