📄 spectrum.c
字号:
/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * Taiwan, R.O.C. * * (c) Copyright 2002-2007, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ************************************************************************* Module Name: action.c Abstract: Handle association related requests either from WSTA or from local MLME Revision History: Who When What --------- ---------- ---------------------------------------------- Fonchi Wu 2008 created for 802.11h */#include "rt_config.h"#include "action.h"/* The regulatory information in the USA (US) */DOT11_REGULATORY_INFORMATION USARegulatoryInfo[] = {/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ {0, {0, 0, {0}}}, // Invlid entry {1, {4, 16, {36, 40, 44, 48}}}, {2, {4, 23, {52, 56, 60, 64}}}, {3, {4, 29, {149, 153, 157, 161}}}, {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, {5, {5, 30, {149, 153, 157, 161, 165}}}, {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}, {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}, {8, {5, 17, {11, 13, 15, 17, 19}}}, {9, {5, 30, {11, 13, 15, 17, 19}}}, {10, {2, 20, {21, 25}}}, {11, {2, 33, {21, 25}}}, {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}}};#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))/* The regulatory information in Europe */DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo[] = {/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ {0, {0, 0, {0}}}, // Invalid entry {1, {4, 20, {36, 40, 44, 48}}}, {2, {4, 20, {52, 56, 60, 64}}}, {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}};#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))/* The regulatory information in Japan */DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo[] = {/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ {0, {0, 0, {0}}}, // Invalid entry {1, {4, 22, {34, 38, 42, 46}}}, {2, {3, 24, {8, 12, 16}}}, {3, {3, 24, {8, 12, 16}}}, {4, {3, 24, {8, 12, 16}}}, {5, {3, 24, {8, 12, 16}}}, {6, {3, 22, {8, 12, 16}}}, {7, {4, 24, {184, 188, 192, 196}}}, {8, {4, 24, {184, 188, 192, 196}}}, {9, {4, 24, {184, 188, 192, 196}}}, {10, {4, 24, {184, 188, 192, 196}}}, {11, {4, 22, {184, 188, 192, 196}}}, {12, {4, 24, {7, 8, 9, 11}}}, {13, {4, 24, {7, 8, 9, 11}}}, {14, {4, 24, {7, 8, 9, 11}}}, {15, {4, 24, {7, 8, 9, 11}}}, {16, {6, 24, {183, 184, 185, 187, 188, 189}}}, {17, {6, 24, {183, 184, 185, 187, 188, 189}}}, {18, {6, 24, {183, 184, 185, 187, 188, 189}}}, {19, {6, 24, {183, 184, 185, 187, 188, 189}}}, {20, {6, 17, {183, 184, 185, 187, 188, 189}}}, {21, {6, 24, {6, 7, 8, 9, 10, 11}}}, {22, {6, 24, {6, 7, 8, 9, 10, 11}}}, {23, {6, 24, {6, 7, 8, 9, 10, 11}}}, {24, {6, 24, {6, 7, 8, 9, 10, 11}}}, {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}}}, {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}, {31, {1, 23, {14}}}, {32, {4, 22, {52, 56, 60, 64}}}};#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))CHAR RTMP_GetTxPwr( IN PRTMP_ADAPTER pAd, IN HTTRANSMIT_SETTING HTTxMode){typedef struct __TX_PWR_CFG{ UINT8 Mode; UINT8 MCS; UINT16 req; UINT8 shift; UINT32 BitMask;} TX_PWR_CFG; UINT32 Value; INT Idx; UINT8 PhyMode; CHAR CurTxPwr; UINT8 TxPwrRef = 0; CHAR DaltaPwr; ULONG TxPwr[5]; TX_PWR_CFG TxPwrCfg[] = { {MODE_CCK, 0, 0, 4, 0x000000f0}, {MODE_CCK, 1, 0, 0, 0x0000000f}, {MODE_CCK, 2, 0, 12, 0x0000f000}, {MODE_CCK, 3, 0, 8, 0x00000f00}, {MODE_OFDM, 0, 0, 20, 0x00f00000}, {MODE_OFDM, 1, 0, 16, 0x000f0000}, {MODE_OFDM, 2, 0, 28, 0xf0000000}, {MODE_OFDM, 3, 0, 24, 0x0f000000}, {MODE_OFDM, 4, 1, 4, 0x000000f0}, {MODE_OFDM, 5, 1, 0, 0x0000000f}, {MODE_OFDM, 6, 1, 12, 0x0000f000}, {MODE_OFDM, 7, 1, 8, 0x00000f00}, {MODE_HTMIX, 0, 1, 20, 0x00f00000}, {MODE_HTMIX, 1, 1, 16, 0x000f0000}, {MODE_HTMIX, 2, 1, 28, 0xf0000000}, {MODE_HTMIX, 3, 1, 24, 0x0f000000}, {MODE_HTMIX, 4, 2, 4, 0x000000f0}, {MODE_HTMIX, 5, 2, 0, 0x0000000f}, {MODE_HTMIX, 6, 2, 12, 0x0000f000}, {MODE_HTMIX, 7, 2, 8, 0x00000f00}, {MODE_HTMIX, 8, 2, 20, 0x00f00000}, {MODE_HTMIX, 9, 2, 16, 0x000f0000}, {MODE_HTMIX, 10, 2, 28, 0xf0000000}, {MODE_HTMIX, 11, 2, 24, 0x0f000000}, {MODE_HTMIX, 12, 3, 4, 0x000000f0}, {MODE_HTMIX, 13, 3, 0, 0x0000000f}, {MODE_HTMIX, 14, 3, 12, 0x0000f000}, {MODE_HTMIX, 15, 3, 8, 0x00000f00} };#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG))#ifdef SINGLE_SKU CurTxPwr = pAd->CommonCfg.DefineMaxTxPwr;#else CurTxPwr = 19;#endif /* check Tx Power setting from UI. */ if (pAd->CommonCfg.TxPowerPercentage > 90) ; else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */ CurTxPwr -= 1; else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */ CurTxPwr -= 3; else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */ CurTxPwr -= 6; else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */ CurTxPwr -= 9; else /* reduce Pwr for 12 dB. */ CurTxPwr -= 12; if (pAd->CommonCfg.BBPCurrentBW == BW_40) { if (pAd->CommonCfg.CentralChannel > 14) { TxPwr[0] = pAd->Tx40MPwrCfgABand[0]; TxPwr[1] = pAd->Tx40MPwrCfgABand[1]; TxPwr[2] = pAd->Tx40MPwrCfgABand[2]; TxPwr[3] = pAd->Tx40MPwrCfgABand[3]; TxPwr[4] = pAd->Tx40MPwrCfgABand[4]; } else { TxPwr[0] = pAd->Tx40MPwrCfgGBand[0]; TxPwr[1] = pAd->Tx40MPwrCfgGBand[1]; TxPwr[2] = pAd->Tx40MPwrCfgGBand[2]; TxPwr[3] = pAd->Tx40MPwrCfgGBand[3]; TxPwr[4] = pAd->Tx40MPwrCfgGBand[4]; } } else { if (pAd->CommonCfg.Channel > 14) { TxPwr[0] = pAd->Tx20MPwrCfgABand[0]; TxPwr[1] = pAd->Tx20MPwrCfgABand[1]; TxPwr[2] = pAd->Tx20MPwrCfgABand[2]; TxPwr[3] = pAd->Tx20MPwrCfgABand[3]; TxPwr[4] = pAd->Tx20MPwrCfgABand[4]; } else { TxPwr[0] = pAd->Tx20MPwrCfgGBand[0]; TxPwr[1] = pAd->Tx20MPwrCfgGBand[1]; TxPwr[2] = pAd->Tx20MPwrCfgGBand[2]; TxPwr[3] = pAd->Tx20MPwrCfgGBand[3]; TxPwr[4] = pAd->Tx20MPwrCfgGBand[4]; } } switch(HTTxMode.field.MODE) { case MODE_CCK: case MODE_OFDM: Value = TxPwr[1]; TxPwrRef = (Value & 0x00000f00) >> 8; break;#ifdef DOT11_N_SUPPORT case MODE_HTMIX: case MODE_HTGREENFIELD: if (pAd->CommonCfg.TxStream == 1) { Value = TxPwr[2]; TxPwrRef = (Value & 0x00000f00) >> 8; } else if (pAd->CommonCfg.TxStream == 2) { Value = TxPwr[3]; TxPwrRef = (Value & 0x00000f00) >> 8; } break;#endif // DOT11_N_SUPPORT // } PhyMode =#ifdef DOT11_N_SUPPORT (HTTxMode.field.MODE == MODE_HTGREENFIELD) ? MODE_HTMIX :#endif // DOT11_N_SUPPORT // HTTxMode.field.MODE; for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) { if ((TxPwrCfg[Idx].Mode == PhyMode) && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) { Value = TxPwr[TxPwrCfg[Idx].req]; DaltaPwr = TxPwrRef - (CHAR)((Value & TxPwrCfg[Idx].BitMask) >> TxPwrCfg[Idx].shift); CurTxPwr -= DaltaPwr; break; } } return CurTxPwr;}VOID MeasureReqTabInit( IN PRTMP_ADAPTER pAd){ NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock); pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC); if (pAd->CommonCfg.pMeasureReqTab) NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB)); else DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__)); return;}VOID MeasureReqTabExit( IN PRTMP_ADAPTER pAd){ NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock); if (pAd->CommonCfg.pMeasureReqTab) kfree(pAd->CommonCfg.pMeasureReqTab); pAd->CommonCfg.pMeasureReqTab = NULL; return;}PMEASURE_REQ_ENTRY MeasureReqLookUp( IN PRTMP_ADAPTER pAd, IN UINT8 DialogToken){ UINT HashIdx; PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; PMEASURE_REQ_ENTRY pEntry = NULL; PMEASURE_REQ_ENTRY pPrevEntry = NULL; if (pTab == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__)); return NULL; } RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken); pEntry = pTab->Hash[HashIdx]; while (pEntry) { if (pEntry->DialogToken == DialogToken) break; else { pPrevEntry = pEntry; pEntry = pEntry->pNext; } } RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); return pEntry;}PMEASURE_REQ_ENTRY MeasureReqInsert( IN PRTMP_ADAPTER pAd, IN UINT8 DialogToken){ INT i; ULONG HashIdx; PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry; ULONG Now; if(pTab == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__)); return NULL; } pEntry = MeasureReqLookUp(pAd, DialogToken); if (pEntry == NULL) { RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) { NdisGetSystemUpTime(&Now); pEntry = &pTab->Content[i]; if ((pEntry->Valid == TRUE) && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT))) { PMEASURE_REQ_ENTRY pPrevEntry = NULL; ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; // update Hash list do { if (pProbeEntry == pEntry) { if (pPrevEntry == NULL) { pTab->Hash[HashIdx] = pEntry->pNext; } else { pPrevEntry->pNext = pEntry->pNext; } break; } pPrevEntry = pProbeEntry; pProbeEntry = pProbeEntry->pNext; } while (pProbeEntry); NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY)); pTab->Size--; break; } if (pEntry->Valid == FALSE) break; } if (i < MAX_MEASURE_REQ_TAB_SIZE) { NdisGetSystemUpTime(&Now); pEntry->lastTime = Now; pEntry->Valid = TRUE; pEntry->DialogToken = DialogToken; pTab->Size++; } else { pEntry = NULL; DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__)); } // add this Neighbor entry into HASH table if (pEntry) { HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken); if (pTab->Hash[HashIdx] == NULL) { pTab->Hash[HashIdx] = pEntry; } else { pCurrEntry = pTab->Hash[HashIdx]; while (pCurrEntry->pNext != NULL) pCurrEntry = pCurrEntry->pNext; pCurrEntry->pNext = pEntry; } } RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); } return pEntry;}VOID MeasureReqDelete( IN PRTMP_ADAPTER pAd, IN UINT8 DialogToken){ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; PMEASURE_REQ_ENTRY pEntry = NULL; if(pTab == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__)); return; } // if empty, return if (pTab->Size == 0) { DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n")); return; } pEntry = MeasureReqLookUp(pAd, DialogToken); if (pEntry != NULL) { PMEASURE_REQ_ENTRY pPrevEntry = NULL; ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); // update Hash list do { if (pProbeEntry == pEntry) { if (pPrevEntry == NULL) { pTab->Hash[HashIdx] = pEntry->pNext; } else { pPrevEntry->pNext = pEntry->pNext; } break; } pPrevEntry = pProbeEntry; pProbeEntry = pProbeEntry->pNext; } while (pProbeEntry); NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY)); pTab->Size--; RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); } return;}VOID TpcReqTabInit( IN PRTMP_ADAPTER pAd){ NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock); pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC); if (pAd->CommonCfg.pTpcReqTab) NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB)); else DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__)); return;}VOID TpcReqTabExit( IN PRTMP_ADAPTER pAd){ NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock); if (pAd->CommonCfg.pTpcReqTab) kfree(pAd->CommonCfg.pTpcReqTab); pAd->CommonCfg.pTpcReqTab = NULL; return;}static PTPC_REQ_ENTRY TpcReqLookUp( IN PRTMP_ADAPTER pAd, IN UINT8 DialogToken){ UINT HashIdx; PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab; PTPC_REQ_ENTRY pEntry = NULL; PTPC_REQ_ENTRY pPrevEntry = NULL; if (pTab == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__)); return NULL; } RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken); pEntry = pTab->Hash[HashIdx]; while (pEntry) { if (pEntry->DialogToken == DialogToken) break; else { pPrevEntry = pEntry; pEntry = pEntry->pNext; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -