예제 #1
0
/**
 * @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;
}
예제 #2
0
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;
}
예제 #3
0
static int
oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
{
	char ufiname[256] = {0};
	uint32_t status = 1;
	struct oce_softc *sc  = (struct oce_softc *)arg1;
	const struct firmware *fw;

	status = sysctl_handle_string(oidp, ufiname, sizeof(ufiname), req);
	if (status || !req->newptr)
		return status;

	fw = firmware_get(ufiname);
	if (fw == NULL) {
		device_printf(sc->dev, "Unable to get Firmware. "
			"Make sure %s is copied to /boot/modules\n", ufiname);
		return ENOENT;
	}

	if (IS_BE(sc)) {
		if ((sc->flags & OCE_FLAGS_BE2)) {
			device_printf(sc->dev, 
				"Flashing not supported for BE2 yet.\n");
			status = 1;
			goto done;
		}
		status = oce_be3_fwupgrade(sc, fw);
	} else if (IS_SH(sc)) {
		status = oce_skyhawk_fwupgrade(sc,fw);
	} else
		status = oce_lancer_fwupgrade(sc, fw);
done:
	if (status) {
		device_printf(sc->dev, "Firmware Upgrade failed\n");
	} else {
		device_printf(sc->dev, "Firmware Flashed successfully\n");
	}

	/* Release Firmware*/
	firmware_put(fw, FIRMWARE_UNLOAD);

	return status;
}
예제 #4
0
int
oce_refresh_nic_stats(POCE_SOFTC sc)
{
	int rc = 0, reset = 0;

	if (IS_BE(sc) || IS_SH(sc)) {
		if (sc->flags & OCE_FLAGS_BE2) {
			rc = oce_mbox_get_nic_stats_v0(sc, &sc->stats_mem);
			if (!rc)
				copy_stats_to_sc_be2(sc);
		} else {
			rc = oce_mbox_get_nic_stats(sc, &sc->stats_mem);
			if (!rc)
				copy_stats_to_sc_be3(sc);
		}

	} else {
		rc = oce_mbox_get_pport_stats(sc, &sc->stats_mem, reset);
		if (!rc)
			copy_stats_to_sc_xe201(sc);
	}

	return rc;
}
예제 #5
0
static int oce_get_ufi_type(POCE_SOFTC sc,
			    const struct flash_file_hdr *fhdr)
{
	if (fhdr == NULL)
		goto be_get_ufi_exit;

	if (IS_SH(sc) && fhdr->build[0] == '4') {
		if (fhdr->asic_type_rev >= 0x10)
			return UFI_TYPE4R;
		else
			return UFI_TYPE4;
	} else if (IS_BE3(sc) && fhdr->build[0] == '3') {
		if (fhdr->asic_type_rev == 0x10)
			return UFI_TYPE3R;
		else
			return UFI_TYPE3;
	} else if (IS_BE2(sc) && fhdr->build[0] == '2')
		return UFI_TYPE2;

be_get_ufi_exit:
	device_printf(sc->dev,
		"UFI and Interface are not compatible for flashing\n");
	return -1;
}
예제 #6
0
void
oce_add_sysctls(POCE_SOFTC sc)
{

	struct sysctl_ctx_list *ctx = &sc->sysctl_ctx;
	struct sysctl_oid *tree = sc->sysctl_tree;
	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
	struct sysctl_oid *stats_node;

	SYSCTL_ADD_STRING(ctx, child,
			OID_AUTO, "component_revision",
			CTLTYPE_INT | CTLFLAG_RD,
			&component_revision,
			sizeof(component_revision),
			"EMULEX One-Connect device driver revision");

	SYSCTL_ADD_STRING(ctx, child,
			OID_AUTO, "firmware_version",
			CTLTYPE_INT | CTLFLAG_RD,
			&sc->fw_version,
			sizeof(sc->fw_version),
			"EMULEX One-Connect Firmware Version");

	SYSCTL_ADD_INT(ctx, child,
			OID_AUTO, "max_rsp_handled",
			CTLTYPE_INT | CTLFLAG_RW,
			&oce_max_rsp_handled,
			sizeof(oce_max_rsp_handled),
			"Maximum receive frames handled per interrupt");

	if ((sc->function_mode & FNM_FLEX10_MODE) ||
	    (sc->function_mode & FNM_UMC_MODE))
		SYSCTL_ADD_UINT(ctx, child,
				OID_AUTO, "speed",
				CTLFLAG_RD,
				&sc->qos_link_speed,
				0,"QOS Speed");
	else
		SYSCTL_ADD_UINT(ctx, child,
				OID_AUTO, "speed",
				CTLFLAG_RD,
				&sc->speed,
				0,"Link Speed");

	if (sc->function_mode & FNM_UMC_MODE)
		SYSCTL_ADD_UINT(ctx, child,
				OID_AUTO, "pvid",
				CTLFLAG_RD,
				&sc->pvid,
				0,"PVID");

	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "loop_back",
		CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
		oce_sysctl_loopback, "I", "Loop Back Tests");

	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fw_upgrade",
		CTLTYPE_STRING | CTLFLAG_RW, (void *)sc, 0,
		oce_sys_fwupgrade, "A", "Firmware ufi file");

        /*
         *  Dumps Transceiver data
	 *  "sysctl hw.oce0.sfp_vpd_dump=0"
         *  "sysctl -x hw.oce0.sfp_vpd_dump_buffer" for hex dump
         *  "sysctl -b hw.oce0.sfp_vpd_dump_buffer > sfp.bin" for binary dump
         */
	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "sfp_vpd_dump",
			CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, oce_sysctl_sfp_vpd_dump,
			"I", "Initiate a sfp_vpd_dump operation");
	SYSCTL_ADD_OPAQUE(ctx, child, OID_AUTO, "sfp_vpd_dump_buffer",
			CTLFLAG_RD, sfp_vpd_dump_buffer,
			TRANSCEIVER_DATA_SIZE, "IU", "Access sfp_vpd_dump buffer");

	stats_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats",
				CTLFLAG_RD, NULL, "Ethernet Statistics");

	if (IS_BE(sc) || IS_SH(sc))
		oce_add_stats_sysctls_be3(sc, ctx, stats_node);
	else
		oce_add_stats_sysctls_xe201(sc, ctx, stats_node);


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

}