diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 466 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h | 2 |
2 files changed, 447 insertions, 21 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 5ea3a5ef819b..2836d7eb0d05 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
@@ -28,10 +28,26 @@ | |||
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #include "dm_common.h" | 30 | #include "dm_common.h" |
31 | #include "phy_common.h" | ||
32 | #include "../pci.h" | ||
33 | #include "../base.h" | ||
31 | 34 | ||
32 | struct dig_t dm_digtable; | 35 | struct dig_t dm_digtable; |
33 | static struct ps_t dm_pstable; | 36 | static struct ps_t dm_pstable; |
34 | 37 | ||
38 | #define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1) | ||
39 | #define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1) | ||
40 | #define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1) | ||
41 | #define BT_RSSI_STATE_BG_EDCA_LOW BIT_OFFSET_LEN_MASK_32(3, 1) | ||
42 | #define BT_RSSI_STATE_TXPOWER_LOW BIT_OFFSET_LEN_MASK_32(4, 1) | ||
43 | |||
44 | #define RTLPRIV (struct rtl_priv *) | ||
45 | #define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ | ||
46 | ((RTLPRIV(_priv))->mac80211.opmode == \ | ||
47 | NL80211_IFTYPE_ADHOC) ? \ | ||
48 | ((RTLPRIV(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) : \ | ||
49 | ((RTLPRIV(_priv))->dm.undecorated_smoothed_pwdb) | ||
50 | |||
35 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { | 51 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { |
36 | 0x7f8001fe, | 52 | 0x7f8001fe, |
37 | 0x788001e2, | 53 | 0x788001e2, |
@@ -461,10 +477,7 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) | |||
461 | if (mac->act_scanning == true) | 477 | if (mac->act_scanning == true) |
462 | return; | 478 | return; |
463 | 479 | ||
464 | if ((mac->link_state > MAC80211_NOLINK) && | 480 | if (mac->link_state >= MAC80211_LINKED) |
465 | (mac->link_state < MAC80211_LINKED)) | ||
466 | dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; | ||
467 | else if (mac->link_state >= MAC80211_LINKED) | ||
468 | dm_digtable.cursta_connectctate = DIG_STA_CONNECT; | 481 | dm_digtable.cursta_connectctate = DIG_STA_CONNECT; |
469 | else | 482 | else |
470 | dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; | 483 | dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; |
@@ -562,23 +575,42 @@ EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo); | |||
562 | static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) | 575 | static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) |
563 | { | 576 | { |
564 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 577 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
578 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
565 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 579 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
580 | |||
566 | static u64 last_txok_cnt; | 581 | static u64 last_txok_cnt; |
567 | static u64 last_rxok_cnt; | 582 | static u64 last_rxok_cnt; |
568 | u64 cur_txok_cnt; | 583 | static u32 last_bt_edca_ul; |
569 | u64 cur_rxok_cnt; | 584 | static u32 last_bt_edca_dl; |
585 | u64 cur_txok_cnt = 0; | ||
586 | u64 cur_rxok_cnt = 0; | ||
570 | u32 edca_be_ul = 0x5ea42b; | 587 | u32 edca_be_ul = 0x5ea42b; |
571 | u32 edca_be_dl = 0x5ea42b; | 588 | u32 edca_be_dl = 0x5ea42b; |
589 | bool bt_change_edca = false; | ||
572 | 590 | ||
573 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | 591 | if ((last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) || |
574 | goto dm_checkedcaturbo_exit; | 592 | (last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) { |
593 | rtlpriv->dm.current_turbo_edca = false; | ||
594 | last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul; | ||
595 | last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl; | ||
596 | } | ||
597 | |||
598 | if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) { | ||
599 | edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul; | ||
600 | bt_change_edca = true; | ||
601 | } | ||
602 | |||
603 | if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) { | ||
604 | edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl; | ||
605 | bt_change_edca = true; | ||
606 | } | ||
575 | 607 | ||
576 | if (mac->link_state != MAC80211_LINKED) { | 608 | if (mac->link_state != MAC80211_LINKED) { |
577 | rtlpriv->dm.current_turbo_edca = false; | 609 | rtlpriv->dm.current_turbo_edca = false; |
578 | return; | 610 | return; |
579 | } | 611 | } |
580 | 612 | ||
581 | if (!mac->ht_enable) { /*FIX MERGE */ | 613 | if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) { |
582 | if (!(edca_be_ul & 0xffff0000)) | 614 | if (!(edca_be_ul & 0xffff0000)) |
583 | edca_be_ul |= 0x005e0000; | 615 | edca_be_ul |= 0x005e0000; |
584 | 616 | ||
@@ -586,10 +618,12 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
586 | edca_be_dl |= 0x005e0000; | 618 | edca_be_dl |= 0x005e0000; |
587 | } | 619 | } |
588 | 620 | ||
589 | if ((!rtlpriv->dm.is_any_nonbepkts) && | 621 | if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && |
590 | (!rtlpriv->dm.disable_framebursting)) { | 622 | (!rtlpriv->dm.disable_framebursting))) { |
623 | |||
591 | cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; | 624 | cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; |
592 | cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; | 625 | cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; |
626 | |||
593 | if (cur_rxok_cnt > 4 * cur_txok_cnt) { | 627 | if (cur_rxok_cnt > 4 * cur_txok_cnt) { |
594 | if (!rtlpriv->dm.is_cur_rdlstate || | 628 | if (!rtlpriv->dm.is_cur_rdlstate || |
595 | !rtlpriv->dm.current_turbo_edca) { | 629 | !rtlpriv->dm.current_turbo_edca) { |
@@ -618,7 +652,6 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
618 | } | 652 | } |
619 | } | 653 | } |
620 | 654 | ||
621 | dm_checkedcaturbo_exit: | ||
622 | rtlpriv->dm.is_any_nonbepkts = false; | 655 | rtlpriv->dm.is_any_nonbepkts = false; |
623 | last_txok_cnt = rtlpriv->stats.txbytesunicast; | 656 | last_txok_cnt = rtlpriv->stats.txbytesunicast; |
624 | last_rxok_cnt = rtlpriv->stats.rxbytesunicast; | 657 | last_rxok_cnt = rtlpriv->stats.rxbytesunicast; |
@@ -633,7 +666,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | |||
633 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 666 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
634 | u8 thermalvalue, delta, delta_lck, delta_iqk; | 667 | u8 thermalvalue, delta, delta_lck, delta_iqk; |
635 | long ele_a, ele_d, temp_cck, val_x, value32; | 668 | long ele_a, ele_d, temp_cck, val_x, value32; |
636 | long val_y, ele_c; | 669 | long val_y, ele_c = 0; |
637 | u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; | 670 | u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; |
638 | int i; | 671 | int i; |
639 | bool is2t = IS_92C_SERIAL(rtlhal->version); | 672 | bool is2t = IS_92C_SERIAL(rtlhal->version); |
@@ -683,7 +716,6 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | |||
683 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { | 716 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { |
684 | if (ele_d == (ofdmswing_table[i] & | 717 | if (ele_d == (ofdmswing_table[i] & |
685 | MASKOFDM_D)) { | 718 | MASKOFDM_D)) { |
686 | ofdm_index_old[1] = (u8) i; | ||
687 | 719 | ||
688 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, | 720 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, |
689 | DBG_LOUD, | 721 | DBG_LOUD, |
@@ -1132,6 +1164,7 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | |||
1132 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1164 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
1133 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | 1165 | struct rate_adaptive *p_ra = &(rtlpriv->ra); |
1134 | u32 low_rssithresh_for_ra, high_rssithresh_for_ra; | 1166 | u32 low_rssithresh_for_ra, high_rssithresh_for_ra; |
1167 | struct ieee80211_sta *sta = NULL; | ||
1135 | 1168 | ||
1136 | if (is_hal_stop(rtlhal)) { | 1169 | if (is_hal_stop(rtlhal)) { |
1137 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | 1170 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, |
@@ -1145,8 +1178,8 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | |||
1145 | return; | 1178 | return; |
1146 | } | 1179 | } |
1147 | 1180 | ||
1148 | if (mac->link_state == MAC80211_LINKED) { | 1181 | if (mac->link_state == MAC80211_LINKED && |
1149 | 1182 | mac->opmode == NL80211_IFTYPE_STATION) { | |
1150 | switch (p_ra->pre_ratr_state) { | 1183 | switch (p_ra->pre_ratr_state) { |
1151 | case DM_RATR_STA_HIGH: | 1184 | case DM_RATR_STA_HIGH: |
1152 | high_rssithresh_for_ra = 50; | 1185 | high_rssithresh_for_ra = 50; |
@@ -1185,10 +1218,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | |||
1185 | ("PreState = %d, CurState = %d\n", | 1218 | ("PreState = %d, CurState = %d\n", |
1186 | p_ra->pre_ratr_state, p_ra->ratr_state)); | 1219 | p_ra->pre_ratr_state, p_ra->ratr_state)); |
1187 | 1220 | ||
1188 | rtlpriv->cfg->ops->update_rate_mask(hw, | 1221 | rcu_read_lock(); |
1222 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | ||
1223 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, | ||
1189 | p_ra->ratr_state); | 1224 | p_ra->ratr_state); |
1190 | 1225 | ||
1191 | p_ra->pre_ratr_state = p_ra->ratr_state; | 1226 | p_ra->pre_ratr_state = p_ra->ratr_state; |
1227 | rcu_read_unlock(); | ||
1192 | } | 1228 | } |
1193 | } | 1229 | } |
1194 | } | 1230 | } |
@@ -1202,7 +1238,7 @@ static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) | |||
1202 | dm_pstable.rssi_val_min = 0; | 1238 | dm_pstable.rssi_val_min = 0; |
1203 | } | 1239 | } |
1204 | 1240 | ||
1205 | static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) | 1241 | void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) |
1206 | { | 1242 | { |
1207 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1243 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1208 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 1244 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -1352,7 +1388,9 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) | |||
1352 | } | 1388 | } |
1353 | 1389 | ||
1354 | if (IS_92C_SERIAL(rtlhal->version)) | 1390 | if (IS_92C_SERIAL(rtlhal->version)) |
1355 | rtl92c_dm_1r_cca(hw); | 1391 | ;/* rtl92c_dm_1r_cca(hw); */ |
1392 | else | ||
1393 | rtl92c_dm_rf_saving(hw, false); | ||
1356 | } | 1394 | } |
1357 | 1395 | ||
1358 | void rtl92c_dm_init(struct ieee80211_hw *hw) | 1396 | void rtl92c_dm_init(struct ieee80211_hw *hw) |
@@ -1369,6 +1407,84 @@ void rtl92c_dm_init(struct ieee80211_hw *hw) | |||
1369 | } | 1407 | } |
1370 | EXPORT_SYMBOL(rtl92c_dm_init); | 1408 | EXPORT_SYMBOL(rtl92c_dm_init); |
1371 | 1409 | ||
1410 | void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) | ||
1411 | { | ||
1412 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1413 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1414 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1415 | long undecorated_smoothed_pwdb; | ||
1416 | |||
1417 | if (!rtlpriv->dm.dynamic_txpower_enable) | ||
1418 | return; | ||
1419 | |||
1420 | if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { | ||
1421 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
1422 | return; | ||
1423 | } | ||
1424 | |||
1425 | if ((mac->link_state < MAC80211_LINKED) && | ||
1426 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | ||
1427 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
1428 | ("Not connected to any\n")); | ||
1429 | |||
1430 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
1431 | |||
1432 | rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
1433 | return; | ||
1434 | } | ||
1435 | |||
1436 | if (mac->link_state >= MAC80211_LINKED) { | ||
1437 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
1438 | undecorated_smoothed_pwdb = | ||
1439 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1440 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1441 | ("AP Client PWDB = 0x%lx\n", | ||
1442 | undecorated_smoothed_pwdb)); | ||
1443 | } else { | ||
1444 | undecorated_smoothed_pwdb = | ||
1445 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
1446 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1447 | ("STA Default Port PWDB = 0x%lx\n", | ||
1448 | undecorated_smoothed_pwdb)); | ||
1449 | } | ||
1450 | } else { | ||
1451 | undecorated_smoothed_pwdb = | ||
1452 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1453 | |||
1454 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1455 | ("AP Ext Port PWDB = 0x%lx\n", | ||
1456 | undecorated_smoothed_pwdb)); | ||
1457 | } | ||
1458 | |||
1459 | if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { | ||
1460 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
1461 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1462 | ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); | ||
1463 | } else if ((undecorated_smoothed_pwdb < | ||
1464 | (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && | ||
1465 | (undecorated_smoothed_pwdb >= | ||
1466 | TX_POWER_NEAR_FIELD_THRESH_LVL1)) { | ||
1467 | |||
1468 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
1469 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1470 | ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); | ||
1471 | } else if (undecorated_smoothed_pwdb < | ||
1472 | (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { | ||
1473 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
1474 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1475 | ("TXHIGHPWRLEVEL_NORMAL\n")); | ||
1476 | } | ||
1477 | |||
1478 | if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { | ||
1479 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1480 | ("PHY_SetTxPowerLevel8192S() Channel = %d\n", | ||
1481 | rtlphy->current_channel)); | ||
1482 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
1483 | } | ||
1484 | |||
1485 | rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; | ||
1486 | } | ||
1487 | |||
1372 | void rtl92c_dm_watchdog(struct ieee80211_hw *hw) | 1488 | void rtl92c_dm_watchdog(struct ieee80211_hw *hw) |
1373 | { | 1489 | { |
1374 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1490 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -1388,11 +1504,319 @@ void rtl92c_dm_watchdog(struct ieee80211_hw *hw) | |||
1388 | rtl92c_dm_dig(hw); | 1504 | rtl92c_dm_dig(hw); |
1389 | rtl92c_dm_false_alarm_counter_statistics(hw); | 1505 | rtl92c_dm_false_alarm_counter_statistics(hw); |
1390 | rtl92c_dm_dynamic_bb_powersaving(hw); | 1506 | rtl92c_dm_dynamic_bb_powersaving(hw); |
1391 | rtlpriv->cfg->ops->dm_dynamic_txpower(hw); | 1507 | rtl92c_dm_dynamic_txpower(hw); |
1392 | rtl92c_dm_check_txpower_tracking(hw); | 1508 | rtl92c_dm_check_txpower_tracking(hw); |
1393 | rtl92c_dm_refresh_rate_adaptive_mask(hw); | 1509 | rtl92c_dm_refresh_rate_adaptive_mask(hw); |
1510 | rtl92c_dm_bt_coexist(hw); | ||
1394 | rtl92c_dm_check_edca_turbo(hw); | 1511 | rtl92c_dm_check_edca_turbo(hw); |
1395 | |||
1396 | } | 1512 | } |
1397 | } | 1513 | } |
1398 | EXPORT_SYMBOL(rtl92c_dm_watchdog); | 1514 | EXPORT_SYMBOL(rtl92c_dm_watchdog); |
1515 | |||
1516 | static u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw) | ||
1517 | { | ||
1518 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1519 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1520 | long undecorated_smoothed_pwdb; | ||
1521 | u8 curr_bt_rssi_state = 0x00; | ||
1522 | |||
1523 | if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { | ||
1524 | undecorated_smoothed_pwdb = | ||
1525 | GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); | ||
1526 | } else { | ||
1527 | if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0) | ||
1528 | undecorated_smoothed_pwdb = 100; | ||
1529 | else | ||
1530 | undecorated_smoothed_pwdb = | ||
1531 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1532 | } | ||
1533 | |||
1534 | /* Check RSSI to determine HighPower/NormalPower state for | ||
1535 | * BT coexistence. */ | ||
1536 | if (undecorated_smoothed_pwdb >= 67) | ||
1537 | curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER); | ||
1538 | else if (undecorated_smoothed_pwdb < 62) | ||
1539 | curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER; | ||
1540 | |||
1541 | /* Check RSSI to determine AMPDU setting for BT coexistence. */ | ||
1542 | if (undecorated_smoothed_pwdb >= 40) | ||
1543 | curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF); | ||
1544 | else if (undecorated_smoothed_pwdb <= 32) | ||
1545 | curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF; | ||
1546 | |||
1547 | /* Marked RSSI state. It will be used to determine BT coexistence | ||
1548 | * setting later. */ | ||
1549 | if (undecorated_smoothed_pwdb < 35) | ||
1550 | curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW; | ||
1551 | else | ||
1552 | curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); | ||
1553 | |||
1554 | /* Set Tx Power according to BT status. */ | ||
1555 | if (undecorated_smoothed_pwdb >= 30) | ||
1556 | curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW; | ||
1557 | else if (undecorated_smoothed_pwdb < 25) | ||
1558 | curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW); | ||
1559 | |||
1560 | /* Check BT state related to BT_Idle in B/G mode. */ | ||
1561 | if (undecorated_smoothed_pwdb < 15) | ||
1562 | curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW; | ||
1563 | else | ||
1564 | curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW); | ||
1565 | |||
1566 | if (curr_bt_rssi_state != rtlpcipriv->bt_coexist.bt_rssi_state) { | ||
1567 | rtlpcipriv->bt_coexist.bt_rssi_state = curr_bt_rssi_state; | ||
1568 | return true; | ||
1569 | } else { | ||
1570 | return false; | ||
1571 | } | ||
1572 | } | ||
1573 | |||
1574 | static bool rtl92c_bt_state_change(struct ieee80211_hw *hw) | ||
1575 | { | ||
1576 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1577 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1578 | |||
1579 | u32 polling, ratio_tx, ratio_pri; | ||
1580 | u32 bt_tx, bt_pri; | ||
1581 | u8 bt_state; | ||
1582 | u8 cur_service_type; | ||
1583 | |||
1584 | if (rtlpriv->mac80211.link_state < MAC80211_LINKED) | ||
1585 | return false; | ||
1586 | |||
1587 | bt_state = rtl_read_byte(rtlpriv, 0x4fd); | ||
1588 | bt_tx = rtl_read_dword(rtlpriv, 0x488); | ||
1589 | bt_tx = bt_tx & 0x00ffffff; | ||
1590 | bt_pri = rtl_read_dword(rtlpriv, 0x48c); | ||
1591 | bt_pri = bt_pri & 0x00ffffff; | ||
1592 | polling = rtl_read_dword(rtlpriv, 0x490); | ||
1593 | |||
1594 | if (bt_tx == 0xffffffff && bt_pri == 0xffffffff && | ||
1595 | polling == 0xffffffff && bt_state == 0xff) | ||
1596 | return false; | ||
1597 | |||
1598 | bt_state &= BIT_OFFSET_LEN_MASK_32(0, 1); | ||
1599 | if (bt_state != rtlpcipriv->bt_coexist.bt_cur_state) { | ||
1600 | rtlpcipriv->bt_coexist.bt_cur_state = bt_state; | ||
1601 | |||
1602 | if (rtlpcipriv->bt_coexist.reg_bt_sco == 3) { | ||
1603 | rtlpcipriv->bt_coexist.bt_service = BT_IDLE; | ||
1604 | |||
1605 | bt_state = bt_state | | ||
1606 | ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ? | ||
1607 | 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) | | ||
1608 | BIT_OFFSET_LEN_MASK_32(2, 1); | ||
1609 | rtl_write_byte(rtlpriv, 0x4fd, bt_state); | ||
1610 | } | ||
1611 | return true; | ||
1612 | } | ||
1613 | |||
1614 | ratio_tx = bt_tx * 1000 / polling; | ||
1615 | ratio_pri = bt_pri * 1000 / polling; | ||
1616 | rtlpcipriv->bt_coexist.ratio_tx = ratio_tx; | ||
1617 | rtlpcipriv->bt_coexist.ratio_pri = ratio_pri; | ||
1618 | |||
1619 | if (bt_state && rtlpcipriv->bt_coexist.reg_bt_sco == 3) { | ||
1620 | |||
1621 | if ((ratio_tx < 30) && (ratio_pri < 30)) | ||
1622 | cur_service_type = BT_IDLE; | ||
1623 | else if ((ratio_pri > 110) && (ratio_pri < 250)) | ||
1624 | cur_service_type = BT_SCO; | ||
1625 | else if ((ratio_tx >= 200) && (ratio_pri >= 200)) | ||
1626 | cur_service_type = BT_BUSY; | ||
1627 | else if ((ratio_tx >= 350) && (ratio_tx < 500)) | ||
1628 | cur_service_type = BT_OTHERBUSY; | ||
1629 | else if (ratio_tx >= 500) | ||
1630 | cur_service_type = BT_PAN; | ||
1631 | else | ||
1632 | cur_service_type = BT_OTHER_ACTION; | ||
1633 | |||
1634 | if (cur_service_type != rtlpcipriv->bt_coexist.bt_service) { | ||
1635 | rtlpcipriv->bt_coexist.bt_service = cur_service_type; | ||
1636 | bt_state = bt_state | | ||
1637 | ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ? | ||
1638 | 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) | | ||
1639 | ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) ? | ||
1640 | 0 : BIT_OFFSET_LEN_MASK_32(2, 1)); | ||
1641 | |||
1642 | /* Add interrupt migration when bt is not ini | ||
1643 | * idle state (no traffic). */ | ||
1644 | if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) { | ||
1645 | rtl_write_word(rtlpriv, 0x504, 0x0ccc); | ||
1646 | rtl_write_byte(rtlpriv, 0x506, 0x54); | ||
1647 | rtl_write_byte(rtlpriv, 0x507, 0x54); | ||
1648 | } else { | ||
1649 | rtl_write_byte(rtlpriv, 0x506, 0x00); | ||
1650 | rtl_write_byte(rtlpriv, 0x507, 0x00); | ||
1651 | } | ||
1652 | |||
1653 | rtl_write_byte(rtlpriv, 0x4fd, bt_state); | ||
1654 | return true; | ||
1655 | } | ||
1656 | } | ||
1657 | |||
1658 | return false; | ||
1659 | |||
1660 | } | ||
1661 | |||
1662 | static bool rtl92c_bt_wifi_connect_change(struct ieee80211_hw *hw) | ||
1663 | { | ||
1664 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1665 | static bool media_connect; | ||
1666 | |||
1667 | if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { | ||
1668 | media_connect = false; | ||
1669 | } else { | ||
1670 | if (!media_connect) { | ||
1671 | media_connect = true; | ||
1672 | return true; | ||
1673 | } | ||
1674 | media_connect = true; | ||
1675 | } | ||
1676 | |||
1677 | return false; | ||
1678 | } | ||
1679 | |||
1680 | static void rtl92c_bt_set_normal(struct ieee80211_hw *hw) | ||
1681 | { | ||
1682 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1683 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1684 | |||
1685 | |||
1686 | if (rtlpcipriv->bt_coexist.bt_service == BT_OTHERBUSY) { | ||
1687 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72b; | ||
1688 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72b; | ||
1689 | } else if (rtlpcipriv->bt_coexist.bt_service == BT_BUSY) { | ||
1690 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82f; | ||
1691 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82f; | ||
1692 | } else if (rtlpcipriv->bt_coexist.bt_service == BT_SCO) { | ||
1693 | if (rtlpcipriv->bt_coexist.ratio_tx > 160) { | ||
1694 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72f; | ||
1695 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72f; | ||
1696 | } else { | ||
1697 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea32b; | ||
1698 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea42b; | ||
1699 | } | ||
1700 | } else { | ||
1701 | rtlpcipriv->bt_coexist.bt_edca_ul = 0; | ||
1702 | rtlpcipriv->bt_coexist.bt_edca_dl = 0; | ||
1703 | } | ||
1704 | |||
1705 | if ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) && | ||
1706 | (rtlpriv->mac80211.mode == WIRELESS_MODE_G || | ||
1707 | (rtlpriv->mac80211.mode == (WIRELESS_MODE_G | WIRELESS_MODE_B))) && | ||
1708 | (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1709 | BT_RSSI_STATE_BG_EDCA_LOW)) { | ||
1710 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82b; | ||
1711 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82b; | ||
1712 | } | ||
1713 | } | ||
1714 | |||
1715 | static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw) | ||
1716 | { | ||
1717 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1718 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1719 | |||
1720 | |||
1721 | /* Only enable HW BT coexist when BT in "Busy" state. */ | ||
1722 | if (rtlpriv->mac80211.vendor == PEER_CISCO && | ||
1723 | rtlpcipriv->bt_coexist.bt_service == BT_OTHER_ACTION) { | ||
1724 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); | ||
1725 | } else { | ||
1726 | if ((rtlpcipriv->bt_coexist.bt_service == BT_BUSY) && | ||
1727 | (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1728 | BT_RSSI_STATE_NORMAL_POWER)) { | ||
1729 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); | ||
1730 | } else if ((rtlpcipriv->bt_coexist.bt_service == | ||
1731 | BT_OTHER_ACTION) && (rtlpriv->mac80211.mode < | ||
1732 | WIRELESS_MODE_N_24G) && | ||
1733 | (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1734 | BT_RSSI_STATE_SPECIAL_LOW)) { | ||
1735 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); | ||
1736 | } else if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) { | ||
1737 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); | ||
1738 | } else { | ||
1739 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); | ||
1740 | } | ||
1741 | } | ||
1742 | |||
1743 | if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) | ||
1744 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x10100); | ||
1745 | else | ||
1746 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x0); | ||
1747 | |||
1748 | if (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1749 | BT_RSSI_STATE_NORMAL_POWER) { | ||
1750 | rtl92c_bt_set_normal(hw); | ||
1751 | } else { | ||
1752 | rtlpcipriv->bt_coexist.bt_edca_ul = 0; | ||
1753 | rtlpcipriv->bt_coexist.bt_edca_dl = 0; | ||
1754 | } | ||
1755 | |||
1756 | if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) { | ||
1757 | rtlpriv->cfg->ops->set_rfreg(hw, | ||
1758 | RF90_PATH_A, | ||
1759 | 0x1e, | ||
1760 | 0xf0, 0xf); | ||
1761 | } else { | ||
1762 | rtlpriv->cfg->ops->set_rfreg(hw, | ||
1763 | RF90_PATH_A, 0x1e, 0xf0, | ||
1764 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); | ||
1765 | } | ||
1766 | |||
1767 | if (!rtlpriv->dm.dynamic_txpower_enable) { | ||
1768 | if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) { | ||
1769 | if (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1770 | BT_RSSI_STATE_TXPOWER_LOW) { | ||
1771 | rtlpriv->dm.dynamic_txhighpower_lvl = | ||
1772 | TXHIGHPWRLEVEL_BT2; | ||
1773 | } else { | ||
1774 | rtlpriv->dm.dynamic_txhighpower_lvl = | ||
1775 | TXHIGHPWRLEVEL_BT1; | ||
1776 | } | ||
1777 | } else { | ||
1778 | rtlpriv->dm.dynamic_txhighpower_lvl = | ||
1779 | TXHIGHPWRLEVEL_NORMAL; | ||
1780 | } | ||
1781 | rtl92c_phy_set_txpower_level(hw, | ||
1782 | rtlpriv->phy.current_channel); | ||
1783 | } | ||
1784 | } | ||
1785 | |||
1786 | static void rtl92c_check_bt_change(struct ieee80211_hw *hw) | ||
1787 | { | ||
1788 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1789 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1790 | |||
1791 | if (rtlpcipriv->bt_coexist.bt_cur_state) { | ||
1792 | if (rtlpcipriv->bt_coexist.bt_ant_isolation) | ||
1793 | rtl92c_bt_ant_isolation(hw); | ||
1794 | } else { | ||
1795 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); | ||
1796 | rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0, | ||
1797 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); | ||
1798 | |||
1799 | rtlpcipriv->bt_coexist.bt_edca_ul = 0; | ||
1800 | rtlpcipriv->bt_coexist.bt_edca_dl = 0; | ||
1801 | } | ||
1802 | } | ||
1803 | |||
1804 | void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw) | ||
1805 | { | ||
1806 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1807 | |||
1808 | bool wifi_connect_change; | ||
1809 | bool bt_state_change; | ||
1810 | bool rssi_state_change; | ||
1811 | |||
1812 | if ((rtlpcipriv->bt_coexist.bt_coexistence) && | ||
1813 | (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) { | ||
1814 | |||
1815 | wifi_connect_change = rtl92c_bt_wifi_connect_change(hw); | ||
1816 | bt_state_change = rtl92c_bt_state_change(hw); | ||
1817 | rssi_state_change = rtl92c_bt_rssi_state_change(hw); | ||
1818 | |||
1819 | if (wifi_connect_change || bt_state_change || rssi_state_change) | ||
1820 | rtl92c_check_bt_change(hw); | ||
1821 | } | ||
1822 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h index b9cbb0a3c03f..b9736d3e9a39 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h | |||
@@ -200,5 +200,7 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); | |||
200 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); | 200 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); |
201 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); | 201 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); |
202 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); | 202 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); |
203 | void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); | ||
204 | void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw); | ||
203 | 205 | ||
204 | #endif | 206 | #endif |