Beispiel #1
0
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;
}
Beispiel #2
0
static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
{
	efx_oword_t reg;

	if ((falcon_rev(efx) != FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
		return;

	/* We expect xgmii faults if the wireside link is up */
	if (!EFX_WORKAROUND_5147(efx) || !efx->link_up)
		return;

	/* We can only use this interrupt to signal the negative edge of
	 * xaui_align [we have to poll the positive edge]. */
	if (!efx->mac_up)
		return;

	/* Flush the ISR */
	if (enable)
		falcon_read(efx, &reg, XM_MGT_INT_REG_B0);

	EFX_POPULATE_OWORD_2(reg,
			     XM_MSK_RMTFLT, !enable,
			     XM_MSK_LCLFLT, !enable);
	falcon_write(efx, &reg, XM_MGT_INT_MSK_REG_B0);
}
Beispiel #3
0
static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
{
	efx_oword_t reg;

	if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
		return;

	/* Flush the ISR */
	if (enable)
		falcon_read(efx, &reg, XM_MGT_INT_REG_B0);

	EFX_POPULATE_OWORD_2(reg,
			     XM_MSK_RMTFLT, !enable,
			     XM_MSK_LCLFLT, !enable);
	falcon_write(efx, &reg, XM_MGT_INT_MSK_REG_B0);
}
Beispiel #4
0
static bool falcon_xgmii_status(struct efx_nic *efx)
{
	efx_oword_t reg;

	if (falcon_rev(efx) < FALCON_REV_B0)
		return true;

	/* The ISR latches, so clear it and re-read */
	falcon_read(efx, &reg, XM_MGT_INT_REG_B0);
	falcon_read(efx, &reg, XM_MGT_INT_REG_B0);

	if (EFX_OWORD_FIELD(reg, XM_LCLFLT) ||
	    EFX_OWORD_FIELD(reg, XM_RMTFLT)) {
		EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
		return false;
	}

	return true;
}
Beispiel #5
0
static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
{
	efx_oword_t reg;

	if ((falcon_rev(efx) != FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
		return;

	
	if (!EFX_WORKAROUND_5147(efx) || !efx->link_up)
		return;

	
	if (!efx->mac_up)
		return;

	
	if (enable)
		falcon_read(efx, &reg, XM_MGT_INT_REG_B0);

	EFX_POPULATE_OWORD_2(reg,
			     XM_MSK_RMTFLT, !enable,
			     XM_MSK_LCLFLT, !enable);
	falcon_write(efx, &reg, XM_MGT_INT_MSK_REG_B0);
}