0001
0002
0003
0004
0005
0006
0007
0008 #include "odm_precomp.h"
0009
0010
0011
0012 u32 OFDMSwingTable[OFDM_TABLE_SIZE] = {
0013 0x7f8001fe,
0014 0x788001e2,
0015 0x71c001c7,
0016 0x6b8001ae,
0017 0x65400195,
0018 0x5fc0017f,
0019 0x5a400169,
0020 0x55400155,
0021 0x50800142,
0022 0x4c000130,
0023 0x47c0011f,
0024 0x43c0010f,
0025 0x40000100,
0026 0x3c8000f2,
0027 0x390000e4,
0028 0x35c000d7,
0029 0x32c000cb,
0030 0x300000c0,
0031 0x2d4000b5,
0032 0x2ac000ab,
0033 0x288000a2,
0034 0x26000098,
0035 0x24000090,
0036 0x22000088,
0037 0x20000080,
0038 0x1e400079,
0039 0x1c800072,
0040 0x1b00006c,
0041 0x19800066,
0042 0x18000060,
0043 0x16c0005b,
0044 0x15800056,
0045 0x14400051,
0046 0x1300004c,
0047 0x12000048,
0048 0x11000044,
0049 0x10000040,
0050 };
0051
0052 u8 CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8] = {
0053 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
0054 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
0055 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
0056 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
0057 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
0058 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
0059 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
0060 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
0061 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
0062 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
0063 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
0064 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
0065 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
0066 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
0067 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
0068 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
0069 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
0070 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
0071 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
0072 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0073 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0074 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
0075 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
0076 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
0077 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
0078 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
0079 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
0080 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
0081 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
0082 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
0083 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
0084 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
0085 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
0086 };
0087
0088 u8 CCKSwingTable_Ch14[CCK_TABLE_SIZE][8] = {
0089 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
0090 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
0091 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
0092 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
0093 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
0094 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
0095 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
0096 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
0097 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
0098 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
0099 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
0100 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
0101 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
0102 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
0103 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
0104 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
0105 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
0106 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
0107 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
0108 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0109 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0110 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
0111 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
0112 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0113 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0114 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
0115 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0116 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0117 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0118 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0119 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0120 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0121 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
0122 };
0123
0124 u32 OFDMSwingTable_New[OFDM_TABLE_SIZE] = {
0125 0x0b40002d,
0126 0x0c000030,
0127 0x0cc00033,
0128 0x0d800036,
0129 0x0e400039,
0130 0x0f00003c,
0131 0x10000040,
0132 0x11000044,
0133 0x12000048,
0134 0x1300004c,
0135 0x14400051,
0136 0x15800056,
0137 0x16c0005b,
0138 0x18000060,
0139 0x19800066,
0140 0x1b00006c,
0141 0x1c800072,
0142 0x1e400079,
0143 0x20000080,
0144 0x22000088,
0145 0x24000090,
0146 0x26000098,
0147 0x288000a2,
0148 0x2ac000ab,
0149 0x2d4000b5,
0150 0x300000c0,
0151 0x32c000cb,
0152 0x35c000d7,
0153 0x390000e4,
0154 0x3c8000f2,
0155 0x40000100,
0156 0x43c0010f,
0157 0x47c0011f,
0158 0x4c000130,
0159 0x50800142,
0160 0x55400155,
0161 0x5a400169,
0162 0x5fc0017f,
0163 0x65400195,
0164 0x6b8001ae,
0165 0x71c001c7,
0166 0x788001e2,
0167 0x7f8001fe
0168 };
0169
0170 u8 CCKSwingTable_Ch1_Ch13_New[CCK_TABLE_SIZE][8] = {
0171 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01},
0172 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
0173 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
0174 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
0175 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
0176 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
0177 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
0178 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
0179 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
0180 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
0181 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
0182 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
0183 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0184 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0185 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
0186 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
0187 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
0188 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
0189 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
0190 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
0191 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
0192 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
0193 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
0194 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
0195 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
0196 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
0197 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
0198 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
0199 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
0200 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
0201 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
0202 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
0203 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}
0204 };
0205
0206 u8 CCKSwingTable_Ch14_New[CCK_TABLE_SIZE][8] = {
0207 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00},
0208 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0209 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0210 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0211 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0212 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0213 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0214 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
0215 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0216 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0217 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
0218 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
0219 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0220 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0221 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
0222 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
0223 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
0224 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
0225 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
0226 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
0227 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
0228 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
0229 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
0230 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
0231 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
0232 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
0233 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
0234 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
0235 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
0236 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
0237 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
0238 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
0239 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}
0240 };
0241
0242 u32 TxScalingTable_Jaguar[TXSCALE_TABLE_SIZE] = {
0243 0x081,
0244 0x088,
0245 0x090,
0246 0x099,
0247 0x0A2,
0248 0x0AC,
0249 0x0B6,
0250 0x0C0,
0251 0x0CC,
0252 0x0D8,
0253 0x0E5,
0254 0x0F2,
0255 0x101,
0256 0x110,
0257 0x120,
0258 0x131,
0259 0x143,
0260 0x156,
0261 0x16A,
0262 0x180,
0263 0x197,
0264 0x1AF,
0265 0x1C8,
0266 0x1E3,
0267 0x200,
0268 0x21E,
0269 0x23E,
0270 0x261,
0271 0x285,
0272 0x2AB,
0273 0x2D3,
0274 0x2FE,
0275 0x32B,
0276 0x35C,
0277 0x38E,
0278 0x3C4,
0279 0x3FE
0280 };
0281
0282
0283
0284 static void odm_CommonInfoSelfInit(struct dm_odm_t *pDM_Odm)
0285 {
0286 pDM_Odm->bCckHighPower = (bool) PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG(CCK_RPT_FORMAT, pDM_Odm), ODM_BIT(CCK_RPT_FORMAT, pDM_Odm));
0287 pDM_Odm->RFPathRxEnable = (u8) PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG(BB_RX_PATH, pDM_Odm), ODM_BIT(BB_RX_PATH, pDM_Odm));
0288
0289 pDM_Odm->TxRate = 0xFF;
0290 }
0291
0292 static void odm_CommonInfoSelfUpdate(struct dm_odm_t *pDM_Odm)
0293 {
0294 u8 EntryCnt = 0;
0295 u8 i;
0296 PSTA_INFO_T pEntry;
0297
0298 if (*(pDM_Odm->pBandWidth) == ODM_BW40M) {
0299 if (*(pDM_Odm->pSecChOffset) == 1)
0300 pDM_Odm->ControlChannel = *(pDM_Odm->pChannel)-2;
0301 else if (*(pDM_Odm->pSecChOffset) == 2)
0302 pDM_Odm->ControlChannel = *(pDM_Odm->pChannel)+2;
0303 } else
0304 pDM_Odm->ControlChannel = *(pDM_Odm->pChannel);
0305
0306 for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
0307 pEntry = pDM_Odm->pODM_StaInfo[i];
0308 if (IS_STA_VALID(pEntry))
0309 EntryCnt++;
0310 }
0311
0312 if (EntryCnt == 1)
0313 pDM_Odm->bOneEntryOnly = true;
0314 else
0315 pDM_Odm->bOneEntryOnly = false;
0316 }
0317
0318 static void odm_CmnInfoInit_Debug(struct dm_odm_t *pDM_Odm)
0319 {
0320 }
0321
0322 static void odm_BasicDbgMessage(struct dm_odm_t *pDM_Odm)
0323 {
0324 }
0325
0326
0327
0328
0329
0330
0331
0332
0333 static void odm_RateAdaptiveMaskInit(struct dm_odm_t *pDM_Odm)
0334 {
0335 struct odm_rate_adaptive *pOdmRA = &pDM_Odm->RateAdaptive;
0336
0337 pOdmRA->Type = DM_Type_ByDriver;
0338 if (pOdmRA->Type == DM_Type_ByDriver)
0339 pDM_Odm->bUseRAMask = true;
0340 else
0341 pDM_Odm->bUseRAMask = false;
0342
0343 pOdmRA->RATRState = DM_RATR_STA_INIT;
0344 pOdmRA->LdpcThres = 35;
0345 pOdmRA->bUseLdpc = false;
0346 pOdmRA->HighRSSIThresh = 50;
0347 pOdmRA->LowRSSIThresh = 20;
0348 }
0349
0350 u32 ODM_Get_Rate_Bitmap(
0351 struct dm_odm_t *pDM_Odm,
0352 u32 macid,
0353 u32 ra_mask,
0354 u8 rssi_level
0355 )
0356 {
0357 PSTA_INFO_T pEntry;
0358 u32 rate_bitmap = 0;
0359 u8 WirelessMode;
0360
0361 pEntry = pDM_Odm->pODM_StaInfo[macid];
0362 if (!IS_STA_VALID(pEntry))
0363 return ra_mask;
0364
0365 WirelessMode = pEntry->wireless_mode;
0366
0367 switch (WirelessMode) {
0368 case ODM_WM_B:
0369 if (ra_mask & 0x0000000c)
0370 rate_bitmap = 0x0000000d;
0371 else
0372 rate_bitmap = 0x0000000f;
0373 break;
0374
0375 case (ODM_WM_G):
0376 if (rssi_level == DM_RATR_STA_HIGH)
0377 rate_bitmap = 0x00000f00;
0378 else
0379 rate_bitmap = 0x00000ff0;
0380 break;
0381
0382 case (ODM_WM_B|ODM_WM_G):
0383 if (rssi_level == DM_RATR_STA_HIGH)
0384 rate_bitmap = 0x00000f00;
0385 else if (rssi_level == DM_RATR_STA_MIDDLE)
0386 rate_bitmap = 0x00000ff0;
0387 else
0388 rate_bitmap = 0x00000ff5;
0389 break;
0390
0391 case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
0392 case (ODM_WM_B|ODM_WM_N24G):
0393 case (ODM_WM_G|ODM_WM_N24G):
0394 if (rssi_level == DM_RATR_STA_HIGH)
0395 rate_bitmap = 0x000f0000;
0396 else if (rssi_level == DM_RATR_STA_MIDDLE)
0397 rate_bitmap = 0x000ff000;
0398 else {
0399 if (*(pDM_Odm->pBandWidth) == ODM_BW40M)
0400 rate_bitmap = 0x000ff015;
0401 else
0402 rate_bitmap = 0x000ff005;
0403 }
0404 break;
0405
0406 default:
0407 rate_bitmap = 0x0fffffff;
0408 break;
0409 }
0410
0411 return ra_mask & rate_bitmap;
0412
0413 }
0414
0415 static void odm_RefreshRateAdaptiveMaskCE(struct dm_odm_t *pDM_Odm)
0416 {
0417 u8 i;
0418 struct adapter *padapter = pDM_Odm->Adapter;
0419
0420 if (padapter->bDriverStopped) {
0421 return;
0422 }
0423
0424 if (!pDM_Odm->bUseRAMask) {
0425 return;
0426 }
0427
0428 for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
0429 PSTA_INFO_T pstat = pDM_Odm->pODM_StaInfo[i];
0430
0431 if (IS_STA_VALID(pstat)) {
0432 if (IS_MCAST(pstat->hwaddr))
0433 continue;
0434
0435 if (true == ODM_RAStateCheck(pDM_Odm, pstat->rssi_stat.UndecoratedSmoothedPWDB, false, &pstat->rssi_level)) {
0436
0437 rtw_hal_update_ra_mask(pstat, pstat->rssi_level);
0438 }
0439
0440 }
0441 }
0442 }
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461 static void odm_RefreshRateAdaptiveMask(struct dm_odm_t *pDM_Odm)
0462 {
0463
0464 if (!(pDM_Odm->SupportAbility & ODM_BB_RA_MASK)) {
0465 return;
0466 }
0467 odm_RefreshRateAdaptiveMaskCE(pDM_Odm);
0468 }
0469
0470
0471
0472 bool ODM_RAStateCheck(
0473 struct dm_odm_t *pDM_Odm,
0474 s32 RSSI,
0475 bool bForceUpdate,
0476 u8 *pRATRState
0477 )
0478 {
0479 struct odm_rate_adaptive *pRA = &pDM_Odm->RateAdaptive;
0480 const u8 GoUpGap = 5;
0481 u8 HighRSSIThreshForRA = pRA->HighRSSIThresh;
0482 u8 LowRSSIThreshForRA = pRA->LowRSSIThresh;
0483 u8 RATRState;
0484
0485
0486
0487
0488 switch (*pRATRState) {
0489 case DM_RATR_STA_INIT:
0490 case DM_RATR_STA_HIGH:
0491 break;
0492
0493 case DM_RATR_STA_MIDDLE:
0494 HighRSSIThreshForRA += GoUpGap;
0495 break;
0496
0497 case DM_RATR_STA_LOW:
0498 HighRSSIThreshForRA += GoUpGap;
0499 LowRSSIThreshForRA += GoUpGap;
0500 break;
0501
0502 default:
0503 netdev_dbg(pDM_Odm->Adapter->pnetdev,
0504 "wrong rssi level setting %d !", *pRATRState);
0505 break;
0506 }
0507
0508
0509 if (RSSI > HighRSSIThreshForRA)
0510 RATRState = DM_RATR_STA_HIGH;
0511 else if (RSSI > LowRSSIThreshForRA)
0512 RATRState = DM_RATR_STA_MIDDLE;
0513 else
0514 RATRState = DM_RATR_STA_LOW;
0515
0516
0517 if (*pRATRState != RATRState || bForceUpdate) {
0518 *pRATRState = RATRState;
0519 return true;
0520 }
0521
0522 return false;
0523 }
0524
0525
0526
0527
0528
0529
0530
0531 static void odm_RSSIMonitorInit(struct dm_odm_t *pDM_Odm)
0532 {
0533 struct ra_t *pRA_Table = &pDM_Odm->DM_RA_Table;
0534
0535 pRA_Table->firstconnect = false;
0536
0537 }
0538
0539 static void FindMinimumRSSI(struct adapter *padapter)
0540 {
0541 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
0542 struct dm_priv *pdmpriv = &pHalData->dmpriv;
0543 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
0544
0545
0546
0547 if (
0548 (pDM_Odm->bLinked != true) &&
0549 (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)
0550 ) {
0551 pdmpriv->MinUndecoratedPWDBForDM = 0;
0552 } else
0553 pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB;
0554 }
0555
0556 static void odm_RSSIMonitorCheckCE(struct dm_odm_t *pDM_Odm)
0557 {
0558 struct adapter *Adapter = pDM_Odm->Adapter;
0559 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
0560 struct dm_priv *pdmpriv = &pHalData->dmpriv;
0561 int i;
0562 int tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff;
0563 u8 sta_cnt = 0;
0564 u32 PWDB_rssi[NUM_STA] = {0};
0565 struct ra_t *pRA_Table = &pDM_Odm->DM_RA_Table;
0566
0567 if (pDM_Odm->bLinked != true)
0568 return;
0569
0570 pRA_Table->firstconnect = pDM_Odm->bLinked;
0571
0572
0573 {
0574 struct sta_info *psta;
0575
0576 for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
0577 psta = pDM_Odm->pODM_StaInfo[i];
0578 if (IS_STA_VALID(psta)) {
0579 if (IS_MCAST(psta->hwaddr))
0580 continue;
0581
0582 if (psta->rssi_stat.UndecoratedSmoothedPWDB == (-1))
0583 continue;
0584
0585 if (psta->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB)
0586 tmpEntryMinPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
0587
0588 if (psta->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB)
0589 tmpEntryMaxPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
0590
0591 if (psta->rssi_stat.UndecoratedSmoothedPWDB != (-1))
0592 PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16));
0593 }
0594 }
0595
0596
0597
0598 for (i = 0; i < sta_cnt; i++) {
0599 if (PWDB_rssi[i] != (0)) {
0600 if (pHalData->fw_ractrl == true)
0601 rtl8723b_set_rssi_cmd(Adapter, (u8 *)(&PWDB_rssi[i]));
0602 }
0603 }
0604 }
0605
0606
0607
0608 if (tmpEntryMaxPWDB != 0)
0609 pdmpriv->EntryMaxUndecoratedSmoothedPWDB = tmpEntryMaxPWDB;
0610 else
0611 pdmpriv->EntryMaxUndecoratedSmoothedPWDB = 0;
0612
0613 if (tmpEntryMinPWDB != 0xff)
0614 pdmpriv->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB;
0615 else
0616 pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0;
0617
0618 FindMinimumRSSI(Adapter);
0619
0620 pDM_Odm->RSSI_Min = pdmpriv->MinUndecoratedPWDBForDM;
0621
0622 }
0623
0624 static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm)
0625 {
0626 if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR))
0627 return;
0628
0629 odm_RSSIMonitorCheckCE(pDM_Odm);
0630
0631 }
0632
0633
0634
0635
0636 static void odm_SwAntDetectInit(struct dm_odm_t *pDM_Odm)
0637 {
0638 struct swat_t *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
0639
0640 pDM_SWAT_Table->SWAS_NoLink_BK_Reg92c = rtw_read32(pDM_Odm->Adapter, rDPDT_control);
0641 pDM_SWAT_Table->PreAntenna = MAIN_ANT;
0642 pDM_SWAT_Table->CurAntenna = MAIN_ANT;
0643 pDM_SWAT_Table->SWAS_NoLink_State = 0;
0644 }
0645
0646
0647
0648
0649
0650 static u8 getSwingIndex(struct dm_odm_t *pDM_Odm)
0651 {
0652 struct adapter *Adapter = pDM_Odm->Adapter;
0653 u8 i = 0;
0654 u32 bbSwing;
0655 u32 swingTableSize;
0656 u32 *pSwingTable;
0657
0658 bbSwing = PHY_QueryBBReg(Adapter, rOFDM0_XATxIQImbalance, 0xFFC00000);
0659
0660 pSwingTable = OFDMSwingTable_New;
0661 swingTableSize = OFDM_TABLE_SIZE;
0662
0663 for (i = 0; i < swingTableSize; ++i) {
0664 u32 tableValue = pSwingTable[i];
0665
0666 if (tableValue >= 0x100000)
0667 tableValue >>= 22;
0668 if (bbSwing == tableValue)
0669 break;
0670 }
0671 return i;
0672 }
0673
0674 void odm_TXPowerTrackingInit(struct dm_odm_t *pDM_Odm)
0675 {
0676 u8 defaultSwingIndex = getSwingIndex(pDM_Odm);
0677 u8 p = 0;
0678 struct adapter *Adapter = pDM_Odm->Adapter;
0679 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
0680
0681
0682 struct dm_priv *pdmpriv = &pHalData->dmpriv;
0683
0684 pdmpriv->bTXPowerTracking = true;
0685 pdmpriv->TXPowercount = 0;
0686 pdmpriv->bTXPowerTrackingInit = false;
0687
0688 if (*(pDM_Odm->mp_mode) != 1)
0689 pdmpriv->TxPowerTrackControl = true;
0690 else
0691 pdmpriv->TxPowerTrackControl = false;
0692
0693
0694 pDM_Odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter;
0695 pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = pHalData->EEPROMThermalMeter;
0696 pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = pHalData->EEPROMThermalMeter;
0697
0698
0699 pDM_Odm->DefaultOfdmIndex = (defaultSwingIndex >= OFDM_TABLE_SIZE) ? 30 : defaultSwingIndex;
0700 pDM_Odm->DefaultCckIndex = 20;
0701
0702 pDM_Odm->BbSwingIdxCckBase = pDM_Odm->DefaultCckIndex;
0703 pDM_Odm->RFCalibrateInfo.CCK_index = pDM_Odm->DefaultCckIndex;
0704
0705 for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {
0706 pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->DefaultOfdmIndex;
0707 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = pDM_Odm->DefaultOfdmIndex;
0708 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = 0;
0709 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p] = 0;
0710 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
0711 }
0712
0713 }
0714
0715 void ODM_TXPowerTrackingCheck(struct dm_odm_t *pDM_Odm)
0716 {
0717 struct adapter *Adapter = pDM_Odm->Adapter;
0718
0719 if (!(pDM_Odm->SupportAbility & ODM_RF_TX_PWR_TRACK))
0720 return;
0721
0722 if (!pDM_Odm->RFCalibrateInfo.TM_Trigger) {
0723 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_T_METER_NEW, (BIT17 | BIT16), 0x03);
0724
0725 pDM_Odm->RFCalibrateInfo.TM_Trigger = 1;
0726 return;
0727 } else {
0728 ODM_TXPowerTrackingCallback_ThermalMeter(Adapter);
0729 pDM_Odm->RFCalibrateInfo.TM_Trigger = 0;
0730 }
0731 }
0732
0733
0734
0735
0736
0737
0738
0739
0740 void ODM_DMInit(struct dm_odm_t *pDM_Odm)
0741 {
0742
0743 odm_CommonInfoSelfInit(pDM_Odm);
0744 odm_CmnInfoInit_Debug(pDM_Odm);
0745 odm_DIGInit(pDM_Odm);
0746 odm_NHMCounterStatisticsInit(pDM_Odm);
0747 odm_AdaptivityInit(pDM_Odm);
0748 odm_RateAdaptiveMaskInit(pDM_Odm);
0749 ODM_CfoTrackingInit(pDM_Odm);
0750 ODM_EdcaTurboInit(pDM_Odm);
0751 odm_RSSIMonitorInit(pDM_Odm);
0752 odm_TXPowerTrackingInit(pDM_Odm);
0753
0754 ODM_ClearTxPowerTrackingState(pDM_Odm);
0755
0756 odm_DynamicBBPowerSavingInit(pDM_Odm);
0757 odm_DynamicTxPowerInit(pDM_Odm);
0758
0759 odm_SwAntDetectInit(pDM_Odm);
0760 }
0761
0762
0763
0764
0765
0766
0767 void ODM_DMWatchdog(struct dm_odm_t *pDM_Odm)
0768 {
0769 odm_CommonInfoSelfUpdate(pDM_Odm);
0770 odm_BasicDbgMessage(pDM_Odm);
0771 odm_FalseAlarmCounterStatistics(pDM_Odm);
0772 odm_NHMCounterStatistics(pDM_Odm);
0773
0774 odm_RSSIMonitorCheck(pDM_Odm);
0775
0776
0777
0778
0779
0780 if ((adapter_to_pwrctl(pDM_Odm->Adapter)->pwr_mode != PS_MODE_ACTIVE)
0781
0782
0783
0784
0785 ) {
0786 odm_DIGbyRSSI_LPS(pDM_Odm);
0787 } else
0788 odm_DIG(pDM_Odm);
0789
0790 {
0791 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
0792
0793 odm_Adaptivity(pDM_Odm, pDM_DigTable->CurIGValue);
0794 }
0795 odm_CCKPacketDetectionThresh(pDM_Odm);
0796
0797 if (*(pDM_Odm->pbPowerSaving) == true)
0798 return;
0799
0800
0801 odm_RefreshRateAdaptiveMask(pDM_Odm);
0802 odm_EdcaTurboCheck(pDM_Odm);
0803 ODM_CfoTracking(pDM_Odm);
0804
0805 ODM_TXPowerTrackingCheck(pDM_Odm);
0806
0807
0808
0809
0810
0811 pDM_Odm->PhyDbgInfo.NumQryBeaconPkt = 0;
0812 }
0813
0814
0815
0816
0817
0818 void ODM_CmnInfoInit(struct dm_odm_t *pDM_Odm, enum odm_cmninfo_e CmnInfo, u32 Value)
0819 {
0820
0821
0822
0823 switch (CmnInfo) {
0824
0825
0826
0827 case ODM_CMNINFO_ABILITY:
0828 pDM_Odm->SupportAbility = (u32)Value;
0829 break;
0830
0831 case ODM_CMNINFO_PLATFORM:
0832 pDM_Odm->SupportPlatform = (u8)Value;
0833 break;
0834
0835 case ODM_CMNINFO_INTERFACE:
0836 pDM_Odm->SupportInterface = (u8)Value;
0837 break;
0838
0839 case ODM_CMNINFO_IC_TYPE:
0840 pDM_Odm->SupportICType = Value;
0841 break;
0842
0843 case ODM_CMNINFO_CUT_VER:
0844 pDM_Odm->CutVersion = (u8)Value;
0845 break;
0846
0847 case ODM_CMNINFO_FAB_VER:
0848 pDM_Odm->FabVersion = (u8)Value;
0849 break;
0850
0851 case ODM_CMNINFO_RFE_TYPE:
0852 pDM_Odm->RFEType = (u8)Value;
0853 break;
0854
0855 case ODM_CMNINFO_RF_ANTENNA_TYPE:
0856 pDM_Odm->AntDivType = (u8)Value;
0857 break;
0858
0859 case ODM_CMNINFO_PACKAGE_TYPE:
0860 pDM_Odm->PackageType = (u8)Value;
0861 break;
0862
0863 case ODM_CMNINFO_EXT_LNA:
0864 pDM_Odm->ExtLNA = (u8)Value;
0865 break;
0866
0867 case ODM_CMNINFO_EXT_PA:
0868 pDM_Odm->ExtPA = (u8)Value;
0869 break;
0870
0871 case ODM_CMNINFO_GPA:
0872 pDM_Odm->TypeGPA = (enum odm_type_gpa_e)Value;
0873 break;
0874 case ODM_CMNINFO_APA:
0875 pDM_Odm->TypeAPA = (enum odm_type_apa_e)Value;
0876 break;
0877 case ODM_CMNINFO_GLNA:
0878 pDM_Odm->TypeGLNA = (enum odm_type_glna_e)Value;
0879 break;
0880 case ODM_CMNINFO_ALNA:
0881 pDM_Odm->TypeALNA = (enum odm_type_alna_e)Value;
0882 break;
0883
0884 case ODM_CMNINFO_EXT_TRSW:
0885 pDM_Odm->ExtTRSW = (u8)Value;
0886 break;
0887 case ODM_CMNINFO_PATCH_ID:
0888 pDM_Odm->PatchID = (u8)Value;
0889 break;
0890 case ODM_CMNINFO_BINHCT_TEST:
0891 pDM_Odm->bInHctTest = (bool)Value;
0892 break;
0893 case ODM_CMNINFO_BWIFI_TEST:
0894 pDM_Odm->bWIFITest = (bool)Value;
0895 break;
0896
0897 case ODM_CMNINFO_SMART_CONCURRENT:
0898 pDM_Odm->bDualMacSmartConcurrent = (bool)Value;
0899 break;
0900
0901
0902 default:
0903
0904 break;
0905 }
0906
0907 }
0908
0909
0910 void ODM_CmnInfoHook(struct dm_odm_t *pDM_Odm, enum odm_cmninfo_e CmnInfo, void *pValue)
0911 {
0912
0913
0914
0915 switch (CmnInfo) {
0916
0917
0918
0919 case ODM_CMNINFO_MAC_PHY_MODE:
0920 pDM_Odm->pMacPhyMode = pValue;
0921 break;
0922
0923 case ODM_CMNINFO_TX_UNI:
0924 pDM_Odm->pNumTxBytesUnicast = pValue;
0925 break;
0926
0927 case ODM_CMNINFO_RX_UNI:
0928 pDM_Odm->pNumRxBytesUnicast = pValue;
0929 break;
0930
0931 case ODM_CMNINFO_WM_MODE:
0932 pDM_Odm->pwirelessmode = pValue;
0933 break;
0934
0935 case ODM_CMNINFO_SEC_CHNL_OFFSET:
0936 pDM_Odm->pSecChOffset = pValue;
0937 break;
0938
0939 case ODM_CMNINFO_SEC_MODE:
0940 pDM_Odm->pSecurity = pValue;
0941 break;
0942
0943 case ODM_CMNINFO_BW:
0944 pDM_Odm->pBandWidth = pValue;
0945 break;
0946
0947 case ODM_CMNINFO_CHNL:
0948 pDM_Odm->pChannel = pValue;
0949 break;
0950
0951 case ODM_CMNINFO_DMSP_GET_VALUE:
0952 pDM_Odm->pbGetValueFromOtherMac = pValue;
0953 break;
0954
0955 case ODM_CMNINFO_BUDDY_ADAPTOR:
0956 pDM_Odm->pBuddyAdapter = pValue;
0957 break;
0958
0959 case ODM_CMNINFO_DMSP_IS_MASTER:
0960 pDM_Odm->pbMasterOfDMSP = pValue;
0961 break;
0962
0963 case ODM_CMNINFO_SCAN:
0964 pDM_Odm->pbScanInProcess = pValue;
0965 break;
0966
0967 case ODM_CMNINFO_POWER_SAVING:
0968 pDM_Odm->pbPowerSaving = pValue;
0969 break;
0970
0971 case ODM_CMNINFO_ONE_PATH_CCA:
0972 pDM_Odm->pOnePathCCA = pValue;
0973 break;
0974
0975 case ODM_CMNINFO_DRV_STOP:
0976 pDM_Odm->pbDriverStopped = pValue;
0977 break;
0978
0979 case ODM_CMNINFO_PNP_IN:
0980 pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep = pValue;
0981 break;
0982
0983 case ODM_CMNINFO_INIT_ON:
0984 pDM_Odm->pinit_adpt_in_progress = pValue;
0985 break;
0986
0987 case ODM_CMNINFO_ANT_TEST:
0988 pDM_Odm->pAntennaTest = pValue;
0989 break;
0990
0991 case ODM_CMNINFO_NET_CLOSED:
0992 pDM_Odm->pbNet_closed = pValue;
0993 break;
0994
0995 case ODM_CMNINFO_FORCED_RATE:
0996 pDM_Odm->pForcedDataRate = pValue;
0997 break;
0998
0999 case ODM_CMNINFO_FORCED_IGI_LB:
1000 pDM_Odm->pu1ForcedIgiLb = pValue;
1001 break;
1002
1003 case ODM_CMNINFO_MP_MODE:
1004 pDM_Odm->mp_mode = pValue;
1005 break;
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026 default:
1027
1028 break;
1029 }
1030
1031 }
1032
1033
1034 void ODM_CmnInfoPtrArrayHook(
1035 struct dm_odm_t *pDM_Odm,
1036 enum odm_cmninfo_e CmnInfo,
1037 u16 Index,
1038 void *pValue
1039 )
1040 {
1041
1042
1043
1044 switch (CmnInfo) {
1045
1046
1047
1048 case ODM_CMNINFO_STA_STATUS:
1049 pDM_Odm->pODM_StaInfo[Index] = (PSTA_INFO_T)pValue;
1050 break;
1051
1052 default:
1053
1054 break;
1055 }
1056
1057 }
1058
1059
1060
1061
1062
1063 void ODM_CmnInfoUpdate(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value)
1064 {
1065
1066
1067
1068 switch (CmnInfo) {
1069 case ODM_CMNINFO_LINK_IN_PROGRESS:
1070 pDM_Odm->bLinkInProcess = (bool)Value;
1071 break;
1072
1073 case ODM_CMNINFO_ABILITY:
1074 pDM_Odm->SupportAbility = (u32)Value;
1075 break;
1076
1077 case ODM_CMNINFO_WIFI_DIRECT:
1078 pDM_Odm->bWIFI_Direct = (bool)Value;
1079 break;
1080
1081 case ODM_CMNINFO_WIFI_DISPLAY:
1082 pDM_Odm->bWIFI_Display = (bool)Value;
1083 break;
1084
1085 case ODM_CMNINFO_LINK:
1086 pDM_Odm->bLinked = (bool)Value;
1087 break;
1088
1089 case ODM_CMNINFO_STATION_STATE:
1090 pDM_Odm->bsta_state = (bool)Value;
1091 break;
1092
1093 case ODM_CMNINFO_RSSI_MIN:
1094 pDM_Odm->RSSI_Min = (u8)Value;
1095 break;
1096
1097 case ODM_CMNINFO_RA_THRESHOLD_HIGH:
1098 pDM_Odm->RateAdaptive.HighRSSIThresh = (u8)Value;
1099 break;
1100
1101 case ODM_CMNINFO_RA_THRESHOLD_LOW:
1102 pDM_Odm->RateAdaptive.LowRSSIThresh = (u8)Value;
1103 break;
1104
1105 case ODM_CMNINFO_BT_ENABLED:
1106 pDM_Odm->bBtEnabled = (bool)Value;
1107 break;
1108
1109 case ODM_CMNINFO_BT_HS_CONNECT_PROCESS:
1110 pDM_Odm->bBtConnectProcess = (bool)Value;
1111 break;
1112
1113 case ODM_CMNINFO_BT_HS_RSSI:
1114 pDM_Odm->btHsRssi = (u8)Value;
1115 break;
1116
1117 case ODM_CMNINFO_BT_OPERATION:
1118 pDM_Odm->bBtHsOperation = (bool)Value;
1119 break;
1120
1121 case ODM_CMNINFO_BT_LIMITED_DIG:
1122 pDM_Odm->bBtLimitedDig = (bool)Value;
1123 break;
1124
1125 case ODM_CMNINFO_BT_DISABLE_EDCA:
1126 pDM_Odm->bBtDisableEdcaTurbo = (bool)Value;
1127 break;
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154 default:
1155
1156 break;
1157 }
1158
1159
1160 }
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197