Beispiel #1
0
/* Implement CRC using Octeon's CRC hardware unit.  This provides a significant
 * speed up, especially when the code is executing from flash (and the data
 * being CRC'ed is in flash, as is done during boot.)
 */
uint32_t ZEXPORT crc32_no_comp(uint32_t crc, const Bytef *buf, uInt len)
{
	volatile uint64_t *ptr64;
	volatile uint8_t *ptr = (void *)buf;
	uint32_t poly = 0;

	poly = 0x04c11db7; /* Bit reversed standard CRC32 polynomial - 0xedb88320 */
	CVMX_MT_CRC_POLYNOMIAL(poly);
	/* Do endian byte swap on CRC, then use reflect mode of
	 * MT IV to reverse the bits within the bytes.  This results
	 * in a bit-reversed IV. */
	CVMX_ES32(crc, crc);
	CVMX_MT_CRC_IV_REFLECT(crc);
	while ((((uint32_t)ptr) & 0x7) && len) {
		CVMX_MT_CRC_BYTE_REFLECT(*ptr++);
		len--;
	}
	ptr64 = (void *)ptr;
	while (len > 8) {
		CVMX_MT_CRC_DWORD_REFLECT(*ptr64++);
		len -= 8;
	}
	ptr = (void *)ptr64;
	while (len--)
		CVMX_MT_CRC_BYTE_REFLECT(*ptr++);

	CVMX_MF_CRC_IV_REFLECT(crc);

	return crc;
}
void __octeon_board_create_random_mac_addr(void)
{
#ifndef CONFIG_OCTEON_SIM
	uint8_t fuse_buf[128];
	cvmx_mio_fus_rcmd_t fus_rcmd;
	uint32_t poly = 0x04c11db7;
	uint32_t crc = 0xffffffff;
	uint64_t *ptr;
	int ser_len = strlen((char *)gd->arch.board_desc.serial_str);
	int i;

	memset(fuse_buf, 0, sizeof(fuse_buf));
	fuse_buf[0] = gd->arch.board_desc.board_type;
	fuse_buf[1] = (gd->arch.board_desc.rev_major << 4)
			| gd->arch.board_desc.rev_minor;
	fuse_buf[2] = ser_len;
	strncpy((char*)(fuse_buf+3), (char*)gd->arch.board_desc.serial_str,
		sizeof(fuse_buf)-3);

	/* For a random number we perform a CRC32 using the board type,
	 * revision, serial number length, serial number and for OCTEON 2 and 3
	 * the fuse settings.
	 */

	CVMX_MT_CRC_POLYNOMIAL(poly);
	CVMX_ES32(crc, crc);
	CVMX_MT_CRC_IV_REFLECT(crc);
	ptr = (uint64_t *)fuse_buf;
	for (i = 0; i < sizeof(fuse_buf); i += 8)
		CVMX_MT_CRC_DWORD_REFLECT(*ptr++);

	if (!OCTEON_IS_OCTEON1PLUS()) {
		fus_rcmd.u64 = 0;
		fus_rcmd.s.pend = 1;
		for (i = 0; i < sizeof(fuse_buf); i++) {
			do {
				fus_rcmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD);
			} while (fus_rcmd.s.pend == 1);
			fuse_buf[i] = fus_rcmd.s.dat;
		}
		for (i = 0; i < sizeof(fuse_buf); i += 8)
			CVMX_MT_CRC_DWORD_REFLECT(*ptr++);
	}
	/* Get the final CRC32 */
	CVMX_MF_CRC_IV_REFLECT(crc);
	crc ^= 0xffffffff;

	gd->arch.mac_desc.count = 255;
	gd->arch.mac_desc.mac_addr_base[0] = 0x02;	/* locally administered */
	gd->arch.mac_desc.mac_addr_base[1] = crc & 0xff;
	gd->arch.mac_desc.mac_addr_base[2] = (crc >> 8) & 0xff;
	gd->arch.mac_desc.mac_addr_base[3] = (crc >> 16) & 0xff;
	gd->arch.mac_desc.mac_addr_base[4] = (crc >> 24) & 0xff;
	gd->arch.mac_desc.mac_addr_base[5] = 0;
	debug("Created random MAC address %pM", gd->arch.mac_desc.mac_addr_base);
#else
	gd->arch.mac_desc.mac_addr_base[0] = 2;
	gd->arch.mac_desc.mac_addr_base[1] = 0x00;
	gd->arch.mac_desc.mac_addr_base[2] = 0xDE;
	gd->arch.mac_desc.mac_addr_base[3] = 0xAD;
	gd->arch.mac_desc.mac_addr_base[4] = 0xBF;
	gd->arch.mac_desc.mac_addr_base[5] = 0x00;
	gd->arch.mac_desc.count = 255;
#endif
}