예제 #1
0
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;

}
예제 #2
0
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;
	}

}