/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails * to come back up. Bash it until it comes back up */ static bool falcon_check_xaui_link_up(struct efx_nic *efx) { int max_tries, tries; tries = EFX_WORKAROUND_5147(efx) ? 5 : 1; max_tries = tries; if ((efx->loopback_mode == LOOPBACK_NETWORK) || (efx->phy_type == PHY_TYPE_NONE) || efx_phy_mode_disabled(efx->phy_mode)) return false; while (tries) { if (falcon_xaui_link_ok(efx)) return true; EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n", __func__, tries); falcon_reset_xaui(efx); udelay(200); tries--; } EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n", max_tries); return false; }
static int efx_test_loopback(struct efx_tx_queue *tx_queue, struct efx_loopback_self_tests *lb_tests) { struct efx_nic *efx = tx_queue->efx; struct efx_loopback_state *state = efx->loopback_selftest; int i, begin_rc, end_rc; for (i = 0; i < 3; i++) { /* Determine how many packets to send */ state->packet_count = EFX_TXQ_SIZE / 3; state->packet_count = min(1 << (i << 2), state->packet_count); state->skbs = kzalloc(sizeof(state->skbs[0]) * state->packet_count, GFP_KERNEL); if (!state->skbs) return -ENOMEM; state->flush = false; EFX_LOG(efx, "TX queue %d testing %s loopback with %d " "packets\n", tx_queue->queue, LOOPBACK_MODE(efx), state->packet_count); efx_iterate_state(efx); begin_rc = efx_begin_loopback(tx_queue); /* This will normally complete very quickly, but be * prepared to wait up to 100 ms. */ msleep(1); if (!efx_poll_loopback(efx)) { msleep(100); efx_poll_loopback(efx); } end_rc = efx_end_loopback(tx_queue, lb_tests); kfree(state->skbs); if (begin_rc || end_rc) { /* Wait a while to ensure there are no packets * floating around after a failure. */ schedule_timeout_uninterruptible(HZ / 10); return begin_rc ? begin_rc : end_rc; } } EFX_LOG(efx, "TX queue %d passed %s loopback test with a burst length " "of %d packets\n", tx_queue->queue, LOOPBACK_MODE(efx), state->packet_count); return 0; }
void efx_init_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; unsigned int max_fill, trigger, limit; EFX_LOG(rx_queue->efx, "initialising RX queue %d\n", rx_queue->queue); /* Initialise ptr fields */ rx_queue->added_count = 0; rx_queue->notified_count = 0; rx_queue->removed_count = 0; rx_queue->min_fill = -1U; rx_queue->min_overfill = -1U; /* Initialise limit fields */ max_fill = efx->type->rxd_ring_mask + 1 - EFX_RXD_HEAD_ROOM; trigger = max_fill * min(rx_refill_threshold, 100U) / 100U; limit = max_fill * min(rx_refill_limit, 100U) / 100U; rx_queue->max_fill = max_fill; rx_queue->fast_fill_trigger = trigger; rx_queue->fast_fill_limit = limit; /* Set up RX descriptor ring */ falcon_init_rx(rx_queue); }
static void falcon_switch_mac(struct efx_nic *efx) { struct efx_mac_operations *old_mac_op = efx->mac_op; struct falcon_nic_data *nic_data = efx->nic_data; unsigned int stats_done_offset; WARN_ON(!mutex_is_locked(&efx->mac_lock)); WARN_ON(nic_data->stats_disable_count == 0); efx->mac_op = (EFX_IS10G(efx) ? &falcon_xmac_operations : &falcon_gmac_operations); if (EFX_IS10G(efx)) stats_done_offset = XgDmaDone_offset; else stats_done_offset = GDmaDone_offset; nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset; if (old_mac_op == efx->mac_op) return; falcon_clock_mac(efx); EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); /* Not all macs support a mac-level link state */ efx->xmac_poll_required = false; falcon_reset_macs(efx); }
void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) { int i; struct efx_rx_buffer *rx_buf; EFX_LOG(rx_queue->efx, "shutting down RX queue %d\n", rx_queue->queue); falcon_fini_rx(rx_queue); /* Release RX buffers NB start at index 0 not current HW ptr */ if (rx_queue->buffer) { for (i = 0; i <= rx_queue->efx->type->rxd_ring_mask; i++) { rx_buf = efx_rx_buffer(rx_queue, i); efx_fini_rx_buffer(rx_queue, rx_buf); } } /* For a page that is part-way through splitting into RX buffers */ if (rx_queue->buf_page != NULL) { pci_unmap_page(rx_queue->efx->pci_dev, rx_queue->buf_dma_addr, efx_rx_buf_size(rx_queue->efx), PCI_DMA_FROMDEVICE); __free_pages(rx_queue->buf_page, rx_queue->efx->rx_buffer_order); rx_queue->buf_page = NULL; } }
int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control) { bool reset; if (flow_control & EFX_FC_AUTO) { EFX_LOG(efx, "10G does not support flow control " "autonegotiation\n"); return -EINVAL; } if ((flow_control & EFX_FC_TX) && !(flow_control & EFX_FC_RX)) return -EINVAL; /* TX flow control may automatically turn itself off if the * link partner (intermittently) stops responding to pause * frames. There isn't any indication that this has happened, * so the best we do is leave it up to the user to spot this * and fix it be cycling transmit flow control on this end. */ reset = ((flow_control & EFX_FC_TX) && !(efx->flow_control & EFX_FC_TX)); if (EFX_WORKAROUND_11482(efx) && reset) { if (falcon_rev(efx) >= FALCON_REV_B0) { /* Recover by resetting the EM block */ if (efx->link_up) falcon_drain_tx_fifo(efx); } else { /* Schedule a reset to recover */ efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); } } efx->flow_control = flow_control; return 0; }
int efx_probe_tx_queue(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; unsigned int txq_size; int i, rc; EFX_LOG(efx, "creating TX queue %d\n", tx_queue->queue); /* Allocate software ring */ txq_size = (efx->type->txd_ring_mask + 1) * sizeof(*tx_queue->buffer); tx_queue->buffer = kzalloc(txq_size, GFP_KERNEL); if (!tx_queue->buffer) return -ENOMEM; for (i = 0; i <= efx->type->txd_ring_mask; ++i) tx_queue->buffer[i].continuation = true; /* Allocate hardware ring */ rc = falcon_probe_tx(tx_queue); if (rc) goto fail; return 0; fail: kfree(tx_queue->buffer); tx_queue->buffer = NULL; return rc; }
/* Extract non-volatile configuration */ static int falcon_probe_nvconfig(struct efx_nic *efx) { struct falcon_nvconfig *nvconfig; int board_rev; int rc; nvconfig = kmalloc(sizeof(*nvconfig), GFP_KERNEL); if (!nvconfig) return -ENOMEM; rc = falcon_read_nvram(efx, nvconfig); if (rc == -EINVAL) { EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n"); efx->phy_type = PHY_TYPE_NONE; efx->mdio.prtad = MDIO_PRTAD_NONE; board_rev = 0; rc = 0; } else if (rc) { goto fail1; } else { struct falcon_nvconfig_board_v2 *v2 = &nvconfig->board_v2; struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3; efx->phy_type = v2->port0_phy_type; efx->mdio.prtad = v2->port0_phy_addr; board_rev = le16_to_cpu(v2->board_revision); if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) { rc = falcon_spi_device_init( efx, &efx->spi_flash, FFE_AB_SPI_DEVICE_FLASH, le32_to_cpu(v3->spi_device_type [FFE_AB_SPI_DEVICE_FLASH])); if (rc) goto fail2; rc = falcon_spi_device_init( efx, &efx->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM, le32_to_cpu(v3->spi_device_type [FFE_AB_SPI_DEVICE_EEPROM])); if (rc) goto fail2; } } /* Read the MAC addresses */ memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN); EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad); falcon_probe_board(efx, board_rev); kfree(nvconfig); return 0; fail2: falcon_remove_spi_devices(efx); fail1: kfree(nvconfig); return rc; }
void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) { EFX_LOG(tx_queue->efx, "destroying TX queue %d\n", tx_queue->queue); falcon_remove_tx(tx_queue); kfree(tx_queue->buffer); tx_queue->buffer = NULL; }
static int efx_end_loopback(struct efx_tx_queue *tx_queue, struct efx_loopback_self_tests *lb_tests) { struct efx_nic *efx = tx_queue->efx; struct efx_loopback_state *state = efx->loopback_selftest; struct sk_buff *skb; int tx_done = 0, rx_good, rx_bad; int i, rc = 0; if (efx_dev_registered(efx)) netif_tx_lock_bh(efx->net_dev); /* Count the number of tx completions, and decrement the refcnt. Any * skbs not already completed will be free'd when the queue is flushed */ for (i=0; i < state->packet_count; i++) { skb = state->skbs[i]; if (skb && !skb_shared(skb)) ++tx_done; dev_kfree_skb_any(skb); } if (efx_dev_registered(efx)) netif_tx_unlock_bh(efx->net_dev); /* Check TX completion and received packet counts */ rx_good = atomic_read(&state->rx_good); rx_bad = atomic_read(&state->rx_bad); if (tx_done != state->packet_count) { /* Don't free the skbs; they will be picked up on TX * overflow or channel teardown. */ EFX_ERR(efx, "TX queue %d saw only %d out of an expected %d " "TX completion events in %s loopback test\n", tx_queue->queue, tx_done, state->packet_count, LOOPBACK_MODE(efx)); rc = -ETIMEDOUT; /* Allow to fall through so we see the RX errors as well */ } /* We may always be up to a flush away from our desired packet total */ if (rx_good != state->packet_count) { EFX_LOG(efx, "TX queue %d saw only %d out of an expected %d " "received packets in %s loopback test\n", tx_queue->queue, rx_good, state->packet_count, LOOPBACK_MODE(efx)); rc = -ETIMEDOUT; /* Fall through */ } /* Update loopback test structure */ lb_tests->tx_sent[tx_queue->queue] += state->packet_count; lb_tests->tx_done[tx_queue->queue] += tx_done; lb_tests->rx_good += rx_good; lb_tests->rx_bad += rx_bad; return rc; }
void efx_remove_rx_queue(struct efx_rx_queue *rx_queue) { EFX_LOG(rx_queue->efx, "destroying RX queue %d\n", rx_queue->queue); falcon_remove_rx(rx_queue); kfree(rx_queue->buffer); rx_queue->buffer = NULL; }
void efx_init_tx_queue(struct efx_tx_queue *tx_queue) { EFX_LOG(tx_queue->efx, "initialising TX queue %d\n", tx_queue->queue); tx_queue->insert_count = 0; tx_queue->write_count = 0; tx_queue->read_count = 0; tx_queue->old_read_count = 0; BUG_ON(tx_queue->stopped); /* Set up TX descriptor ring */ falcon_init_tx(tx_queue); }
/* This call is responsible for hooking in the MAC and PHY operations */ static int falcon_probe_port(struct efx_nic *efx) { int rc; switch (efx->phy_type) { case PHY_TYPE_SFX7101: efx->phy_op = &falcon_sfx7101_phy_ops; break; case PHY_TYPE_SFT9001A: case PHY_TYPE_SFT9001B: efx->phy_op = &falcon_sft9001_phy_ops; break; case PHY_TYPE_QT2022C2: case PHY_TYPE_QT2025C: efx->phy_op = &falcon_qt202x_phy_ops; break; default: EFX_ERR(efx, "Unknown PHY type %d\n", efx->phy_type); return -ENODEV; } /* Fill out MDIO structure and loopback modes */ efx->mdio.mdio_read = falcon_mdio_read; efx->mdio.mdio_write = falcon_mdio_write; rc = efx->phy_op->probe(efx); if (rc != 0) return rc; /* Initial assumption */ efx->link_state.speed = 10000; efx->link_state.fd = true; /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) efx->wanted_fc = EFX_FC_RX | EFX_FC_TX; else efx->wanted_fc = EFX_FC_RX; /* Allocate buffer for stats */ rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer, FALCON_MAC_STATS_SIZE); if (rc) return rc; EFX_LOG(efx, "stats buffer at %llx (virt %p phys %llx)\n", (u64)efx->stats_buffer.dma_addr, efx->stats_buffer.addr, (u64)virt_to_phys(efx->stats_buffer.addr)); return 0; }
int sft9001_wait_boot(struct efx_nic *efx) { unsigned long timeout = jiffies + HZ + 1; int boot_stat; for (;;) { boot_stat = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PCS, PCS_BOOT_STATUS_REG); if (boot_stat >= 0) { EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat); switch (boot_stat & ((1 << PCS_BOOT_FATAL_ERROR_LBN) | (3 << PCS_BOOT_PROGRESS_LBN) | (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) | (1 << PCS_BOOT_CODE_STARTED_LBN))) { case ((1 << PCS_BOOT_FATAL_ERROR_LBN) | (PCS_BOOT_PROGRESS_CHECKSUM << PCS_BOOT_PROGRESS_LBN)): case ((1 << PCS_BOOT_FATAL_ERROR_LBN) | (PCS_BOOT_PROGRESS_INIT << PCS_BOOT_PROGRESS_LBN) | (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)): return -EINVAL; case ((PCS_BOOT_PROGRESS_WAIT_MDIO << PCS_BOOT_PROGRESS_LBN) | (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)): return (efx->phy_mode & PHY_MODE_SPECIAL) ? 0 : -EIO; case ((PCS_BOOT_PROGRESS_JUMP << PCS_BOOT_PROGRESS_LBN) | (1 << PCS_BOOT_CODE_STARTED_LBN)): case ((PCS_BOOT_PROGRESS_JUMP << PCS_BOOT_PROGRESS_LBN) | (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) | (1 << PCS_BOOT_CODE_STARTED_LBN)): return (efx->phy_mode & PHY_MODE_SPECIAL) ? -EIO : 0; default: if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN)) return -EIO; break; } } if (time_after_eq(jiffies, timeout)) return -ETIMEDOUT; msleep(50); } }
/* Test generation and receipt of interrupts */ static int efx_test_interrupts(struct efx_nic *efx, struct efx_self_tests *tests) { struct efx_channel *channel; EFX_LOG(efx, "testing interrupts\n"); tests->interrupt = -1; /* Reset interrupt flag */ efx->last_irq_cpu = -1; smp_wmb(); /* ACK each interrupting event queue. Receiving an interrupt due to * traffic before a test event is raised is considered a pass */ efx_for_each_channel(channel, efx) { if (channel->work_pending) efx_process_channel_now(channel); if (efx->last_irq_cpu >= 0) goto success; } efx_nic_generate_interrupt(efx); /* Wait for arrival of test interrupt. */ EFX_LOG(efx, "waiting for test interrupt\n"); schedule_timeout_uninterruptible(HZ / 10); if (efx->last_irq_cpu >= 0) goto success; EFX_ERR(efx, "timed out waiting for interrupt\n"); return -ETIMEDOUT; success: EFX_LOG(efx, "%s test interrupt seen on CPU%d\n", INT_MODE(efx), efx->last_irq_cpu); tests->interrupt = 1; return 0; }
/* Probe all SPI devices on the NIC */ static void falcon_probe_spi_devices(struct efx_nic *efx) { efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg; int boot_dev; efx_reado(efx, &gpio_ctl, FR_AB_GPIO_CTL); efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); efx_reado(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0); if (EFX_OWORD_FIELD(gpio_ctl, FRF_AB_GPIO3_PWRUP_VALUE)) { boot_dev = (EFX_OWORD_FIELD(nic_stat, FRF_AB_SF_PRST) ? FFE_AB_SPI_DEVICE_FLASH : FFE_AB_SPI_DEVICE_EEPROM); EFX_LOG(efx, "Booted from %s\n", boot_dev == FFE_AB_SPI_DEVICE_FLASH ? "flash" : "EEPROM"); } else { /* Disable VPD and set clock dividers to safe * values for initial programming. */ boot_dev = -1; EFX_LOG(efx, "Booted from internal ASIC settings;" " setting SPI config\n"); EFX_POPULATE_OWORD_3(ee_vpd_cfg, FRF_AB_EE_VPD_EN, 0, /* 125 MHz / 7 ~= 20 MHz */ FRF_AB_EE_SF_CLOCK_DIV, 7, /* 125 MHz / 63 ~= 2 MHz */ FRF_AB_EE_EE_CLOCK_DIV, 63); efx_writeo(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0); } if (boot_dev == FFE_AB_SPI_DEVICE_FLASH) falcon_spi_device_init(efx, &efx->spi_flash, FFE_AB_SPI_DEVICE_FLASH, default_flash_type); if (boot_dev == FFE_AB_SPI_DEVICE_EEPROM) falcon_spi_device_init(efx, &efx->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM, large_eeprom_type); }
/* Zeroes out the SRAM contents. This routine must be called in * process context and is allowed to sleep. */ static int falcon_reset_sram(struct efx_nic *efx) { efx_oword_t srm_cfg_reg_ker, gpio_cfg_reg_ker; int count; /* Set the SRAM wake/sleep GPIO appropriately. */ efx_reado(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL); EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OEN, 1); EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OUT, 1); efx_writeo(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL); /* Initiate SRAM reset */ EFX_POPULATE_OWORD_2(srm_cfg_reg_ker, FRF_AZ_SRM_INIT_EN, 1, FRF_AZ_SRM_NB_SZ, 0); efx_writeo(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG); /* Wait for SRAM reset to complete */ count = 0; do { EFX_LOG(efx, "waiting for SRAM reset (attempt %d)...\n", count); /* SRAM reset is slow; expect around 16ms */ schedule_timeout_uninterruptible(HZ / 50); /* Check for reset complete */ efx_reado(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG); if (!EFX_OWORD_FIELD(srm_cfg_reg_ker, FRF_AZ_SRM_INIT_EN)) { EFX_LOG(efx, "SRAM reset complete\n"); return 0; } } while (++count < 20); /* wait upto 0.4 sec */ EFX_ERR(efx, "timed out waiting for SRAM reset\n"); return -ETIMEDOUT; }
/* Read an MDIO register of a PHY connected to Falcon. */ static int falcon_mdio_read(struct net_device *net_dev, int prtad, int devad, u16 addr) { struct efx_nic *efx = netdev_priv(net_dev); efx_oword_t reg; int rc; mutex_lock(&efx->mdio_lock); /* Check MDIO not currently being accessed */ rc = falcon_gmii_wait(efx); if (rc) goto out; EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_PHY_ADR, addr); efx_writeo(efx, ®, FR_AB_MD_PHY_ADR); EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_PRT_ADR, prtad, FRF_AB_MD_DEV_ADR, devad); efx_writeo(efx, ®, FR_AB_MD_ID); /* Request data to be read */ EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_RDC, 1, FRF_AB_MD_GC, 0); efx_writeo(efx, ®, FR_AB_MD_CS); /* Wait for data to become available */ rc = falcon_gmii_wait(efx); if (rc == 0) { efx_reado(efx, ®, FR_AB_MD_RXD); rc = EFX_OWORD_FIELD(reg, FRF_AB_MD_RXD); EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n", prtad, devad, addr, rc); } else { /* Abort the read operation */ EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_RIC, 0, FRF_AB_MD_GC, 1); efx_writeo(efx, ®, FR_AB_MD_CS); EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n", prtad, devad, addr, rc); } out: mutex_unlock(&efx->mdio_lock); return rc; }
void efx_fini_tx_queue(struct efx_tx_queue *tx_queue) { EFX_LOG(tx_queue->efx, "shutting down TX queue %d\n", tx_queue->queue); /* Flush TX queue, remove descriptor ring */ falcon_fini_tx(tx_queue); efx_release_tx_buffers(tx_queue); /* Free up TSO header cache */ efx_fini_tso(tx_queue); /* Release queue's stop on port, if any */ if (tx_queue->stopped) { tx_queue->stopped = 0; efx_wake_queue(tx_queue->efx); } }
static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries) { efx->mac_up = falcon_xaui_link_ok(efx); if ((efx->loopback_mode == LOOPBACK_NETWORK) || efx_phy_mode_disabled(efx->phy_mode)) return; while (!efx->mac_up && tries) { EFX_LOG(efx, "bashing xaui\n"); falcon_reset_xaui(efx); udelay(200); efx->mac_up = falcon_xaui_link_ok(efx); --tries; } }
int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; unsigned int rxq_size; int rc; EFX_LOG(efx, "creating RX queue %d\n", rx_queue->queue); /* Allocate RX buffers */ rxq_size = (efx->type->rxd_ring_mask + 1) * sizeof(*rx_queue->buffer); rx_queue->buffer = kzalloc(rxq_size, GFP_KERNEL); if (!rx_queue->buffer) return -ENOMEM; rc = falcon_probe_rx(rx_queue); if (rc) { kfree(rx_queue->buffer); rx_queue->buffer = NULL; } return rc; }
/* This must be called with rtnl_lock held. */ int efx_ethtool_set_settings(struct net_device *net_dev, struct ethtool_cmd *ecmd) { struct efx_nic *efx = netdev_priv(net_dev); int rc; /* Falcon GMAC does not support 1000Mbps HD */ if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" " setting\n"); return -EINVAL; } mutex_lock(&efx->mac_lock); rc = efx->phy_op->set_settings(efx, ecmd); mutex_unlock(&efx->mac_lock); if (!rc) efx_reconfigure_port(efx); return rc; }
/* Try to bring up the Falcon side of the Falcon-Phy XAUI link */ static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries) { bool mac_up = falcon_xmac_link_ok(efx); if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS || efx_phy_mode_disabled(efx->phy_mode)) /* XAUI link is expected to be down */ return mac_up; falcon_stop_nic_stats(efx); while (!mac_up && tries) { EFX_LOG(efx, "bashing xaui\n"); falcon_reset_xaui(efx); udelay(200); mac_up = falcon_xmac_link_ok(efx); --tries; } falcon_start_nic_stats(efx); return mac_up; }
/* Resets NIC to known state. This routine must be called in process * context and is allowed to sleep. */ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) { struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t glb_ctl_reg_ker; int rc; EFX_LOG(efx, "performing %s hardware reset\n", RESET_TYPE(method)); /* Initiate device reset */ if (method == RESET_TYPE_WORLD) { rc = pci_save_state(efx->pci_dev); if (rc) { EFX_ERR(efx, "failed to backup PCI state of primary " "function prior to hardware reset\n"); goto fail1; } if (efx_nic_is_dual_func(efx)) { rc = pci_save_state(nic_data->pci_dev2); if (rc) { EFX_ERR(efx, "failed to backup PCI state of " "secondary function prior to " "hardware reset\n"); goto fail2; } } EFX_POPULATE_OWORD_2(glb_ctl_reg_ker, FRF_AB_EXT_PHY_RST_DUR, FFE_AB_EXT_PHY_RST_DUR_10240US, FRF_AB_SWRST, 1); } else { EFX_POPULATE_OWORD_7(glb_ctl_reg_ker, /* exclude PHY from "invisible" reset */ FRF_AB_EXT_PHY_RST_CTL, method == RESET_TYPE_INVISIBLE, /* exclude EEPROM/flash and PCIe */ FRF_AB_PCIE_CORE_RST_CTL, 1, FRF_AB_PCIE_NSTKY_RST_CTL, 1, FRF_AB_PCIE_SD_RST_CTL, 1, FRF_AB_EE_RST_CTL, 1, FRF_AB_EXT_PHY_RST_DUR, FFE_AB_EXT_PHY_RST_DUR_10240US, FRF_AB_SWRST, 1); } efx_writeo(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL); EFX_LOG(efx, "waiting for hardware reset\n"); schedule_timeout_uninterruptible(HZ / 20); /* Restore PCI configuration if needed */ if (method == RESET_TYPE_WORLD) { if (efx_nic_is_dual_func(efx)) { rc = pci_restore_state(nic_data->pci_dev2); if (rc) { EFX_ERR(efx, "failed to restore PCI config for " "the secondary function\n"); goto fail3; } } rc = pci_restore_state(efx->pci_dev); if (rc) { EFX_ERR(efx, "failed to restore PCI config for the " "primary function\n"); goto fail4; } EFX_LOG(efx, "successfully restored PCI config\n"); } /* Assert that reset complete */ efx_reado(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL); if (EFX_OWORD_FIELD(glb_ctl_reg_ker, FRF_AB_SWRST) != 0) { rc = -ETIMEDOUT; EFX_ERR(efx, "timed out waiting for hardware reset\n"); goto fail5; } EFX_LOG(efx, "hardware reset complete\n"); return 0; /* pci_save_state() and pci_restore_state() MUST be called in pairs */ fail2: fail3: pci_restore_state(efx->pci_dev); fail1: fail4: fail5: 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; }
static void falcon_reset_macs(struct efx_nic *efx) { struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t reg, mac_ctrl; int count; if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) { /* It's not safe to use GLB_CTL_REG to reset the * macs, so instead use the internal MAC resets */ if (!EFX_IS10G(efx)) { EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 1); efx_writeo(efx, ®, FR_AB_GM_CFG1); udelay(1000); EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0); efx_writeo(efx, ®, FR_AB_GM_CFG1); udelay(1000); return; } else { EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1); efx_writeo(efx, ®, FR_AB_XM_GLB_CFG); for (count = 0; count < 10000; count++) { efx_reado(efx, ®, FR_AB_XM_GLB_CFG); if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) == 0) return; udelay(10); } EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); } } /* Mac stats will fail whist the TX fifo is draining */ WARN_ON(nic_data->stats_disable_count == 0); efx_reado(efx, &mac_ctrl, FR_AB_MAC_CTRL); EFX_SET_OWORD_FIELD(mac_ctrl, FRF_BB_TXFIFO_DRAIN_EN, 1); efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL); efx_reado(efx, ®, FR_AB_GLB_CTL); EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGTX, 1); EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGRX, 1); EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_EM, 1); efx_writeo(efx, ®, FR_AB_GLB_CTL); count = 0; while (1) { efx_reado(efx, ®, FR_AB_GLB_CTL); if (!EFX_OWORD_FIELD(reg, FRF_AB_RST_XGTX) && !EFX_OWORD_FIELD(reg, FRF_AB_RST_XGRX) && !EFX_OWORD_FIELD(reg, FRF_AB_RST_EM)) { EFX_LOG(efx, "Completed MAC reset after %d loops\n", count); break; } if (count > 20) { EFX_ERR(efx, "MAC reset failed\n"); break; } count++; udelay(10); } /* Ensure the correct MAC is selected before statistics * are re-enabled by the caller */ efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL); }
/* Test generation and receipt of interrupting events */ static int efx_test_eventq_irq(struct efx_channel *channel, struct efx_self_tests *tests) { unsigned int magic, count; /* Channel specific code, limited to 20 bits */ magic = (0x00010150 + channel->channel); EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n", channel->channel, magic); tests->eventq_dma[channel->channel] = -1; tests->eventq_int[channel->channel] = -1; tests->eventq_poll[channel->channel] = -1; /* Reset flag and zero magic word */ channel->efx->last_irq_cpu = -1; channel->eventq_magic = 0; smp_wmb(); efx_nic_generate_test_event(channel, magic); /* Wait for arrival of interrupt */ count = 0; do { schedule_timeout_uninterruptible(HZ / 100); if (channel->work_pending) efx_process_channel_now(channel); if (channel->eventq_magic == magic) goto eventq_ok; } while (++count < 2); EFX_ERR(channel->efx, "channel %d timed out waiting for event queue\n", channel->channel); /* See if interrupt arrived */ if (channel->efx->last_irq_cpu >= 0) { EFX_ERR(channel->efx, "channel %d saw interrupt on CPU%d " "during event queue test\n", channel->channel, raw_smp_processor_id()); tests->eventq_int[channel->channel] = 1; } /* Check to see if event was received even if interrupt wasn't */ efx_process_channel_now(channel); if (channel->eventq_magic == magic) { EFX_ERR(channel->efx, "channel %d event was generated, but " "failed to trigger an interrupt\n", channel->channel); tests->eventq_dma[channel->channel] = 1; } return -ETIMEDOUT; eventq_ok: EFX_LOG(channel->efx, "channel %d event queue passed\n", channel->channel); tests->eventq_dma[channel->channel] = 1; tests->eventq_int[channel->channel] = 1; tests->eventq_poll[channel->channel] = 1; return 0; }