/* *Finds the highest rate index we can use *if skb is special data like DHCP/EAPOL, we set should *it to lowest rate CCK_1M, otherwise we set rate to *CCK11M or OFDM_54M based on wireless mode. */ static u8 _rtl_rc_get_highest_rix( struct rtl_priv *rtlpriv, struct ieee80211_sta *sta, struct sk_buff *skb, bool not_data ) { struct rtl_mac *rtlmac = rtl_mac( rtlpriv ); struct rtl_hal *rtlhal = rtl_hal( rtlpriv ); struct rtl_phy *rtlphy = &( rtlpriv->phy ); struct rtl_sta_info *sta_entry = NULL; u8 wireless_mode = 0; /* *this rate is no use for true rate, firmware *will control rate at all it just used for *1.show in iwconfig in B/G mode *2.in rtl_get_tcb_desc when we check rate is * 1M we will not use FW rate but user rate. */ if ( rtlmac->opmode == NL80211_IFTYPE_AP || rtlmac->opmode == NL80211_IFTYPE_ADHOC || rtlmac->opmode == NL80211_IFTYPE_MESH_POINT ) { if ( sta ) { sta_entry = ( struct rtl_sta_info * ) sta->drv_priv; wireless_mode = sta_entry->wireless_mode; } else { return 0; } } else { wireless_mode = rtlmac->mode; } if ( rtl_is_special_data( rtlpriv->mac80211.hw, skb, true ) || not_data ) { return 0; } else { if ( rtlhal->current_bandtype == BAND_ON_2_4G ) { if ( wireless_mode == WIRELESS_MODE_B ) { return B_MODE_MAX_RIX; } else if ( wireless_mode == WIRELESS_MODE_G ) { return G_MODE_MAX_RIX; } else { if ( get_rf_type( rtlphy ) != RF_2T2R ) return N_MODE_MCS7_RIX; else return N_MODE_MCS15_RIX; } } else { if ( wireless_mode == WIRELESS_MODE_A ) { return A_MODE_MAX_RIX; } else { if ( get_rf_type( rtlphy ) != RF_2T2R ) return N_MODE_MCS7_RIX; else return N_MODE_MCS15_RIX; } } } }
static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, struct ieee80211_sta_ht_cap *ht_cap) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); ht_cap->ht_supported = true; ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; if (rtlpriv->rtlhal.disable_amsdu_8k) ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; /* *Maximum length of AMPDU that the STA can receive. *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) */ ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; /*Minimum MPDU start spacing , */ ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; /* *hw->wiphy->bands[IEEE80211_BAND_2GHZ] *base on ant_num *rx_mask: RX mask *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15 *if rx_ant >=3 rx_mask[2]=0xff; *if BW_40 rx_mask[4]=0x01; *highest supported RX rate */ if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T2R or 2T2R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0xFF; ht_cap->mcs.rx_mask[4] = 0x01; ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); } else if (get_rf_type(rtlphy) == RF_1T1R) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0x00; ht_cap->mcs.rx_mask[4] = 0x01; ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7); } }
static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, struct ieee80211_sta_ht_cap *ht_cap) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); ht_cap->ht_supported = true; ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; if (rtlpriv->rtlhal.disable_amsdu_8k) ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T2R or 2T2R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0xFF; ht_cap->mcs.rx_mask[4] = 0x01; ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); } else if (get_rf_type(rtlphy) == RF_1T1R) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0x00; ht_cap->mcs.rx_mask[4] = 0x01; ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7); } }
static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); u8 hw_rate; if (get_rf_type(rtlphy) == RF_2T2R) hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15]; else hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7]; return hw_rate; }
void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); if (dm_pstable.rssi_val_min != 0) { if (dm_pstable.pre_ccastate == CCA_2R) { if (dm_pstable.rssi_val_min >= 35) dm_pstable.cur_ccasate = CCA_1R; else dm_pstable.cur_ccasate = CCA_2R; } else { if (dm_pstable.rssi_val_min <= 30) dm_pstable.cur_ccasate = CCA_2R; else dm_pstable.cur_ccasate = CCA_1R; } } else { dm_pstable.cur_ccasate = CCA_MAX; } if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { if (dm_pstable.cur_ccasate == CCA_1R) { if (get_rf_type(rtlphy) == RF_2T2R) { rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x13); rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); } else { rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); } } else { rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x33); rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); } dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; } RT_TRACE(DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", (dm_pstable.cur_ccasate == 0) ? "1RCCA" : "2RCCA")); }
void rtl92c_read_chip_version(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); enum version_8192c chip_version = VERSION_UNKNOWN; const char *versionid; u32 value32; value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); if (value32 & TRP_VAUX_EN) { chip_version = (value32 & TYPE_ID) ? VERSION_TEST_CHIP_92C : VERSION_TEST_CHIP_88C; } else { /* Normal mass production chip. */ chip_version = NORMAL_CHIP; chip_version |= ((value32 & TYPE_ID) ? CHIP_92C : 0); chip_version |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0); /* RTL8723 with BT function. */ chip_version |= ((value32 & BT_FUNC) ? CHIP_8723 : 0); if (IS_VENDOR_UMC(chip_version)) chip_version |= ((value32 & CHIP_VER_RTL_MASK) ? CHIP_VENDOR_UMC_B_CUT : 0); if (IS_92C_SERIAL(chip_version)) { value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM); chip_version |= ((CHIP_BONDING_IDENTIFIER(value32) == CHIP_BONDING_92C_1T2R) ? CHIP_92C_1T2R : 0); } else if (IS_8723_SERIES(chip_version)) { value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS); chip_version |= ((value32 & RF_RL_ID) ? CHIP_8723_DRV_REV : 0); } } rtlhal->version = (enum version_8192c)chip_version; pr_info("Chip version 0x%x\n", chip_version); switch (rtlhal->version) { case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: versionid = "NORMAL_B_CHIP_92C"; break; case VERSION_NORMAL_TSMC_CHIP_92C: versionid = "NORMAL_TSMC_CHIP_92C"; break; case VERSION_NORMAL_TSMC_CHIP_88C: versionid = "NORMAL_TSMC_CHIP_88C"; break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: versionid = "NORMAL_UMC_CHIP_92C_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: versionid = "NORMAL_UMC_CHIP_88C_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: versionid = "NORMAL_UMC_CHIP_92C_B_CUT"; break; case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: versionid = "NORMAL_UMC_CHIP_88C_B_CUT"; break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT: versionid = "NORMAL_UMC_CHIP_8723_1T1R_A_CUT"; break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT: versionid = "NORMAL_UMC_CHIP_8723_1T1R_B_CUT"; break; case VERSION_TEST_CHIP_92C: versionid = "TEST_CHIP_92C"; break; case VERSION_TEST_CHIP_88C: versionid = "TEST_CHIP_88C"; break; default: versionid = "UNKNOWN"; break; } RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Chip Version ID: %s\n", versionid); if (IS_92C_SERIAL(rtlhal->version)) rtlphy->rf_type = (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R; else rtlphy->rf_type = RF_1T1R; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R"); if (get_rf_type(rtlphy) == RF_1T1R) rtlpriv->dm.rfpath_rxenable[0] = true; else rtlpriv->dm.rfpath_rxenable[0] = rtlpriv->dm.rfpath_rxenable[1] = true; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", rtlhal->version); }
static void _rtl8723e_write_ofdm_power_reg( struct ieee80211_hw *hw, u8 index, u32 *pvalue ) { struct rtl_priv *rtlpriv = rtl_priv( hw ); struct rtl_phy *rtlphy = &rtlpriv->phy; u16 regoffset_a[6] = { RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 }; u16 regoffset_b[6] = { RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 }; u8 i, rf, pwr_val[4]; u32 writeval; u16 regoffset; for ( rf = 0; rf < 2; rf++ ) { writeval = pvalue[rf]; for ( i = 0; i < 4; i++ ) { pwr_val[i] = ( u8 )( ( writeval & ( 0x7f << ( i * 8 ) ) ) >> ( i * 8 ) ); if ( pwr_val[i] > RF6052_MAX_TX_PWR ) pwr_val[i] = RF6052_MAX_TX_PWR; } writeval = ( pwr_val[3] << 24 ) | ( pwr_val[2] << 16 ) | ( pwr_val[1] << 8 ) | pwr_val[0]; if ( rf == 0 ) regoffset = regoffset_a[index]; else regoffset = regoffset_b[index]; rtl_set_bbreg( hw, regoffset, MASKDWORD, writeval ); RTPRINT( rtlpriv, FPHY, PHY_TXPWR, "Set 0x%x = %08x\n", regoffset, writeval ); if ( ( ( get_rf_type( rtlphy ) == RF_2T2R ) && ( regoffset == RTXAGC_A_MCS15_MCS12 || regoffset == RTXAGC_B_MCS15_MCS12 ) ) || ( ( get_rf_type( rtlphy ) != RF_2T2R ) && ( regoffset == RTXAGC_A_MCS07_MCS04 || regoffset == RTXAGC_B_MCS07_MCS04 ) ) ) { writeval = pwr_val[3]; if ( regoffset == RTXAGC_A_MCS15_MCS12 || regoffset == RTXAGC_A_MCS07_MCS04 ) regoffset = 0xc90; if ( regoffset == RTXAGC_B_MCS15_MCS12 || regoffset == RTXAGC_B_MCS07_MCS04 ) regoffset = 0xc98; for ( i = 0; i < 3; i++ ) { writeval = ( writeval > 6 ) ? ( writeval - 6 ) : 0; rtl_write_byte( rtlpriv, ( u32 ) ( regoffset + i ), ( u8 )writeval ); } } } }