/** * @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_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; }
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; }
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; }
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); }
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; }
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; } }