/* This call performs hardware-specific global initialisation, such as * defining the descriptor cache sizes and number of RSS channels. * It does not set up any buffers, descriptor rings or event queues. */ static int siena_init_nic(struct efx_nic *efx) { efx_oword_t temp; int rc; /* Recover from a failed assertion post-reset */ rc = efx_mcdi_handle_assertion(efx); if (rc) return rc; /* Squash TX of packets of 16 bytes or less */ efx_reado(efx, &temp, FR_AZ_TX_RESERVED); EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); /* Do not enable TX_NO_EOP_DISC_EN, since it limits packets to 16 * descriptors (which is bad). */ efx_reado(efx, &temp, FR_AZ_TX_CFG); EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_NO_EOP_DISC_EN, 0); EFX_SET_OWORD_FIELD(temp, FRF_CZ_TX_FILTER_EN_BIT, 1); efx_writeo(efx, &temp, FR_AZ_TX_CFG); efx_reado(efx, &temp, FR_AZ_RX_CFG); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_DESC_PUSH_EN, 0); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_INGR_EN, 1); /* Enable hash insertion. This is broken for the 'Falcon' hash * if IPv6 hashing is also enabled, so also select Toeplitz * TCP/IPv4 and IPv4 hashes. */ EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_HASH_INSRT_HDR, 1); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_HASH_ALG, 1); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_IP_HASH, 1); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_USR_BUF_SIZE, EFX_RX_USR_BUF_SIZE >> 5); efx_writeo(efx, &temp, FR_AZ_RX_CFG); siena_rx_push_rss_config(efx, false, efx->rss_context.rx_indir_table, NULL); efx->rss_context.context_id = 0; /* indicates RSS is active */ /* Enable event logging */ rc = efx_mcdi_log_ctrl(efx, true, false, 0); if (rc) return rc; /* Set destination of both TX and RX Flush events */ EFX_POPULATE_OWORD_1(temp, FRF_BZ_FLS_EVQ_ID, 0); efx_writeo(efx, &temp, FR_BZ_DP_CTRL); EFX_POPULATE_OWORD_1(temp, FRF_CZ_USREV_DIS, 1); efx_writeo(efx, &temp, FR_CZ_USR_EV_CFG); efx_farch_init_common(efx); return 0; }
static int siena_reset_hw(struct efx_nic *efx, enum reset_type method) { int rc; /* Recover from a failed assertion pre-reset */ rc = efx_mcdi_handle_assertion(efx); if (rc) return rc; if (method == RESET_TYPE_WORLD) return efx_mcdi_reset_mc(efx); else return efx_mcdi_reset_port(efx); }
/* This call performs hardware-specific global initialisation, such as * defining the descriptor cache sizes and number of RSS channels. * It does not set up any buffers, descriptor rings or event queues. */ static int siena_init_nic(struct efx_nic *efx) { efx_oword_t temp; int rc; /* Recover from a failed assertion post-reset */ rc = efx_mcdi_handle_assertion(efx); if (rc) return rc; /* Squash TX of packets of 16 bytes or less */ efx_reado(efx, &temp, FR_AZ_TX_RESERVED); EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); /* Do not enable TX_NO_EOP_DISC_EN, since it limits packets to 16 * descriptors (which is bad). */ efx_reado(efx, &temp, FR_AZ_TX_CFG); EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_NO_EOP_DISC_EN, 0); EFX_SET_OWORD_FIELD(temp, FRF_CZ_TX_FILTER_EN_BIT, 1); efx_writeo(efx, &temp, FR_AZ_TX_CFG); efx_reado(efx, &temp, FR_AZ_RX_CFG); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_DESC_PUSH_EN, 0); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_INGR_EN, 1); /* Enable hash insertion. This is broken for the 'Falcon' hash * if IPv6 hashing is also enabled, so also select Toeplitz * TCP/IPv4 and IPv4 hashes. */ EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_HASH_INSRT_HDR, 1); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_HASH_ALG, 1); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_IP_HASH, 1); efx_writeo(efx, &temp, FR_AZ_RX_CFG); /* Set hash key for IPv4 */ memcpy(&temp, efx->rx_hash_key, sizeof(temp)); efx_writeo(efx, &temp, FR_BZ_RX_RSS_TKEY); /* Enable IPv6 RSS */ BUILD_BUG_ON(sizeof(efx->rx_hash_key) < 2 * sizeof(temp) + FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8 || FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN != 0); memcpy(&temp, efx->rx_hash_key, sizeof(temp)); efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG1); memcpy(&temp, efx->rx_hash_key + sizeof(temp), sizeof(temp)); efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG2); EFX_POPULATE_OWORD_2(temp, FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1, FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, 1); memcpy(&temp, efx->rx_hash_key + 2 * sizeof(temp), FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8); efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG3); /* Enable event logging */ rc = efx_mcdi_log_ctrl(efx, true, false, 0); if (rc) return rc; /* Set destination of both TX and RX Flush events */ EFX_POPULATE_OWORD_1(temp, FRF_BZ_FLS_EVQ_ID, 0); efx_writeo(efx, &temp, FR_BZ_DP_CTRL); EFX_POPULATE_OWORD_1(temp, FRF_CZ_USREV_DIS, 1); efx_writeo(efx, &temp, FR_CZ_USR_EV_CFG); efx_nic_init_common(efx); return 0; }
static int siena_probe_nic(struct efx_nic *efx) { struct siena_nic_data *nic_data; bool already_attached = 0; efx_oword_t reg; int rc; /* Allocate storage for hardware specific data */ nic_data = kzalloc(sizeof(struct siena_nic_data), GFP_KERNEL); if (!nic_data) return -ENOMEM; efx->nic_data = nic_data; if (efx_nic_fpga_ver(efx) != 0) { netif_err(efx, probe, efx->net_dev, "Siena FPGA not supported\n"); rc = -ENODEV; goto fail1; } efx_reado(efx, ®, FR_AZ_CS_DEBUG); efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; /* Initialise MCDI */ nic_data->mcdi_smem = ioremap_nocache(efx->membase_phys + FR_CZ_MC_TREG_SMEM, FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS); if (!nic_data->mcdi_smem) { netif_err(efx, probe, efx->net_dev, "could not map MCDI at %llx+%x\n", (unsigned long long)efx->membase_phys + FR_CZ_MC_TREG_SMEM, FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS); rc = -ENOMEM; goto fail1; } efx_mcdi_init(efx); /* Recover from a failed assertion before probing */ rc = efx_mcdi_handle_assertion(efx); if (rc) goto fail2; /* Let the BMC know that the driver is now in charge of link and * filter settings. We must do this before we reset the NIC */ rc = efx_mcdi_drv_attach(efx, true, &already_attached); if (rc) { netif_err(efx, probe, efx->net_dev, "Unable to register driver with MCPU\n"); goto fail2; } if (already_attached) /* Not a fatal error */ netif_err(efx, probe, efx->net_dev, "Host already registered with MCPU\n"); /* Now we can reset the NIC */ rc = siena_reset_hw(efx, RESET_TYPE_ALL); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to reset NIC\n"); goto fail3; } siena_init_wol(efx); /* 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); netif_dbg(efx, probe, efx->net_dev, "INT_KER at %llx (virt %p phys %llx)\n", (unsigned long long)efx->irq_status.dma_addr, efx->irq_status.addr, (unsigned long long)virt_to_phys(efx->irq_status.addr)); /* Read in the non-volatile configuration */ rc = siena_probe_nvconfig(efx); if (rc == -EINVAL) { netif_err(efx, probe, efx->net_dev, "NVRAM is invalid therefore using defaults\n"); efx->phy_type = PHY_TYPE_NONE; efx->mdio.prtad = MDIO_PRTAD_NONE; } else if (rc) { goto fail5; } return 0; fail5: efx_nic_free_buffer(efx, &efx->irq_status); fail4: fail3: efx_mcdi_drv_attach(efx, false, NULL); fail2: iounmap(nic_data->mcdi_smem); fail1: kfree(efx->nic_data); return rc; }