• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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