Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtlwifi / rtl8192se / hw.c
index 084e7773bce2a1f6585d2b115e7a525315dc7a39..4f461786a7eb24abb3ae49a1dbccc4311d54ea58 100644 (file)
@@ -400,6 +400,39 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 
                        break;
                }
+       case HW_VAR_FW_LPS_ACTION: {
+               bool enter_fwlps = *((bool *)val);
+               u8 rpwm_val, fw_pwrmode;
+               bool fw_current_inps;
+
+               if (enter_fwlps) {
+                       rpwm_val = 0x02;        /* RF off */
+                       fw_current_inps = true;
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                       HW_VAR_FW_PSMODE_STATUS,
+                                       (u8 *)(&fw_current_inps));
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                       HW_VAR_H2C_FW_PWRMODE,
+                                       (u8 *)(&ppsc->fwctrl_psmode));
+
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                       HW_VAR_SET_RPWM,
+                                       (u8 *)(&rpwm_val));
+               } else {
+                       rpwm_val = 0x0C;        /* RF on */
+                       fw_pwrmode = FW_PS_ACTIVE_MODE;
+                       fw_current_inps = false;
+                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
+                                       (u8 *)(&rpwm_val));
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                       HW_VAR_H2C_FW_PWRMODE,
+                                       (u8 *)(&fw_pwrmode));
+
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                       HW_VAR_FW_PSMODE_STATUS,
+                                       (u8 *)(&fw_current_inps));
+               }
+               break; }
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
                         "switch case not processed\n");
@@ -438,7 +471,7 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
 
 }
 
-static u8 _rtl92ce_halset_sysclk(struct ieee80211_hw *hw, u8 data)
+static u8 _rtl92se_halset_sysclk(struct ieee80211_hw *hw, u8 data)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u8 waitcount = 100;
@@ -547,7 +580,7 @@ static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
                tmpu1b &= ~(BIT(6) | BIT(7));
 
                /* Set failed, return to prevent hang. */
-               if (!_rtl92ce_halset_sysclk(hw, tmpu1b))
+               if (!_rtl92se_halset_sysclk(hw, tmpu1b))
                        return;
        }
 
@@ -650,7 +683,7 @@ static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
 
        tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
        tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
-       if (!_rtl92ce_halset_sysclk(hw, tmpu1b))
+       if (!_rtl92se_halset_sysclk(hw, tmpu1b))
                return; /* Set failed, return to prevent hang. */
 
        rtl_write_word(rtlpriv, CMDR, 0x07FC);
@@ -967,6 +1000,15 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
                return rtstatus;
        }
 
+       /* because last function modify RCR, so we update
+        * rcr var here, or TP will unstable for receive_config
+        * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
+        * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
+        */
+       rtlpci->receive_config = rtl_read_dword(rtlpriv, RCR);
+       rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
+       rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config);
+
        /* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */
        /* We must set flag avoid BB/RF config period later!! */
        rtl_write_dword(rtlpriv, CMDR, 0x37FC);
@@ -982,25 +1024,6 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
 
        rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
 
-       /* RF Power Save */
-#if 0
-       /* H/W or S/W RF OFF before sleep. */
-       if (rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS) {
-               u32 rfoffreason = rtlpriv->psc.rfoff_reason;
-
-               rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT;
-               rtlpriv->psc.rfpwr_state = ERFON;
-               /* FIXME: check spinlocks if this block is uncommented */
-               rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason);
-       } else {
-               /* gpio radio on/off is out of adapter start */
-               if (rtlpriv->psc.hwradiooff == false) {
-                       rtlpriv->psc.rfpwr_state = ERFON;
-                       rtlpriv->psc.rfoff_reason = 0;
-               }
-       }
-#endif
-
        /* Before RF-R/W we must execute the IO from Scott's suggestion. */
        rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB);
        if (rtlhal->version == VERSION_8192S_ACUT)
@@ -1058,7 +1081,22 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
 
        /* We enable high power and RA related mechanism after NIC
         * initialized. */
-       rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT);
+       if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
+               /* Fw v.53 and later. */
+               rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT);
+       } else if (hal_get_firmwareversion(rtlpriv) == 0x34) {
+               /* Fw v.52. */
+               rtl_write_dword(rtlpriv, WFM5, FW_RA_INIT);
+               rtl92s_phy_chk_fwcmd_iodone(hw);
+       } else {
+               /* Compatible earlier FW version. */
+               rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
+               rtl92s_phy_chk_fwcmd_iodone(hw);
+               rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
+               rtl92s_phy_chk_fwcmd_iodone(hw);
+               rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
+               rtl92s_phy_chk_fwcmd_iodone(hw);
+       }
 
        /* Add to prevent ASPM bug. */
        /* Always enable hst and NIC clock request. */
@@ -1229,7 +1267,6 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
        synchronize_irq(rtlpci->pdev->irq);
 }
 
-
 static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1754,7 +1791,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
                }
 
                for (i = 0; i < 14; i++) {
-                       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+                       RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                                "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
                                rf_path, i,
                                rtlefuse->txpwrlevel_cck[rf_path][i],
@@ -1791,11 +1828,11 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
                                ((rtlefuse->eeprom_pwrgroup[rf_path][index] &
                                0xf0) >> 4);
 
-                       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+                       RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                                "RF-%d pwrgroup_ht20[%d] = 0x%x\n",
                                rf_path, i,
                                rtlefuse->pwrgroup_ht20[rf_path][i]);
-                       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+                       RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                                "RF-%d pwrgroup_ht40[%d] = 0x%x\n",
                                rf_path, i,
                                rtlefuse->pwrgroup_ht40[rf_path][i]);
@@ -1850,27 +1887,27 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
                        rtlefuse->eeprom_regulatory =
                                 (hwinfo[EEPROM_REGULATORY] & 0x1);
        }
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+       RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
 
        for (i = 0; i < 14; i++)
-               RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+               RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                        "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
                        i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
        for (i = 0; i < 14; i++)
-               RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+               RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                        "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
                        i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
        for (i = 0; i < 14; i++)
-               RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+               RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                        "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
                        i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
        for (i = 0; i < 14; i++)
-               RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+               RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                        "RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
                        i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
 
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+       RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag);
 
        /* Read RF-indication and Tx Power gain
@@ -1880,7 +1917,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        rtlefuse->legacy_httxpowerdiff =
                rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];
 
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+       RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff);
 
        /* Get TSSI value for each path. */
@@ -1889,7 +1926,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        usvalue = hwinfo[EEPROM_TSSI_B];
        rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff);
 
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+       RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
                rtlefuse->eeprom_tssi[RF90_PATH_A],
                rtlefuse->eeprom_tssi[RF90_PATH_B]);
 
@@ -1897,7 +1934,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        /* and read ThermalMeter from EEPROM */
        tempval = hwinfo[EEPROM_THERMALMETER];
        rtlefuse->eeprom_thermalmeter = tempval;
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+       RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
 
        /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */
@@ -1914,7 +1951,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        /* Version ID, Channel plan */
        rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
        rtlefuse->txpwr_fromeprom = true;
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+       RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
                "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan);
 
        /* Read Customer ID or Board Type!!! */
@@ -1999,6 +2036,8 @@ static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw,
                ratr_value = sta->supp_rates[1] << 4;
        else
                ratr_value = sta->supp_rates[0];
+       if (mac->opmode == NL80211_IFTYPE_ADHOC)
+               ratr_value = 0xfff;
        ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
                        sta->ht_cap.mcs.rx_mask[0] << 12);
        switch (wirelessmode) {
@@ -2112,6 +2151,8 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
                ratr_bitmap = sta->supp_rates[1] << 4;
        else
                ratr_bitmap = sta->supp_rates[0];
+       if (mac->opmode == NL80211_IFTYPE_ADHOC)
+               ratr_bitmap = 0xfff;
        ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
                        sta->ht_cap.mcs.rx_mask[0] << 12);
        switch (wirelessmode) {
@@ -2200,6 +2241,7 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
                        ratr_bitmap &= 0x0f8ff0ff;
                break;
        }
+       sta_entry->ratr_index = ratr_index;
 
        if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
                ratr_bitmap &= 0x0FFFFFFF;
@@ -2438,23 +2480,9 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
                                rtl_cam_del_entry(hw, p_macaddr);
                        rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
                } else {
-                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                "The insert KEY length is %d\n",
-                                rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
-                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                "The insert KEY is %x %x\n",
-                                rtlpriv->sec.key_buf[0][0],
-                                rtlpriv->sec.key_buf[0][1]);
-
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
                                 "add one entry\n");
                        if (is_pairwise) {
-                               RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
-                                             "Pairwise Key content",
-                                             rtlpriv->sec.pairwise_key,
-                                             rtlpriv->sec.
-                                             key_len[PAIRWISE_KEYIDX]);
-
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
                                         "set Pairwise key\n");
 
@@ -2502,3 +2530,23 @@ void rtl92se_resume(struct ieee80211_hw *hw)
                pci_write_config_dword(rtlpci->pdev, 0x40,
                        val & 0xffff00ff);
 }
+
+/* Turn on AAP (RCR:bit 0) for promicuous mode. */
+void rtl92se_allow_all_destaddr(struct ieee80211_hw *hw,
+                               bool allow_all_da, bool write_into_reg)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       if (allow_all_da) /* Set BIT0 */
+               rtlpci->receive_config |= RCR_AAP;
+       else /* Clear BIT0 */
+               rtlpci->receive_config &= ~RCR_AAP;
+
+       if (write_into_reg)
+               rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config);
+
+       RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
+                "receive_config=0x%08X, write_into_reg=%d\n",
+                rtlpci->receive_config, write_into_reg);
+}