#include #include #include #define I2C_CTRL_ENABLE (1<<0) #define I2C_CTRL_SPEED_25 (0<<1) #define I2C_CTRL_SPEED_50 (1<<1) #define I2C_CTRL_SPEED_100 (2<<1) #define I2C_CTRL_SPEED_200 (3<<1) #define I2C_CTRL_SPEED_400 (4<<1) #define I2C_CTRL_SPEED_600 (5<<1) #define I2C_CTRL_SPEED_800 (6<<1) #define I2C_CTRL_SPEED_1000 (7<<1) #define I2C_CTRL_SLAVEID(id) (((id) & 0x7f) << 4) #define I2C_DATA_SEND_STOP (1<<8) #define I2C_DATA_READ (1<<9) #define I2C_DATA_SEND_START (1<<10) #define I2C_DATA_BUSY (1<<11) #define I2C_DATA_EXECUTE (1<<11) #define I2C_DATA_RDF (1<<12) /* INS */ #define AT88_WRITE_USER_ZONE 0xb0 #define AT88_READ_USER_ZONE 0xb2 #define AT88_SYSTEM_WRITE 0xb4 #define AT88_SYSTEM_READ 0xb6 /* P1 */ #define AT88_READ_CONFIG_ZONE 0x00 #define AT88_SET_USER_ZONE 0x03 #define SEND_START (1<<0) #define SEND_STOP (1<<1) #define IGNORE_RDF (1<<2) #define MAX_USER_ZONE_SIZE 128 /* * netx i2c functions */ static inline void i2c_set_slaveid(uchar id) { unsigned int val; val = NETX_I2C_CTRL_REG; val &= 0xf; val |= I2C_CTRL_SLAVEID(id); NETX_I2C_CTRL_REG = val; } static inline uchar i2c_read_byte(int flags) { unsigned int val = I2C_DATA_EXECUTE | I2C_DATA_READ; if(flags & SEND_START) val |= I2C_DATA_SEND_START; if(flags & SEND_STOP) val |= I2C_DATA_SEND_STOP; NETX_I2C_DATA_REG = val; while(NETX_I2C_DATA_REG & I2C_DATA_BUSY); return NETX_I2C_DATA_REG & 0xff; } static inline void i2c_write_byte(uchar byte, int flags) { unsigned int val = byte; if(flags & SEND_START) val |= I2C_DATA_SEND_START; if(flags & SEND_STOP) val |= I2C_DATA_SEND_STOP; val |= I2C_DATA_EXECUTE; NETX_I2C_DATA_REG = val; while(NETX_I2C_DATA_REG & I2C_DATA_BUSY); } void i2c_init (int speed) { unsigned int val; switch(speed) { case 25000: val = I2C_CTRL_SPEED_25; break; case 50000: val = I2C_CTRL_SPEED_50; break; case 100000: val = I2C_CTRL_SPEED_100; break; case 200000: val = I2C_CTRL_SPEED_200; break; case 400000: val = I2C_CTRL_SPEED_400; break; case 600000: val = I2C_CTRL_SPEED_600; break; case 800000: val = I2C_CTRL_SPEED_800; break; case 1000000: val = I2C_CTRL_SPEED_1000; break; default: printf("unsupported speed %d. defaulting to 100kHz\n",speed); val = I2C_CTRL_SPEED_100; break; } NETX_I2C_CTRL_REG = val | I2C_CTRL_ENABLE; i2c_write_byte(0xff, 0); udelay(2000); } /* * at88SCxxxx CryptoMemory functions */ struct at88_parm { char *name; int zones; int zone_size; uchar atr[8]; }; struct at88_parm at88_parm_table[] = { { .name = "at88sc0104c", .zones = 4, .zone_size = 32, .atr = { 0x3b, 0xb2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x01 } }, { .name = "at88sc0204c", .zones = 4, .zone_size = 64, .atr = { 0x3b, 0xb2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x02 } }, { .name = "at88sc0404c", .zones = 4, .zone_size = 128, .atr = { 0x3b, 0xb2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x04 } }, { .name = "at88sc0808c", .zones = 8, .zone_size = 128, .atr = { 0x3b, 0xb2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x08 } }, { .name = "at88sc1616c", .zones = 16, .zone_size = 128, .atr = { 0x3b, 0xb2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x16 } }, }; #define parm_size (sizeof(at88_parm_table) / sizeof(struct at88_parm)) struct at88_parm *at88_parm = NULL; int set_user_zone(uchar zone) { if(zone >= at88_parm->zones) return -1; i2c_set_slaveid(AT88_SYSTEM_WRITE >> 1); i2c_write_byte(AT88_SET_USER_ZONE, SEND_START); i2c_write_byte(zone, 0); i2c_write_byte(8, SEND_STOP); return 0; } /* * We chose the easy way here and read/write whole zones at once */ int read_user_zone(char *buf) { int i; i2c_set_slaveid(AT88_READ_USER_ZONE >> 1); i2c_write_byte(0, SEND_START); i2c_write_byte(0, 0); i2c_write_byte(at88_parm->zone_size, 0); for(i=0; i < at88_parm->zone_size; i++) buf[i] = i2c_read_byte( i==at88_parm->zone_size - 1 ? SEND_STOP : 0); return 0; } #define BLK_SIZE 16 int write_user_zone(char *buf) { int i,block; for(block=0; block < at88_parm->zone_size/16; block++) { i2c_set_slaveid(AT88_WRITE_USER_ZONE >> 1); i2c_write_byte(0, SEND_START); i2c_write_byte(block * BLK_SIZE, 0); i2c_write_byte(BLK_SIZE, 0); for(i=0; iarea_1 ) ) return -1; set_user_zone(2); if( write_user_zone( (char *)&area->area_2 ) ) return -1; set_user_zone(3); if( write_user_zone( (char *)&area->area_2 ) ) return -1; return 0; } unsigned short crc16(unsigned short crc, unsigned int data) { crc = (crc >> 8) | ((crc & 0xff) << 8); crc ^= data; crc ^= (crc & 0xff) >> 4; crc ^= (crc & 0x0f) << 12; crc ^= ((crc & 0xff) << 4) << 1; return crc; } #define ETH_MAC_4321 0x1564 #define ETH_MAC_65 0x1568 int netx_cm_init(void) { int i; char buf[MAX_USER_ZONE_SIZE]; struct netx_cm_userarea *area; i2c_init(100000); i2c_set_slaveid(AT88_SYSTEM_READ >> 1); i2c_write_byte(AT88_READ_CONFIG_ZONE, SEND_START); i2c_write_byte(0, 0); /* adr */ i2c_write_byte(8, 0); /* len */ for(i=0;i<8;i++) buf[i] = i2c_read_byte( i==7 ? SEND_STOP : 0 ); for(i=0; iname); area = netx_cm_get_userarea(); for(i=0;i<4;i++) { printf("xc%d mac: %02x:%02x:%02x:%02x:%02x:%02x\n", i, area->area_1.mac[i][0], area->area_1.mac[i][1], area->area_1.mac[i][2], area->area_1.mac[i][3], area->area_1.mac[i][4], area->area_1.mac[i][5]); XPEC_REG(i, XPEC_RAM_START + ETH_MAC_4321) = area->area_1.mac[i][0] | area->area_1.mac[i][1]<<8 | area->area_1.mac[i][2]<<16 | area->area_1.mac[i][3]<<24; XPEC_REG(i, XPEC_RAM_START + ETH_MAC_65) = area->area_1.mac[i][4] | area->area_1.mac[i][5]<<8; } for(i=0; i<6; i++) gd->bd->bi_enetaddr[i] = area->area_1.mac[CONFIG_DRIVER_NET_NETX_XCNO][i]; sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", area->area_1.mac[CONFIG_DRIVER_NET_NETX_XCNO][0], area->area_1.mac[CONFIG_DRIVER_NET_NETX_XCNO][1], area->area_1.mac[CONFIG_DRIVER_NET_NETX_XCNO][2], area->area_1.mac[CONFIG_DRIVER_NET_NETX_XCNO][3], area->area_1.mac[CONFIG_DRIVER_NET_NETX_XCNO][4], area->area_1.mac[CONFIG_DRIVER_NET_NETX_XCNO][5]); setenv("ethaddr", buf); return 0; }