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