__checkReturn efx_rc_t siena_nic_init( __in efx_nic_t *enp) { efx_rc_t rc; EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); /* Enable reporting of some events (e.g. link change) */ if ((rc = efx_mcdi_log_ctrl(enp)) != 0) goto fail1; siena_sram_init(enp); /* Configure Siena's RX block */ siena_nic_rx_cfg(enp); /* Disable USR_EVents for now */ siena_nic_usrev_dis(enp); /* bug17057: Ensure set_link is called */ if ((rc = siena_phy_reconfigure(enp)) != 0) goto fail2; enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1; return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); }
/* 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; }
/* 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; }