xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/vendor.c (revision f36ea2f6e17621c4d9dd97c4dbfab62d03d061df)
1 /*
2  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <malloc.h>
9 #include <asm/arch/vendor.h>
10 #include <boot_rkimg.h>
11 #include <nand.h>
12 #include <part.h>
13 
14 /* tag for vendor check */
15 #define VENDOR_TAG		0x524B5644
16 /* The Vendor partition contains the number of Vendor blocks */
17 #define MTD_VENDOR_PART_NUM	1
18 #define NAND_VENDOR_PART_NUM	2
19 #define VENDOR_PART_NUM		4
20 /* align to 64 bytes */
21 #define VENDOR_BTYE_ALIGN	0x3F
22 #define VENDOR_BLOCK_SIZE	512
23 
24 /* --- Emmc define --- */
25 /* Starting address of the Vendor in memory. */
26 #define EMMC_VENDOR_PART_OFFSET		(1024 * 7)
27 /*
28  * The number of memory blocks used by each
29  * Vendor structure(128 * 512B = 64KB)
30  */
31 #define EMMC_VENDOR_PART_BLKS		128
32 /* The maximum number of items in each Vendor block */
33 #define EMMC_VENDOR_ITEM_NUM		126
34 
35 /* --- Spi Nand/SLC/MLC large capacity case define --- */
36 /* The Vendor partition contains the number of Vendor blocks */
37 #define NAND_VENDOR_PART_OFFSET		0
38 /*
39  * The number of memory blocks used by each
40  * Vendor structure(8 * 512B = 4KB)
41  */
42 #define NAND_VENDOR_PART_BLKS		128
43 /* The maximum number of items in each Vendor block */
44 #define NAND_VENDOR_ITEM_NUM		126
45 
46 /* --- Spi/Spi Nand/SLC/MLC small capacity case define --- */
47 /* The Vendor partition contains the number of Vendor blocks */
48 #define	FLASH_VENDOR_PART_OFFSET	8
49 /*
50  * The number of memory blocks used by each
51  * Vendor structure(8 * 512B = 4KB)
52  */
53 #define FLASH_VENDOR_PART_BLKS		8
54 /* The maximum number of items in each Vendor block */
55 #define FLASH_VENDOR_ITEM_NUM		62
56 
57 /* Vendor uinit test define */
58 int vendor_storage_test(void);
59 
60 struct vendor_hdr {
61 	u32	tag;
62 	u32	version;
63 	u16	next_index;
64 	u16	item_num;
65 	u16	free_offset; /* Free space offset */
66 	u16	free_size; /* Free space size */
67 };
68 
69 /*
70  * Different types of Flash vendor info are different.
71  * EMMC:EMMC_VENDOR_PART_BLKS * BLOCK_SIZE(512) = 64KB;
72  * Spi Nor/Spi Nand/SLC/MLC: FLASH_VENDOR_PART_BLKS *
73  * BLOCK_SIZE(512) = 4KB.
74  * hash: For future expansion.
75  * version2: Together with hdr->version, it is used to
76  * ensure the current Vendor block content integrity.
77  *   (version2 == hdr->version):Data valid;
78  *   (version2 != hdr->version):Data invalid.
79  */
80 struct vendor_info {
81 	struct vendor_hdr *hdr;
82 	struct vendor_item *item;
83 	u8 *data;
84 	u32 *hash;
85 	u32 *version2;
86 };
87 
88 struct mtd_flash_info {
89 	u32 part_offset;
90 	u32 part_size;
91 	u32 blk_offset;
92 	u32 page_offset;
93 	u32 version;
94 	u32 ops_size;
95 	u32 blk_size;
96 };
97 
98 /*
99  * Calculate the offset of each field for emmc.
100  * Emmc vendor info size: 64KB
101  */
102 #define EMMC_VENDOR_INFO_SIZE	(EMMC_VENDOR_PART_BLKS * VENDOR_BLOCK_SIZE)
103 #define EMMC_VENDOR_DATA_OFFSET	(sizeof(struct vendor_hdr) + EMMC_VENDOR_ITEM_NUM * sizeof(struct vendor_item))
104 #define EMMC_VENDOR_HASH_OFFSET (EMMC_VENDOR_INFO_SIZE - 8)
105 #define EMMC_VENDOR_VERSION2_OFFSET (EMMC_VENDOR_INFO_SIZE - 4)
106 
107 /*
108  * Calculate the offset of each field for spi nand/slc/mlc large capacity case.
109  * Flash vendor info size: 4KB
110  */
111 #define NAND_VENDOR_INFO_SIZE	(NAND_VENDOR_PART_BLKS * VENDOR_BLOCK_SIZE)
112 #define NAND_VENDOR_DATA_OFFSET	(sizeof(struct vendor_hdr) + NAND_VENDOR_ITEM_NUM * sizeof(struct vendor_item))
113 #define NAND_VENDOR_HASH_OFFSET (NAND_VENDOR_INFO_SIZE - 8)
114 #define NAND_VENDOR_VERSION2_OFFSET (NAND_VENDOR_INFO_SIZE - 4)
115 
116 /*
117  * Calculate the offset of each field for spi nor/spi nand/slc/mlc large small capacity case.
118  * Flash vendor info size: 4KB
119  */
120 #define FLASH_VENDOR_INFO_SIZE	(FLASH_VENDOR_PART_BLKS * VENDOR_BLOCK_SIZE)
121 #define FLASH_VENDOR_DATA_OFFSET (sizeof(struct vendor_hdr) + FLASH_VENDOR_ITEM_NUM * sizeof(struct vendor_item))
122 #define FLASH_VENDOR_HASH_OFFSET (FLASH_VENDOR_INFO_SIZE - 8)
123 #define FLASH_VENDOR_VERSION2_OFFSET (FLASH_VENDOR_INFO_SIZE - 4)
124 
125 /* vendor info */
126 static struct vendor_info vendor_info;
127 /* The storage type of the device */
128 static int bootdev_type;
129 
130 #ifdef CONFIG_MTD_BLK
131 static struct mtd_flash_info s_flash_info;
132 static const char *vendor_mtd_name = "vnvm";
133 #endif
134 
135 /* vendor private read write ops*/
136 static	int (*_flash_read)(struct blk_desc *dev_desc,
137 			   u32 sec,
138 			   u32 n_sec,
139 			   void *buffer);
140 static	int (*_flash_write)(struct blk_desc *dev_desc,
141 			    u32 sec,
142 			    u32 n_sec,
143 			    void *buffer);
144 
145 int flash_vendor_dev_ops_register(int (*read)(struct blk_desc *dev_desc,
146 					      u32 sec,
147 					      u32 n_sec,
148 					      void *p_data),
149 				  int (*write)(struct blk_desc *dev_desc,
150 					       u32 sec,
151 					       u32 n_sec,
152 					       void *p_data))
153 {
154 	if (!_flash_read) {
155 		_flash_read = read;
156 		_flash_write = write;
157 		return 0;
158 	}
159 
160 	return -EPERM;
161 }
162 
163 #ifdef CONFIG_MTD_BLK
164 static int mtd_vendor_storage_init(struct blk_desc *dev_desc)
165 {
166 	struct mtd_info *mtd = (struct mtd_info *)dev_desc->bdev->priv;
167 	disk_partition_t vnvm_part_info;
168 	void *buf = vendor_info.hdr;
169 	int ret, offset;
170 	int part_num, bad_block_size;
171 
172 	memset(&vnvm_part_info, 0x0, sizeof(vnvm_part_info));
173 	part_num = part_get_info_by_name(dev_desc, vendor_mtd_name, &vnvm_part_info);
174 	if (part_num < 0)
175 		return -EIO;
176 
177 	s_flash_info.part_offset = (u32)vnvm_part_info.start;
178 	s_flash_info.part_size = (u32)vnvm_part_info.size;
179 	s_flash_info.page_offset = 0;
180 	s_flash_info.blk_offset = 0;
181 	s_flash_info.version = 0;
182 	/* SPI Nor unified to Support 64KB erase block */
183 	if (dev_desc->devnum == BLK_MTD_SPI_NOR)
184 		s_flash_info.blk_size = 0x80;
185 	else
186 		s_flash_info.blk_size = mtd->erasesize >> 9;
187 	s_flash_info.ops_size = roundup(FLASH_VENDOR_INFO_SIZE, mtd->writesize) >> 9;
188 
189 	/* scan bad block and calculate the real size can be used */
190 	bad_block_size = 0;
191 	for (offset = 0; offset < s_flash_info.part_size; offset += s_flash_info.blk_size) {
192 		if (mtd_block_isbad(mtd, (s_flash_info.part_offset + offset) << 9))
193 			bad_block_size += s_flash_info.blk_size;
194 	}
195 	s_flash_info.part_size -= bad_block_size;
196 
197 	for (offset = 0; offset < s_flash_info.part_size; offset += s_flash_info.blk_size) {
198 		ret = blk_dread(dev_desc, s_flash_info.part_offset + offset,
199 				FLASH_VENDOR_INFO_SIZE >> 9,
200 				(u8 *)buf);
201 		debug("%s: read %x version = %x\n", __func__,
202 		      s_flash_info.part_offset + offset,
203 		      vendor_info.hdr->version);
204 		if (ret == (FLASH_VENDOR_INFO_SIZE >> 9) && vendor_info.hdr->tag == VENDOR_TAG &&
205 		    vendor_info.hdr->version == *vendor_info.version2) {
206 			if (vendor_info.hdr->version > s_flash_info.version) {
207 				s_flash_info.version = vendor_info.hdr->version;
208 				s_flash_info.blk_offset = offset;
209 			}
210 		}
211 	}
212 
213 	debug("%s: s_flash_info.version = %x %x\n", __func__, s_flash_info.version, s_flash_info.blk_offset);
214 	if (s_flash_info.version) {
215 		for (offset = s_flash_info.blk_size  - s_flash_info.ops_size;
216 		     offset >= 0;
217 		     offset -= s_flash_info.ops_size) {
218 			ret = blk_dread(dev_desc, s_flash_info.part_offset +
219 					s_flash_info.blk_offset + offset,
220 					1,
221 					(u8 *)buf);
222 
223 			/* the page is not programmed */
224 			if (ret == 1 && vendor_info.hdr->tag == 0xFFFFFFFF)
225 				continue;
226 
227 			/* point to the next free page */
228 			if (s_flash_info.page_offset < offset)
229 				s_flash_info.page_offset = offset + s_flash_info.ops_size;
230 
231 			if (ret != 1 || vendor_info.hdr->tag != VENDOR_TAG)
232 				continue;
233 			ret = blk_dread(dev_desc, s_flash_info.part_offset +
234 					s_flash_info.blk_offset + offset,
235 					FLASH_VENDOR_INFO_SIZE >> 9,
236 					(u8 *)buf);
237 			debug("%s: read %x version = %x\n", __func__,
238 			      s_flash_info.part_offset + s_flash_info.blk_offset  + offset,
239 			      vendor_info.hdr->version);
240 
241 			if (ret == (FLASH_VENDOR_INFO_SIZE >> 9)  && vendor_info.hdr->tag == VENDOR_TAG &&
242 			    vendor_info.hdr->version == *vendor_info.version2) {
243 				s_flash_info.version = vendor_info.hdr->version;
244 				break;
245 			}
246 		}
247 	} else {
248 		memset((u8 *)vendor_info.hdr, 0, FLASH_VENDOR_INFO_SIZE);
249 		vendor_info.hdr->version = 1;
250 		vendor_info.hdr->tag = VENDOR_TAG;
251 		vendor_info.hdr->free_size =
252 			((u32)(size_t)vendor_info.hash
253 			- (u32)(size_t)vendor_info.data);
254 		*vendor_info.version2 = vendor_info.hdr->version;
255 	}
256 
257 	return 0;
258 }
259 
260 static int mtd_vendor_write(struct blk_desc *dev_desc,
261 			    u32 sec,
262 			    u32 n_sec,
263 			    void *buf)
264 {
265 	int ret, count = 0, err = 0;
266 
267 re_write:
268 	debug("[Vendor INFO]:%s page_offset=0x%x count = %x\n", __func__, s_flash_info.part_offset +
269 	      s_flash_info.blk_offset + s_flash_info.page_offset, count);
270 	if (s_flash_info.page_offset >= s_flash_info.blk_size) {
271 		s_flash_info.blk_offset += s_flash_info.blk_size;
272 		if (s_flash_info.blk_offset >= s_flash_info.part_size)
273 			s_flash_info.blk_offset = 0;
274 		s_flash_info.page_offset = 0;
275 	}
276 
277 	dev_desc->op_flag |= BLK_MTD_CONT_WRITE;
278 	ret = blk_dwrite(dev_desc, s_flash_info.part_offset +
279 			 s_flash_info.blk_offset + s_flash_info.page_offset,
280 			 FLASH_VENDOR_INFO_SIZE >> 9,
281 			 (u8 *)buf);
282 	dev_desc->op_flag &= ~(BLK_MTD_CONT_WRITE);
283 
284 	s_flash_info.page_offset += s_flash_info.ops_size;
285 	if (ret != (FLASH_VENDOR_INFO_SIZE >> 9)) {
286 		err++;
287 		if (err > 3)
288 			return -EIO;
289 		goto re_write;
290 	}
291 
292 	count++;
293 	/* write 2 copies for reliability */
294 	if (count < 2)
295 		goto re_write;
296 
297 	return ret;
298 }
299 #endif
300 
301 /**********************************************************/
302 /*              vendor API implementation                 */
303 /**********************************************************/
304 static int vendor_ops(u8 *buffer, u32 addr, u32 n_sec, int write)
305 {
306 	struct blk_desc *dev_desc;
307 	unsigned int lba = 0;
308 	int ret = 0;
309 
310 	dev_desc = rockchip_get_bootdev();
311 	if (!dev_desc) {
312 		printf("%s: dev_desc is NULL!\n", __func__);
313 		return -ENODEV;
314 	}
315 	/* Get the offset address according to the device type */
316 	switch (dev_desc->if_type) {
317 	case IF_TYPE_MMC:
318 		/*
319 		 * The location of VendorStorage in Flash is shown in the
320 		 * following figure. The starting address of the VendorStorage
321 		 * partition offset is 3.5MB(EMMC_VENDOR_PART_OFFSET*BLOCK_SIZE(512)),
322 		 * and the partition size is 256KB.
323 		 * ----------------------------------------------------
324 		 * |   3.5MB    |  VendorStorage  |                   |
325 		 * ----------------------------------------------------
326 		 */
327 		lba = EMMC_VENDOR_PART_OFFSET;
328 		debug("[Vendor INFO]:VendorStorage offset address=0x%x\n", lba);
329 		break;
330 	case IF_TYPE_RKNAND:
331 	case IF_TYPE_SPINAND:
332 		/*
333 		 * The location of VendorStorage in Flash is shown in the
334 		 * following figure. The starting address of the VendorStorage
335 		 * partition offset is 0KB in FTL vendor block,
336 		 * and the partition size is 128KB.
337 		 * ----------------------------------------------------
338 		 * |  VendorStorage  |                     |
339 		 * ----------------------------------------------------
340 		 */
341 		lba = NAND_VENDOR_PART_OFFSET;
342 		debug("[Vendor INFO]:VendorStorage offset address=0x%x\n", lba);
343 		break;
344 	case IF_TYPE_SPINOR:
345 		/*
346 		 * The location of VendorStorage in Flash is shown in the
347 		 * following figure. The starting address of the VendorStorage
348 		 * partition offset is 4KB (FLASH_VENDOR_PART_OFFSET * BLOCK_SIZE),
349 		 * and the partition size is 16KB.
350 		 * ----------------------------------------------------
351 		 * |   4KB    |  VendorStorage  |                     |
352 		 * ----------------------------------------------------
353 		 */
354 		lba = FLASH_VENDOR_PART_OFFSET;
355 		debug("[Vendor INFO]:VendorStorage offset address=0x%x\n", lba);
356 		break;
357 #ifdef CONFIG_MTD_BLK
358 	case IF_TYPE_MTD:
359 		/*
360 		 * The location of VendorStorage in NAND FLASH or SPI NAND partition "vnvm"
361 		 * is shown in the following figure. The partition size is at least  4
362 		 * NAND FLASH blocks.
363 		 * ----------------------------------------------------
364 		 * |   .....    |  vnvm  |  .......                   |
365 		 * ----------------------------------------------------
366 		 */
367 		lba = 0;
368 		break;
369 #endif
370 	default:
371 		printf("[Vendor ERROR]:Boot device type is invalid!\n");
372 		return -ENODEV;
373 	}
374 	if (write) {
375 		if (_flash_write)
376 			ret = _flash_write(dev_desc, lba + addr, n_sec, buffer);
377 		else
378 			ret = blk_dwrite(dev_desc, lba + addr, n_sec, buffer);
379 	} else {
380 		if (_flash_read)
381 			ret = _flash_read(dev_desc, lba + addr, n_sec, buffer);
382 		else
383 			ret = blk_dread(dev_desc, lba + addr, n_sec, buffer);
384 	}
385 
386 	debug("[Vendor INFO]:op=%s, ret=%d\n", write ? "write" : "read", ret);
387 
388 	return ret;
389 }
390 
391 /*
392  * The VendorStorage partition is divided into four parts
393  * (vendor 0-3) and its structure is shown in the following figure.
394  * The init function is used to select the latest and valid vendor.
395  *
396  * |******************** FLASH ********************|
397  * -------------------------------------------------
398  * |  vendor0  |  vendor1  |  vendor2  |  vendor3  |
399  * -------------------------------------------------
400  * Notices:
401  *   1. "version" and "version2" are used to verify that the vendor
402  *      is valid (equal is valid).
403  *   2. the "version" value is larger, indicating that the current
404  *      verndor data is new.
405  */
406 int vendor_storage_init(void)
407 {
408 	int ret = 0;
409 	int ret_size;
410 	u8 *buffer;
411 	u32 size, i;
412 	u32 max_ver = 0;
413 	u32 max_index = 0;
414 	u16 data_offset, hash_offset, part_num;
415 	u16 version2_offset, part_size;
416 	struct blk_desc *dev_desc;
417 
418 	dev_desc = rockchip_get_bootdev();
419 	if (!dev_desc) {
420 		printf("[Vendor ERROR]:Invalid boot device type(%d)\n",
421 		       bootdev_type);
422 		return -ENODEV;
423 	}
424 
425 	switch (dev_desc->if_type) {
426 	case IF_TYPE_MMC:
427 		size = EMMC_VENDOR_INFO_SIZE;
428 		part_size = EMMC_VENDOR_PART_BLKS;
429 		data_offset = EMMC_VENDOR_DATA_OFFSET;
430 		hash_offset = EMMC_VENDOR_HASH_OFFSET;
431 		version2_offset = EMMC_VENDOR_VERSION2_OFFSET;
432 		part_num = VENDOR_PART_NUM;
433 		break;
434 	case IF_TYPE_RKNAND:
435 	case IF_TYPE_SPINAND:
436 		size = NAND_VENDOR_INFO_SIZE;
437 		part_size = NAND_VENDOR_PART_BLKS;
438 		data_offset = NAND_VENDOR_DATA_OFFSET;
439 		hash_offset = NAND_VENDOR_HASH_OFFSET;
440 		version2_offset = NAND_VENDOR_VERSION2_OFFSET;
441 		part_num = NAND_VENDOR_PART_NUM;
442 		break;
443 	case IF_TYPE_SPINOR:
444 		size = FLASH_VENDOR_INFO_SIZE;
445 		part_size = FLASH_VENDOR_PART_BLKS;
446 		data_offset = FLASH_VENDOR_DATA_OFFSET;
447 		hash_offset = FLASH_VENDOR_HASH_OFFSET;
448 		version2_offset = FLASH_VENDOR_VERSION2_OFFSET;
449 		part_num = VENDOR_PART_NUM;
450 		break;
451 #ifdef CONFIG_MTD_BLK
452 	case IF_TYPE_MTD:
453 		size = FLASH_VENDOR_INFO_SIZE;
454 		part_size = FLASH_VENDOR_PART_BLKS;
455 		data_offset = FLASH_VENDOR_DATA_OFFSET;
456 		hash_offset = FLASH_VENDOR_HASH_OFFSET;
457 		version2_offset = FLASH_VENDOR_VERSION2_OFFSET;
458 		part_num = MTD_VENDOR_PART_NUM;
459 		_flash_write = mtd_vendor_write;
460 		break;
461 #endif
462 	default:
463 		debug("[Vendor ERROR]:Boot device type is invalid!\n");
464 		ret = -ENODEV;
465 		break;
466 	}
467 	/* Invalid bootdev type */
468 	if (ret)
469 		return ret;
470 
471 	/* Initialize */
472 	bootdev_type = dev_desc->if_type;
473 
474 	/* Always use, no need to release */
475 	buffer = (u8 *)malloc(size);
476 	if (!buffer) {
477 		printf("[Vendor ERROR]:Malloc failed!\n");
478 		ret = -ENOMEM;
479 		goto out;
480 	}
481 	/* Pointer initialization */
482 	vendor_info.hdr = (struct vendor_hdr *)buffer;
483 	vendor_info.item = (struct vendor_item *)(buffer + sizeof(struct vendor_hdr));
484 	vendor_info.data = buffer + data_offset;
485 	vendor_info.hash = (u32 *)(buffer + hash_offset);
486 	vendor_info.version2 = (u32 *)(buffer + version2_offset);
487 
488 #ifdef CONFIG_MTD_BLK
489 	if (dev_desc->if_type == IF_TYPE_MTD) {
490 		ret = mtd_vendor_storage_init(dev_desc);
491 		goto out;
492 	}
493 #endif
494 
495 	/* Find valid and up-to-date one from (vendor0 - vendor3) */
496 	for (i = 0; i < part_num; i++) {
497 		ret_size = vendor_ops((u8 *)vendor_info.hdr,
498 				      part_size * i, part_size, 0);
499 		if (ret_size != part_size) {
500 			ret = -EIO;
501 			goto out;
502 		}
503 
504 		if ((vendor_info.hdr->tag == VENDOR_TAG) &&
505 		    (*(vendor_info.version2) == vendor_info.hdr->version)) {
506 			if (max_ver < vendor_info.hdr->version) {
507 				max_index = i;
508 				max_ver = vendor_info.hdr->version;
509 			}
510 		}
511 	}
512 
513 	if (max_ver) {
514 		debug("[Vendor INFO]:max_ver=%d, vendor_id=%d.\n", max_ver, max_index);
515 		/*
516 		 * Keep vendor_info the same as the largest
517 		 * version of vendor
518 		 */
519 		if (max_index != (part_num - 1)) {
520 			ret_size = vendor_ops((u8 *)vendor_info.hdr,
521 					       part_size * max_index, part_size, 0);
522 			if (ret_size != part_size) {
523 				ret = -EIO;
524 				goto out;
525 			}
526 		}
527 	} else {
528 		debug("[Vendor INFO]:Reset vendor info...\n");
529 		memset((u8 *)vendor_info.hdr, 0, size);
530 		vendor_info.hdr->version = 1;
531 		vendor_info.hdr->tag = VENDOR_TAG;
532 		/* data field length */
533 		vendor_info.hdr->free_size =
534 			((u32)(size_t)vendor_info.hash
535 			- (u32)(size_t)vendor_info.data);
536 		*(vendor_info.version2) = vendor_info.hdr->version;
537 	}
538 	debug("[Vendor INFO]:ret=%d.\n", ret);
539 
540 out:
541 	if (ret)
542 		bootdev_type = 0;
543 
544 	return ret;
545 }
546 
547 /*
548  * @id: item id, first 4 id is occupied:
549  *	VENDOR_SN_ID
550  *	VENDOR_WIFI_MAC_ID
551  *	VENDOR_LAN_MAC_ID
552  *	VENDOR_BLUETOOTH_ID
553  * @pbuf: read data buffer;
554  * @size: read bytes;
555  *
556  * return: bytes equal to @size is success, other fail;
557  */
558 int vendor_storage_read(u16 id, void *pbuf, u16 size)
559 {
560 	int ret = 0;
561 	u32 i;
562 	u16 offset;
563 	struct vendor_item *item;
564 
565 	/* init vendor storage */
566 	if (!bootdev_type) {
567 		ret = vendor_storage_init();
568 		if (ret < 0)
569 			return ret;
570 	}
571 
572 	item = vendor_info.item;
573 	for (i = 0; i < vendor_info.hdr->item_num; i++) {
574 		if ((item + i)->id == id) {
575 			debug("[Vendor INFO]:Find the matching item, id=%d\n", id);
576 			/* Correct the size value */
577 			if (size > (item + i)->size)
578 				size = (item + i)->size;
579 			offset = (item + i)->offset;
580 			memcpy(pbuf, (vendor_info.data + offset), size);
581 			return size;
582 		}
583 	}
584 	debug("[Vendor ERROR]:No matching item, id=%d\n", id);
585 
586 	return -EINVAL;
587 }
588 
589 /*
590  * @id: item id, first 4 id is occupied:
591  *	VENDOR_SN_ID
592  *	VENDOR_WIFI_MAC_ID
593  *	VENDOR_LAN_MAC_ID
594  *	VENDOR_BLUETOOTH_ID
595  * @pbuf: write data buffer;
596  * @size: write bytes;
597  *
598  * return: bytes equal to @size is success, other fail;
599  */
600 int vendor_storage_write(u16 id, void *pbuf, u16 size)
601 {
602 	int cnt, ret = 0;
603 	u32 i, next_index, align_size;
604 	struct vendor_item *item;
605 	u16 part_size, max_item_num, offset, part_num;
606 
607 	/* init vendor storage */
608 	if (!bootdev_type) {
609 		ret = vendor_storage_init();
610 		if (ret < 0)
611 			return ret;
612 	}
613 
614 	switch (bootdev_type) {
615 	case IF_TYPE_MMC:
616 		part_size = EMMC_VENDOR_PART_BLKS;
617 		max_item_num = EMMC_VENDOR_ITEM_NUM;
618 		part_num = VENDOR_PART_NUM;
619 		break;
620 	case IF_TYPE_RKNAND:
621 	case IF_TYPE_SPINAND:
622 		part_size = NAND_VENDOR_PART_BLKS;
623 		max_item_num = NAND_VENDOR_ITEM_NUM;
624 		part_num = NAND_VENDOR_PART_NUM;
625 		break;
626 	case IF_TYPE_SPINOR:
627 		part_size = FLASH_VENDOR_PART_BLKS;
628 		max_item_num = FLASH_VENDOR_ITEM_NUM;
629 		part_num = VENDOR_PART_NUM;
630 		break;
631 #ifdef CONFIG_MTD_BLK
632 	case IF_TYPE_MTD:
633 		part_size = FLASH_VENDOR_PART_BLKS;
634 		max_item_num = FLASH_VENDOR_ITEM_NUM;
635 		part_num = MTD_VENDOR_PART_NUM;
636 		break;
637 #endif
638 	default:
639 		ret = -ENODEV;
640 		break;
641 	}
642 	/* Invalid bootdev? */
643 	if (ret < 0)
644 		return ret;
645 
646 	next_index = vendor_info.hdr->next_index;
647 	/* algin to 64 bytes*/
648 	align_size = (size + VENDOR_BTYE_ALIGN) & (~VENDOR_BTYE_ALIGN);
649 	if (size > align_size)
650 		return -EINVAL;
651 
652 	item = vendor_info.item;
653 	/* If item already exist, update the item data */
654 	for (i = 0; i < vendor_info.hdr->item_num; i++) {
655 		if ((item + i)->id == id) {
656 			debug("[Vendor INFO]:Find the matching item, id=%d\n", id);
657 			offset = (item + i)->offset;
658 			memcpy((vendor_info.data + offset), pbuf, size);
659 			(item + i)->size = size;
660 			vendor_info.hdr->version++;
661 			*(vendor_info.version2) = vendor_info.hdr->version;
662 			vendor_info.hdr->next_index++;
663 			if (vendor_info.hdr->next_index >= part_num)
664 				vendor_info.hdr->next_index = 0;
665 			cnt = vendor_ops((u8 *)vendor_info.hdr, part_size * next_index, part_size, 1);
666 			return (cnt == part_size) ? size : -EIO;
667 		}
668 	}
669 	/*
670 	 * If item does not exist, and free size is enough,
671 	 * creat a new one
672 	 */
673 	if ((vendor_info.hdr->item_num < max_item_num) &&
674 	    (vendor_info.hdr->free_size >= align_size)) {
675 		debug("[Vendor INFO]:Create new Item, id=%d\n", id);
676 		item = vendor_info.item + vendor_info.hdr->item_num;
677 		item->id = id;
678 		item->offset = vendor_info.hdr->free_offset;
679 		item->size = size;
680 
681 		vendor_info.hdr->free_offset += align_size;
682 		vendor_info.hdr->free_size -= align_size;
683 		memcpy((vendor_info.data + item->offset), pbuf, size);
684 		vendor_info.hdr->item_num++;
685 		vendor_info.hdr->version++;
686 		vendor_info.hdr->next_index++;
687 		*(vendor_info.version2) = vendor_info.hdr->version;
688 		if (vendor_info.hdr->next_index >= part_num)
689 			vendor_info.hdr->next_index = 0;
690 
691 		cnt = vendor_ops((u8 *)vendor_info.hdr, part_size * next_index, part_size, 1);
692 		return (cnt == part_size) ? size : -EIO;
693 	}
694 	debug("[Vendor ERROR]:Vendor has no space left!\n");
695 
696 	return -ENOMEM;
697 }
698 
699 /**********************************************************/
700 /*              vendor API uinit test                      */
701 /**********************************************************/
702 /* Reset the vendor storage space to the initial state */
703 static void vendor_test_reset(void)
704 {
705 	u16 i, part_size, part_num;
706 	u32 size;
707 
708 	switch (bootdev_type) {
709 	case IF_TYPE_MMC:
710 		size = EMMC_VENDOR_INFO_SIZE;
711 		part_size = EMMC_VENDOR_PART_BLKS;
712 		part_num = VENDOR_PART_NUM;
713 		break;
714 	case IF_TYPE_RKNAND:
715 	case IF_TYPE_SPINAND:
716 		size = NAND_VENDOR_INFO_SIZE;
717 		part_size = NAND_VENDOR_PART_BLKS;
718 		part_num = NAND_VENDOR_PART_NUM;
719 		break;
720 	case IF_TYPE_SPINOR:
721 		size = FLASH_VENDOR_INFO_SIZE;
722 		part_size = FLASH_VENDOR_PART_BLKS;
723 		part_num = VENDOR_PART_NUM;
724 		break;
725 	default:
726 		size = 0;
727 		part_size = 0;
728 		break;
729 	}
730 	/* Invalid bootdev? */
731 	if (!size)
732 		return;
733 
734 	memset((u8 *)vendor_info.hdr, 0, size);
735 	vendor_info.hdr->version = 1;
736 	vendor_info.hdr->tag = VENDOR_TAG;
737 	/* data field length */
738 	vendor_info.hdr->free_size = (unsigned long)vendor_info.hash -
739 				     (unsigned long)vendor_info.data;
740 	*(vendor_info.version2) = vendor_info.hdr->version;
741 	/* write to flash. */
742 	for (i = 0; i < part_num; i++)
743 		vendor_ops((u8 *)vendor_info.hdr, part_size * i, part_size, 1);
744 }
745 
746 /*
747  * A total of four tests
748  * 1.All items test.
749  * 2.Overrides the maximum number of items test.
750  * 3.Single Item memory overflow test.
751  * 4.Total memory overflow test.
752  */
753 int vendor_storage_test(void)
754 {
755 	u16 id, size, j, item_num;
756 	u32 total_size;
757 	u8 *buffer = NULL;
758 	int ret = 0;
759 
760 	if (!bootdev_type) {
761 		ret = vendor_storage_init();
762 		if (ret) {
763 			printf("%s: vendor storage init failed, ret=%d\n",
764 			       __func__, ret);
765 			return ret;
766 		}
767 	}
768 
769 	/*
770 	 * Calculate the maximum number of items and the maximum
771 	 * allocable memory for each item.
772 	 */
773 	switch (bootdev_type) {
774 	case IF_TYPE_MMC:
775 		item_num = EMMC_VENDOR_ITEM_NUM;
776 		total_size = (unsigned long)vendor_info.hash -
777 			     (unsigned long)vendor_info.data;
778 		size = total_size / item_num;
779 		break;
780 	case IF_TYPE_RKNAND:
781 	case IF_TYPE_SPINAND:
782 		item_num = NAND_VENDOR_ITEM_NUM;
783 		total_size = (unsigned long)vendor_info.hash -
784 			     (unsigned long)vendor_info.data;
785 		size = total_size / item_num;
786 		break;
787 	case IF_TYPE_SPINOR:
788 	case IF_TYPE_MTD:
789 		item_num = FLASH_VENDOR_ITEM_NUM;
790 		total_size = (unsigned long)vendor_info.hash -
791 			     (unsigned long)vendor_info.data;
792 		size = total_size / item_num;
793 		break;
794 	default:
795 		total_size = 0;
796 		break;
797 	}
798 	/* Invalid bootdev? */
799 	if (!total_size)
800 		return -ENODEV;
801 	/* 64 bytes are aligned and rounded down */
802 	if (size > 64)
803 		size = (size / 64) * 64;
804 	/* malloc memory */
805 	buffer = (u8 *)malloc(size);
806 	if (!buffer) {
807 		printf("[Vendor Test]:Malloc failed(size=%d)!\n", size);
808 		return -ENOMEM;
809 	}
810 	printf("[Vendor Test]:Test Start...\n");
811 	printf("[Vendor Test]:Before Test, Vendor Resetting.\n");
812 	if (bootdev_type != IF_TYPE_MTD)
813 		vendor_test_reset();
814 
815 	/* FIRST TEST: test all items can be used correctly */
816 	printf("[Vendor Test]:<All Items Used> Test Start...\n");
817 	printf("[Vendor Test]:item_num=%d, size=%d.\n", item_num, size);
818 	/*
819 	 * Write data, then read the data, and compare the
820 	 * data consistency
821 	 */
822 	for (id = 0; id < item_num; id++) {
823 		memset(buffer, id, size);
824 		ret = vendor_storage_write(id, buffer, size);
825 		if (ret < 0) {
826 			printf("[Vendor Test]:vendor write failed(id=%d)!\n", id);
827 			free(buffer);
828 			return ret;
829 		}
830 	}
831 	/* Read data */
832 	for (id = 0; id < item_num; id++) {
833 		memset(buffer, 0, size);
834 		ret = vendor_storage_read(id, buffer, size);
835 		if (ret < 0) {
836 			printf("[Vendor Test]:vendor read failed(id=%d)!\n", id);
837 			free(buffer);
838 			return ret;
839 		}
840 		/* check data Correctness */
841 		for (j = 0; j < size; j++) {
842 			if (*(buffer + j) != id) {
843 				printf("[Vendor Test]:Unexpected error occurs(id=%d)\n", id);
844 				printf("the data content is:\n");
845 				print_buffer(0, buffer, 1, size, 16);
846 
847 				free(buffer);
848 				return -1;
849 			}
850 		}
851 		debug("\t#id=%03d success,data=0x%02x,size=%d.\n", id, *buffer, size);
852 	}
853 	printf("[Vendor Test]:<All Items Used> Test End,States:OK\n");
854 
855 	printf("[Vendor Test]:<All Items Used> re init,States:OK\n");
856 	ret = vendor_storage_init();
857 	/* Read data */
858 	for (id = 0; id < item_num; id++) {
859 		memset(buffer, 0, size);
860 		ret = vendor_storage_read(id, buffer, size);
861 		if (ret < 0) {
862 			printf("[Vendor Test]:vendor read failed(id=%d)!\n", id);
863 			free(buffer);
864 			return ret;
865 		}
866 		/* check data Correctness */
867 		for (j = 0; j < size; j++) {
868 			if (*(buffer + j) != id) {
869 				printf("[Vendor Test]:Unexpected error occurs(id=%d)\n", id);
870 				printf("the data content is:\n");
871 				print_buffer(0, buffer, 1, size, 16);
872 
873 				free(buffer);
874 				return -1;
875 			}
876 		}
877 		debug("\t#id=%03d success,data=0x%02x,size=%d.\n", id, *buffer, size);
878 	}
879 	printf("[Vendor Test]:<All Items Used> Test End,States:OK\n");
880 #ifdef CONFIG_MTD_BLK
881 	if (bootdev_type == IF_TYPE_MTD)
882 		return 0;
883 #endif
884 	/*
885 	 * SECOND TEST: Overrides the maximum number of items to see if the
886 	 * return value matches the expectation
887 	 */
888 	printf("[Vendor Test]:<Overflow Items Cnt> Test Start...\n");
889 	/* Any id value that was not used before */
890 	id = item_num;
891 	printf("[Vendor Test]:id=%d, size=%d.\n", id, size);
892 	ret = vendor_storage_write(id, buffer, size);
893 	if (ret == -ENOMEM)
894 		printf("[Vendor Test]:<Overflow Items Cnt> Test End,States:OK\n");
895 	else
896 		printf("[Vendor Test]:<Overflow Items Cnt> Test End,States:Failed\n");
897 
898 	/* free buffer, remalloc later */
899 	free(buffer);
900 	buffer = NULL;
901 	/*
902 	 * remalloc memory and recalculate size to test memory overflow
903 	 * (1) item_num > 10: Memory is divided into 10 blocks,
904 	 * 11th memory will overflow.
905 	 * (2) 10 > item_num > 1: Memory is divided into item_num-1
906 	 * blocks. item_num block, memory will overflow.
907 	 * (3) item_num = 1: size = total_size + 512 Bytes, The first
908 	 * block, memory will overflow.
909 	 * The reason to do so is to minimize the size of the memory,
910 	 * making malloc easier to perform successfully.
911 	 */
912 	item_num = (item_num > 10) ? 10 : (item_num - 1);
913 	size = item_num ? (total_size / item_num) : (total_size + 512);
914 	size = (size + VENDOR_BTYE_ALIGN) & (~VENDOR_BTYE_ALIGN);
915 	/* Find item_num value that can make the memory overflow */
916 	for (id = 0; id <= item_num; id++) {
917 		if (((id + 1) * size) > total_size) {
918 			item_num = id;
919 			break;
920 		}
921 	}
922 	/* malloc */
923 	buffer = (u8 *)malloc(size);
924 	if (buffer == NULL) {
925 		printf("[Vendor Test]:Malloc failed(size=%d)!\n", size);
926 		return -ENOMEM;
927 	}
928 
929 	/* THIRD TEST: Single Item memory overflow test */
930 	printf("[Vendor Test]:<Single Item Memory Overflow> Test Start...\n");
931 	/* The value can be arbitrary */
932 	memset(buffer, 'a', size);
933 	/* Any id value that was used before */
934 	id = 0;
935 	printf("[Vendor Test]:id=%d, size=%d.\n", id, size);
936 	ret = vendor_storage_write(id, buffer, size);
937 	if (ret == size)
938 		printf("[Vendor Test]:<Single Item Memory Overflow> Test End, States:OK\n");
939 	else
940 		printf("[Vendor Test]:<Single Item Memory Overflow> Test End, States:Failed\n");
941 
942 	/* FORTH TEST: Total memory overflow test */
943 	printf("[Vendor Test]:<Total memory overflow> Test Start...\n");
944 	printf("[Vendor Test]:item_num=%d, size=%d.\n", item_num, size);
945 
946 	vendor_test_reset();
947 	for (id = 0; id < item_num; id++) {
948 		memset(buffer, id, size);
949 		ret = vendor_storage_write(id, buffer, size);
950 		if (ret < 0) {
951 			if ((id == item_num) && (ret == -ENOMEM)) {
952 				printf("[Vendor Test]:<Total memory overflow> Test End, States:OK\n");
953 				break;
954 			} else {
955 				printf("[Vendor Test]:<Total memory overflow> Test End, States:Failed\n");
956 				break;
957 			}
958 		}
959 		debug("\t#id=%03d success,data=0x%02x,size=%d.\n", id, *buffer, size);
960 	}
961 
962 	/* Test end */
963 	printf("[Vendor Test]:After Test, Vendor Resetting...\n");
964 	vendor_test_reset();
965 	printf("[Vendor Test]:Test End.\n");
966 	free(buffer);
967 
968 	return 0;
969 }
970