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 void oce_fill_flash_img_data(POCE_SOFTC sc, const struct flash_sec_info * fsec, struct flash_img_attri *pimg, int i, const struct firmware *fw, int bin_offset) { if (IS_SH(sc)) { pimg->img_offset = HOST_32(fsec->fsec_entry[i].offset); pimg->img_size = HOST_32(fsec->fsec_entry[i].pad_size); } pimg->img_type = HOST_32(fsec->fsec_entry[i].type); pimg->skip_image = FALSE; switch (pimg->img_type) { case IMG_ISCSI: pimg->optype = 0; if (IS_BE3(sc)) { pimg->img_offset = 2097152; pimg->img_size = 2097152; } break; case IMG_REDBOOT: pimg->optype = 1; if (IS_BE3(sc)) { pimg->img_offset = 262144; pimg->img_size = 1048576; } if (!oce_img_flashing_required(sc, fw->data, pimg->optype, pimg->img_offset, pimg->img_size, bin_offset)) pimg->skip_image = TRUE; break; case IMG_BIOS: pimg->optype = 2; if (IS_BE3(sc)) { pimg->img_offset = 12582912; pimg->img_size = 524288; } break; case IMG_PXEBIOS: pimg->optype = 3; if (IS_BE3(sc)) { pimg->img_offset = 13107200;; pimg->img_size = 524288; } break; case IMG_FCOEBIOS: pimg->optype = 8; if (IS_BE3(sc)) { pimg->img_offset = 13631488; pimg->img_size = 524288; } break; case IMG_ISCSI_BAK: pimg->optype = 9; if (IS_BE3(sc)) { pimg->img_offset = 4194304; pimg->img_size = 2097152; } break; case IMG_FCOE: pimg->optype = 10; if (IS_BE3(sc)) { pimg->img_offset = 6291456; pimg->img_size = 2097152; } break; case IMG_FCOE_BAK: pimg->optype = 11; if (IS_BE3(sc)) { pimg->img_offset = 8388608; pimg->img_size = 2097152; } break; case IMG_NCSI: pimg->optype = 13; if (IS_BE3(sc)) { pimg->img_offset = 15990784; pimg->img_size = 262144; } break; case IMG_PHY: pimg->optype = 99; if (IS_BE3(sc)) { pimg->img_offset = 1310720; pimg->img_size = 262144; } if (!oce_phy_flashing_required(sc)) pimg->skip_image = TRUE; break; default: pimg->skip_image = TRUE; break; } }