linux/drivers/staging/rtlwifi/phydm/phydm_kfree.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2016  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
  26/*============================================================*/
  27/*include files*/
  28/*============================================================*/
  29#include "mp_precomp.h"
  30#include "phydm_precomp.h"
  31
  32/*<YuChen, 150720> Add for KFree Feature Requested by RF David.*/
  33/*This is a phydm API*/
  34
  35static void phydm_set_kfree_to_rf_8814a(void *dm_void, u8 e_rf_path, u8 data)
  36{
  37        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
  38        struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
  39        bool is_odd;
  40
  41        if ((data % 2) != 0) { /*odd->positive*/
  42                data = data - 1;
  43                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19),
  44                               1);
  45                is_odd = true;
  46        } else { /*even->negative*/
  47                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19),
  48                               0);
  49                is_odd = false;
  50        }
  51        ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): RF_0x55[19]= %d\n", __func__,
  52                     is_odd);
  53        switch (data) {
  54        case 0:
  55                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
  56                               0);
  57                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
  58                               BIT(17) | BIT(16) | BIT(15), 0);
  59                cali_info->kfree_offset[e_rf_path] = 0;
  60                break;
  61        case 2:
  62                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
  63                               1);
  64                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
  65                               BIT(17) | BIT(16) | BIT(15), 0);
  66                cali_info->kfree_offset[e_rf_path] = 0;
  67                break;
  68        case 4:
  69                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
  70                               0);
  71                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
  72                               BIT(17) | BIT(16) | BIT(15), 1);
  73                cali_info->kfree_offset[e_rf_path] = 1;
  74                break;
  75        case 6:
  76                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
  77                               1);
  78                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
  79                               BIT(17) | BIT(16) | BIT(15), 1);
  80                cali_info->kfree_offset[e_rf_path] = 1;
  81                break;
  82        case 8:
  83                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
  84                               0);
  85                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
  86                               BIT(17) | BIT(16) | BIT(15), 2);
  87                cali_info->kfree_offset[e_rf_path] = 2;
  88                break;
  89        case 10:
  90                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
  91                               1);
  92                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
  93                               BIT(17) | BIT(16) | BIT(15), 2);
  94                cali_info->kfree_offset[e_rf_path] = 2;
  95                break;
  96        case 12:
  97                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
  98                               0);
  99                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
 100                               BIT(17) | BIT(16) | BIT(15), 3);
 101                cali_info->kfree_offset[e_rf_path] = 3;
 102                break;
 103        case 14:
 104                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
 105                               1);
 106                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
 107                               BIT(17) | BIT(16) | BIT(15), 3);
 108                cali_info->kfree_offset[e_rf_path] = 3;
 109                break;
 110        case 16:
 111                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
 112                               0);
 113                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
 114                               BIT(17) | BIT(16) | BIT(15), 4);
 115                cali_info->kfree_offset[e_rf_path] = 4;
 116                break;
 117        case 18:
 118                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
 119                               1);
 120                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
 121                               BIT(17) | BIT(16) | BIT(15), 4);
 122                cali_info->kfree_offset[e_rf_path] = 4;
 123                break;
 124        case 20:
 125                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
 126                               0);
 127                odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
 128                               BIT(17) | BIT(16) | BIT(15), 5);
 129                cali_info->kfree_offset[e_rf_path] = 5;
 130                break;
 131
 132        default:
 133                break;
 134        }
 135
 136        if (!is_odd) {
 137                /*that means Kfree offset is negative, we need to record it.*/
 138                cali_info->kfree_offset[e_rf_path] =
 139                        (-1) * cali_info->kfree_offset[e_rf_path];
 140                ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n",
 141                             __func__, cali_info->kfree_offset[e_rf_path]);
 142        } else {
 143                ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n",
 144                             __func__, cali_info->kfree_offset[e_rf_path]);
 145        }
 146}
 147
 148static void phydm_set_kfree_to_rf(void *dm_void, u8 e_rf_path, u8 data)
 149{
 150        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 151
 152        if (dm->support_ic_type & ODM_RTL8814A)
 153                phydm_set_kfree_to_rf_8814a(dm, e_rf_path, data);
 154}
 155
 156void phydm_config_kfree(void *dm_void, u8 channel_to_sw, u8 *kfree_table)
 157{
 158        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 159        struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
 160        u8 rfpath = 0, max_rf_path = 0;
 161        u8 channel_idx = 0;
 162
 163        if (dm->support_ic_type & ODM_RTL8814A)
 164                max_rf_path = 4; /*0~3*/
 165        else if (dm->support_ic_type &
 166                 (ODM_RTL8812 | ODM_RTL8192E | ODM_RTL8822B))
 167                max_rf_path = 2; /*0~1*/
 168        else
 169                max_rf_path = 1;
 170
 171        ODM_RT_TRACE(dm, ODM_COMP_MP, "===>%s()\n", __func__);
 172
 173        if (cali_info->reg_rf_kfree_enable == 2) {
 174                ODM_RT_TRACE(dm, ODM_COMP_MP,
 175                             "%s(): reg_rf_kfree_enable == 2, Disable\n",
 176                             __func__);
 177                return;
 178        }
 179
 180        if (cali_info->reg_rf_kfree_enable != 1 &&
 181            cali_info->reg_rf_kfree_enable != 0) {
 182                ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__);
 183                return;
 184        }
 185
 186        ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): reg_rf_kfree_enable == true\n",
 187                     __func__);
 188        /*Make sure the targetval is defined*/
 189        if (((cali_info->reg_rf_kfree_enable == 1) &&
 190             (kfree_table[0] != 0xFF)) ||
 191            cali_info->rf_kfree_enable) {
 192                /*if kfree_table[0] == 0xff, means no Kfree*/
 193                if (*dm->band_type == ODM_BAND_2_4G) {
 194                        if (channel_to_sw <= 14 && channel_to_sw >= 1)
 195                                channel_idx = PHYDM_2G;
 196                } else if (*dm->band_type == ODM_BAND_5G) {
 197                        if (channel_to_sw >= 36 && channel_to_sw <= 48)
 198                                channel_idx = PHYDM_5GLB1;
 199                        if (channel_to_sw >= 52 && channel_to_sw <= 64)
 200                                channel_idx = PHYDM_5GLB2;
 201                        if (channel_to_sw >= 100 && channel_to_sw <= 120)
 202                                channel_idx = PHYDM_5GMB1;
 203                        if (channel_to_sw >= 124 && channel_to_sw <= 144)
 204                                channel_idx = PHYDM_5GMB2;
 205                        if (channel_to_sw >= 149 && channel_to_sw <= 177)
 206                                channel_idx = PHYDM_5GHB;
 207                }
 208
 209                for (rfpath = ODM_RF_PATH_A; rfpath < max_rf_path; rfpath++) {
 210                        ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): PATH_%d: %#x\n",
 211                                     __func__, rfpath,
 212                                     kfree_table[channel_idx * max_rf_path +
 213                                                 rfpath]);
 214                        phydm_set_kfree_to_rf(
 215                                dm, rfpath,
 216                                kfree_table[channel_idx * max_rf_path +
 217                                            rfpath]);
 218                }
 219        } else {
 220                ODM_RT_TRACE(
 221                        dm, ODM_COMP_MP,
 222                        "%s(): targetval not defined, Don't execute KFree Process.\n",
 223                        __func__);
 224                return;
 225        }
 226
 227        ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__);
 228}
 229