1 // Copyright (C) 2022 Beken Corporation
2 //
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
15 #include <common/bk_include.h>
16 #include <components/log.h>
17 #include "param_config.h"
18 #include "bk_drv_model.h"
19 #include "bk_uart.h"
20 #include "bk_wifi_private.h"
21 #include "bk_net_param.h" //TODO should finally remove this include
22 #include "bk_sys_ctrl.h"
23 #include <driver/efuse.h>
24 #include <os/mem.h>
25 #include "bk_phy.h"
26 #include <components/system.h>
27 #include <components/log.h>
28 #if (CONFIG_RANDOM_MAC_ADDR)
29 #include <driver/trng.h>
30 #endif
31
32 #define TAG "mac"
33
34 #if ((CONFIG_SOC_BK7231) && (CONFIG_BASE_MAC_FROM_EFUSE))
35 #error "BK7231 not support efuse!"
36 #endif
37
38 #define DEFAULT_MAC_ADDR "\xC8\x47\x8C\x00\x00\x18"
39 static uint8_t s_base_mac[] = DEFAULT_MAC_ADDR;
40 static bool s_mac_inited = false;
41
42 #if (CONFIG_BASE_MAC_FROM_EFUSE)
write_base_mac_to_efuse(const uint8_t * mac)43 static int write_base_mac_to_efuse(const uint8_t *mac)
44 {
45 #if 0
46 uint8_t efuse_addr = 0;
47 uint8_t efuse_data = 0;
48 int i = 0, ret;
49
50 if (!mac)
51 return BK_ERR_PARAM;
52
53 for (i = 0; i < EFUSE_MAC_LEN; i++) {
54 efuse_addr = EFUSE_MAC_START_ADDR + i;
55 efuse_data = mac[i];
56
57 if (i == 0) {
58 // ensure mac[0]-bit0 in efuse not '1'
59 efuse_data &= ~(0x01);
60 }
61
62 ret = bk_efuse_write_byte(efuse_addr, efuse_data);
63 if (ret != BK_OK) {
64 BK_LOGI(TAG, "efuse set mac failed(%x)\r\n", ret);
65 return ret;
66 }
67 }
68
69 BK_LOGI(TAG, "efuse set mac: "BK_MAC_FORMAT"\n", BK_MAC_STR(mac));
70 return BK_OK;
71 #else
72 BK_LOGI(TAG, "write mac to eufse stub");
73 return BK_OK;
74 #endif
75 }
76
read_base_mac_from_efuse(uint8_t * mac)77 static int read_base_mac_from_efuse(uint8_t *mac)
78 {
79 uint8_t efuse_addr = 0;
80 uint8_t efuse_data = 0;
81 int i = 0, ret;
82
83 if (!mac)
84 return BK_ERR_PARAM;
85
86 for (i = 0; i < BK_MAC_ADDR_LEN; i++) {
87 efuse_addr = EFUSE_MAC_START_ADDR + i;
88 efuse_data = 0;
89
90 ret = bk_efuse_read_byte(efuse_addr, &efuse_data);
91 if (ret == BK_OK)
92 mac[i] = efuse_data;
93 else {
94 os_memset(mac, 0, BK_MAC_ADDR_LEN);
95 mac[i] = 0;
96 BK_LOGE(TAG, "efuse get mac failed(%x)\n", ret);
97 return ret;
98 }
99 }
100
101 BK_LOGI(TAG, "efuse get mac: "BK_MAC_FORMAT"\n", BK_MAC_STR(mac));
102
103 if (BK_IS_ZERO_MAC(mac)) {
104 BK_LOGE(TAG, "efuse MAC all zero, see as error\r\n");
105 return BK_ERR_ZERO_MAC;
106 }
107
108 return BK_OK;
109 }
110 #endif
111
112 #if (CONFIG_BASE_MAC_FROM_RF_OTP_FLASH)
read_base_mac_from_rf_otp_flash(uint8_t * mac)113 static int read_base_mac_from_rf_otp_flash(uint8_t *mac)
114 {
115 if (manual_cal_get_macaddr_from_flash((uint8_t *)mac))
116 return BK_OK;
117 else
118 return BK_FAIL;
119 }
120
write_base_mac_to_rf_otp_flash(const uint8_t * mac)121 static int write_base_mac_to_rf_otp_flash(const uint8_t *mac)
122 {
123 if (manual_cal_write_macaddr_to_flash((uint8_t *)s_base_mac))
124 return BK_OK;
125 else
126 return BK_FAIL;
127 }
128
129 #endif
130
131 #if (CONFIG_BASE_MAC_FROM_NVS)
read_base_mac_from_nvs(uint8_t * mac)132 static int read_base_mac_from_nvs(uint8_t *mac)
133 {
134 uint8_t tmp_mac[8] = {0};
135 if (get_info_item(WIFI_MAC_ITEM, (uint8_t *)tmp_mac, NULL, NULL)) {
136 os_memcpy(mac, tmp_mac, BK_MAC_ADDR_LEN);
137 return BK_OK;
138 } else {
139 return BK_FAIL;
140 }
141 }
142
write_base_mac_to_nvs(const uint8_t * mac)143 static int write_base_mac_to_nvs(const uint8_t *mac)
144 {
145 if (save_info_item(WIFI_MAC_ITEM, (uint8_t *)s_base_mac, NULL, NULL))
146 return BK_OK;
147 else
148 return BK_FAIL;
149 }
150 #endif
151
152 #if (CONFIG_RANDOM_MAC_ADDR)
random_mac_address(u8 * mac)153 static void random_mac_address(u8 *mac)
154 {
155 int i = 0;
156
157 mac[3] = bk_rand() & 0xff;
158 mac[4] = bk_rand() & 0xff;
159 mac[5] = bk_rand() & 0xff;
160
161 os_printf("mac:");
162 for (i = 0; i < 6; i++)
163 os_printf("%02X ", mac[i]);
164 os_printf("\n");
165 }
166 #endif
167
mac_init(void)168 static int mac_init(void)
169 {
170 int ret = BK_FAIL;
171
172 #if (CONFIG_BASE_MAC_FROM_EFUSE)
173 ret = read_base_mac_from_efuse(s_base_mac);
174 #elif (CONFIG_BASE_MAC_FROM_RF_OTP_FLASH)
175 ret = read_base_mac_from_rf_otp_flash(s_base_mac);
176 #elif (CONFIG_BASE_MAC_FROM_NVS)
177 ret = read_base_mac_from_nvs(s_base_mac);
178 #endif
179
180 #if (CONFIG_RANDOM_MAC_ADDR)
181 if ((BK_OK != ret) ||BK_IS_GROUP_MAC(s_base_mac)) {
182 os_memcpy(s_base_mac, DEFAULT_MAC_ADDR, BK_MAC_ADDR_LEN);
183 random_mac_address(s_base_mac);
184 #if (CONFIG_BASE_MAC_FROM_EFUSE)
185 ret = write_base_mac_to_efuse(s_base_mac);
186 #elif (CONFIG_BASE_MAC_FROM_RF_OTP_FLASH)
187 ret = write_base_mac_to_rf_otp_flash(s_base_mac);
188 #elif (CONFIG_BASE_MAC_FROM_NVS)
189 ret = write_base_mac_to_nvs(s_base_mac);
190 #endif
191 BK_LOGI(TAG, "use random mac "BK_MAC_FORMAT" as base mac\n", BK_MAC_STR(s_base_mac));
192 }
193 #else
194 if (BK_OK != ret) {
195 os_memcpy(s_base_mac, DEFAULT_MAC_ADDR, BK_MAC_ADDR_LEN);
196 if (BK_IS_GROUP_MAC(s_base_mac)) {
197 BK_LOGE(TAG, "base mac is group mac"BK_MAC_FORMAT"\n", BK_MAC_STR(s_base_mac));
198 return BK_ERR_GROUP_MAC;
199 } else {
200 BK_LOGI(TAG, "use default mac "BK_MAC_FORMAT" as base mac\n", BK_MAC_STR(s_base_mac));
201 }
202 } else {
203 BK_LOGI(TAG, "base mac "BK_MAC_FORMAT"\n", BK_MAC_STR(s_base_mac));
204 }
205 #endif
206
207 return BK_OK;
208 }
209
bk_get_mac(uint8_t * mac,mac_type_t type)210 bk_err_t bk_get_mac(uint8_t *mac, mac_type_t type)
211 {
212 uint8_t mac_mask = (0xff & (2/*NX_VIRT_DEV_MAX*/ - 1));
213 uint8_t mac_low;
214
215
216 if (s_mac_inited == false) {
217 mac_init();
218 s_mac_inited = true;
219 }
220
221 switch (type) {
222 case MAC_TYPE_BASE:
223 os_memcpy(mac, s_base_mac, BK_MAC_ADDR_LEN);
224 break;
225
226 case MAC_TYPE_AP:
227 mac_mask = (0xff & (2/*NX_VIRT_DEV_MAX*/ - 1));
228
229 os_memcpy(mac, s_base_mac, BK_MAC_ADDR_LEN);
230 mac_low = mac[5];
231
232 // if NX_VIRT_DEV_MAX == 4.
233 // if support AP+STA, mac addr should be equal with each other in byte0-4 & byte5[7:2],
234 // byte5[1:0] can be different
235 // ie: mac[5]= 0xf7, so mac[5] can be 0xf4, f5, f6. here wre chose 0xf4
236 mac[5] &= ~mac_mask;
237 mac_low = ((mac_low & mac_mask) ^ mac_mask);
238 mac[5] |= mac_low;
239 break;
240
241 case MAC_TYPE_STA:
242 os_memcpy(mac, s_base_mac, BK_MAC_ADDR_LEN);
243 break;
244
245 default:
246 return BK_ERR_INVALID_MAC_TYPE;
247 }
248
249 return BK_OK;
250 }
251
bk_set_base_mac(const uint8_t * mac)252 bk_err_t bk_set_base_mac(const uint8_t *mac)
253 {
254 int ret = BK_FAIL;
255
256 if (!mac)
257 return BK_ERR_NULL_PARAM;
258
259 if (BK_IS_GROUP_MAC(mac)) {
260 BK_LOGE(TAG, "set failed, cann't be a bc/mc address\r\n");
261 return BK_ERR_GROUP_MAC;
262 }
263
264 os_memcpy(s_base_mac, mac, BK_MAC_ADDR_LEN);
265
266 #if (CONFIG_BASE_MAC_FROM_EFUSE)
267 ret = write_base_mac_to_efuse(mac);
268 #elif (CONFIG_BASE_MAC_FROM_RF_OTP_FLASH)
269 ret = write_base_mac_to_rf_otp_flash(mac);
270 #elif (CONFIG_BASE_MAC_FROM_NVS)
271 ret = write_base_mac_to_nvs(mac);
272 #endif
273
274 if (ret != BK_OK)
275 BK_LOGE(TAG, "failed to write base mac, ret(%x)\n", ret);
276
277 return ret;
278 }
279
280