static int oce_lancer_fwupgrade(POCE_SOFTC sc, const struct firmware *fw) { int rc = 0; OCE_DMA_MEM dma_mem; const uint8_t *data = NULL; uint8_t *dest_image_ptr = NULL; size_t size = 0; uint32_t data_written = 0, chunk_size = 0; uint32_t offset = 0, add_status = 0; if (!IS_ALIGNED(fw->datasize, sizeof(uint32_t))) { device_printf(sc->dev, "Lancer FW image is not 4 byte aligned."); return EINVAL; } rc = oce_dma_alloc(sc, 32*1024, &dma_mem, 0); if (rc) { device_printf(sc->dev, "Memory allocation failure while flashing Lancer\n"); return ENOMEM; } size = fw->datasize; data = fw->data; dest_image_ptr = OCE_DMAPTR(&dma_mem, uint8_t); while (size) { chunk_size = MIN(size, (32*1024)); bcopy(data, dest_image_ptr, chunk_size); rc = oce_mbox_lancer_write_flashrom(sc, chunk_size, offset, &dma_mem, &data_written, &add_status); if (rc) break; size -= data_written; data += data_written; offset += data_written; tsleep(oce_lancer_fwupgrade, 0, "yield", 10); } if (!rc) /* Commit the firmware*/ rc = oce_mbox_lancer_write_flashrom(sc, 0, offset, &dma_mem, &data_written, &add_status); if (rc) { device_printf(sc->dev, "Lancer firmware load error. " "Addstatus = 0x%x, status = %d \n", add_status, rc); rc = EIO; } oce_dma_free(sc, &dma_mem); return rc; }
/** * @brief Function for hardware initialization * @param sc software handle to the device */ int oce_hw_init(POCE_SOFTC sc) { int rc = 0; rc = oce_POST(sc); if (rc) return rc; /* create the bootstrap mailbox */ rc = oce_dma_alloc(sc, sizeof(struct oce_bmbx), &sc->bsmbx, 0); if (rc) { device_printf(sc->dev, "Mailbox alloc failed\n"); return rc; } rc = oce_reset_fun(sc); if (rc) goto error; rc = oce_mbox_init(sc); if (rc) goto error; rc = oce_get_fw_version(sc); if (rc) goto error; rc = oce_get_fw_config(sc); if (rc) goto error; sc->macaddr.size_of_struct = 6; rc = oce_read_mac_addr(sc, 0, 1, MAC_ADDRESS_TYPE_NETWORK, &sc->macaddr); if (rc) goto error; if ((IS_BE(sc) && (sc->flags & OCE_FLAGS_BE3)) || IS_SH(sc)) { rc = oce_mbox_check_native_mode(sc); if (rc) goto error; } else sc->be3_native = 0; return rc; error: oce_dma_free(sc, &sc->bsmbx); device_printf(sc->dev, "Hardware initialisation failed\n"); return rc; }
int oce_stats_init(POCE_SOFTC sc) { int rc = 0, sz; if (IS_BE(sc) || IS_SH(sc)) { if (sc->flags & OCE_FLAGS_BE2) sz = sizeof(struct mbx_get_nic_stats_v0); else sz = sizeof(struct mbx_get_nic_stats); } else sz = sizeof(struct mbx_get_pport_stats); rc = oce_dma_alloc(sc, sz, &sc->stats_mem, 0); return rc; }
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; }