1 // SPDX-License-Identifier: GPL-2.0
2 /* Implement 802.11d. */
6 void Dot11d_Init(struct ieee80211_device
*ieee
)
8 PRT_DOT11D_INFO pDot11dInfo
= GET_DOT11D_INFO(ieee
);
10 pDot11dInfo
->bEnabled
= false;
12 pDot11dInfo
->State
= DOT11D_STATE_NONE
;
13 pDot11dInfo
->CountryIeLen
= 0;
14 memset(pDot11dInfo
->channel_map
, 0, MAX_CHANNEL_NUMBER
+1);
15 memset(pDot11dInfo
->MaxTxPwrDbmList
, 0xFF, MAX_CHANNEL_NUMBER
+1);
16 RESET_CIE_WATCHDOG(ieee
);
18 netdev_info(ieee
->dev
, "Dot11d_Init()\n");
20 EXPORT_SYMBOL(Dot11d_Init
);
22 /* Reset to the state as we are just entering a regulatory domain. */
23 void Dot11d_Reset(struct ieee80211_device
*ieee
)
26 PRT_DOT11D_INFO pDot11dInfo
= GET_DOT11D_INFO(ieee
);
27 /* Clear old channel map */
28 memset(pDot11dInfo
->channel_map
, 0, MAX_CHANNEL_NUMBER
+1);
29 memset(pDot11dInfo
->MaxTxPwrDbmList
, 0xFF, MAX_CHANNEL_NUMBER
+1);
30 /* Set new channel map */
31 for (i
= 1; i
<= 11; i
++)
32 (pDot11dInfo
->channel_map
)[i
] = 1;
34 for (i
= 12; i
<= 14; i
++)
35 (pDot11dInfo
->channel_map
)[i
] = 2;
37 pDot11dInfo
->State
= DOT11D_STATE_NONE
;
38 pDot11dInfo
->CountryIeLen
= 0;
39 RESET_CIE_WATCHDOG(ieee
);
41 EXPORT_SYMBOL(Dot11d_Reset
);
44 * Update country IE from Beacon or Probe Resopnse and configure PHY for
45 * operation in the regulatory domain.
47 * TODO: Configure Tx power.
49 * 1. IS_DOT11D_ENABLE() is TRUE.
50 * 2. Input IE is an valid one.
52 void Dot11d_UpdateCountryIe(struct ieee80211_device
*dev
, u8
*pTaddr
,
53 u16 CoutryIeLen
, u8
*pCoutryIe
)
55 PRT_DOT11D_INFO pDot11dInfo
= GET_DOT11D_INFO(dev
);
56 u8 i
, j
, NumTriples
, MaxChnlNum
;
57 PCHNL_TXPOWER_TRIPLE pTriple
;
59 memset(pDot11dInfo
->channel_map
, 0, MAX_CHANNEL_NUMBER
+1);
60 memset(pDot11dInfo
->MaxTxPwrDbmList
, 0xFF, MAX_CHANNEL_NUMBER
+1);
62 NumTriples
= (CoutryIeLen
- 3) / 3; /* skip 3-byte country string. */
63 pTriple
= (PCHNL_TXPOWER_TRIPLE
)(pCoutryIe
+ 3);
64 for (i
= 0; i
< NumTriples
; i
++) {
65 if (MaxChnlNum
>= pTriple
->FirstChnl
) {
66 /* It is not in a monotonically increasing order, so
69 netdev_err(dev
->dev
, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
72 if (MAX_CHANNEL_NUMBER
< (pTriple
->FirstChnl
+ pTriple
->NumChnls
)) {
73 /* It is not a valid set of channel id, so stop
76 netdev_err(dev
->dev
, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
80 for (j
= 0; j
< pTriple
->NumChnls
; j
++) {
81 pDot11dInfo
->channel_map
[pTriple
->FirstChnl
+ j
] = 1;
82 pDot11dInfo
->MaxTxPwrDbmList
[pTriple
->FirstChnl
+ j
] = pTriple
->MaxTxPowerInDbm
;
83 MaxChnlNum
= pTriple
->FirstChnl
+ j
;
86 pTriple
= (PCHNL_TXPOWER_TRIPLE
)((u8
*)pTriple
+ 3);
88 netdev_info(dev
->dev
, "Channel List:");
89 for (i
= 1; i
<= MAX_CHANNEL_NUMBER
; i
++)
90 if (pDot11dInfo
->channel_map
[i
] > 0)
91 netdev_info(dev
->dev
, " %d", i
);
92 netdev_info(dev
->dev
, "\n");
94 UPDATE_CIE_SRC(dev
, pTaddr
);
96 pDot11dInfo
->CountryIeLen
= CoutryIeLen
;
97 memcpy(pDot11dInfo
->CountryIeBuf
, pCoutryIe
, CoutryIeLen
);
98 pDot11dInfo
->State
= DOT11D_STATE_LEARNED
;
100 EXPORT_SYMBOL(Dot11d_UpdateCountryIe
);
102 u8
DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device
*dev
, u8 Channel
)
104 PRT_DOT11D_INFO pDot11dInfo
= GET_DOT11D_INFO(dev
);
105 u8 MaxTxPwrInDbm
= 255;
107 if (Channel
> MAX_CHANNEL_NUMBER
) {
108 netdev_err(dev
->dev
, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
109 return MaxTxPwrInDbm
;
111 if (pDot11dInfo
->channel_map
[Channel
])
112 MaxTxPwrInDbm
= pDot11dInfo
->MaxTxPwrDbmList
[Channel
];
114 return MaxTxPwrInDbm
;
116 EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm
);
118 void DOT11D_ScanComplete(struct ieee80211_device
*dev
)
120 PRT_DOT11D_INFO pDot11dInfo
= GET_DOT11D_INFO(dev
);
122 switch (pDot11dInfo
->State
) {
123 case DOT11D_STATE_LEARNED
:
124 pDot11dInfo
->State
= DOT11D_STATE_DONE
;
127 case DOT11D_STATE_DONE
:
128 if (GET_CIE_WATCHDOG(dev
) == 0) {
129 /* Reset country IE if previous one is gone. */
133 case DOT11D_STATE_NONE
:
137 EXPORT_SYMBOL(DOT11D_ScanComplete
);
139 int IsLegalChannel(struct ieee80211_device
*dev
, u8 channel
)
141 PRT_DOT11D_INFO pDot11dInfo
= GET_DOT11D_INFO(dev
);
143 if (channel
> MAX_CHANNEL_NUMBER
) {
144 netdev_err(dev
->dev
, "IsLegalChannel(): Invalid Channel\n");
147 if (pDot11dInfo
->channel_map
[channel
] > 0)
151 EXPORT_SYMBOL(IsLegalChannel
);
153 int ToLegalChannel(struct ieee80211_device
*dev
, u8 channel
)
155 PRT_DOT11D_INFO pDot11dInfo
= GET_DOT11D_INFO(dev
);
159 for (i
= 1; i
<= MAX_CHANNEL_NUMBER
; i
++) {
160 if (pDot11dInfo
->channel_map
[i
] > 0) {
166 if (channel
> MAX_CHANNEL_NUMBER
) {
167 netdev_err(dev
->dev
, "IsLegalChannel(): Invalid Channel\n");
171 if (pDot11dInfo
->channel_map
[channel
] > 0)
176 EXPORT_SYMBOL(ToLegalChannel
);