/* 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 }