static int oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs) { char cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "}; const char *p = (const char *)fw->data; const struct flash_sec_info *fsec = NULL; struct mbx_common_read_write_flashrom *req; int rc = 0, i, img_type, bin_offset = 0; boolean_t skip_image; uint32_t optype = 0, size = 0, start = 0, num_bytes = 0; uint32_t opcode = 0; OCE_DMA_MEM dma_mem; /* Validate Cookie */ bin_offset = (sizeof(struct flash_file_hdr) + (num_imgs * sizeof(struct image_hdr))); p += bin_offset; while (p < ((const char *)fw->data + fw->datasize)) { fsec = (const struct flash_sec_info *)p; if (!memcmp(cookie, fsec->cookie, sizeof(cookie))) break; fsec = NULL; p += 32; } if (!fsec) { device_printf(sc->dev, "Invalid Cookie. Firmware image corrupted ?\n"); return EINVAL; } rc = oce_dma_alloc(sc, sizeof(struct mbx_common_read_write_flashrom) + 32*1024, &dma_mem, 0); if (rc) { device_printf(sc->dev, "Memory allocation failure while flashing\n"); return ENOMEM; } req = OCE_DMAPTR(&dma_mem, struct mbx_common_read_write_flashrom); for (i = 0; i < MAX_FLASH_COMP; i++) { img_type = fsec->fsec_entry[i].type; skip_image = FALSE; switch (img_type) { case IMG_ISCSI: optype = 0; size = 2097152; start = 2097152; break; case IMG_REDBOOT: optype = 1; size = 1048576; start = 262144; if (!oce_img_flashing_required(sc, fw->data, optype, start, size, bin_offset)) skip_image = TRUE; break; case IMG_BIOS: optype = 2; size = 524288; start = 12582912; break; case IMG_PXEBIOS: optype = 3; size = 524288; start = 13107200; break; case IMG_FCOEBIOS: optype = 8; size = 524288; start = 13631488; break; case IMG_ISCSI_BAK: optype = 9; size = 2097152; start = 4194304; break; case IMG_FCOE: optype = 10; size = 2097152; start = 6291456; break; case IMG_FCOE_BAK: optype = 11; size = 2097152; start = 8388608; break; case IMG_NCSI: optype = 13; size = 262144; start = 15990784; break; case IMG_PHY: optype = 99; size = 262144; start = 1310720; if (!oce_phy_flashing_required(sc)) skip_image = TRUE; break; default: skip_image = TRUE; break; } if (skip_image) continue; p = fw->data; p = p + bin_offset + start; if ((p + size) > ((const char *)fw->data + fw->datasize)) { rc = 1; goto ret; } while (size) { if (size > 32*1024) num_bytes = 32*1024; else num_bytes = size; size -= num_bytes; if (!size) opcode = FLASHROM_OPER_FLASH; else opcode = FLASHROM_OPER_SAVE; memcpy(req->data_buffer, p, num_bytes); p += num_bytes; rc = oce_mbox_write_flashrom(sc, optype, opcode, &dma_mem, num_bytes); if (rc) { device_printf(sc->dev, "cmd to write to flash rom failed.\n"); rc = EIO; goto ret; } /* Leave the CPU for others for some time */ tsleep(oce_be3_flashdata, 0, "yield", 10); } } ret: oce_dma_free(sc, &dma_mem); return rc; }
static int oce_sh_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int32_t num_imgs) { char cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "}; const char *p = (const char *)fw->data; const struct flash_sec_info *fsec = NULL; struct mbx_common_read_write_flashrom *req; int rc = 0, i, bin_offset = 0, opcode, num_bytes; OCE_DMA_MEM dma_mem; struct flash_img_attri imgatt; /* Validate Cookie */ bin_offset = (sizeof(struct flash_file_hdr) + (num_imgs * sizeof(struct image_hdr))); p += bin_offset; while (p < ((const char *)fw->data + fw->datasize)) { fsec = (const struct flash_sec_info *)p; if (!memcmp(cookie, fsec->cookie, sizeof(cookie))) break; fsec = NULL; p += 32; } if (!fsec) { device_printf(sc->dev, "Invalid Cookie. Firmware image corrupted ?\n"); return EINVAL; } rc = oce_dma_alloc(sc, sizeof(struct mbx_common_read_write_flashrom), &dma_mem, 0); if (rc) { device_printf(sc->dev, "Memory allocation failure while flashing\n"); return ENOMEM; } req = OCE_DMAPTR(&dma_mem, struct mbx_common_read_write_flashrom); if (IS_SH(sc)) num_imgs = HOST_32(fsec->fsec_hdr.num_images); else if (IS_BE3(sc)) num_imgs = MAX_FLASH_COMP; for (i = 0; i < num_imgs; i++) { bzero(&imgatt, sizeof(struct flash_img_attri)); oce_fill_flash_img_data(sc, fsec, &imgatt, i, fw, bin_offset); if (imgatt.skip_image) continue; p = fw->data; p = p + bin_offset + imgatt.img_offset; if ((p + imgatt.img_size) > ((const char *)fw->data + fw->datasize)) { rc = 1; goto ret; } while (imgatt.img_size) { if (imgatt.img_size > 32*1024) num_bytes = 32*1024; else num_bytes = imgatt.img_size; imgatt.img_size -= num_bytes; if (!imgatt.img_size) opcode = FLASHROM_OPER_FLASH; else opcode = FLASHROM_OPER_SAVE; memcpy(req->data_buffer, p, num_bytes); p += num_bytes; rc = oce_mbox_write_flashrom(sc, imgatt.optype, opcode, &dma_mem, num_bytes); if (rc) { device_printf(sc->dev, "cmd to write to flash rom failed.\n"); rc = EIO; goto ret; } /* Leave the CPU for others for some time */ pause("yield", 10); } } ret: oce_dma_free(sc, &dma_mem); return rc; }