static void sfe4001_poweroff(struct efx_nic *efx) { struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client; struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client; /* Turn off all power rails and disable outputs */ i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff); i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff); i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff); /* Clear any over-temperature alert */ i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL); }
static int efx_check_lm87(struct efx_nic *efx, unsigned mask) { struct i2c_client *client = falcon_board(efx)->hwmon_client; s32 alarms1, alarms2; /* If link is up then do not monitor temperature */ if (EFX_WORKAROUND_7884(efx) && efx->link_state.up) return 0; alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1); alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2); if (alarms1 < 0) return alarms1; if (alarms2 < 0) return alarms2; alarms1 &= mask; alarms2 &= mask >> 8; if (alarms1 || alarms2) { EFX_ERR(efx, "LM87 detected a hardware failure (status %02x:%02x)" "%s%s\n", alarms1, alarms2, (alarms1 & LM87_ALARM_TEMP_INT) ? " INTERNAL" : "", (alarms1 & LM87_ALARM_TEMP_EXT1) ? " EXTERNAL" : ""); return -ERANGE; } return 0; }
static void sfn4111t_fini(struct efx_nic *efx) { EFX_INFO(efx, "%s\n", __func__); device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); i2c_unregister_device(falcon_board(efx)->hwmon_client); }
int falcon_probe_board(struct efx_nic *efx, u16 revision_info) { struct falcon_board *board = falcon_board(efx); u8 type_id = FALCON_BOARD_TYPE(revision_info); int i; board->major = FALCON_BOARD_MAJOR(revision_info); board->minor = FALCON_BOARD_MINOR(revision_info); for (i = 0; i < ARRAY_SIZE(board_types); i++) if (board_types[i].id == type_id) board->type = &board_types[i]; if (board->type) { netif_info(efx, probe, efx->net_dev, "board is %s rev %c%d\n", (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC) ? board->type->ref_model : board->type->gen_type, 'A' + board->major, board->minor); return 0; } else { netif_err(efx, probe, efx->net_dev, "unknown board type %d\n", type_id); return -ENODEV; } }
static int sfe4001_check_hw(struct efx_nic *efx) { s32 status; /* If XAUI link is up then do not monitor */ if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required) return 0; /* Check the powered status of the PHY. Lack of power implies that * the MAX6647 has shut down power to it, probably due to a temp. * alarm. Reading the power status rather than the MAX6647 status * directly because the later is read-to-clear and would thus * start to power up the PHY again when polled, causing us to blip * the power undesirably. * We know we can read from the IO expander because we did * it during power-on. Assume failure now is bad news. */ status = i2c_smbus_read_byte_data(falcon_board(efx)->ioexp_client, P1_IN); if (status >= 0 && (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0) return 0; /* Use board power control, not PHY power control */ sfe4001_poweroff(efx); efx->phy_mode = PHY_MODE_OFF; return (status < 0) ? -EIO : -ERANGE; }
static int sfn4111t_init(struct efx_nic *efx) { struct falcon_board *board = falcon_board(efx); int rc; board->hwmon_client = i2c_new_device(&board->i2c_adap, (board->minor < 5) ? &sfn4111t_a0_hwmon_info : &sfn4111t_r5_hwmon_info); if (!board->hwmon_client) return -EIO; rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); if (rc) goto fail_hwmon; if (efx->phy_mode & PHY_MODE_SPECIAL) /* PHY may not generate a 156.25 MHz clock and MAC * stats fetch will fail. */ falcon_stop_nic_stats(efx); return 0; fail_hwmon: i2c_unregister_device(board->hwmon_client); return rc; }
static int tenxpress_phy_init(struct efx_nic *efx) { int rc; falcon_board(efx)->type->init_phy(efx); if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) return rc; rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) return rc; } rc = tenxpress_init(efx); if (rc < 0) return rc; /* Reinitialise flow control settings */ efx_link_set_wanted_fc(efx, efx->wanted_fc); efx_mdio_an_reconfigure(efx); schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ /* Let XGXS and SerDes out of reset */ falcon_reset_xaui(efx); return 0; }
static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, const u8 *reg_values) { struct falcon_board *board = falcon_board(efx); struct i2c_client *client = i2c_new_device(&board->i2c_adap, info); int rc; if (!client) return -EIO; while (*reg_values) { u8 reg = *reg_values++; u8 value = *reg_values++; rc = i2c_smbus_write_byte_data(client, reg, value); if (rc) goto err; } board->hwmon_client = client; return 0; err: i2c_unregister_device(client); return rc; }
static int efx_check_lm87(struct efx_nic *efx, unsigned mask) { struct i2c_client *client = falcon_board(efx)->hwmon_client; s32 alarms1, alarms2; /* If link is up then do not monitor temperature */ if (EFX_WORKAROUND_7884(efx) && efx->link_state.up) return 0; alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1); alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2); if (alarms1 < 0) return alarms1; if (alarms2 < 0) return alarms2; alarms1 &= mask; alarms2 &= mask >> 8; if (alarms1 || alarms2) { netif_err(efx, hw, efx->net_dev, "LM87 detected a hardware failure (status %02x:%02x)" "%s%s%s\n", alarms1, alarms2, (alarms1 & LM87_ALARM_TEMP_INT) ? "; board is overheating" : "", (alarms1 & LM87_ALARM_TEMP_EXT1) ? "; controller is overheating" : "", (alarms1 & ~(LM87_ALARM_TEMP_INT | LM87_ALARM_TEMP_EXT1) || alarms2) ? "; electrical fault" : ""); return -ERANGE; } return 0; }
static int sfn4111t_reset(struct efx_nic *efx) { struct falcon_board *board = falcon_board(efx); efx_oword_t reg; /* GPIO 3 and the GPIO register are shared with I2C, so block that */ i2c_lock_adapter(&board->i2c_adap); /* Pull RST_N (GPIO 2) low then let it up again, setting the * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the * output enables; the output levels should always be 0 (low) * and we rely on external pull-ups. */ efx_reado(efx, ®, FR_AB_GPIO_CTL); EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, true); efx_writeo(efx, ®, FR_AB_GPIO_CTL); msleep(1000); EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, false); EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN, !!(efx->phy_mode & PHY_MODE_SPECIAL)); efx_writeo(efx, ®, FR_AB_GPIO_CTL); msleep(1); i2c_unlock_adapter(&board->i2c_adap); ssleep(1); return 0; }
/* Set up the GPIO direction register */ void txc_set_gpio_dir(struct efx_nic *efx, int pin, int dir) { struct falcon_board *board = falcon_board(efx); if (board->minor < 3 && board->major == 0) return; efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, TXC_GPIO_DIR, 1 << pin, dir); }
static void sfe4001_fini(struct efx_nic *efx) { struct falcon_board *board = falcon_board(efx); EFX_INFO(efx, "%s\n", __func__); device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); sfe4001_poweroff(efx); i2c_unregister_device(board->ioexp_client); i2c_unregister_device(board->hwmon_client); }
static void sfe4003_init_phy(struct efx_nic *efx) { struct falcon_board *board = falcon_board(efx); /* The LEDs were not wired to GPIOs before A3 */ if (board->minor < 3 && board->major == 0) return; falcon_txc_set_gpio_dir(efx, SFE4003_RED_LED_GPIO, TXC_GPIO_DIR_OUTPUT); falcon_txc_set_gpio_val(efx, SFE4003_RED_LED_GPIO, SFE4003_LED_OFF); }
static int sfe4002_check_hw(struct efx_nic *efx) { struct falcon_board *board = falcon_board(efx); /* A0 board rev. 4002s report a temperature fault the whole time * (bad sensor) so we mask it out. */ unsigned alarm_mask = (board->major == 0 && board->minor == 0) ? ~LM87_ALARM_TEMP_EXT1 : ~0; return efx_check_lm87(efx, alarm_mask); }
static void sfe4003_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) { struct falcon_board *board = falcon_board(efx); /* The LEDs were not wired to GPIOs before A3 */ if (board->minor < 3 && board->major == 0) return; falcon_txc_set_gpio_val( efx, SFE4003_RED_LED_GPIO, (mode == EFX_LED_ON) ? SFE4003_LED_ON : SFE4003_LED_OFF); }
/* This board uses an I2C expander to provider power to the PHY, which needs to * be turned on before the PHY can be used. * Context: Process context, rtnl lock held */ static int sfe4001_init(struct efx_nic *efx) { struct falcon_board *board = falcon_board(efx); int rc; #if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE) board->hwmon_client = i2c_new_device(&board->i2c_adap, &sfe4001_hwmon_info); #else board->hwmon_client = i2c_new_dummy(&board->i2c_adap, sfe4001_hwmon_info.addr); #endif if (!board->hwmon_client) return -EIO; /* Raise board/PHY high limit from 85 to 90 degrees Celsius */ rc = i2c_smbus_write_byte_data(board->hwmon_client, MAX664X_REG_WLHO, 90); if (rc) goto fail_hwmon; board->ioexp_client = i2c_new_dummy(&board->i2c_adap, PCA9539); if (!board->ioexp_client) { rc = -EIO; goto fail_hwmon; } if (efx->phy_mode & PHY_MODE_SPECIAL) { /* PHY won't generate a 156.25 MHz clock and MAC stats fetch * will fail. */ falcon_stop_nic_stats(efx); } rc = sfe4001_poweron(efx); if (rc) goto fail_ioexp; rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); if (rc) goto fail_on; EFX_INFO(efx, "PHY is powered on\n"); return 0; fail_on: sfe4001_poweroff(efx); fail_ioexp: i2c_unregister_device(board->ioexp_client); fail_hwmon: i2c_unregister_device(board->hwmon_client); return rc; }
static int sfn4111t_check_hw(struct efx_nic *efx) { s32 status; /* If XAUI link is up then do not monitor */ if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required) return 0; /* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */ status = i2c_smbus_read_byte_data(falcon_board(efx)->hwmon_client, MAX664X_REG_RSL); if (status < 0) return -EIO; if (status & 0x57) return -ERANGE; return 0; }
/* Push the non-configurable defaults into the PHY. This must be * done after every full reset */ static void txc_apply_defaults(struct efx_nic *efx) { int mctrl; /* Turn amplitude down and preemphasis off on the host side * (PHY<->MAC) as this is believed less likely to upset Falcon * and no adverse effects have been noted. It probably also * saves a picowatt or two */ /* Turn off preemphasis */ efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE0, TXC_ATXPRE_NONE); efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE1, TXC_ATXPRE_NONE); /* Turn down the amplitude */ efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXAMP0, TXC_ATXAMP_0820_BOTH); efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXAMP1, TXC_ATXAMP_0820_BOTH); /* Set the line side amplitude and preemphasis to the databook * defaults as an erratum causes them to be 0 on at least some * PHY rev.s */ efx_mdio_write(efx, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXPRE0, TXC_ATXPRE_DEFAULT); efx_mdio_write(efx, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXPRE1, TXC_ATXPRE_DEFAULT); efx_mdio_write(efx, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXAMP0, TXC_ATXAMP_DEFAULT); efx_mdio_write(efx, MDIO_MMD_PMAPMD, TXC_ALRGS_ATXAMP1, TXC_ATXAMP_DEFAULT); /* Set up the LEDs */ mctrl = efx_mdio_read(efx, MDIO_MMD_PHYXS, TXC_MRGS_CTL); /* Set the Green and Red LEDs to their default modes */ mctrl &= ~((1 << TXC_MCTL_TXLED_LBN) | (1 << TXC_MCTL_RXLED_LBN)); efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_MRGS_CTL, mctrl); /* Databook recommends doing this after configuration changes */ txc_reset_logic(efx); falcon_board(efx)->type->init_phy(efx); }
static int tenxpress_phy_init(struct efx_nic *efx) { int rc; falcon_board(efx)->type->init_phy(efx); if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { if (efx->phy_type == PHY_TYPE_SFT9001A) { int reg; reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); reg |= (1 << PMA_PMD_EXT_SSR_LBN); efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); mdelay(200); } rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) return rc; rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); if (rc < 0) return rc; } rc = tenxpress_init(efx); if (rc < 0) return rc; /* Reinitialise flow control settings */ efx_link_set_wanted_fc(efx, efx->wanted_fc); efx_mdio_an_reconfigure(efx); schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ /* Let XGXS and SerDes out of reset */ falcon_reset_xaui(efx); return 0; }
static void falcon_monitor(struct efx_nic *efx) { bool link_changed; int rc; BUG_ON(!mutex_is_locked(&efx->mac_lock)); rc = falcon_board(efx)->type->monitor(efx); if (rc) { netif_err(efx, hw, efx->net_dev, "Board sensor %s; shutting down PHY\n", (rc == -ERANGE) ? "reported fault" : "failed"); efx->phy_mode |= PHY_MODE_LOW_POWER; rc = __efx_reconfigure_port(efx); WARN_ON(rc); } if (LOOPBACK_INTERNAL(efx)) link_changed = falcon_loopback_link_poll(efx); else link_changed = efx->phy_op->poll(efx); if (link_changed) { falcon_stop_nic_stats(efx); falcon_deconfigure_mac_wrapper(efx); falcon_reset_macs(efx); rc = falcon_reconfigure_xmac(efx); BUG_ON(rc); falcon_start_nic_stats(efx); efx_link_status_changed(efx); } falcon_poll_xmac(efx); }
static ssize_t set_phy_flash_cfg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); enum efx_phy_mode old_mode, new_mode; int err; rtnl_lock(); old_mode = efx->phy_mode; if (count == 0 || *buf == '0') new_mode = old_mode & ~PHY_MODE_SPECIAL; else new_mode = PHY_MODE_SPECIAL; if (old_mode == new_mode) { err = 0; } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { err = -EBUSY; } else { /* Reset the PHY, reconfigure the MAC and enable/disable * MAC stats accordingly. */ efx->phy_mode = new_mode; if (new_mode & PHY_MODE_SPECIAL) falcon_stop_nic_stats(efx); if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001) err = sfe4001_poweron(efx); else err = sfn4111t_reset(efx); if (!err) err = efx_reconfigure_port(efx); if (!(new_mode & PHY_MODE_SPECIAL)) falcon_start_nic_stats(efx); } rtnl_unlock(); return err ? err : count; }
static int falcon_probe_nic(struct efx_nic *efx) { struct falcon_nic_data *nic_data; struct falcon_board *board; int rc; nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); if (!nic_data) return -ENOMEM; efx->nic_data = nic_data; rc = -ENODEV; if (efx_nic_fpga_ver(efx) != 0) { netif_err(efx, probe, efx->net_dev, "Falcon FPGA not supported\n"); goto fail1; } if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { efx_oword_t nic_stat; struct pci_dev *dev; u8 pci_rev = efx->pci_dev->revision; if ((pci_rev == 0xff) || (pci_rev == 0)) { netif_err(efx, probe, efx->net_dev, "Falcon rev A0 not supported\n"); goto fail1; } efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) { netif_err(efx, probe, efx->net_dev, "Falcon rev A1 1G not supported\n"); goto fail1; } if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) { netif_err(efx, probe, efx->net_dev, "Falcon rev A1 PCI-X not supported\n"); goto fail1; } dev = pci_dev_get(efx->pci_dev); while ((dev = pci_get_device(PCI_VENDOR_ID_SOLARFLARE, PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, dev))) { if (dev->bus == efx->pci_dev->bus && dev->devfn == efx->pci_dev->devfn + 1) { nic_data->pci_dev2 = dev; break; } } if (!nic_data->pci_dev2) { netif_err(efx, probe, efx->net_dev, "failed to find secondary function\n"); rc = -ENODEV; goto fail2; } } rc = __falcon_reset_hw(efx, RESET_TYPE_ALL); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to reset NIC\n"); goto fail3; } rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t)); if (rc) goto fail4; BUG_ON(efx->irq_status.dma_addr & 0x0f); netif_dbg(efx, probe, efx->net_dev, "INT_KER at %llx (virt %p phys %llx)\n", (u64)efx->irq_status.dma_addr, efx->irq_status.addr, (u64)virt_to_phys(efx->irq_status.addr)); falcon_probe_spi_devices(efx); rc = falcon_probe_nvconfig(efx); if (rc) { if (rc == -EINVAL) netif_err(efx, probe, efx->net_dev, "NVRAM is invalid\n"); goto fail5; } efx->timer_quantum_ns = 4968; board = falcon_board(efx); board->i2c_adap.owner = THIS_MODULE; board->i2c_data = falcon_i2c_bit_operations; board->i2c_data.data = efx; board->i2c_adap.algo_data = &board->i2c_data; board->i2c_adap.dev.parent = &efx->pci_dev->dev; strlcpy(board->i2c_adap.name, "SFC4000 GPIO", sizeof(board->i2c_adap.name)); rc = i2c_bit_add_bus(&board->i2c_adap); if (rc) goto fail5; rc = falcon_board(efx)->type->init(efx); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to initialise board\n"); goto fail6; } nic_data->stats_disable_count = 1; setup_timer(&nic_data->stats_timer, &falcon_stats_timer_func, (unsigned long)efx); return 0; fail6: BUG_ON(i2c_del_adapter(&board->i2c_adap)); memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); fail5: efx_nic_free_buffer(efx, &efx->irq_status); fail4: fail3: if (nic_data->pci_dev2) { pci_dev_put(nic_data->pci_dev2); nic_data->pci_dev2 = NULL; } fail2: fail1: kfree(efx->nic_data); return rc; }
static void efx_fini_lm87(struct efx_nic *efx) { i2c_unregister_device(falcon_board(efx)->hwmon_client); }
static int sfe4001_poweron(struct efx_nic *efx) { struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client; struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client; unsigned int i, j; int rc; u8 out; /* Clear any previous over-temperature alert */ rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL); if (rc < 0) return rc; /* Enable port 0 and port 1 outputs on IO expander */ rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00); if (rc) return rc; rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff & ~(1 << P1_SPARE_LBN)); if (rc) goto fail_on; /* If PHY power is on, turn it all off and wait 1 second to * ensure a full reset. */ rc = i2c_smbus_read_byte_data(ioexp_client, P0_OUT); if (rc < 0) goto fail_on; out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) | (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) | (0 << P0_EN_1V0X_LBN)); if (rc != out) { EFX_INFO(efx, "power-cycling PHY\n"); rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); if (rc) goto fail_on; schedule_timeout_uninterruptible(HZ); } for (i = 0; i < 20; ++i) { /* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */ out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) | (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) | (1 << P0_X_TRST_LBN)); if (efx->phy_mode & PHY_MODE_SPECIAL) out |= 1 << P0_EN_3V3X_LBN; rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); if (rc) goto fail_on; msleep(10); /* Turn on 1V power rail */ out &= ~(1 << P0_EN_1V0X_LBN); rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); if (rc) goto fail_on; EFX_INFO(efx, "waiting for DSP boot (attempt %d)...\n", i); /* In flash config mode, DSP does not turn on AFE, so * just wait 1 second. */ if (efx->phy_mode & PHY_MODE_SPECIAL) { schedule_timeout_uninterruptible(HZ); return 0; } for (j = 0; j < 10; ++j) { msleep(100); /* Check DSP has asserted AFE power line */ rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN); if (rc < 0) goto fail_on; if (rc & (1 << P1_AFE_PWD_LBN)) return 0; } } EFX_INFO(efx, "timed out waiting for DSP boot\n"); rc = -ETIMEDOUT; fail_on: sfe4001_poweroff(efx); return rc; }
static int falcon_probe_nic(struct efx_nic *efx) { struct falcon_nic_data *nic_data; struct falcon_board *board; int rc; /* Allocate storage for hardware specific data */ nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); if (!nic_data) return -ENOMEM; efx->nic_data = nic_data; rc = -ENODEV; if (efx_nic_fpga_ver(efx) != 0) { EFX_ERR(efx, "Falcon FPGA not supported\n"); goto fail1; } if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { efx_oword_t nic_stat; struct pci_dev *dev; u8 pci_rev = efx->pci_dev->revision; if ((pci_rev == 0xff) || (pci_rev == 0)) { EFX_ERR(efx, "Falcon rev A0 not supported\n"); goto fail1; } efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) { EFX_ERR(efx, "Falcon rev A1 1G not supported\n"); goto fail1; } if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) { EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); goto fail1; } dev = pci_dev_get(efx->pci_dev); while ((dev = pci_get_device(EFX_VENDID_SFC, FALCON_A_S_DEVID, dev))) { if (dev->bus == efx->pci_dev->bus && dev->devfn == efx->pci_dev->devfn + 1) { nic_data->pci_dev2 = dev; break; } } if (!nic_data->pci_dev2) { EFX_ERR(efx, "failed to find secondary function\n"); rc = -ENODEV; goto fail2; } } /* Now we can reset the NIC */ rc = falcon_reset_hw(efx, RESET_TYPE_ALL); if (rc) { EFX_ERR(efx, "failed to reset NIC\n"); goto fail3; } /* Allocate memory for INT_KER */ rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t)); if (rc) goto fail4; BUG_ON(efx->irq_status.dma_addr & 0x0f); EFX_LOG(efx, "INT_KER at %llx (virt %p phys %llx)\n", (u64)efx->irq_status.dma_addr, efx->irq_status.addr, (u64)virt_to_phys(efx->irq_status.addr)); falcon_probe_spi_devices(efx); /* Read in the non-volatile configuration */ rc = falcon_probe_nvconfig(efx); if (rc) goto fail5; /* Initialise I2C adapter */ board = falcon_board(efx); board->i2c_adap.owner = THIS_MODULE; board->i2c_data = falcon_i2c_bit_operations; board->i2c_data.data = efx; board->i2c_adap.algo_data = &board->i2c_data; board->i2c_adap.dev.parent = &efx->pci_dev->dev; strlcpy(board->i2c_adap.name, "SFC4000 GPIO", sizeof(board->i2c_adap.name)); rc = i2c_bit_add_bus(&board->i2c_adap); if (rc) goto fail5; rc = falcon_board(efx)->type->init(efx); if (rc) { EFX_ERR(efx, "failed to initialise board\n"); goto fail6; } nic_data->stats_disable_count = 1; setup_timer(&nic_data->stats_timer, &falcon_stats_timer_func, (unsigned long)efx); return 0; fail6: BUG_ON(i2c_del_adapter(&board->i2c_adap)); memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); fail5: falcon_remove_spi_devices(efx); efx_nic_free_buffer(efx, &efx->irq_status); fail4: fail3: if (nic_data->pci_dev2) { pci_dev_put(nic_data->pci_dev2); nic_data->pci_dev2 = NULL; } fail2: fail1: kfree(efx->nic_data); return rc; }