in meta-facebook/meta-fby3/recipes-fby3/fw-util/files/bmc_cpld_capsule.cpp [242:426]
int BmcCpldCapsuleComponent::bmc_update_capsule(string image) {
FILE *fp;
int i2cfd = 0;
int ret = 0;
int retry;
uint8_t bmc_location = 0;
uint8_t tbuf[2] = {0}, rdbuf[1] = {0};
uint8_t tlen = 2, rlen = 1;
int pfr_adress = CPLD_INTENT_CTRL_ADDR;
int mtd_no;
char rbuf[256], mtd_name[32], dev[16] = {0}, cmd[256] = {0};
char path[128];
string bmc_location_str;
string comp = component();
uint8_t intent_val_o = 0;
if ( fby3_common_get_bmc_location(&bmc_location) < 0 ) {
printf("Failed to initialize the fw-util\n");
return FW_STATUS_FAILURE;
}
if ( bmc_location == NIC_BMC ) {
bmc_location_str = "NIC Expansion";
snprintf(path, sizeof(path), NIC_CPLD_CTRL_BUS);
} else {
bmc_location_str = "baseboard";
snprintf(path, sizeof(path), BB_CPLD_CTRL_BUS);
}
// Check PFR provision status
i2cfd = open(path, O_RDWR);
if ( i2cfd < 0 ) {
syslog(LOG_WARNING, "%s() Failed to open %s", __func__, path);
return -1;
}
retry = 0;
tlen = 1;
tbuf[0] = UFM_STATUS_OFFSET;
while (retry < RETRY_TIME) {
ret = i2c_rdwr_msg_transfer(i2cfd, pfr_adress, tbuf, tlen, rdbuf, rlen);
if ( ret < 0 ) {
retry++;
msleep(100);
} else {
break;
}
}
if ( i2cfd > 0 ) close(i2cfd);
if (retry == RETRY_TIME) {
syslog(LOG_WARNING, "%s() Failed to do i2c_rdwr_msg_transfer, tlen=%d", __func__, tlen);
return -1;
}
if (!(rdbuf[0] & UFM_PROVISIONED_MSK)) {
printf("BMC is un-provisioned. Stopping the update! \n");
return -1;
}
tbuf[0] = CPLD_INTENT_CTRL_OFFSET;
printf("Start to update capsule...\n");
if (comp == "bmc_cap" || comp == "bmc_cap_rcvy") {
if ((fp = fopen("/proc/mtd", "r"))) {
while (fgets(rbuf, sizeof(rbuf), fp)) {
if ((sscanf(rbuf, "mtd%d: %*x %*x %s", &mtd_no, mtd_name) == 2) &&
!strcmp("\"stg-bmc\"", mtd_name)) {
sprintf(dev, "/dev/mtd%d", mtd_no);
break;
}
}
fclose(fp);
}
if (!dev[0] || !(fp = fopen(dev, "rb"))) {
printf("stg-bmc not found\n");
return FW_STATUS_FAILURE;
}
fclose(fp);
if (comp == "bmc_cap_rcvy") {
tbuf[1] = BMC_INTENT_RCVY_VALUE;
syslog(LOG_CRIT, "Updating BMC Capsule, Target to Recovery Region on %s. File: %s", bmc_location_str.c_str(), image.c_str());
} else {
tbuf[1] = BMC_INTENT_VALUE;
syslog(LOG_CRIT, "Updating BMC Capsule, Target to Active Region on %s. File: %s", bmc_location_str.c_str(), image.c_str());
}
snprintf(cmd, sizeof(cmd), "/usr/sbin/flashcp -v %s %s", image.c_str(), dev);
if (system(cmd) != 0) {
syslog(LOG_WARNING, "[%s] %s failed\n", __func__, cmd);
return FW_STATUS_FAILURE;
}
if (comp == "bmc_cap_rcvy") {
syslog(LOG_CRIT, "Updated BMC Capsule, Target to Recovery Region on %s. File: %s", bmc_location_str.c_str(), image.c_str());
} else {
syslog(LOG_CRIT, "Updated BMC Capsule, Target to Active Region on %s. File: %s", bmc_location_str.c_str(), image.c_str());
}
} else if (comp == "cpld_cap" || comp == "cpld_cap_rcvy") {
if ((fp = fopen("/proc/mtd", "r"))) {
while (fgets(rbuf, sizeof(rbuf), fp)) {
if ((sscanf(rbuf, "mtd%d: %*x %*x %s", &mtd_no, mtd_name) == 2) &&
!strcmp("\"stg-cpld\"", mtd_name)) {
sprintf(dev, "/dev/mtd%d", mtd_no);
break;
}
}
fclose(fp);
}
if (!dev[0] || !(fp = fopen(dev, "rb"))) {
printf("stg-cpld not found\n");
return FW_STATUS_FAILURE;
}
if (comp == "cpld_cap_rcvy") {
tbuf[1] = CPLD_INTENT_RCVY_VALUE;
syslog(LOG_CRIT, "Updating CPLD Capsule, Target to Recovery Region on %s. File: %s", bmc_location_str.c_str(), image.c_str());
} else {
tbuf[1] = CPLD_INTENT_VALUE;
syslog(LOG_CRIT, "Updating CPLD Capsule, Target to Active Region on %s. File: %s", bmc_location_str.c_str(), image.c_str());
}
snprintf(cmd, sizeof(cmd), "/usr/sbin/flashcp -v %s %s", image.c_str(), dev);
if (system(cmd) != 0) {
syslog(LOG_WARNING, "[%s] %s failed\n", __func__, cmd);
return FW_STATUS_FAILURE;
}
set_pfr_cap_ver_str(image, comp);
if (comp == "cpld_cap_rcvy") {
syslog(LOG_CRIT, "Updated CPLD Capsule, Target to Recovery Region on %s. File: %s", bmc_location_str.c_str(), image.c_str());
} else {
syslog(LOG_CRIT, "Updated CPLD Capsule, Target to Active Region on %s. File: %s", bmc_location_str.c_str(), image.c_str());
}
} else {
return FW_STATUS_NOT_SUPPORTED;
}
// Update Intent
i2cfd = open(path, O_RDWR);
if ( i2cfd < 0 ) {
syslog(LOG_WARNING, "%s() Failed to open %s", __func__, path);
return -1;
}
retry = 0;
tlen = 1;
while (retry < RETRY_TIME) {
ret = i2c_rdwr_msg_transfer(i2cfd, pfr_adress, tbuf, tlen, rdbuf, rlen);
if ( ret < 0 ) {
retry++;
msleep(100);
} else {
break;
}
}
intent_val_o = rdbuf[0];
if ( retry == RETRY_TIME ) {
if ( i2cfd > 0 ) close(i2cfd);
return -1;
}
tbuf[1] |= (intent_val_o | UPDATE_AT_RESET);
retry = 0;
tlen = 2;
while (retry < RETRY_TIME) {
ret = i2c_rdwr_msg_transfer(i2cfd, pfr_adress, tbuf, tlen, NULL, 0);
if ( ret < 0 ) {
retry++;
msleep(100);
} else {
break;
}
}
if ( i2cfd > 0 ) close(i2cfd);
if (retry == RETRY_TIME) {
syslog(LOG_WARNING, "%s() Failed to do i2c_rdwr_msg_transfer, tlen=%d", __func__, tlen);
return -1;
}
return 0;
}