1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: mac_addr依赖efuse和ini文件系统(63未支持),当前仅用全局变量暂存
15 * 对应AT命令:cmd_set_macaddr,cmd_get_macaddr
16 */
17 #include "securec.h"
18 #include "errcode.h"
19 #include "soc_osal.h"
20 #include "osal_timer.h"
21 #include "debug_print.h"
22 #include "trng.h"
23 #if defined(CONFIG_MIDDLEWARE_SUPPORT_NV)
24 #include "nv.h"
25 #endif
26 #if defined(CONFIG_DRIVER_SUPPORT_EFUSE)
27 #include "efuse.h"
28 #include "efuse_porting.h"
29 #endif
30 #include "mac_addr.h"
31
32 #ifdef __cplusplus
33 #if __cplusplus
34 extern "C" {
35 #endif
36 #endif
37
38 #define SIZE_8_BITS 8
39 #define WLAN_MAC_ADDR_LEN 6
40 #define WLAN_MAC_MASK_LEN 2
41 #define BIT_8_MASK 0x100
42 #define LOW_8_BITS_MASK 0xFF
43 #define HIGH_MAC_MASK 0xFE
44
45 enum service_nl80211_iftype {
46 SERVICE_NL80211_IFTYPE_UNSPECIFIED,
47 SERVICE_NL80211_IFTYPE_ADHOC,
48 SERVICE_NL80211_IFTYPE_STATION,
49 SERVICE_NL80211_IFTYPE_AP,
50 SERVICE_NL80211_IFTYPE_AP_VLAN,
51 SERVICE_NL80211_IFTYPE_WDS,
52 SERVICE_NL80211_IFTYPE_MONITOR,
53 SERVICE_NL80211_IFTYPE_MESH_POINT,
54 SERVICE_NL80211_IFTYPE_P2P_CLIENT,
55 SERVICE_NL80211_IFTYPE_P2P_GO,
56 SERVICE_NL80211_IFTYPE_P2P_DEVICE,
57 /* keep last */
58 SERVICE_NUM_NL80211_IFTYPES,
59 SERVICE_NL80211_IFTYPE_MAX = SERVICE_NUM_NL80211_IFTYPES - 1
60 };
61
62 typedef enum {
63 ADDR_IDX_STA = 0,
64 ADDR_IDX_BLE = 1,
65 ADDR_IDX_AP = 2,
66 ADDR_IDX_P2P = 3,
67 ADDR_IDX_GLE = 4,
68 ADDR_IDX_BUTT
69 }addr_idx;
70
71 typedef struct {
72 uint8_t ac_addr[WLAN_MAC_ADDR_LEN];
73 uint16_t us_status;
74 }dev_addr_stru;
75
76 dev_addr_stru g_mac_addr = {0};
77 dev_addr_stru g_ap_dev_addr = {0};
78 dev_addr_stru g_p2p_dev_addr = {0};
79 mac_derivation_ptr g_mac_derivation_ptr = NULL;
80
set_mac_derivation_ptr(mac_derivation_ptr ptr)81 void set_mac_derivation_ptr(mac_derivation_ptr ptr)
82 {
83 g_mac_derivation_ptr = ptr;
84 }
85
mac_addr_is_zero(const uint8_t * mac_addr)86 static uint8_t mac_addr_is_zero(const uint8_t *mac_addr)
87 {
88 uint8_t zero_mac_addr[WLAN_MAC_ADDR_LEN] = {0};
89 return (memcmp(zero_mac_addr, mac_addr, WLAN_MAC_ADDR_LEN) == 0);
90 }
91
92 #if defined(CONFIG_MIDDLEWARE_SUPPORT_NV)
mac_addr_nv_check(uint8_t * mac_addr)93 static uint32_t mac_addr_nv_check(uint8_t *mac_addr)
94 {
95 uint8_t zero_mac_addr[WLAN_MAC_ADDR_LEN] = {0};
96 uint8_t one_mac_addr[WLAN_MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
97 if (memcmp(zero_mac_addr, mac_addr, WLAN_MAC_ADDR_LEN) == 0) {
98 return ERRCODE_FAIL;
99 }
100 if (memcmp(one_mac_addr, mac_addr, WLAN_MAC_ADDR_LEN) == 0) {
101 if (memcpy_s(mac_addr, WLAN_MAC_ADDR_LEN, zero_mac_addr, WLAN_MAC_ADDR_LEN) != EOK) {
102 PRINT("{mac_addr_nv_check failed !}\n");
103 return ERRCODE_MEMCPY;
104 }
105 return ERRCODE_FAIL;
106 }
107 return ERRCODE_SUCC;
108 }
109 #endif
110
111 #if defined(CONFIG_DRIVER_SUPPORT_EFUSE)
get_mac_from_efuse(uint8_t mac[],uint8_t mac_len)112 static uint32_t get_mac_from_efuse(uint8_t mac[], uint8_t mac_len)
113 {
114 uint8_t index;
115 uint16_t efuse_index;
116
117 for (index = 0; index < EFUSE_MAC_NUM; index++) {
118 efuse_index = EFUSE_MAC_ADDR_LAST_ID - index;
119 if (efuse_read_item(efuse_index, mac, mac_len) == ERRCODE_SUCC) {
120 if (mac_addr_is_zero(mac) == ERRCODE_SUCC) {
121 return ERRCODE_SUCC;
122 }
123 }
124 }
125 return ERRCODE_FAIL;
126 }
127 #endif
128
random_ether_addr(uint8_t * addr,uint32_t addr_length)129 static void random_ether_addr(uint8_t *addr, uint32_t addr_length)
130 {
131 uapi_drv_cipher_trng_get_random_bytes(addr, addr_length);
132 }
133
get_dev_addr_idx(uint8_t type)134 static addr_idx get_dev_addr_idx(uint8_t type)
135 {
136 addr_idx addr_idx = ADDR_IDX_BUTT;
137
138 switch (type) {
139 case SERVICE_NL80211_IFTYPE_STATION:
140 addr_idx = ADDR_IDX_STA;
141 break;
142 case SERVICE_NL80211_IFTYPE_AP:
143 addr_idx = ADDR_IDX_AP;
144 break;
145 case SERVICE_NL80211_IFTYPE_P2P_CLIENT:
146 case SERVICE_NL80211_IFTYPE_P2P_GO:
147 case SERVICE_NL80211_IFTYPE_P2P_DEVICE:
148 case SERVICE_NL80211_IFTYPE_MESH_POINT:
149 addr_idx = ADDR_IDX_P2P;
150 break;
151 case IFTYPE_BLE:
152 addr_idx = ADDR_IDX_BLE;
153 break;
154 default:
155 PRINT("get_dev_addr_idx iftype error!!!\n");
156 break;
157 }
158
159 return addr_idx;
160 }
161
mac_carry(uint16_t * mac_low,uint16_t * mac_high)162 static void mac_carry(uint16_t *mac_low, uint16_t *mac_high)
163 {
164 (*mac_high) += (((*mac_low) & BIT_8_MASK) >> SIZE_8_BITS);
165 (*mac_low) = (*mac_low) & LOW_8_BITS_MASK;
166 }
167
168 #define WIFI_MAC_ADDR_DERIVE_BIT 4
169 #define BLE_MAC_ADDR_DERIVE_BIT 5
get_derived_mac(uint8_t mac[],uint8_t mac_len,addr_idx idx)170 static uint32_t get_derived_mac(uint8_t mac[], uint8_t mac_len, addr_idx idx)
171 {
172 uint16_t us_addr[WLAN_MAC_ADDR_LEN];
173 uint32_t tmp;
174 uint8_t derive_bit = ((idx == ADDR_IDX_BLE) ? BLE_MAC_ADDR_DERIVE_BIT : WIFI_MAC_ADDR_DERIVE_BIT);
175
176 if (mac_len != WLAN_MAC_ADDR_LEN) {
177 PRINT("get_dev_addr::get_derived_mac, error mac_len != 6.\n");
178 return ERRCODE_FAIL;
179 }
180
181 for (tmp = 0; tmp < WLAN_MAC_ADDR_LEN; tmp++) {
182 us_addr[tmp] = (uint16_t)g_mac_addr.ac_addr[tmp];
183 }
184 us_addr[derive_bit] += (uint16_t)idx; // 4 字节增加idx
185 for (tmp = derive_bit; tmp > 0; tmp--) {
186 mac_carry(&(us_addr[tmp]), &(us_addr[tmp - 1]));
187 }
188 if (us_addr[0] > LOW_8_BITS_MASK) {
189 us_addr[0] = 0;
190 }
191 if (idx != ADDR_IDX_BLE) {
192 us_addr[0] &= HIGH_MAC_MASK;
193 }
194 for (tmp = 0; tmp < WLAN_MAC_ADDR_LEN; tmp++) {
195 mac[tmp] = (uint8_t)us_addr[tmp];
196 }
197 return ERRCODE_SUCC;
198 }
199
get_dev_addr(uint8_t * pc_addr,uint8_t addr_len,uint8_t type)200 uint32_t get_dev_addr(uint8_t *pc_addr, uint8_t addr_len, uint8_t type)
201 {
202 uint32_t tmp;
203 uint8_t zero_mac[WLAN_MAC_ADDR_LEN] = {0};
204 addr_idx addr_idx;
205 if (pc_addr == NULL) {
206 PRINT("pc_addr == NULL)!!!\n");
207 return ERRCODE_FAIL;
208 }
209
210 if ((type == SERVICE_NL80211_IFTYPE_AP) && (memcmp(g_ap_dev_addr.ac_addr, zero_mac, WLAN_MAC_ADDR_LEN) != 0)) {
211 for (tmp = 0; tmp < WLAN_MAC_ADDR_LEN; tmp++) {
212 pc_addr[tmp] = g_ap_dev_addr.ac_addr[tmp];
213 }
214 return ERRCODE_SUCC;
215 }
216
217 if (((type == SERVICE_NL80211_IFTYPE_MESH_POINT) || (type == SERVICE_NL80211_IFTYPE_P2P_CLIENT) ||
218 (type == SERVICE_NL80211_IFTYPE_P2P_GO) || (type == SERVICE_NL80211_IFTYPE_P2P_DEVICE)) &&
219 (memcmp(g_p2p_dev_addr.ac_addr, zero_mac, WLAN_MAC_ADDR_LEN) != 0)) {
220 for (tmp = 0; tmp < WLAN_MAC_ADDR_LEN; tmp++) {
221 pc_addr[tmp] = g_p2p_dev_addr.ac_addr[tmp];
222 }
223 return ERRCODE_SUCC;
224 }
225
226 addr_idx = get_dev_addr_idx(type);
227 if (addr_idx >= ADDR_IDX_BUTT) {
228 PRINT("type=%d,error!!!\n", type);
229 return ERRCODE_FAIL;
230 }
231 if (g_mac_derivation_ptr != NULL) {
232 return g_mac_derivation_ptr(g_mac_addr.ac_addr, WLAN_MAC_ADDR_LEN, type, pc_addr, WLAN_MAC_ADDR_LEN);
233 } else {
234 return get_derived_mac(pc_addr, addr_len, addr_idx);
235 }
236 }
237
mac_addr_check(const uint8_t * pc_addr,uint8_t mac_len)238 static uint32_t mac_addr_check(const uint8_t *pc_addr, uint8_t mac_len)
239 {
240 uint8_t zero_mac[WLAN_MAC_ADDR_LEN] = {0};
241 uint8_t broadcast_mac[WLAN_MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
242
243 if ((pc_addr[0] & 0x1) == 0x1) {
244 PRINT("Multicast mac addr not support!!!\r\n");
245 return ERRCODE_FAIL;
246 }
247 if (memcmp(pc_addr, broadcast_mac, mac_len) == ERRCODE_SUCC) {
248 PRINT("Broadcast mac addr not support!!!\r\n");
249 return ERRCODE_FAIL;
250 }
251 if (memcmp(pc_addr, zero_mac, mac_len) == ERRCODE_SUCC) {
252 PRINT("Zero mac addr not support!!!\r\n");
253 return ERRCODE_FAIL;
254 }
255 return ERRCODE_SUCC;
256 }
257
258
set_dev_addr(const uint8_t * pc_addr,uint8_t mac_len,uint8_t type)259 uint32_t set_dev_addr(const uint8_t *pc_addr, uint8_t mac_len, uint8_t type)
260 {
261 if (mac_addr_check(pc_addr, mac_len) != ERRCODE_SUCC) {
262 return ERRCODE_FAIL;
263 }
264 if (type == SERVICE_NL80211_IFTYPE_AP) {
265 if (memcpy_s(g_ap_dev_addr.ac_addr, WLAN_MAC_ADDR_LEN, pc_addr, mac_len) != ERRCODE_SUCC) {
266 return ERRCODE_FAIL;
267 } else {
268 return ERRCODE_SUCC;
269 }
270 } else if ((type == SERVICE_NL80211_IFTYPE_MESH_POINT) || (type == SERVICE_NL80211_IFTYPE_P2P_CLIENT) ||
271 (type == SERVICE_NL80211_IFTYPE_P2P_GO) || (type == SERVICE_NL80211_IFTYPE_P2P_DEVICE)) {
272 if (memcpy_s(g_p2p_dev_addr.ac_addr, WLAN_MAC_ADDR_LEN, pc_addr, mac_len) != ERRCODE_SUCC) {
273 return ERRCODE_FAIL;
274 } else {
275 return ERRCODE_SUCC;
276 }
277 } else {
278 if (memcpy_s(g_mac_addr.ac_addr, WLAN_MAC_ADDR_LEN, pc_addr, mac_len) != ERRCODE_SUCC) {
279 return ERRCODE_FAIL;
280 } else {
281 return ERRCODE_SUCC;
282 }
283 }
284 }
285
286 /*****************************************************************************
287 功能描述 : 随机化初始mac地址 让单板启动时携带默认mac
288 获取优先级:配置文件-->读efuse-->随机生成
289 *****************************************************************************/
290 #define RANDOM_DEFOURT_MAC1 0x00
291 #define RANDOM_DEFOURT_MAC2 0x73
init_dev_addr(void)292 void init_dev_addr(void)
293 {
294 uint8_t index;
295 errcode_t get_mac_res = ERRCODE_FAIL;
296
297 #if defined(CONFIG_MIDDLEWARE_SUPPORT_NV)
298 uint16_t nv_mac_length;
299 if (mac_addr_is_zero(g_mac_addr.ac_addr) != 0) {
300 uapi_nv_read(NV_ID_SYSTEM_FACTORY_MAC, WLAN_MAC_ADDR_LEN, &nv_mac_length, &(g_mac_addr.ac_addr[0]));
301 get_mac_res = mac_addr_nv_check(&(g_mac_addr.ac_addr[0]));
302 }
303 #endif
304
305 #if defined(CONFIG_DRIVER_SUPPORT_EFUSE)
306 if (get_mac_res != ERRCODE_SUCC) {
307 get_mac_res = get_mac_from_efuse(&(g_mac_addr.ac_addr[0]), WLAN_MAC_ADDR_LEN);
308 }
309 #endif
310
311 if (get_mac_res != ERRCODE_SUCC) {
312 random_ether_addr(g_mac_addr.ac_addr, WLAN_MAC_ADDR_LEN);
313 g_mac_addr.ac_addr[1] = RANDOM_DEFOURT_MAC1; /* 1 地址第2位 0x00 */
314 g_mac_addr.ac_addr[2] = RANDOM_DEFOURT_MAC2; /* 2 地址第3位 0x73 */
315 g_mac_addr.us_status = 0;
316 get_mac_res = ERRCODE_SUCC;
317 }
318
319 PRINT("init_dev_addr, mac_addr:");
320 for (index = 0; index < WLAN_MAC_ADDR_LEN - WLAN_MAC_MASK_LEN; index++) {
321 print_str("0x%2x,", g_mac_addr.ac_addr[index]);
322 }
323 for (index = WLAN_MAC_ADDR_LEN - WLAN_MAC_MASK_LEN; index < WLAN_MAC_ADDR_LEN; index++) {
324 print_str("0x**,", g_mac_addr.ac_addr[index]);
325 }
326 print_str("\r\n");
327 }
328
329 #ifdef __cplusplus
330 #if __cplusplus
331 }
332 #endif
333 #endif